2011-10-15 13:25:57 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2013-05-07 18:32:06 +00:00
|
|
|
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
2017-10-22 00:48:25 +00:00
|
|
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
|
2023-11-05 12:19:51 +00:00
|
|
|
* Copyright (C) 2013-2023 CERN (www.cern.ch)
|
2024-04-17 18:31:50 +00:00
|
|
|
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
2011-10-15 13:25:57 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2021-06-15 13:24:55 +00:00
|
|
|
#include <symbol_library.h>
|
2012-01-23 04:33:36 +00:00
|
|
|
#include <confirm.h>
|
2023-03-12 14:49:57 +00:00
|
|
|
#include <common.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <connection_graph.h>
|
|
|
|
#include <dialog_migrate_buses.h>
|
|
|
|
#include <dialog_symbol_remap.h>
|
2023-10-30 06:34:45 +00:00
|
|
|
#include <dialog_import_choose_project.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <eeschema_settings.h>
|
2020-01-03 16:04:54 +00:00
|
|
|
#include <id.h>
|
2021-09-14 22:45:14 +00:00
|
|
|
#include <kiface_base.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <kiplatform/app.h>
|
2023-05-24 20:19:48 +00:00
|
|
|
#include <lockfile.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <pgm_base.h>
|
2023-09-07 11:22:10 +00:00
|
|
|
#include <core/profile.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <project/project_file.h>
|
2015-06-22 15:38:54 +00:00
|
|
|
#include <project_rescue.h>
|
2023-09-28 03:04:53 +00:00
|
|
|
#include <project_sch.h>
|
2021-03-31 21:33:30 +00:00
|
|
|
#include <dialog_HTML_reporter_base.h>
|
2023-12-19 17:39:26 +00:00
|
|
|
#include <io/common/plugin_common_choose_project.h>
|
2020-07-03 13:40:31 +00:00
|
|
|
#include <reporter.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <richio.h>
|
2021-11-25 17:12:01 +00:00
|
|
|
#include <sch_bus_entry.h>
|
2023-09-17 02:41:40 +00:00
|
|
|
#include <sch_commit.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <sch_edit_frame.h>
|
2023-12-24 00:31:24 +00:00
|
|
|
#include <sch_io/kicad_legacy/sch_io_kicad_legacy.h>
|
2021-01-31 17:25:38 +00:00
|
|
|
#include <sch_file_versions.h>
|
2021-11-25 17:12:01 +00:00
|
|
|
#include <sch_line.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <sch_sheet.h>
|
|
|
|
#include <sch_sheet_path.h>
|
|
|
|
#include <schematic.h>
|
|
|
|
#include <settings/settings_manager.h>
|
2023-03-03 22:36:07 +00:00
|
|
|
#include <sim/simulator_frame.h>
|
2019-06-04 12:46:02 +00:00
|
|
|
#include <tool/actions.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <tool/tool_manager.h>
|
2020-05-12 17:40:56 +00:00
|
|
|
#include <tools/sch_editor_control.h>
|
2022-06-02 21:56:17 +00:00
|
|
|
#include <tools/sch_navigate_tool.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <trace_helpers.h>
|
2024-05-04 15:27:52 +00:00
|
|
|
#include <widgets/filedlg_import_non_kicad.h>
|
2022-12-28 22:03:03 +00:00
|
|
|
#include <widgets/wx_infobar.h>
|
2020-08-23 19:01:08 +00:00
|
|
|
#include <wildcards_and_files_ext.h>
|
2021-02-22 23:47:17 +00:00
|
|
|
#include <drawing_sheet/ds_data_model.h>
|
2021-10-13 18:48:28 +00:00
|
|
|
#include <wx/app.h>
|
2020-12-12 18:11:51 +00:00
|
|
|
#include <wx/ffile.h>
|
2021-06-07 21:56:43 +00:00
|
|
|
#include <wx/filedlg.h>
|
|
|
|
#include <wx/log.h>
|
2024-04-27 19:57:24 +00:00
|
|
|
#include <wx/richmsgdlg.h>
|
2022-03-08 04:08:54 +00:00
|
|
|
#include <wx/stdpaths.h>
|
2024-02-13 17:18:46 +00:00
|
|
|
#include <tools/ee_actions.h>
|
2020-11-03 19:24:05 +00:00
|
|
|
#include <tools/ee_inspection_tool.h>
|
2024-02-13 17:18:46 +00:00
|
|
|
#include <tools/ee_selection_tool.h>
|
2021-01-23 04:17:32 +00:00
|
|
|
#include <paths.h>
|
2021-06-07 19:12:30 +00:00
|
|
|
#include <wx_filename.h> // For ::ResolvePossibleSymlinks
|
2021-08-14 20:05:21 +00:00
|
|
|
#include <widgets/wx_progress_reporters.h>
|
2022-09-03 18:29:02 +00:00
|
|
|
#include <widgets/wx_html_report_box.h>
|
2016-07-06 09:22:56 +00:00
|
|
|
|
2023-05-25 00:07:46 +00:00
|
|
|
#include <kiplatform/io.h>
|
|
|
|
|
2022-06-12 02:02:26 +00:00
|
|
|
#include "widgets/filedlg_hook_save_project.h"
|
2021-08-21 16:09:13 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
|
2013-01-24 17:46:37 +00:00
|
|
|
{
|
2023-06-29 10:34:04 +00:00
|
|
|
// ensure the splash screen does not obscure any dialog at startup
|
|
|
|
Pgm().HideSplash();
|
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// implement the pseudo code from KIWAY_PLAYER.h:
|
2020-03-25 15:27:15 +00:00
|
|
|
wxString msg;
|
|
|
|
|
2021-07-10 15:37:19 +00:00
|
|
|
EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
|
2020-04-16 16:43:50 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// This is for python:
|
|
|
|
if( aFileSet.size() != 1 )
|
2013-01-24 17:46:37 +00:00
|
|
|
{
|
2020-03-25 15:27:15 +00:00
|
|
|
msg.Printf( "Eeschema:%s() takes only a single filename.", __WXFUNCTION__ );
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
DisplayError( this, msg );
|
|
|
|
return false;
|
2013-01-24 17:46:37 +00:00
|
|
|
}
|
|
|
|
|
2021-08-31 21:38:45 +00:00
|
|
|
wxString fullFileName( aFileSet[0] );
|
|
|
|
wxFileName wx_filename( fullFileName );
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2018-09-15 21:35:32 +00:00
|
|
|
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
|
2023-10-12 13:36:28 +00:00
|
|
|
wxASSERT_MSG( wx_filename.IsAbsolute(), wxS( "Path is not absolute!" ) );
|
2018-09-15 21:35:32 +00:00
|
|
|
|
2014-09-07 19:01:26 +00:00
|
|
|
if( !LockFile( fullFileName ) )
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
{
|
2023-05-30 18:00:08 +00:00
|
|
|
msg.Printf( _( "Schematic '%s' is already open by '%s' at '%s'." ), fullFileName,
|
|
|
|
m_file_checker->GetUsername(), m_file_checker->GetHostname() );
|
2021-08-31 14:03:40 +00:00
|
|
|
|
2023-07-21 22:40:19 +00:00
|
|
|
if( !AskOverrideLock( this, msg ) )
|
2021-08-31 14:03:40 +00:00
|
|
|
return false;
|
2023-05-24 20:19:48 +00:00
|
|
|
|
2023-05-30 18:00:08 +00:00
|
|
|
m_file_checker->OverrideLock();
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
}
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2017-09-20 14:20:38 +00:00
|
|
|
if( !AskToSaveChanges() )
|
|
|
|
return false;
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2021-05-01 14:08:21 +00:00
|
|
|
#ifdef PROFILE
|
2022-09-17 18:43:46 +00:00
|
|
|
PROF_TIMER openFiles( "OpenProjectFile" );
|
2021-05-01 14:08:21 +00:00
|
|
|
#endif
|
2020-07-09 21:57:16 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
wxFileName pro = fullFileName;
|
2023-12-28 02:10:01 +00:00
|
|
|
pro.SetExt( FILEEXT::ProjectFileExtension );
|
2008-03-20 01:50:21 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
bool is_new = !wxFileName::IsFileReadable( fullFileName );
|
2008-03-20 01:50:21 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// If its a non-existent schematic and caller thinks it exists
|
|
|
|
if( is_new && !( aCtl & KICTL_CREATE ) )
|
2008-03-20 01:50:21 +00:00
|
|
|
{
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// notify user that fullFileName does not exist, ask if user wants to create it.
|
2021-06-16 22:35:00 +00:00
|
|
|
msg.Printf( _( "Schematic '%s' does not exist. Do you wish to create it?" ),
|
2020-03-25 15:27:15 +00:00
|
|
|
fullFileName );
|
|
|
|
|
|
|
|
if( !IsOK( this, msg ) )
|
2010-05-17 20:35:46 +00:00
|
|
|
return false;
|
2008-03-20 01:50:21 +00:00
|
|
|
}
|
|
|
|
|
2024-01-18 22:50:50 +00:00
|
|
|
wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGING );
|
|
|
|
ProcessEventLocally( e );
|
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// unload current project file before loading new
|
2008-03-20 01:50:21 +00:00
|
|
|
{
|
2021-09-14 23:41:25 +00:00
|
|
|
ClearUndoRedoList();
|
2018-12-11 14:15:47 +00:00
|
|
|
SetScreen( nullptr );
|
2023-04-12 10:50:56 +00:00
|
|
|
m_toolManager->GetTool<EE_INSPECTION_TOOL>()->Reset( TOOL_BASE::SUPERMODEL_RELOAD );
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
CreateScreens();
|
2008-03-20 01:50:21 +00:00
|
|
|
}
|
2009-04-06 18:54:57 +00:00
|
|
|
|
2010-03-16 18:22:59 +00:00
|
|
|
SetStatusText( wxEmptyString );
|
2021-01-31 17:25:38 +00:00
|
|
|
m_infoBar->Dismiss();
|
2008-03-20 01:50:21 +00:00
|
|
|
|
2021-06-26 19:17:34 +00:00
|
|
|
WX_PROGRESS_REPORTER progressReporter( this, is_new ? _( "Creating Schematic" )
|
|
|
|
: _( "Loading Schematic" ), 1 );
|
2020-07-03 03:42:36 +00:00
|
|
|
|
|
|
|
bool differentProject = pro.GetFullPath() != Prj().GetProjectFullName();
|
|
|
|
|
|
|
|
if( differentProject )
|
|
|
|
{
|
2020-08-25 02:17:21 +00:00
|
|
|
if( !Prj().IsNullProject() )
|
2024-02-25 22:39:14 +00:00
|
|
|
{
|
|
|
|
SaveProjectLocalSettings();
|
2020-08-25 02:17:21 +00:00
|
|
|
GetSettingsManager()->SaveProject();
|
2024-02-25 22:39:14 +00:00
|
|
|
}
|
2020-08-25 02:17:21 +00:00
|
|
|
|
2020-07-03 14:43:23 +00:00
|
|
|
Schematic().SetProject( nullptr );
|
2021-02-22 02:31:45 +00:00
|
|
|
GetSettingsManager()->UnloadProject( &Prj(), false );
|
2020-08-25 02:17:21 +00:00
|
|
|
|
2020-08-30 20:04:39 +00:00
|
|
|
GetSettingsManager()->LoadProject( pro.GetFullPath() );
|
|
|
|
|
2021-02-22 02:31:45 +00:00
|
|
|
wxFileName legacyPro( pro );
|
2023-12-28 02:10:01 +00:00
|
|
|
legacyPro.SetExt( FILEEXT::LegacyProjectFileExtension );
|
2021-02-22 02:31:45 +00:00
|
|
|
|
2020-08-30 20:04:39 +00:00
|
|
|
// Do not allow saving a project if one doesn't exist. This normally happens if we are
|
2020-10-06 02:13:06 +00:00
|
|
|
// standalone and opening a schematic that has been moved from its project folder.
|
2021-02-22 02:31:45 +00:00
|
|
|
if( !pro.Exists() && !legacyPro.Exists() && !( aCtl & KICTL_CREATE ) )
|
2020-08-30 20:04:39 +00:00
|
|
|
Prj().SetReadOnly();
|
2020-08-25 02:17:21 +00:00
|
|
|
|
2020-07-03 14:43:23 +00:00
|
|
|
CreateScreens();
|
2020-07-03 03:42:36 +00:00
|
|
|
}
|
|
|
|
|
2021-06-26 19:17:34 +00:00
|
|
|
SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( fullFileName );
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
2017-02-18 00:31:47 +00:00
|
|
|
{
|
2020-04-16 16:43:50 +00:00
|
|
|
// Don't reload the symbol libraries if we are just launching Eeschema from KiCad again.
|
|
|
|
// They are already saved in the kiface project object.
|
2021-06-15 12:31:28 +00:00
|
|
|
if( differentProject || !Prj().GetElem( PROJECT::ELEM_SCH_SYMBOL_LIBS ) )
|
2020-04-16 16:43:50 +00:00
|
|
|
{
|
|
|
|
// load the libraries here, not in SCH_SCREEN::Draw() which is a context
|
|
|
|
// that will not tolerate DisplayError() dialog since we're already in an
|
|
|
|
// event handler in there.
|
|
|
|
// And when a schematic file is loaded, we need these libs to initialize
|
|
|
|
// some parameters (links to PART LIB, dangling ends ...)
|
2021-06-15 12:31:28 +00:00
|
|
|
Prj().SetElem( PROJECT::ELEM_SCH_SYMBOL_LIBS, nullptr );
|
2023-09-28 03:04:53 +00:00
|
|
|
PROJECT_SCH::SchLibs( &Prj() );
|
2020-04-16 16:43:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No legacy symbol libraries including the cache are loaded with the new file format.
|
2021-06-15 12:31:28 +00:00
|
|
|
Prj().SetElem( PROJECT::ELEM_SCH_SYMBOL_LIBS, nullptr );
|
2017-02-18 00:31:47 +00:00
|
|
|
}
|
2014-08-18 16:39:51 +00:00
|
|
|
|
2017-03-05 22:31:31 +00:00
|
|
|
// Load the symbol library table, this will be used forever more.
|
2021-05-27 20:01:36 +00:00
|
|
|
Prj().SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, nullptr );
|
2023-09-28 03:04:53 +00:00
|
|
|
PROJECT_SCH::SchSymbolLibTable( &Prj() );
|
2017-03-05 22:31:31 +00:00
|
|
|
|
2020-06-08 02:19:46 +00:00
|
|
|
// Load project settings after schematic has been set up with the project link, since this will
|
|
|
|
// update some of the needed schematic settings such as drawing defaults
|
|
|
|
LoadProjectSettings();
|
2020-05-31 21:42:04 +00:00
|
|
|
|
2020-08-24 02:01:14 +00:00
|
|
|
wxFileName rfn( GetCurrentFileName() );
|
|
|
|
rfn.MakeRelativeTo( Prj().GetProjectPath() );
|
|
|
|
LoadWindowState( rfn.GetFullPath() );
|
|
|
|
|
2020-09-01 10:14:51 +00:00
|
|
|
KIPLATFORM::APP::SetShutdownBlockReason( this, _( "Schematic file changes are unsaved" ) );
|
|
|
|
|
2020-07-21 00:33:35 +00:00
|
|
|
if( Kiface().IsSingle() )
|
|
|
|
{
|
|
|
|
KIPLATFORM::APP::RegisterApplicationRestart( fullFileName );
|
|
|
|
}
|
2019-12-19 14:11:11 +00:00
|
|
|
|
2023-10-01 14:32:01 +00:00
|
|
|
if( is_new || schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
|
2008-03-20 01:50:21 +00:00
|
|
|
{
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// mark new, unsaved file as modified.
|
2021-05-28 19:07:04 +00:00
|
|
|
GetScreen()->SetContentModified();
|
2020-10-06 02:13:06 +00:00
|
|
|
GetScreen()->SetFileName( fullFileName );
|
2023-10-01 14:32:01 +00:00
|
|
|
|
|
|
|
if( schFileType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
|
|
|
|
{
|
|
|
|
msg.Printf( _( "Unsupported schematic file '%s'." ), fullFileName );
|
|
|
|
progressReporter.Hide();
|
|
|
|
DisplayErrorMessage( this, msg );
|
|
|
|
}
|
2008-03-20 01:50:21 +00:00
|
|
|
}
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
else
|
|
|
|
{
|
2021-10-13 18:48:28 +00:00
|
|
|
wxFileName autoSaveFn = fullFileName;
|
|
|
|
|
|
|
|
autoSaveFn.SetName( getAutoSaveFileName() );
|
|
|
|
autoSaveFn.ClearExt();
|
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
if( ( aCtl & KICTL_REVERT ) )
|
|
|
|
{
|
2023-11-20 07:47:33 +00:00
|
|
|
DeleteAutoSaveFile( autoSaveFn );
|
2023-11-05 12:19:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This will rename the file if there is an autosave and the user wants to recover
|
|
|
|
CheckForAutoSaveFile( autoSaveFn );
|
|
|
|
}
|
2020-09-01 20:52:05 +00:00
|
|
|
|
2018-12-11 14:15:47 +00:00
|
|
|
SetScreen( nullptr );
|
2019-03-11 21:32:05 +00:00
|
|
|
|
2023-12-27 20:39:29 +00:00
|
|
|
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( schFileType ) );
|
2016-07-06 09:22:56 +00:00
|
|
|
|
2021-06-23 22:53:08 +00:00
|
|
|
pi->SetProgressReporter( &progressReporter );
|
|
|
|
|
2021-05-01 17:11:10 +00:00
|
|
|
bool failedLoad = false;
|
2021-06-30 15:06:07 +00:00
|
|
|
|
2016-07-06 09:22:56 +00:00
|
|
|
try
|
|
|
|
{
|
2022-10-11 11:36:15 +00:00
|
|
|
{
|
|
|
|
wxBusyCursor busy;
|
2023-08-26 19:28:53 +00:00
|
|
|
Schematic().SetRoot( pi->LoadSchematicFile( fullFileName, &Schematic() ) );
|
2024-05-23 11:59:45 +00:00
|
|
|
|
2023-11-27 18:44:49 +00:00
|
|
|
// Make ${SHEETNAME} work on the root sheet until we properly support
|
|
|
|
// naming the root sheet
|
|
|
|
Schematic().Root().SetName( _( "Root" ) );
|
2024-05-23 11:59:45 +00:00
|
|
|
wxLogTrace( tracePathsAndFiles, wxS( "Loaded schematic with root sheet UUID %s" ),
|
|
|
|
Schematic().Root().m_Uuid.AsString() );
|
2022-10-11 11:36:15 +00:00
|
|
|
}
|
2019-03-11 21:32:05 +00:00
|
|
|
|
2017-12-07 00:10:45 +00:00
|
|
|
if( !pi->GetError().IsEmpty() )
|
|
|
|
{
|
2021-06-30 15:06:07 +00:00
|
|
|
DisplayErrorMessage( this, _( "The entire schematic could not be loaded. Errors "
|
|
|
|
"occurred attempting to load hierarchical sheets." ),
|
2017-12-07 00:10:45 +00:00
|
|
|
pi->GetError() );
|
|
|
|
}
|
2016-07-06 09:22:56 +00:00
|
|
|
}
|
2021-06-30 15:06:07 +00:00
|
|
|
catch( const FUTURE_FORMAT_ERROR& ffe )
|
|
|
|
{
|
|
|
|
msg.Printf( _( "Error loading schematic '%s'." ), fullFileName);
|
|
|
|
progressReporter.Hide();
|
|
|
|
DisplayErrorMessage( this, msg, ffe.Problem() );
|
|
|
|
|
|
|
|
failedLoad = true;
|
|
|
|
}
|
2016-07-06 09:22:56 +00:00
|
|
|
catch( const IO_ERROR& ioe )
|
2021-05-01 17:11:10 +00:00
|
|
|
{
|
2021-06-08 14:52:49 +00:00
|
|
|
msg.Printf( _( "Error loading schematic '%s'." ), fullFileName);
|
2021-06-30 15:06:07 +00:00
|
|
|
progressReporter.Hide();
|
2021-05-01 17:11:10 +00:00
|
|
|
DisplayErrorMessage( this, msg, ioe.What() );
|
|
|
|
|
|
|
|
failedLoad = true;
|
|
|
|
}
|
|
|
|
catch( const std::bad_alloc& )
|
|
|
|
{
|
2021-06-26 11:33:37 +00:00
|
|
|
msg.Printf( _( "Memory exhausted loading schematic '%s'." ), fullFileName );
|
2021-06-30 15:06:07 +00:00
|
|
|
progressReporter.Hide();
|
|
|
|
DisplayErrorMessage( this, msg, wxEmptyString );
|
2021-05-01 17:11:10 +00:00
|
|
|
|
|
|
|
failedLoad = true;
|
|
|
|
}
|
|
|
|
|
2021-09-16 19:27:29 +00:00
|
|
|
// This fixes a focus issue after the progress reporter is done on GTK. It shouldn't
|
|
|
|
// cause any issues on macOS and Windows. If it does, it will have to be conditionally
|
|
|
|
// compiled.
|
|
|
|
Raise();
|
|
|
|
|
2021-05-01 17:11:10 +00:00
|
|
|
if( failedLoad )
|
2016-07-06 09:22:56 +00:00
|
|
|
{
|
2017-03-06 20:30:51 +00:00
|
|
|
// Do not leave g_RootSheet == NULL because it is expected to be
|
|
|
|
// a valid sheet. Therefore create a dummy empty root sheet and screen.
|
|
|
|
CreateScreens();
|
2023-06-26 22:16:51 +00:00
|
|
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen );
|
2017-03-06 20:30:51 +00:00
|
|
|
|
2021-06-08 14:52:49 +00:00
|
|
|
msg.Printf( _( "Failed to load '%s'." ), fullFileName );
|
2020-12-08 05:27:34 +00:00
|
|
|
SetMsgPanel( wxEmptyString, msg );
|
2016-07-07 13:09:32 +00:00
|
|
|
|
2016-07-06 09:22:56 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-04-04 14:57:26 +00:00
|
|
|
|
2017-03-30 19:44:47 +00:00
|
|
|
// It's possible the schematic parser fixed errors due to bugs so warn the user
|
|
|
|
// that the schematic has been fixed (modified).
|
2020-05-13 02:00:37 +00:00
|
|
|
SCH_SHEET_LIST sheetList = Schematic().GetSheets();
|
2017-03-30 19:44:47 +00:00
|
|
|
|
|
|
|
if( sheetList.IsModified() )
|
|
|
|
{
|
|
|
|
DisplayInfoMessage( this,
|
|
|
|
_( "An error was found when loading the schematic that has "
|
|
|
|
"been automatically fixed. Please save the schematic to "
|
|
|
|
"repair the broken file or it may not be usable with other "
|
|
|
|
"versions of KiCad." ) );
|
|
|
|
}
|
2008-03-20 01:50:21 +00:00
|
|
|
|
2020-10-18 20:30:37 +00:00
|
|
|
if( sheetList.AllSheetPageNumbersEmpty() )
|
|
|
|
sheetList.SetInitialPageNumbers();
|
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
UpdateFileHistory( fullFileName );
|
2015-04-25 22:26:51 +00:00
|
|
|
|
2020-05-13 02:00:37 +00:00
|
|
|
SCH_SCREENS schematic( Schematic().Root() );
|
2017-03-05 18:18:26 +00:00
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
// LIB_ID checks and symbol rescue only apply to the legacy file formats.
|
|
|
|
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
2017-09-01 20:42:20 +00:00
|
|
|
{
|
2021-11-25 17:12:01 +00:00
|
|
|
// Convert any legacy bus-bus entries to just be bus wires
|
|
|
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
|
|
|
{
|
|
|
|
std::vector<SCH_ITEM*> deleted;
|
|
|
|
|
|
|
|
for( SCH_ITEM* item : screen->Items() )
|
|
|
|
{
|
|
|
|
if( item->Type() == SCH_BUS_BUS_ENTRY_T )
|
|
|
|
{
|
|
|
|
SCH_BUS_BUS_ENTRY* entry = static_cast<SCH_BUS_BUS_ENTRY*>( item );
|
|
|
|
std::unique_ptr<SCH_LINE> wire = std::make_unique<SCH_LINE>();
|
|
|
|
|
|
|
|
wire->SetLayer( LAYER_BUS );
|
|
|
|
wire->SetStartPoint( entry->GetPosition() );
|
|
|
|
wire->SetEndPoint( entry->GetEnd() );
|
|
|
|
|
|
|
|
screen->Append( wire.release() );
|
|
|
|
deleted.push_back( item );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for( SCH_ITEM* item : deleted )
|
|
|
|
screen->Remove( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
// Convert old projects over to use symbol library table.
|
|
|
|
if( schematic.HasNoFullyDefinedLibIds() )
|
|
|
|
{
|
|
|
|
DIALOG_SYMBOL_REMAP dlgRemap( this );
|
2017-09-01 20:42:20 +00:00
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
dlgRemap.ShowQuasiModal();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Double check to ensure no legacy library list entries have been
|
2021-10-13 18:48:28 +00:00
|
|
|
// added to the project file symbol library list.
|
2020-04-16 16:43:50 +00:00
|
|
|
wxString paths;
|
|
|
|
wxArrayString libNames;
|
2019-08-01 17:26:21 +00:00
|
|
|
|
2022-10-11 10:22:09 +00:00
|
|
|
SYMBOL_LIBS::GetLibNamesAndPaths( &Prj(), &paths, &libNames );
|
2019-08-01 17:26:21 +00:00
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
if( !libNames.IsEmpty() )
|
2019-08-01 17:26:21 +00:00
|
|
|
{
|
2020-04-16 16:43:50 +00:00
|
|
|
if( eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog )
|
|
|
|
{
|
|
|
|
wxRichMessageDialog invalidLibDlg(
|
|
|
|
this,
|
|
|
|
_( "Illegal entry found in project file symbol library list." ),
|
|
|
|
_( "Project Load Warning" ),
|
|
|
|
wxOK | wxCENTER | wxICON_EXCLAMATION );
|
|
|
|
invalidLibDlg.ShowDetailedText(
|
|
|
|
_( "Symbol libraries defined in the project file symbol library "
|
2021-03-10 14:52:41 +00:00
|
|
|
"list are no longer supported and will be removed.\n\n"
|
|
|
|
"This may cause broken symbol library links under certain "
|
|
|
|
"conditions." ) );
|
2020-04-16 16:43:50 +00:00
|
|
|
invalidLibDlg.ShowCheckBox( _( "Do not show this dialog again." ) );
|
|
|
|
invalidLibDlg.ShowModal();
|
|
|
|
eeconfig()->m_Appearance.show_illegal_symbol_lib_dialog =
|
|
|
|
!invalidLibDlg.IsCheckBoxChecked();
|
|
|
|
}
|
|
|
|
|
|
|
|
libNames.Clear();
|
|
|
|
paths.Clear();
|
2022-10-11 10:22:09 +00:00
|
|
|
SYMBOL_LIBS::SetLibNamesAndPaths( &Prj(), paths, libNames );
|
2019-08-01 17:26:21 +00:00
|
|
|
}
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
if( !cfg || !cfg->m_RescueNeverShow )
|
2020-05-12 17:12:38 +00:00
|
|
|
{
|
|
|
|
SCH_EDITOR_CONTROL* editor = m_toolManager->GetTool<SCH_EDITOR_CONTROL>();
|
|
|
|
editor->RescueSymbolLibTableProject( false );
|
|
|
|
}
|
2019-08-01 17:26:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-10 14:52:41 +00:00
|
|
|
// Ensure there is only one legacy library loaded and that it is the cache library.
|
2023-09-28 03:04:53 +00:00
|
|
|
SYMBOL_LIBS* legacyLibs = PROJECT_SCH::SchLibs( &Schematic().Prj() );
|
2021-03-10 14:52:41 +00:00
|
|
|
|
|
|
|
if( legacyLibs->GetLibraryCount() == 0 )
|
|
|
|
{
|
|
|
|
wxString extMsg;
|
|
|
|
wxFileName cacheFn = pro;
|
|
|
|
|
|
|
|
cacheFn.SetName( cacheFn.GetName() + "-cache" );
|
2023-12-28 02:10:01 +00:00
|
|
|
cacheFn.SetExt( FILEEXT::LegacySymbolLibFileExtension );
|
2021-03-10 14:52:41 +00:00
|
|
|
|
|
|
|
msg.Printf( _( "The project symbol library cache file '%s' was not found." ),
|
|
|
|
cacheFn.GetFullName() );
|
|
|
|
extMsg = _( "This can result in a broken schematic under certain conditions. "
|
|
|
|
"If the schematic does not have any missing symbols upon opening, "
|
|
|
|
"save it immediately before making any changes to prevent data "
|
|
|
|
"loss. If there are missing symbols, either manual recovery of "
|
|
|
|
"the schematic or recovery of the symbol cache library file and "
|
|
|
|
"reloading the schematic is required." );
|
|
|
|
|
|
|
|
wxMessageDialog dlgMissingCache( this, msg, _( "Warning" ),
|
|
|
|
wxOK | wxCANCEL | wxICON_EXCLAMATION | wxCENTER );
|
|
|
|
dlgMissingCache.SetExtendedMessage( extMsg );
|
|
|
|
dlgMissingCache.SetOKCancelLabels(
|
|
|
|
wxMessageDialog::ButtonLabel( _( "Load Without Cache File" ) ),
|
|
|
|
wxMessageDialog::ButtonLabel( _( "Abort" ) ) );
|
|
|
|
|
|
|
|
if( dlgMissingCache.ShowModal() == wxID_CANCEL )
|
|
|
|
{
|
|
|
|
Schematic().Reset();
|
|
|
|
CreateScreens();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
// Update all symbol library links for all sheets.
|
|
|
|
schematic.UpdateSymbolLinks();
|
2017-10-22 00:48:25 +00:00
|
|
|
|
2021-01-31 17:25:38 +00:00
|
|
|
m_infoBar->RemoveAllButtons();
|
|
|
|
m_infoBar->AddCloseButton();
|
|
|
|
m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
|
|
|
|
"It will be converted to the new format when saved." ),
|
2021-02-16 23:42:39 +00:00
|
|
|
wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
|
2020-04-16 16:43:50 +00:00
|
|
|
|
2020-05-19 15:01:00 +00:00
|
|
|
// Legacy schematic can have duplicate time stamps so fix that before converting
|
|
|
|
// to the s-expression format.
|
|
|
|
schematic.ReplaceDuplicateTimeStamps();
|
|
|
|
|
2023-02-20 17:55:02 +00:00
|
|
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
|
|
|
screen->FixLegacyPowerSymbolMismatches();
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
// Allow the schematic to be saved to new file format without making any edits.
|
|
|
|
OnModify();
|
|
|
|
}
|
|
|
|
else // S-expression schematic.
|
|
|
|
{
|
2021-01-31 17:25:38 +00:00
|
|
|
if( schematic.GetFirst()->GetFileFormatVersionAtLoad() < SEXPR_SCHEMATIC_FILE_VERSION )
|
|
|
|
{
|
|
|
|
m_infoBar->RemoveAllButtons();
|
|
|
|
m_infoBar->AddCloseButton();
|
|
|
|
m_infoBar->ShowMessage( _( "This file was created by an older version of KiCad. "
|
|
|
|
"It will be converted to the new format when saved." ),
|
2021-02-16 23:42:39 +00:00
|
|
|
wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
|
2021-01-31 17:25:38 +00:00
|
|
|
}
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
|
|
|
screen->UpdateLocalLibSymbolLinks();
|
2020-04-26 20:53:29 +00:00
|
|
|
|
2020-10-18 20:30:37 +00:00
|
|
|
// Restore all of the loaded symbol and sheet instances from the root sheet.
|
2022-10-01 12:44:21 +00:00
|
|
|
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221002 )
|
2022-12-06 14:00:11 +00:00
|
|
|
sheetList.UpdateSymbolInstanceData( Schematic().RootScreen()->GetSymbolInstances());
|
2022-10-01 12:44:21 +00:00
|
|
|
|
2022-11-22 19:35:27 +00:00
|
|
|
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20221110 )
|
2022-12-06 14:00:11 +00:00
|
|
|
sheetList.UpdateSheetInstanceData( Schematic().RootScreen()->GetSheetInstances());
|
2022-12-07 01:34:10 +00:00
|
|
|
|
2023-02-20 17:55:02 +00:00
|
|
|
if( Schematic().RootScreen()->GetFileFormatVersionAtLoad() < 20230221 )
|
|
|
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
|
|
|
screen->FixLegacyPowerSymbolMismatches();
|
|
|
|
|
2022-12-07 23:40:05 +00:00
|
|
|
for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
|
|
|
|
screen->MigrateSimModels();
|
2023-11-18 20:26:56 +00:00
|
|
|
|
2023-11-19 23:33:10 +00:00
|
|
|
if( schematic.GetFirst()->GetFileFormatVersionAtLoad() < SEXPR_SCHEMATIC_FILE_VERSION )
|
|
|
|
{
|
|
|
|
// Allow the schematic to be saved to new file format without making any edits.
|
|
|
|
OnModify();
|
|
|
|
}
|
2017-10-22 00:48:25 +00:00
|
|
|
}
|
2017-09-01 20:42:20 +00:00
|
|
|
|
2023-12-03 12:47:57 +00:00
|
|
|
schematic.PruneOrphanedSymbolInstances( Prj().GetProjectName(), Schematic().GetSheets() );
|
2023-12-28 17:18:54 +00:00
|
|
|
schematic.PruneOrphanedSheetInstances( Prj().GetProjectName(), Schematic().GetSheets() );
|
2023-12-03 12:47:57 +00:00
|
|
|
|
2020-05-13 02:00:37 +00:00
|
|
|
Schematic().ConnectionGraph()->Reset();
|
2020-02-04 22:37:14 +00:00
|
|
|
|
2020-05-13 02:00:37 +00:00
|
|
|
SetScreen( GetCurrentSheet().LastScreen() );
|
2017-11-27 19:27:24 +00:00
|
|
|
|
2019-03-11 21:32:05 +00:00
|
|
|
// Migrate conflicting bus definitions
|
|
|
|
// TODO(JE) This should only run once based on schematic file version
|
2020-05-13 02:00:37 +00:00
|
|
|
if( Schematic().ConnectionGraph()->GetBusesNeedingMigration().size() > 0 )
|
2019-03-11 21:32:05 +00:00
|
|
|
{
|
|
|
|
DIALOG_MIGRATE_BUSES dlg( this );
|
|
|
|
dlg.ShowQuasiModal();
|
|
|
|
OnModify();
|
|
|
|
}
|
|
|
|
|
2023-09-17 02:41:40 +00:00
|
|
|
SCH_COMMIT dummy( this );
|
|
|
|
|
|
|
|
RecalculateConnections( &dummy, GLOBAL_CLEANUP );
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
}
|
2011-04-17 17:11:53 +00:00
|
|
|
|
2020-11-19 18:22:26 +00:00
|
|
|
// Load any exclusions from the project file
|
2023-08-13 23:50:05 +00:00
|
|
|
Schematic().ResolveERCExclusionsPostUpdate();
|
2020-11-19 18:22:26 +00:00
|
|
|
|
Mark null project initial screen as zoom-initialized
The variable `m_Initialized` in `BASE_SCREEN` is used by
`SCH_EDIT_FRAME` to mark whether a screen had its zoom level initialized
by the "zoom to fit screen" action. When this variable is `false`, the
function `SCH_EDIT_FRAME::DisplayCurrentSheet()` performs "zoom to fit
screen", modifying the zoom level. This function is indirectly called in
the undo routines, so if `m_Initialized` is not set to `true`, a zoom
change will occur when the user undoes an operation, a behavior that is
undesired.
`m_Initialized` was not initialized to `true` for the null schematic
(the schematic that is loaded if no project is loaded), causing the
aforementioned undesired behavior.
To prevent this, I've changed the `SCH_EDIT_FRAME` constructor to set
`m_Initialized` to `true`, since it zooms to fit screen already. I've
moved `m_Initialized` from `BASE_SCREEN` to `SCH_SCREEN`, as it is used
only in Eeschema, and renamed it to `m_zoomInitialized`, a name I
believe that better describes what this variable does.
I've also introduced the function `SCH_EDIT_FRAME::initScreenZoom()` to
group the "zoom to fit screen" action with setting `m_Initialized` to
`true`, as they often should occur together.
I'd also like to say that I'm not confident whether
`SCH_EDIT_FRAME::DisplayCurrentSheet()` should perform the zoom level
initialization at this point, but I have decided to not change this
behavior for now, as the commit history suggests it's several years old.
Fixes https://gitlab.com/kicad/code/kicad/issues/7343
2021-01-30 22:47:39 +00:00
|
|
|
initScreenZoom();
|
2008-04-30 17:04:22 +00:00
|
|
|
SetSheetNumberAndCount();
|
2019-06-23 15:12:25 +00:00
|
|
|
|
2022-12-03 13:25:20 +00:00
|
|
|
RecomputeIntersheetRefs();
|
2021-04-30 16:54:15 +00:00
|
|
|
GetCurrentSheet().UpdateAllScreenReferences();
|
2020-11-19 19:21:15 +00:00
|
|
|
|
2022-08-18 21:19:28 +00:00
|
|
|
// Re-create junctions if needed. Eeschema optimizes wires by merging
|
2019-06-23 15:12:25 +00:00
|
|
|
// colinear segments. If a schematic is saved without a valid
|
|
|
|
// cache library or missing installed libraries, this can cause connectivity errors
|
|
|
|
// unless junctions are added.
|
2022-08-18 21:19:28 +00:00
|
|
|
//
|
2023-12-24 00:31:24 +00:00
|
|
|
// TODO: (RFB) This really needs to be put inside the Load() function of the SCH_IO_KICAD_LEGACY
|
2022-08-18 21:19:28 +00:00
|
|
|
// I can't put it right now because of the extra code that is above to convert legacy bus-bus
|
|
|
|
// entries to bus wires
|
2021-03-29 18:14:48 +00:00
|
|
|
if( schFileType == SCH_IO_MGR::SCH_LEGACY )
|
2022-08-18 21:19:28 +00:00
|
|
|
Schematic().FixupJunctions();
|
2019-06-23 15:12:25 +00:00
|
|
|
|
2018-08-03 12:18:26 +00:00
|
|
|
SyncView();
|
2017-12-19 00:05:18 +00:00
|
|
|
GetScreen()->ClearDrawingState();
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
|
2022-06-30 21:57:23 +00:00
|
|
|
TestDanglingEnds();
|
|
|
|
|
2024-04-17 18:31:50 +00:00
|
|
|
UpdateHierarchyNavigator( false );
|
2023-06-10 22:05:01 +00:00
|
|
|
|
2024-01-18 22:50:50 +00:00
|
|
|
wxCommandEvent changedEvt( EDA_EVT_SCHEMATIC_CHANGED );
|
|
|
|
ProcessEventLocally( changedEvt );
|
2023-06-10 22:05:01 +00:00
|
|
|
|
|
|
|
for( wxEvtHandler* listener : m_schematicChangeListeners )
|
|
|
|
{
|
|
|
|
wxCHECK2( listener, continue );
|
|
|
|
|
|
|
|
// Use the windows variant when handling event messages in case there is any special
|
|
|
|
// event handler pre and/or post processing specific to windows.
|
|
|
|
wxWindow* win = dynamic_cast<wxWindow*>( listener );
|
|
|
|
|
|
|
|
if( win )
|
|
|
|
win->HandleWindowEvent( e );
|
|
|
|
else
|
|
|
|
listener->SafelyProcessEvent( e );
|
|
|
|
}
|
|
|
|
|
2023-01-12 00:05:43 +00:00
|
|
|
updateTitle();
|
2022-06-02 21:56:17 +00:00
|
|
|
m_toolManager->GetTool<SCH_NAVIGATE_TOOL>()->ResetHistory();
|
2019-03-15 12:09:04 +00:00
|
|
|
|
2020-05-18 23:44:58 +00:00
|
|
|
wxFileName fn = Prj().AbsolutePath( GetScreen()->GetFileName() );
|
|
|
|
|
|
|
|
if( fn.FileExists() && !fn.IsFileWritable() )
|
|
|
|
{
|
|
|
|
m_infoBar->RemoveAllButtons();
|
|
|
|
m_infoBar->AddCloseButton();
|
2022-09-10 20:26:25 +00:00
|
|
|
m_infoBar->ShowMessage( _( "Schematic is read only." ),
|
|
|
|
wxICON_WARNING, WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE );
|
2020-05-18 23:44:58 +00:00
|
|
|
}
|
|
|
|
|
2020-07-09 21:57:16 +00:00
|
|
|
#ifdef PROFILE
|
|
|
|
openFiles.Show();
|
|
|
|
#endif
|
2023-12-05 08:58:25 +00:00
|
|
|
// Ensure all items are redrawn (especially the drawing-sheet items):
|
|
|
|
if( GetCanvas() )
|
|
|
|
GetCanvas()->DisplaySheet( GetCurrentSheet().LastScreen() );
|
2020-07-09 21:57:16 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2008-07-18 07:04:43 +00:00
|
|
|
|
|
|
|
|
2017-11-17 17:00:04 +00:00
|
|
|
bool SCH_EDIT_FRAME::AppendSchematic()
|
2013-01-24 17:46:37 +00:00
|
|
|
{
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
SCH_SCREEN* screen = GetScreen();
|
2013-01-24 17:46:37 +00:00
|
|
|
|
|
|
|
if( !screen )
|
|
|
|
{
|
2023-10-12 13:36:28 +00:00
|
|
|
wxLogError( wxS( "Document not ready, cannot import" ) );
|
2013-01-24 17:46:37 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// open file chooser dialog
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
wxString path = wxPathOnly( Prj().GetProjectFullName() );
|
|
|
|
|
2021-06-18 20:23:09 +00:00
|
|
|
wxFileDialog dlg( this, _( "Insert Schematic" ), path, wxEmptyString,
|
2023-12-28 02:10:01 +00:00
|
|
|
FILEEXT::KiCadSchematicFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST );
|
2013-01-24 17:46:37 +00:00
|
|
|
|
|
|
|
if( dlg.ShowModal() == wxID_CANCEL )
|
|
|
|
return false;
|
|
|
|
|
2022-09-14 22:28:09 +00:00
|
|
|
return AddSheetAndUpdateDisplay( dlg.GetPath() );
|
|
|
|
}
|
|
|
|
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2022-09-14 22:28:09 +00:00
|
|
|
bool SCH_EDIT_FRAME::AddSheetAndUpdateDisplay( const wxString aFullFileName )
|
|
|
|
{
|
2024-02-13 17:18:46 +00:00
|
|
|
SCH_COMMIT commit( m_toolManager );
|
|
|
|
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
|
|
|
|
|
|
|
|
selectionTool->ClearSelection();
|
|
|
|
|
|
|
|
// Mark all existing items on the screen so we don't select them after appending
|
|
|
|
for( EDA_ITEM* item : GetScreen()->Items() )
|
|
|
|
item->SetFlags( SKIP_STRUCT );
|
|
|
|
|
2022-09-14 22:28:09 +00:00
|
|
|
if( !LoadSheetFromFile( GetCurrentSheet().Last(), &GetCurrentSheet(), aFullFileName ) )
|
2017-11-17 17:00:04 +00:00
|
|
|
return false;
|
|
|
|
|
Mark null project initial screen as zoom-initialized
The variable `m_Initialized` in `BASE_SCREEN` is used by
`SCH_EDIT_FRAME` to mark whether a screen had its zoom level initialized
by the "zoom to fit screen" action. When this variable is `false`, the
function `SCH_EDIT_FRAME::DisplayCurrentSheet()` performs "zoom to fit
screen", modifying the zoom level. This function is indirectly called in
the undo routines, so if `m_Initialized` is not set to `true`, a zoom
change will occur when the user undoes an operation, a behavior that is
undesired.
`m_Initialized` was not initialized to `true` for the null schematic
(the schematic that is loaded if no project is loaded), causing the
aforementioned undesired behavior.
To prevent this, I've changed the `SCH_EDIT_FRAME` constructor to set
`m_Initialized` to `true`, since it zooms to fit screen already. I've
moved `m_Initialized` from `BASE_SCREEN` to `SCH_SCREEN`, as it is used
only in Eeschema, and renamed it to `m_zoomInitialized`, a name I
believe that better describes what this variable does.
I've also introduced the function `SCH_EDIT_FRAME::initScreenZoom()` to
group the "zoom to fit screen" action with setting `m_Initialized` to
`true`, as they often should occur together.
I'd also like to say that I'm not confident whether
`SCH_EDIT_FRAME::DisplayCurrentSheet()` should perform the zoom level
initialization at this point, but I have decided to not change this
behavior for now, as the commit history suggests it's several years old.
Fixes https://gitlab.com/kicad/code/kicad/issues/7343
2021-01-30 22:47:39 +00:00
|
|
|
initScreenZoom();
|
2013-01-24 17:46:37 +00:00
|
|
|
SetSheetNumberAndCount();
|
2018-10-18 09:50:43 +00:00
|
|
|
|
2018-08-03 12:18:26 +00:00
|
|
|
SyncView();
|
2018-10-18 09:50:43 +00:00
|
|
|
OnModify();
|
2020-12-06 21:23:16 +00:00
|
|
|
HardRedraw(); // Full reinit of the current screen and the display.
|
2018-08-03 12:18:26 +00:00
|
|
|
|
2024-02-13 17:18:46 +00:00
|
|
|
// Select all new items
|
|
|
|
for( EDA_ITEM* item : GetScreen()->Items() )
|
|
|
|
{
|
|
|
|
if( !item->HasFlag( SKIP_STRUCT ) )
|
|
|
|
{
|
|
|
|
commit.Added( item, GetScreen() );
|
|
|
|
selectionTool->AddItemToSel( item );
|
|
|
|
|
|
|
|
if( item->Type() == SCH_LINE_T )
|
|
|
|
item->SetFlags( STARTPOINT | ENDPOINT );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
item->ClearFlags( SKIP_STRUCT );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start moving selection, cancel undoes the insertion
|
|
|
|
if( !m_toolManager->RunSynchronousAction( EE_ACTIONS::move, &commit ) )
|
|
|
|
commit.Revert();
|
|
|
|
else
|
|
|
|
commit.Push( _( "Import Schematic Sheet Content..." ) );
|
|
|
|
|
2021-06-13 16:15:02 +00:00
|
|
|
UpdateHierarchyNavigator();
|
|
|
|
|
2017-11-17 17:00:04 +00:00
|
|
|
return true;
|
2013-01-24 17:46:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event )
|
|
|
|
{
|
2017-11-17 17:00:04 +00:00
|
|
|
if( GetScreen() && GetScreen()->IsModified() )
|
|
|
|
{
|
|
|
|
wxString msg = _( "This operation cannot be undone.\n\n"
|
|
|
|
"Do you want to save the current document before proceeding?" );
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2017-11-17 17:00:04 +00:00
|
|
|
if( IsOK( this, msg ) )
|
2018-08-01 23:06:12 +00:00
|
|
|
SaveProject();
|
2017-11-17 17:00:04 +00:00
|
|
|
}
|
2013-01-24 17:46:37 +00:00
|
|
|
|
2017-11-17 17:00:04 +00:00
|
|
|
AppendSchematic();
|
2013-01-24 17:46:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-09-20 14:20:38 +00:00
|
|
|
void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
|
|
|
|
{
|
2023-09-22 16:20:57 +00:00
|
|
|
if( Schematic().RootScreen() && !Schematic().RootScreen()->Items().empty() )
|
|
|
|
{
|
2023-10-24 22:17:40 +00:00
|
|
|
wxString msg = _( "This operation replaces the contents of the current schematic, "
|
|
|
|
"which will be permanently lost.\n\n"
|
2023-09-22 16:20:57 +00:00
|
|
|
"Do you want to proceed?" );
|
|
|
|
|
|
|
|
if( !IsOK( this, msg ) )
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-03-16 19:59:09 +00:00
|
|
|
// Set the project location if none is set or if we are running in standalone mode
|
|
|
|
bool setProject = Prj().GetProjectFullName().IsEmpty() || Kiface().IsSingle();
|
2017-09-20 14:20:38 +00:00
|
|
|
wxString path = wxPathOnly( Prj().GetProjectFullName() );
|
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
wxString fileFiltersStr;
|
|
|
|
wxString allWildcardsStr;
|
2020-08-23 19:01:08 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
|
|
|
|
{
|
|
|
|
if( fileType == SCH_IO_MGR::SCH_KICAD || fileType == SCH_IO_MGR::SCH_LEGACY )
|
|
|
|
continue; // this is "Import non-KiCad schematic"
|
2021-03-10 14:52:41 +00:00
|
|
|
|
2023-12-27 20:39:29 +00:00
|
|
|
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( fileType ) );
|
2020-08-23 19:01:08 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
if( !pi )
|
|
|
|
continue;
|
2020-08-23 19:01:08 +00:00
|
|
|
|
2023-12-27 16:34:59 +00:00
|
|
|
const IO_BASE::IO_FILE_DESC& desc = pi->GetSchematicFileDesc();
|
2023-04-22 20:17:08 +00:00
|
|
|
|
2024-04-25 16:19:22 +00:00
|
|
|
if( desc.m_FileExtensions.empty() || !desc.m_CanRead )
|
2023-08-26 19:28:53 +00:00
|
|
|
continue;
|
2020-08-23 19:01:08 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
if( !fileFiltersStr.IsEmpty() )
|
|
|
|
fileFiltersStr += wxChar( '|' );
|
2020-08-23 19:01:08 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
fileFiltersStr += desc.FileFilter();
|
2020-10-02 19:43:02 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
for( const std::string& ext : desc.m_FileExtensions )
|
2023-10-12 13:36:28 +00:00
|
|
|
allWildcardsStr << wxS( "*." ) << formatWildcardExt( ext ) << wxS( ";" );
|
2020-08-23 19:01:08 +00:00
|
|
|
}
|
|
|
|
|
2023-10-12 13:36:28 +00:00
|
|
|
fileFiltersStr = _( "All supported formats" ) + wxS( "|" ) + allWildcardsStr + wxS( "|" )
|
2023-08-26 19:28:53 +00:00
|
|
|
+ fileFiltersStr;
|
2020-10-02 19:43:02 +00:00
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFiltersStr,
|
2021-03-10 14:52:41 +00:00
|
|
|
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
|
2017-09-20 14:20:38 +00:00
|
|
|
|
2024-05-04 15:27:52 +00:00
|
|
|
FILEDLG_IMPORT_NON_KICAD importOptions( eeconfig()->m_System.show_import_issues );
|
|
|
|
dlg.SetCustomizeHook( importOptions );
|
|
|
|
|
2017-09-20 14:20:38 +00:00
|
|
|
if( dlg.ShowModal() == wxID_CANCEL )
|
|
|
|
return;
|
|
|
|
|
2024-05-04 15:27:52 +00:00
|
|
|
eeconfig()->m_System.show_import_issues = importOptions.GetShowIssues();
|
|
|
|
|
2022-03-22 17:41:50 +00:00
|
|
|
// Don't leave dangling pointers to previously-opened document.
|
|
|
|
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
|
|
|
|
ClearUndoRedoList();
|
|
|
|
|
2017-12-12 14:28:21 +00:00
|
|
|
if( setProject )
|
|
|
|
{
|
2020-07-08 00:48:21 +00:00
|
|
|
Schematic().SetProject( nullptr );
|
2021-02-22 02:31:45 +00:00
|
|
|
GetSettingsManager()->UnloadProject( &Prj(), false );
|
2020-07-08 00:48:21 +00:00
|
|
|
|
2023-07-10 22:00:16 +00:00
|
|
|
// Clear view before destroying schematic as repaints depend on schematic being valid
|
|
|
|
SetScreen( nullptr );
|
|
|
|
|
2020-07-08 00:48:21 +00:00
|
|
|
Schematic().Reset();
|
|
|
|
|
2017-12-12 14:28:21 +00:00
|
|
|
wxFileName projectFn( dlg.GetPath() );
|
2023-12-28 02:10:01 +00:00
|
|
|
projectFn.SetExt( FILEEXT::ProjectFileExtension );
|
2020-05-25 20:41:24 +00:00
|
|
|
GetSettingsManager()->LoadProject( projectFn.GetFullPath() );
|
2020-07-08 00:48:21 +00:00
|
|
|
|
|
|
|
Schematic().SetProject( &Prj() );
|
2017-12-12 14:28:21 +00:00
|
|
|
}
|
|
|
|
|
2020-08-23 19:01:08 +00:00
|
|
|
wxFileName fn = dlg.GetPath();
|
|
|
|
|
2024-02-16 11:37:11 +00:00
|
|
|
if( !fn.IsFileReadable() )
|
|
|
|
{
|
|
|
|
wxLogError( _( "Insufficient permissions to read file '%s'." ), fn.GetFullPath() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-23 19:01:08 +00:00
|
|
|
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN;
|
|
|
|
|
2023-08-26 19:28:53 +00:00
|
|
|
for( const SCH_IO_MGR::SCH_FILE_T& fileType : SCH_IO_MGR::SCH_FILE_T_vector )
|
2020-08-23 19:01:08 +00:00
|
|
|
{
|
2023-12-27 20:39:29 +00:00
|
|
|
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( fileType ) );
|
2023-08-26 19:28:53 +00:00
|
|
|
|
|
|
|
if( !pi )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( pi->CanReadSchematicFile( fn.GetFullPath() ) )
|
2020-08-23 19:01:08 +00:00
|
|
|
{
|
2023-08-26 19:28:53 +00:00
|
|
|
pluginType = fileType;
|
2020-08-23 19:01:08 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pluginType == SCH_IO_MGR::SCH_FILE_T::SCH_FILE_UNKNOWN )
|
|
|
|
{
|
2023-08-26 19:28:53 +00:00
|
|
|
wxLogError( _( "No loader can read the specified file: '%s'." ), fn.GetFullPath() );
|
2024-03-01 18:48:14 +00:00
|
|
|
CreateScreens();
|
|
|
|
SetScreen( Schematic().RootScreen() );
|
2020-08-23 19:01:08 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
importFile( dlg.GetPath(), pluginType );
|
2021-06-16 20:01:54 +00:00
|
|
|
|
|
|
|
RefreshCanvas();
|
2017-09-20 14:20:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSavePath )
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
wxFileName schematicFileName;
|
|
|
|
wxFileName oldFileName;
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
SCH_SCREEN* screen = aSheet->GetScreen();
|
|
|
|
|
|
|
|
wxCHECK( screen, false );
|
|
|
|
|
2022-12-27 02:47:17 +00:00
|
|
|
// Cannot save to nowhere
|
|
|
|
wxCHECK( !aSavePath.IsEmpty(), false );
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
// Construct the name of the file to be saved
|
|
|
|
schematicFileName = Prj().AbsolutePath( aSavePath );
|
|
|
|
oldFileName = schematicFileName;
|
|
|
|
|
|
|
|
// Write through symlinks, don't replace them
|
|
|
|
WX_FILENAME::ResolvePossibleSymlinks( schematicFileName );
|
|
|
|
|
|
|
|
if( !IsWritable( schematicFileName ) )
|
|
|
|
return false;
|
|
|
|
|
2023-08-28 12:27:00 +00:00
|
|
|
wxFileName projectFile( schematicFileName );
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
projectFile.SetExt( FILEEXT::ProjectFileExtension );
|
2023-08-28 12:27:00 +00:00
|
|
|
|
|
|
|
if( projectFile.FileExists() )
|
|
|
|
{
|
|
|
|
// Save various ERC settings, such as violation severities (which may have been edited
|
|
|
|
// via the ERC dialog as well as the Schematic Setup dialog), ERC exclusions, etc.
|
|
|
|
saveProjectSettings();
|
|
|
|
}
|
|
|
|
|
2023-01-22 14:41:33 +00:00
|
|
|
wxString tempFile = wxFileName::CreateTempFileName( wxS( "eeschema" ) );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
// Save
|
2023-01-22 14:41:33 +00:00
|
|
|
wxLogTrace( traceAutoSave, wxS( "Saving file " ) + schematicFileName.GetFullPath() );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
2022-09-10 20:26:25 +00:00
|
|
|
if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
|
|
|
|
m_infoBar->Dismiss();
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
SCH_IO_MGR::SCH_FILE_T pluginType = SCH_IO_MGR::GuessPluginTypeFromSchPath(
|
|
|
|
schematicFileName.GetFullPath() );
|
2023-08-26 19:28:53 +00:00
|
|
|
|
|
|
|
if( pluginType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
|
|
|
|
pluginType = SCH_IO_MGR::SCH_KICAD;
|
|
|
|
|
2023-12-27 20:39:29 +00:00
|
|
|
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( pluginType ) );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2023-08-26 19:28:53 +00:00
|
|
|
pi->SaveSchematicFile( tempFile, aSheet, &Schematic() );
|
2021-08-24 03:01:08 +00:00
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
catch( const IO_ERROR& ioe )
|
|
|
|
{
|
|
|
|
msg.Printf( _( "Error saving schematic file '%s'.\n%s" ),
|
|
|
|
schematicFileName.GetFullPath(),
|
|
|
|
ioe.What() );
|
|
|
|
DisplayError( this, msg );
|
|
|
|
|
|
|
|
msg.Printf( _( "Failed to create temporary file '%s'." ),
|
2022-03-08 04:08:54 +00:00
|
|
|
tempFile );
|
2021-08-24 03:01:08 +00:00
|
|
|
SetMsgPanel( wxEmptyString, msg );
|
|
|
|
|
|
|
|
// In case we started a file but didn't fully write it, clean up
|
2022-03-08 04:08:54 +00:00
|
|
|
wxRemoveFile( tempFile );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
success = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( success )
|
|
|
|
{
|
2023-05-25 00:07:46 +00:00
|
|
|
// Preserve the permissions of the current file
|
|
|
|
KIPLATFORM::IO::DuplicatePermissions( schematicFileName.GetFullPath(), tempFile );
|
2023-10-12 13:36:28 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
// Replace the original with the temporary file we just wrote
|
2022-03-08 04:08:54 +00:00
|
|
|
success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
if( !success )
|
|
|
|
{
|
|
|
|
msg.Printf( _( "Error saving schematic file '%s'.\n"
|
|
|
|
"Failed to rename temporary file '%s'." ),
|
|
|
|
schematicFileName.GetFullPath(),
|
2022-03-08 04:08:54 +00:00
|
|
|
tempFile );
|
2021-08-24 03:01:08 +00:00
|
|
|
DisplayError( this, msg );
|
|
|
|
|
|
|
|
msg.Printf( _( "Failed to rename temporary file '%s'." ),
|
2022-03-08 04:08:54 +00:00
|
|
|
tempFile );
|
2021-08-24 03:01:08 +00:00
|
|
|
SetMsgPanel( wxEmptyString, msg );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( success )
|
|
|
|
{
|
|
|
|
// Delete auto save file.
|
|
|
|
wxFileName autoSaveFileName = schematicFileName;
|
2024-04-22 00:58:13 +00:00
|
|
|
autoSaveFileName.SetName( FILEEXT::AutoSaveFilePrefix + schematicFileName.GetName() );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
if( autoSaveFileName.FileExists() )
|
|
|
|
{
|
|
|
|
wxLogTrace( traceAutoSave,
|
2023-10-12 13:36:28 +00:00
|
|
|
wxS( "Removing auto save file <" ) + autoSaveFileName.GetFullPath() +
|
|
|
|
wxS( ">" ) );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
|
|
|
wxRemoveFile( autoSaveFileName.GetFullPath() );
|
|
|
|
}
|
|
|
|
|
|
|
|
screen->SetContentModified( false );
|
|
|
|
|
|
|
|
msg.Printf( _( "File '%s' saved." ), screen->GetFileName() );
|
|
|
|
SetStatusText( msg, 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DisplayError( this, _( "File write operation failed." ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EDIT_FRAME::SaveProject( bool aSaveAs )
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2020-04-26 20:53:29 +00:00
|
|
|
wxString msg;
|
2010-10-26 20:25:48 +00:00
|
|
|
SCH_SCREEN* screen;
|
2020-05-13 02:00:37 +00:00
|
|
|
SCH_SCREENS screens( Schematic().Root() );
|
2022-12-27 02:47:17 +00:00
|
|
|
bool saveCopy = aSaveAs && !Kiface().IsSingle();
|
|
|
|
bool success = true;
|
|
|
|
bool updateFileHistory = false;
|
|
|
|
bool createNewProject = false;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
// I want to see it in the debugger, show me the string! Can't do that with wxFileName.
|
2020-05-13 02:00:37 +00:00
|
|
|
wxString fileName = Prj().AbsolutePath( Schematic().Root().GetFileName() );
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
wxFileName fn = fileName;
|
2011-08-18 19:25:12 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
// Path to save each screen to: will be the stored filename by default, but is overwritten by
|
|
|
|
// a Save As Copy operation.
|
|
|
|
std::unordered_map<SCH_SCREEN*, wxString> filenameMap;
|
|
|
|
|
|
|
|
// Handle "Save As" and saving a new project/schematic for the first time in standalone
|
|
|
|
if( Prj().IsNullProject() || aSaveAs )
|
2021-05-27 20:01:36 +00:00
|
|
|
{
|
2021-08-24 03:01:08 +00:00
|
|
|
// Null project should only be possible in standalone mode.
|
|
|
|
wxCHECK( Kiface().IsSingle() || aSaveAs, false );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
wxFileName newFileName;
|
|
|
|
wxFileName savePath( Prj().GetProjectFullName() );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
if( !savePath.IsOk() || !savePath.IsDirWritable() )
|
|
|
|
{
|
|
|
|
savePath = GetMruPath();
|
|
|
|
|
|
|
|
if( !savePath.IsOk() || !savePath.IsDirWritable() )
|
|
|
|
savePath = PATHS::GetDefaultUserProjectsPath();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( savePath.HasExt() )
|
2023-12-28 02:10:01 +00:00
|
|
|
savePath.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
2021-08-24 03:01:08 +00:00
|
|
|
else
|
|
|
|
savePath.SetName( wxEmptyString );
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
wxFileDialog dlg( this, _( "Schematic Files" ), savePath.GetPath(), savePath.GetFullName(),
|
|
|
|
FILEEXT::KiCadSchematicFileWildcard(),
|
2021-08-24 03:01:08 +00:00
|
|
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
|
|
|
|
|
2022-06-12 02:02:26 +00:00
|
|
|
FILEDLG_HOOK_SAVE_PROJECT newProjectHook;
|
|
|
|
|
2022-12-17 23:17:48 +00:00
|
|
|
// Add a "Create a project" checkbox in standalone mode and one isn't loaded
|
2021-08-24 03:01:08 +00:00
|
|
|
if( Kiface().IsSingle() || aSaveAs )
|
|
|
|
{
|
2022-06-12 02:02:26 +00:00
|
|
|
dlg.SetCustomizeHook( newProjectHook );
|
2021-08-24 03:01:08 +00:00
|
|
|
}
|
2021-08-21 16:09:13 +00:00
|
|
|
|
2021-05-27 20:01:36 +00:00
|
|
|
if( dlg.ShowModal() == wxID_CANCEL )
|
|
|
|
return false;
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
newFileName = EnsureFileExtension( dlg.GetPath(), FILEEXT::KiCadSchematicFileExtension );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
if( ( !newFileName.DirExists() && !newFileName.Mkdir() ) ||
|
|
|
|
!newFileName.IsDirWritable() )
|
2021-05-27 20:01:36 +00:00
|
|
|
{
|
2021-06-08 14:52:49 +00:00
|
|
|
msg.Printf( _( "Folder '%s' could not be created.\n\n"
|
|
|
|
"Make sure you have write permissions and try again." ),
|
|
|
|
newFileName.GetPath() );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
|
|
|
wxMessageDialog dlgBadPath( this, msg, _( "Error" ),
|
|
|
|
wxOK | wxICON_EXCLAMATION | wxCENTER );
|
|
|
|
|
|
|
|
dlgBadPath.ShowModal();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-12-17 23:17:48 +00:00
|
|
|
if( newProjectHook.IsAttachedToDialog() )
|
2022-06-12 02:02:26 +00:00
|
|
|
createNewProject = newProjectHook.GetCreateNewProject();
|
2021-05-27 20:01:36 +00:00
|
|
|
|
2022-04-24 16:38:34 +00:00
|
|
|
if( !saveCopy )
|
2021-08-24 03:01:08 +00:00
|
|
|
{
|
|
|
|
Schematic().Root().SetFileName( newFileName.GetFullName() );
|
|
|
|
Schematic().RootScreen()->SetFileName( newFileName.GetFullPath() );
|
2022-12-27 02:47:17 +00:00
|
|
|
updateFileHistory = true;
|
2021-08-24 03:01:08 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
filenameMap[Schematic().RootScreen()] = newFileName.GetFullPath();
|
|
|
|
}
|
2021-08-21 16:09:13 +00:00
|
|
|
|
2021-05-27 20:01:36 +00:00
|
|
|
// Set the base path to all new sheets.
|
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
|
|
|
{
|
|
|
|
screen = screens.GetScreen( i );
|
|
|
|
|
|
|
|
wxCHECK2( screen, continue );
|
|
|
|
|
|
|
|
// The root screen file name has already been set.
|
|
|
|
if( screen == Schematic().RootScreen() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
wxFileName tmp = screen->GetFileName();
|
|
|
|
|
|
|
|
// Assume existing sheet files are being reused and do not save them to the new
|
|
|
|
// path. Maybe in the future, add a user option to copy schematic files to the
|
|
|
|
// new project path.
|
|
|
|
if( tmp.FileExists() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if( tmp.GetPath().IsEmpty() )
|
|
|
|
{
|
|
|
|
tmp.SetPath( newFileName.GetPath() );
|
|
|
|
}
|
|
|
|
else if( tmp.GetPath() == fn.GetPath() )
|
|
|
|
{
|
|
|
|
tmp.SetPath( newFileName.GetPath() );
|
|
|
|
}
|
|
|
|
else if( tmp.GetPath().StartsWith( fn.GetPath() ) )
|
|
|
|
{
|
|
|
|
// NOTE: this hasn't been tested because the sheet properties dialog no longer
|
|
|
|
// allows adding a path specifier in the file name field.
|
|
|
|
wxString newPath = newFileName.GetPath();
|
|
|
|
newPath += tmp.GetPath().Right( fn.GetPath().Length() );
|
|
|
|
tmp.SetPath( newPath );
|
|
|
|
}
|
|
|
|
|
|
|
|
wxLogTrace( tracePathsAndFiles,
|
2023-10-12 13:36:28 +00:00
|
|
|
wxS( "Moving schematic from '%s' to '%s'." ),
|
2021-06-08 14:52:49 +00:00
|
|
|
screen->GetFileName(),
|
|
|
|
tmp.GetFullPath() );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
|
|
|
if( !tmp.DirExists() && !tmp.Mkdir() )
|
|
|
|
{
|
2021-06-08 14:52:49 +00:00
|
|
|
msg.Printf( _( "Folder '%s' could not be created.\n\n"
|
|
|
|
"Make sure you have write permissions and try again." ),
|
|
|
|
newFileName.GetPath() );
|
2021-05-27 20:01:36 +00:00
|
|
|
|
|
|
|
wxMessageDialog dlgBadFilePath( this, msg, _( "Error" ),
|
|
|
|
wxOK | wxICON_EXCLAMATION | wxCENTER );
|
|
|
|
|
|
|
|
dlgBadFilePath.ShowModal();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-04-24 16:38:34 +00:00
|
|
|
if( saveCopy )
|
2021-08-24 03:01:08 +00:00
|
|
|
filenameMap[screen] = tmp.GetFullPath();
|
|
|
|
else
|
|
|
|
screen->SetFileName( tmp.GetFullPath() );
|
2021-05-27 20:01:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Attempt to make sheet file name paths relative to the new root schematic path.
|
|
|
|
SCH_SHEET_LIST sheets = Schematic().GetSheets();
|
|
|
|
|
|
|
|
for( SCH_SHEET_PATH& sheet : sheets )
|
|
|
|
{
|
|
|
|
if( sheet.Last()->IsRootSheet() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
sheet.MakeFilePathRelativeToParentSheet();
|
|
|
|
}
|
|
|
|
}
|
2022-12-27 02:47:17 +00:00
|
|
|
else if( !fn.FileExists() )
|
|
|
|
{
|
|
|
|
// File doesn't exist yet; true if we just imported something
|
|
|
|
updateFileHistory = true;
|
|
|
|
}
|
2024-06-06 10:31:22 +00:00
|
|
|
else if( !IsContentModified() )
|
2023-10-27 13:57:20 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2021-05-27 20:01:36 +00:00
|
|
|
|
2022-04-24 16:38:34 +00:00
|
|
|
if( filenameMap.empty() || !saveCopy )
|
2021-08-24 03:01:08 +00:00
|
|
|
{
|
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
|
|
|
filenameMap[screens.GetScreen( i )] = screens.GetScreen( i )->GetFileName();
|
|
|
|
}
|
|
|
|
|
2020-04-26 20:53:29 +00:00
|
|
|
// Warn user on potential file overwrite. This can happen on shared sheets.
|
|
|
|
wxArrayString overwrittenFiles;
|
2023-10-27 13:57:20 +00:00
|
|
|
wxArrayString lockedFiles;
|
2020-04-26 20:53:29 +00:00
|
|
|
|
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
2020-04-16 16:43:50 +00:00
|
|
|
{
|
2020-04-26 20:53:29 +00:00
|
|
|
screen = screens.GetScreen( i );
|
|
|
|
|
|
|
|
wxCHECK2( screen, continue );
|
|
|
|
|
|
|
|
// Convert legacy schematics file name extensions for the new format.
|
2021-08-24 03:01:08 +00:00
|
|
|
wxFileName tmpFn = filenameMap[screen];
|
2020-04-26 20:53:29 +00:00
|
|
|
|
2020-10-12 23:41:38 +00:00
|
|
|
if( !tmpFn.IsOk() )
|
|
|
|
continue;
|
|
|
|
|
2023-10-27 13:57:20 +00:00
|
|
|
if( tmpFn.FileExists() && !tmpFn.IsFileWritable() )
|
|
|
|
lockedFiles.Add( tmpFn.GetFullPath() );
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
if( tmpFn.GetExt() == FILEEXT::KiCadSchematicFileExtension )
|
2020-04-26 20:53:29 +00:00
|
|
|
continue;
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
tmpFn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
2020-04-26 20:53:29 +00:00
|
|
|
|
|
|
|
if( tmpFn.FileExists() )
|
|
|
|
overwrittenFiles.Add( tmpFn.GetFullPath() );
|
|
|
|
}
|
|
|
|
|
2023-10-27 13:57:20 +00:00
|
|
|
if( !lockedFiles.IsEmpty() )
|
|
|
|
{
|
|
|
|
for( const wxString& lockedFile : lockedFiles )
|
|
|
|
{
|
|
|
|
if( msg.IsEmpty() )
|
|
|
|
msg = lockedFile;
|
|
|
|
else
|
|
|
|
msg += "\n" + lockedFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
wxRichMessageDialog dlg( this, wxString::Format( _( "Failed to save %s." ),
|
|
|
|
Schematic().Root().GetFileName() ),
|
|
|
|
_( "Locked File Warning" ),
|
|
|
|
wxOK | wxICON_WARNING | wxCENTER );
|
|
|
|
dlg.SetExtendedMessage( _( "You do not have write permissions to:\n\n" ) + msg );
|
|
|
|
|
|
|
|
dlg.ShowModal();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-26 20:53:29 +00:00
|
|
|
if( !overwrittenFiles.IsEmpty() )
|
|
|
|
{
|
2021-02-19 21:45:37 +00:00
|
|
|
for( const wxString& overwrittenFile : overwrittenFiles )
|
2020-04-26 20:53:29 +00:00
|
|
|
{
|
|
|
|
if( msg.IsEmpty() )
|
|
|
|
msg = overwrittenFile;
|
|
|
|
else
|
|
|
|
msg += "\n" + overwrittenFile;
|
|
|
|
}
|
|
|
|
|
2021-02-19 21:45:37 +00:00
|
|
|
wxRichMessageDialog dlg( this, _( "Saving will overwrite existing files." ),
|
|
|
|
_( "Save Warning" ),
|
2021-03-10 14:52:41 +00:00
|
|
|
wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER |
|
|
|
|
wxICON_EXCLAMATION );
|
2021-02-19 21:45:37 +00:00
|
|
|
dlg.ShowDetailedText( _( "The following files will be overwritten:\n\n" ) + msg );
|
2020-04-26 20:53:29 +00:00
|
|
|
dlg.SetOKCancelLabels( wxMessageDialog::ButtonLabel( _( "Overwrite Files" ) ),
|
2021-02-19 21:45:37 +00:00
|
|
|
wxMessageDialog::ButtonLabel( _( "Abort Project Save" ) ) );
|
2020-04-26 20:53:29 +00:00
|
|
|
|
|
|
|
if( dlg.ShowModal() == wxID_CANCEL )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-08-02 18:57:43 +00:00
|
|
|
screens.BuildClientSheetPathList();
|
|
|
|
|
2020-04-26 20:53:29 +00:00
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
|
|
|
{
|
|
|
|
screen = screens.GetScreen( i );
|
|
|
|
|
|
|
|
wxCHECK2( screen, continue );
|
|
|
|
|
2020-04-16 16:43:50 +00:00
|
|
|
// Convert legacy schematics file name extensions for the new format.
|
2021-08-24 03:01:08 +00:00
|
|
|
wxFileName tmpFn = filenameMap[screen];
|
2020-04-16 16:43:50 +00:00
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
if( tmpFn.IsOk() && tmpFn.GetExt() != FILEEXT::KiCadSchematicFileExtension )
|
2020-04-16 16:43:50 +00:00
|
|
|
{
|
2022-12-27 02:47:17 +00:00
|
|
|
updateFileHistory = true;
|
2023-12-28 02:10:01 +00:00
|
|
|
tmpFn.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
2020-04-16 16:43:50 +00:00
|
|
|
|
2022-07-29 21:02:35 +00:00
|
|
|
for( EDA_ITEM* item : screen->Items().OfType( SCH_SHEET_T ) )
|
2020-04-16 16:43:50 +00:00
|
|
|
{
|
|
|
|
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
|
|
|
|
wxFileName sheetFileName = sheet->GetFileName();
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
if( !sheetFileName.IsOk()
|
|
|
|
|| sheetFileName.GetExt() == FILEEXT::KiCadSchematicFileExtension )
|
2020-04-16 16:43:50 +00:00
|
|
|
continue;
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
sheetFileName.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
2020-04-16 16:43:50 +00:00
|
|
|
sheet->SetFileName( sheetFileName.GetFullPath() );
|
2020-08-10 11:40:58 +00:00
|
|
|
UpdateItem( sheet );
|
2020-04-16 16:43:50 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
filenameMap[screen] = tmpFn.GetFullPath();
|
|
|
|
|
2022-04-24 16:38:34 +00:00
|
|
|
if( !saveCopy )
|
2021-08-24 03:01:08 +00:00
|
|
|
screen->SetFileName( tmpFn.GetFullPath() );
|
2020-04-16 16:43:50 +00:00
|
|
|
}
|
|
|
|
|
2022-12-27 02:47:17 +00:00
|
|
|
// Do not save sheet symbols with no valid filename set
|
|
|
|
if( !tmpFn.IsOk() )
|
|
|
|
continue;
|
|
|
|
|
2020-07-31 21:03:25 +00:00
|
|
|
std::vector<SCH_SHEET_PATH>& sheets = screen->GetClientSheetPaths();
|
|
|
|
|
|
|
|
if( sheets.size() == 1 )
|
2020-10-18 20:30:37 +00:00
|
|
|
screen->SetVirtualPageNumber( 1 );
|
2020-07-31 21:03:25 +00:00
|
|
|
else
|
2020-10-18 20:30:37 +00:00
|
|
|
screen->SetVirtualPageNumber( 0 ); // multiple uses; no way to store the real sheet #
|
2020-07-31 21:03:25 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
// This is a new schematic file so make sure it has a unique ID.
|
2022-04-24 16:38:34 +00:00
|
|
|
if( !saveCopy && tmpFn.GetFullPath() != screen->GetFileName() )
|
2021-08-24 03:01:08 +00:00
|
|
|
screen->AssignNewUuid();
|
|
|
|
|
|
|
|
success &= saveSchematicFile( screens.GetSheet( i ), tmpFn.GetFullPath() );
|
2020-04-16 16:43:50 +00:00
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2022-10-10 13:03:10 +00:00
|
|
|
if( success )
|
|
|
|
m_autoSaveRequired = false;
|
|
|
|
|
2021-10-13 18:48:28 +00:00
|
|
|
// One or more of the modified sheets did not save correctly so update the auto save file.
|
|
|
|
if( !aSaveAs && !success )
|
|
|
|
success &= updateAutoSaveFile();
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
if( aSaveAs && success )
|
|
|
|
LockFile( Schematic().RootScreen()->GetFileName() );
|
|
|
|
|
2022-12-27 02:47:17 +00:00
|
|
|
if( updateFileHistory )
|
2020-05-13 02:00:37 +00:00
|
|
|
UpdateFileHistory( Schematic().RootScreen()->GetFileName() );
|
2013-02-01 07:58:49 +00:00
|
|
|
|
2020-02-20 22:52:01 +00:00
|
|
|
// Save the sheet name map to the project file
|
2020-05-26 02:27:27 +00:00
|
|
|
std::vector<FILE_INFO_PAIR>& sheets = Prj().GetProjectFile().GetSheets();
|
|
|
|
sheets.clear();
|
2020-02-20 19:43:39 +00:00
|
|
|
|
2020-05-13 02:00:37 +00:00
|
|
|
for( SCH_SHEET_PATH& sheetPath : Schematic().GetSheets() )
|
2020-02-20 19:43:39 +00:00
|
|
|
{
|
|
|
|
SCH_SHEET* sheet = sheetPath.Last();
|
2021-04-06 18:27:24 +00:00
|
|
|
|
|
|
|
wxCHECK2( sheet, continue );
|
|
|
|
|
|
|
|
// Use the schematic UUID for the root sheet.
|
|
|
|
if( sheet->IsRootSheet() )
|
|
|
|
{
|
|
|
|
screen = sheet->GetScreen();
|
|
|
|
|
|
|
|
wxCHECK2( screen, continue );
|
|
|
|
|
|
|
|
sheets.emplace_back( std::make_pair( screen->GetUuid(), sheet->GetName() ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sheets.emplace_back( std::make_pair( sheet->m_Uuid, sheet->GetName() ) );
|
|
|
|
}
|
2020-02-20 19:43:39 +00:00
|
|
|
}
|
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
wxASSERT( filenameMap.count( Schematic().RootScreen() ) );
|
|
|
|
wxFileName projectPath( filenameMap.at( Schematic().RootScreen() ) );
|
2023-12-28 02:10:01 +00:00
|
|
|
projectPath.SetExt( FILEEXT::ProjectFileExtension );
|
2021-08-24 03:01:08 +00:00
|
|
|
|
2022-04-24 16:38:34 +00:00
|
|
|
if( Prj().IsNullProject() || ( aSaveAs && !saveCopy ) )
|
2021-08-21 16:09:13 +00:00
|
|
|
{
|
2021-08-24 03:01:08 +00:00
|
|
|
Prj().SetReadOnly( !createNewProject );
|
|
|
|
GetSettingsManager()->SaveProjectAs( projectPath.GetFullPath() );
|
|
|
|
}
|
2022-04-24 16:38:34 +00:00
|
|
|
else if( saveCopy && createNewProject )
|
2021-08-24 03:01:08 +00:00
|
|
|
{
|
|
|
|
GetSettingsManager()->SaveProjectCopy( projectPath.GetFullPath() );
|
2021-08-21 16:09:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-03-09 14:56:19 +00:00
|
|
|
saveProjectSettings();
|
2024-02-25 22:39:14 +00:00
|
|
|
SaveProjectLocalSettings();
|
2021-08-21 16:09:13 +00:00
|
|
|
}
|
2020-02-20 19:43:39 +00:00
|
|
|
|
2020-07-12 15:42:05 +00:00
|
|
|
if( !Kiface().IsSingle() )
|
|
|
|
{
|
|
|
|
WX_STRING_REPORTER backupReporter( &msg );
|
2020-07-03 13:40:31 +00:00
|
|
|
|
2020-07-12 15:42:05 +00:00
|
|
|
if( !GetSettingsManager()->TriggerBackupIfNeeded( backupReporter ) )
|
|
|
|
SetStatusText( msg, 0 );
|
|
|
|
}
|
2020-07-03 13:40:31 +00:00
|
|
|
|
2023-01-12 00:05:43 +00:00
|
|
|
updateTitle();
|
2018-08-01 23:06:12 +00:00
|
|
|
|
2021-08-01 20:51:08 +00:00
|
|
|
if( m_infoBar->GetMessageType() == WX_INFOBAR::MESSAGE_TYPE::OUTDATED_SAVE )
|
|
|
|
m_infoBar->Dismiss();
|
2021-02-16 23:42:39 +00:00
|
|
|
|
2018-08-01 23:06:12 +00:00
|
|
|
return success;
|
2007-06-05 12:10:51 +00:00
|
|
|
}
|
2011-10-15 13:25:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EDIT_FRAME::doAutoSave()
|
|
|
|
{
|
2020-05-13 02:00:37 +00:00
|
|
|
wxFileName tmpFileName = Schematic().Root().GetFileName();
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
wxFileName fn = tmpFileName;
|
2011-10-15 13:25:57 +00:00
|
|
|
wxFileName tmp;
|
2020-05-13 02:00:37 +00:00
|
|
|
SCH_SCREENS screens( Schematic().Root() );
|
Modular KiCad Blueprint Milestone B), major portions:
*) When kicad.exe closes a project, close any open KIFACEs so that they cannot
get disassociated from their true PROJECT.
*) Allow loading eeschema library editor from kicad.exe
*) Allow loading pcbnew library editor from kicad.exe
*) Rename LIB_COMPONENT to LIB_PART.
*) Add class PART_LIBS, and PART_LIB.
*) Make PART_LIBS non-global, i.e. PROJECT specific.
*) Implement "data on demand" for PART_LIBS
*) Implement "data on demand" for schematic SEARCH_STACK.
*) Use RSTRINGs to retain eeschema editor's notion of last library and part being edited.
*) Get rid of library search on every SCH_COMPONENT::Draw() call, instead use
a weak pointer.
*) Remove all chdir() calls so projects don't need to be CWD.
*) Romove APPEND support from OpenProjectFiles().
*) Make OpenProjectFiles() robust, even for creating new projects.
*) Load EESCHEMA colors in the KIWAY::OnKiwayStart() rather in window open,
and save them in the .eeschema config file, not in the project file.
*) Fix bug with wxDir() while accessing protected dirs in kicad.exe
*) Consolidate template copying into PROJECT class, not in kicad.exe source.
*) Generally untangle eeschema, making its libraries not global but rather
held in the PROJECT.
2014-08-13 20:28:54 +00:00
|
|
|
|
2021-05-27 23:07:48 +00:00
|
|
|
// Don't run autosave if content has not been modified
|
|
|
|
if( !IsContentModified() )
|
|
|
|
return true;
|
|
|
|
|
2011-10-15 13:25:57 +00:00
|
|
|
bool autoSaveOk = true;
|
|
|
|
|
2020-12-17 02:17:48 +00:00
|
|
|
if( fn.GetPath().IsEmpty() )
|
|
|
|
tmp.AssignDir( Prj().GetProjectPath() );
|
|
|
|
else
|
|
|
|
tmp.AssignDir( fn.GetPath() );
|
2011-10-15 13:25:57 +00:00
|
|
|
|
2015-06-18 18:43:26 +00:00
|
|
|
if( !tmp.IsOk() )
|
|
|
|
return false;
|
|
|
|
|
2011-10-15 13:25:57 +00:00
|
|
|
if( !IsWritable( tmp ) )
|
|
|
|
return false;
|
|
|
|
|
2021-05-12 07:45:23 +00:00
|
|
|
wxString title = GetTitle(); // Save frame title, that can be modified by the save process
|
|
|
|
|
2020-04-26 20:53:29 +00:00
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
2011-10-15 13:25:57 +00:00
|
|
|
{
|
|
|
|
// Only create auto save files for the schematics that have been modified.
|
2021-05-28 19:07:04 +00:00
|
|
|
if( !screens.GetScreen( i )->IsContentModified() )
|
2011-10-15 13:25:57 +00:00
|
|
|
continue;
|
|
|
|
|
2020-04-26 20:53:29 +00:00
|
|
|
tmpFileName = fn = screens.GetScreen( i )->GetFileName();
|
2011-10-15 13:25:57 +00:00
|
|
|
|
2019-03-18 12:22:33 +00:00
|
|
|
// Auto save file name is the normal file name prefixed with GetAutoSavePrefix().
|
2024-04-22 00:58:13 +00:00
|
|
|
fn.SetName( FILEEXT::AutoSaveFilePrefix + fn.GetName() );
|
2011-10-15 13:25:57 +00:00
|
|
|
|
2021-08-24 03:01:08 +00:00
|
|
|
if( saveSchematicFile( screens.GetSheet( i ), fn.GetFullPath() ) )
|
2022-10-10 11:04:19 +00:00
|
|
|
{
|
|
|
|
// This was only an auto-save, not a real save. Reset the modified flag.
|
2021-05-28 19:07:04 +00:00
|
|
|
screens.GetScreen( i )->SetContentModified();
|
2022-10-10 11:04:19 +00:00
|
|
|
}
|
2011-10-15 13:25:57 +00:00
|
|
|
else
|
2022-10-10 11:04:19 +00:00
|
|
|
{
|
2011-10-15 13:25:57 +00:00
|
|
|
autoSaveOk = false;
|
2022-10-10 11:04:19 +00:00
|
|
|
}
|
2011-10-15 13:25:57 +00:00
|
|
|
}
|
|
|
|
|
2021-10-13 18:48:28 +00:00
|
|
|
if( autoSaveOk && updateAutoSaveFile() )
|
2020-07-03 13:40:31 +00:00
|
|
|
{
|
2022-10-10 13:03:10 +00:00
|
|
|
m_autoSaveRequired = false;
|
2022-10-10 11:04:19 +00:00
|
|
|
m_autoSavePending = false;
|
2011-10-15 13:25:57 +00:00
|
|
|
|
2022-10-10 13:03:10 +00:00
|
|
|
if( !Kiface().IsSingle()
|
|
|
|
&& GetSettingsManager()->GetCommonSettings()->m_Backup.backup_on_autosave )
|
2020-07-12 15:42:05 +00:00
|
|
|
{
|
2020-07-03 13:40:31 +00:00
|
|
|
GetSettingsManager()->TriggerBackupIfNeeded( NULL_REPORTER::GetInstance() );
|
2020-07-12 15:42:05 +00:00
|
|
|
}
|
2020-07-03 13:40:31 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 07:45:23 +00:00
|
|
|
SetTitle( title );
|
|
|
|
|
2011-10-15 13:25:57 +00:00
|
|
|
return autoSaveOk;
|
|
|
|
}
|
2017-08-24 15:56:15 +00:00
|
|
|
|
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
|
|
|
|
const STRING_UTF8_MAP* aProperties )
|
2017-10-03 10:23:52 +00:00
|
|
|
{
|
2021-08-31 21:38:45 +00:00
|
|
|
wxFileName filename( aFileName );
|
2021-03-31 21:33:30 +00:00
|
|
|
wxFileName newfilename;
|
|
|
|
SCH_SHEET_LIST sheetList = Schematic().GetSheets();
|
2021-03-28 19:41:12 +00:00
|
|
|
SCH_IO_MGR::SCH_FILE_T fileType = (SCH_IO_MGR::SCH_FILE_T) aFileType;
|
2017-08-24 15:56:15 +00:00
|
|
|
|
2024-01-18 22:50:50 +00:00
|
|
|
wxCommandEvent changingEvt( EDA_EVT_SCHEMATIC_CHANGING );
|
|
|
|
ProcessEventLocally( changingEvt );
|
|
|
|
|
2021-03-28 19:41:12 +00:00
|
|
|
switch( fileType )
|
2017-10-03 10:23:52 +00:00
|
|
|
{
|
2020-08-23 19:01:08 +00:00
|
|
|
case SCH_IO_MGR::SCH_ALTIUM:
|
2020-09-19 22:05:02 +00:00
|
|
|
case SCH_IO_MGR::SCH_CADSTAR_ARCHIVE:
|
2018-10-24 19:37:32 +00:00
|
|
|
case SCH_IO_MGR::SCH_EAGLE:
|
2023-04-22 20:17:08 +00:00
|
|
|
case SCH_IO_MGR::SCH_LTSPICE:
|
2023-09-06 11:58:39 +00:00
|
|
|
case SCH_IO_MGR::SCH_EASYEDA:
|
|
|
|
case SCH_IO_MGR::SCH_EASYEDAPRO:
|
2023-06-13 15:35:28 +00:00
|
|
|
{
|
2018-10-24 19:37:32 +00:00
|
|
|
// We insist on caller sending us an absolute path, if it does not, we say it's a bug.
|
2023-10-30 06:34:45 +00:00
|
|
|
wxCHECK_MSG( filename.IsAbsolute(), false,
|
2023-10-12 13:36:28 +00:00
|
|
|
wxS( "Import schematic: path is not absolute!" ) );
|
2017-08-24 15:56:15 +00:00
|
|
|
|
2018-10-24 19:37:32 +00:00
|
|
|
try
|
|
|
|
{
|
2024-05-23 11:59:45 +00:00
|
|
|
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( fileType ) );
|
|
|
|
DIALOG_HTML_REPORTER errorReporter( this );
|
|
|
|
WX_PROGRESS_REPORTER progressReporter( this, _( "Importing Schematic" ), 1 );
|
2021-03-31 21:33:30 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
PROJECT_CHOOSER_PLUGIN* projectChooserPlugin =
|
2023-12-27 20:39:29 +00:00
|
|
|
dynamic_cast<PROJECT_CHOOSER_PLUGIN*>( pi.get() );
|
2023-10-30 06:34:45 +00:00
|
|
|
|
|
|
|
if( projectChooserPlugin )
|
|
|
|
{
|
|
|
|
projectChooserPlugin->RegisterChooseProjectCallback(
|
|
|
|
std::bind( DIALOG_IMPORT_CHOOSE_PROJECT::GetSelectionsModal, this,
|
|
|
|
std::placeholders::_1 ) );
|
|
|
|
}
|
|
|
|
|
2024-05-04 15:27:52 +00:00
|
|
|
if( eeconfig()->m_System.show_import_issues )
|
|
|
|
pi->SetReporter( errorReporter.m_Reporter );
|
|
|
|
else
|
|
|
|
pi->SetReporter( &NULL_REPORTER::GetInstance() );
|
|
|
|
|
2021-06-23 22:53:08 +00:00
|
|
|
pi->SetProgressReporter( &progressReporter );
|
2017-09-20 14:28:49 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
SCH_SHEET* loadedSheet =
|
|
|
|
pi->LoadSchematicFile( aFileName, &Schematic(), nullptr, aProperties );
|
|
|
|
|
|
|
|
if( loadedSheet )
|
2021-05-29 08:23:11 +00:00
|
|
|
{
|
2023-10-30 06:34:45 +00:00
|
|
|
Schematic().SetRoot( loadedSheet );
|
|
|
|
|
|
|
|
if( errorReporter.m_Reporter->HasMessage() )
|
|
|
|
{
|
|
|
|
errorReporter.m_Reporter->Flush(); // Build HTML messages
|
|
|
|
errorReporter.ShowModal();
|
|
|
|
}
|
2021-03-31 21:33:30 +00:00
|
|
|
|
2024-05-23 11:59:45 +00:00
|
|
|
// Non-KiCad schematics do not use a drawing-sheet (or if they do, it works
|
|
|
|
// differently to KiCad), so set it to an empty one.
|
2023-10-30 06:34:45 +00:00
|
|
|
DS_DATA_MODEL& drawingSheet = DS_DATA_MODEL::GetTheInstance();
|
|
|
|
drawingSheet.SetEmptyLayout();
|
|
|
|
BASE_SCREEN::m_DrawingSheetFileName = "empty.kicad_wks";
|
2018-02-28 15:43:33 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
newfilename.SetPath( Prj().GetProjectPath() );
|
|
|
|
newfilename.SetName( Prj().GetProjectName() );
|
2023-12-28 02:10:01 +00:00
|
|
|
newfilename.SetExt( FILEEXT::KiCadSchematicFileExtension );
|
2018-02-28 15:43:33 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
SetScreen( GetCurrentSheet().LastScreen() );
|
2017-09-20 14:28:49 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
Schematic().Root().SetFileName( newfilename.GetFullName() );
|
|
|
|
GetScreen()->SetFileName( newfilename.GetFullPath() );
|
|
|
|
GetScreen()->SetContentModified();
|
2020-07-08 00:48:21 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
RecalculateConnections( nullptr, GLOBAL_CLEANUP );
|
2021-12-09 00:26:52 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
// Only perform the dangling end test on root sheet.
|
|
|
|
GetScreen()->TestDanglingEnds();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CreateScreens();
|
|
|
|
}
|
2018-10-24 19:37:32 +00:00
|
|
|
}
|
|
|
|
catch( const IO_ERROR& ioe )
|
|
|
|
{
|
|
|
|
// Do not leave g_RootSheet == NULL because it is expected to be
|
|
|
|
// a valid sheet. Therefore create a dummy empty root sheet and screen.
|
|
|
|
CreateScreens();
|
2023-06-26 22:16:51 +00:00
|
|
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen );
|
2017-08-24 15:56:15 +00:00
|
|
|
|
2021-06-08 14:52:49 +00:00
|
|
|
wxString msg = wxString::Format( _( "Error loading schematic '%s'." ), aFileName );
|
|
|
|
DisplayErrorMessage( this, msg, ioe.What() );
|
2017-08-24 15:56:15 +00:00
|
|
|
|
2021-06-08 14:52:49 +00:00
|
|
|
msg.Printf( _( "Failed to load '%s'." ), aFileName );
|
2022-12-06 01:18:05 +00:00
|
|
|
SetMsgPanel( wxEmptyString, msg );
|
|
|
|
}
|
|
|
|
catch( const std::exception& exc )
|
|
|
|
{
|
|
|
|
CreateScreens();
|
2023-06-26 22:16:51 +00:00
|
|
|
m_toolManager->RunAction( ACTIONS::zoomFitScreen );
|
2022-12-06 01:18:05 +00:00
|
|
|
|
2022-12-06 23:04:26 +00:00
|
|
|
wxString msg = wxString::Format( _( "Unhandled exception occurred loading schematic "
|
2022-12-06 01:18:05 +00:00
|
|
|
"'%s'." ), aFileName );
|
|
|
|
DisplayErrorMessage( this, msg, exc.what() );
|
|
|
|
|
|
|
|
msg.Printf( _( "Failed to load '%s'." ), aFileName );
|
2020-12-08 05:27:34 +00:00
|
|
|
SetMsgPanel( wxEmptyString, msg );
|
2023-06-13 15:35:28 +00:00
|
|
|
}
|
2017-08-24 15:56:15 +00:00
|
|
|
|
2023-06-13 15:35:28 +00:00
|
|
|
ClearUndoRedoList();
|
|
|
|
|
|
|
|
initScreenZoom();
|
|
|
|
SetSheetNumberAndCount();
|
|
|
|
SyncView();
|
|
|
|
|
|
|
|
UpdateHierarchyNavigator();
|
|
|
|
|
|
|
|
wxCommandEvent e( EDA_EVT_SCHEMATIC_CHANGED );
|
|
|
|
ProcessEventLocally( e );
|
|
|
|
|
|
|
|
for( wxEvtHandler* listener : m_schematicChangeListeners )
|
|
|
|
{
|
|
|
|
wxCHECK2( listener, continue );
|
|
|
|
|
|
|
|
// Use the windows variant when handling event messages in case there is any
|
|
|
|
// special event handler pre and/or post processing specific to windows.
|
|
|
|
wxWindow* win = dynamic_cast<wxWindow*>( listener );
|
|
|
|
|
|
|
|
if( win )
|
|
|
|
win->HandleWindowEvent( e );
|
|
|
|
else
|
|
|
|
listener->SafelyProcessEvent( e );
|
2018-10-24 19:37:32 +00:00
|
|
|
}
|
|
|
|
|
2023-06-13 15:35:28 +00:00
|
|
|
updateTitle();
|
|
|
|
break;
|
|
|
|
}
|
2018-10-24 19:37:32 +00:00
|
|
|
|
|
|
|
default:
|
2023-06-13 15:35:28 +00:00
|
|
|
break;
|
2017-10-03 10:23:52 +00:00
|
|
|
}
|
2023-06-13 15:35:28 +00:00
|
|
|
|
2023-10-30 06:34:45 +00:00
|
|
|
return true;
|
2017-08-24 15:56:15 +00:00
|
|
|
}
|
2017-09-20 14:20:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EDIT_FRAME::AskToSaveChanges()
|
|
|
|
{
|
2020-05-13 02:00:37 +00:00
|
|
|
SCH_SCREENS screenList( Schematic().Root() );
|
2017-09-20 14:20:38 +00:00
|
|
|
|
|
|
|
// Save any currently open and modified project files.
|
|
|
|
for( SCH_SCREEN* screen = screenList.GetFirst(); screen; screen = screenList.GetNext() )
|
|
|
|
{
|
2023-03-03 22:36:07 +00:00
|
|
|
SIMULATOR_FRAME* simFrame = (SIMULATOR_FRAME*) Kiway().Player( FRAME_SIMULATOR, false );
|
2021-11-07 19:50:54 +00:00
|
|
|
|
|
|
|
// Simulator must be closed before loading another schematic, otherwise it may crash.
|
|
|
|
// If there are any changes in the simulator the user will be prompted to save them.
|
|
|
|
if( simFrame && !simFrame->Close() )
|
|
|
|
return false;
|
|
|
|
|
2021-05-28 19:07:04 +00:00
|
|
|
if( screen->IsContentModified() )
|
2017-09-20 14:20:38 +00:00
|
|
|
{
|
2019-06-17 15:59:39 +00:00
|
|
|
if( !HandleUnsavedChanges( this, _( "The current schematic has been modified. "
|
|
|
|
"Save changes?" ),
|
2021-10-01 20:49:14 +00:00
|
|
|
[&]() -> bool
|
|
|
|
{
|
|
|
|
return SaveProject();
|
|
|
|
} ) )
|
2017-09-20 14:20:38 +00:00
|
|
|
{
|
2018-08-11 20:46:03 +00:00
|
|
|
return false;
|
2017-09-20 14:20:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool SCH_EDIT_FRAME::updateAutoSaveFile()
|
|
|
|
{
|
|
|
|
wxFileName tmpFn = Prj().GetProjectFullName();
|
|
|
|
wxFileName autoSaveFileName( tmpFn.GetPath(), getAutoSaveFileName() );
|
|
|
|
|
|
|
|
wxLogTrace( traceAutoSave, "Creating auto save file %s", autoSaveFileName.GetFullPath() );
|
|
|
|
|
|
|
|
wxCHECK( autoSaveFileName.IsDirWritable(), false );
|
|
|
|
|
|
|
|
wxFileName fn;
|
|
|
|
SCH_SCREENS screens( Schematic().Root() );
|
|
|
|
std::vector< wxString > autoSavedFiles;
|
|
|
|
|
|
|
|
for( size_t i = 0; i < screens.GetCount(); i++ )
|
|
|
|
{
|
|
|
|
// Only create auto save files for the schematics that have been modified.
|
|
|
|
if( !screens.GetScreen( i )->IsContentModified() )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
fn = screens.GetScreen( i )->GetFileName();
|
|
|
|
|
|
|
|
// Auto save file name is the normal file name prefixed with GetAutoSavePrefix().
|
2024-04-22 00:58:13 +00:00
|
|
|
fn.SetName( FILEEXT::AutoSaveFilePrefix + fn.GetName() );
|
2021-10-13 18:48:28 +00:00
|
|
|
autoSavedFiles.emplace_back( fn.GetFullPath() );
|
|
|
|
}
|
|
|
|
|
|
|
|
wxTextFile autoSaveFile( autoSaveFileName.GetFullPath() );
|
|
|
|
|
|
|
|
if( autoSaveFileName.FileExists() && !wxRemoveFile( autoSaveFileName.GetFullPath() ) )
|
|
|
|
{
|
|
|
|
wxLogTrace( traceAutoSave, "Error removing auto save file %s",
|
|
|
|
autoSaveFileName.GetFullPath() );
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// No modified sheet files to save.
|
|
|
|
if( autoSavedFiles.empty() )
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if( !autoSaveFile.Create() )
|
|
|
|
return false;
|
|
|
|
|
2021-10-17 23:29:10 +00:00
|
|
|
for( const wxString& fileName : autoSavedFiles )
|
2021-10-13 18:48:28 +00:00
|
|
|
{
|
|
|
|
wxLogTrace( traceAutoSave, "Adding auto save file %s to %s",
|
|
|
|
fileName, autoSaveFileName.GetName() );
|
|
|
|
autoSaveFile.AddLine( fileName );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !autoSaveFile.Write() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
wxLogTrace( traceAutoSave, "Auto save file '%s' written", autoSaveFileName.GetFullName() );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
void removeFile( const wxString& aFilename, wxArrayString& aUnremoved )
|
|
|
|
{
|
|
|
|
wxLogTrace( traceAutoSave, wxS( "Removing auto save file " ) + aFilename );
|
|
|
|
|
|
|
|
if( wxFileExists( aFilename ) && !wxRemoveFile( aFilename ) )
|
|
|
|
aUnremoved.Add( aFilename );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-10-13 18:48:28 +00:00
|
|
|
void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
|
|
|
{
|
2023-03-24 23:45:56 +00:00
|
|
|
if( !Pgm().IsGUI() )
|
2023-01-19 00:53:16 +00:00
|
|
|
return;
|
|
|
|
|
2023-10-12 13:36:28 +00:00
|
|
|
wxCHECK_RET( aFileName.IsOk(), wxS( "Invalid file name!" ) );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
wxLogTrace( traceAutoSave,
|
2023-10-12 13:36:28 +00:00
|
|
|
wxS( "Checking for auto save file " ) + aFileName.GetFullPath() );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
if( !aFileName.FileExists() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
wxString msg = _(
|
|
|
|
"Well this is potentially embarrassing!\n"
|
|
|
|
"It appears that the last time you were editing one or more of the schematic files\n"
|
|
|
|
"were not saved properly. Do you wish to restore the last saved edits you made?" );
|
|
|
|
|
|
|
|
int response = wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxYES_NO | wxICON_QUESTION,
|
|
|
|
this );
|
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
wxTextFile fileList( aFileName.GetFullPath() );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
if( !fileList.Open() )
|
2021-10-13 18:48:28 +00:00
|
|
|
{
|
2023-11-05 12:19:51 +00:00
|
|
|
msg.Printf( _( "The file '%s' could not be opened.\n"
|
2021-10-13 18:48:28 +00:00
|
|
|
"Manual recovery of automatically saved files is required." ),
|
|
|
|
aFileName.GetFullPath() );
|
|
|
|
|
|
|
|
wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( response == wxYES )
|
|
|
|
{
|
|
|
|
wxArrayString unrecoveredFiles;
|
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
|
2021-10-13 18:48:28 +00:00
|
|
|
{
|
|
|
|
wxFileName recoveredFn = fn;
|
|
|
|
wxString tmp = recoveredFn.GetName();
|
|
|
|
|
|
|
|
// Strip "_autosave-" prefix from the auto save file name.
|
2024-04-22 00:58:13 +00:00
|
|
|
tmp.Replace( FILEEXT::AutoSaveFilePrefix, wxS( "" ), false );
|
2021-10-13 18:48:28 +00:00
|
|
|
recoveredFn.SetName( tmp );
|
|
|
|
|
|
|
|
wxFileName backupFn = recoveredFn;
|
|
|
|
|
2023-12-28 02:10:01 +00:00
|
|
|
backupFn.SetExt( backupFn.GetExt() + FILEEXT::BackupFileSuffix );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-10-12 13:36:28 +00:00
|
|
|
wxLogTrace( traceAutoSave, wxS( "Recovering auto save file:\n"
|
2021-10-13 18:48:28 +00:00
|
|
|
" Original file: '%s'\n"
|
|
|
|
" Backup file: '%s'\n"
|
|
|
|
" Auto save file: '%s'" ),
|
|
|
|
recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
|
|
|
|
|
2022-11-22 15:21:26 +00:00
|
|
|
if( !wxFileExists( fn ) )
|
|
|
|
{
|
|
|
|
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
|
|
|
}
|
2021-10-13 18:48:28 +00:00
|
|
|
// Attempt to back up the last schematic file before overwriting it with the auto
|
|
|
|
// save file.
|
2024-05-05 13:57:07 +00:00
|
|
|
else if( recoveredFn.Exists()
|
|
|
|
&& !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
|
2021-10-13 18:48:28 +00:00
|
|
|
{
|
|
|
|
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
|
|
|
}
|
2022-11-22 15:21:26 +00:00
|
|
|
// Attempt to replace last saved file with auto save file
|
2021-10-13 18:48:28 +00:00
|
|
|
else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
|
|
|
|
{
|
|
|
|
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !unrecoveredFiles.IsEmpty() )
|
|
|
|
{
|
|
|
|
msg = _( "The following automatically saved file(s) could not be restored\n" );
|
|
|
|
|
|
|
|
for( size_t i = 0; i < unrecoveredFiles.GetCount(); i++ )
|
2023-10-12 13:36:28 +00:00
|
|
|
msg += unrecoveredFiles[i] + wxS( "\n" );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
msg += _( "Manual recovery will be required to restore the file(s) above." );
|
|
|
|
wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION,
|
|
|
|
this );
|
|
|
|
}
|
2023-11-05 12:19:51 +00:00
|
|
|
|
2021-10-13 18:48:28 +00:00
|
|
|
wxArrayString unremovedFiles;
|
2023-11-05 12:19:51 +00:00
|
|
|
removeFile( aFileName.GetFullPath(), unremovedFiles );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
if( !unremovedFiles.IsEmpty() )
|
2021-10-13 18:48:28 +00:00
|
|
|
{
|
2023-11-05 12:19:51 +00:00
|
|
|
msg.Printf( _( "The autosave file '%s' could not be removed.\n"
|
|
|
|
"Manual removal will be required." ),
|
|
|
|
unremovedFiles[0] );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
|
2021-10-13 18:48:28 +00:00
|
|
|
}
|
2023-11-05 12:19:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DeleteAutoSaveFile( aFileName );
|
|
|
|
}
|
|
|
|
}
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
void SCH_EDIT_FRAME::DeleteAutoSaveFile( const wxFileName& aFileName )
|
|
|
|
{
|
|
|
|
if( !Pgm().IsGUI() )
|
|
|
|
return;
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
wxCHECK_RET( aFileName.IsOk(), wxS( "Invalid file name!" ) );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
if( !aFileName.FileExists() )
|
|
|
|
return;
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
wxTextFile fileList( aFileName.GetFullPath() );
|
|
|
|
wxArrayString unremovedFiles;
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
for( wxString fn = fileList.GetFirstLine(); !fileList.Eof(); fn = fileList.GetNextLine() )
|
|
|
|
removeFile( fn, unremovedFiles );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
removeFile( aFileName.GetFullPath(), unremovedFiles );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
2023-11-05 12:19:51 +00:00
|
|
|
if( !unremovedFiles.IsEmpty() )
|
|
|
|
{
|
|
|
|
wxString msg = _( "The following automatically saved file(s) could not be removed\n" );
|
|
|
|
|
|
|
|
for( size_t i = 0; i < unremovedFiles.GetCount(); i++ )
|
|
|
|
msg += unremovedFiles[i] + wxS( "\n" );
|
|
|
|
|
|
|
|
msg += _( "Manual removal will be required for the file(s) above." );
|
|
|
|
wxMessageBox( msg, Pgm().App().GetAppDisplayName(), wxOK | wxICON_EXCLAMATION, this );
|
2021-10-13 18:48:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const wxString& SCH_EDIT_FRAME::getAutoSaveFileName() const
|
|
|
|
{
|
2023-10-12 13:36:28 +00:00
|
|
|
static wxString autoSaveFileName( wxS( "#auto_saved_files#" ) );
|
2021-10-13 18:48:28 +00:00
|
|
|
|
|
|
|
return autoSaveFileName;
|
|
|
|
}
|