mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Fix project lock both working and not working.
Turns out project locks would get created and only stick around for a short duration as the default move constructor was letting the og object free the lock. But if you crashed kicad or managed something weird, you can get a lock file with no override prompt which also creates confusion as some stuff gets set read only. So lets just fix this up. - Implement move constructor on lockfile so that the old object will no longer free the lockfile - Move lock ownership to the project itself, just slightly less weird to handle for the lock override - Implement the override lock prompt
This commit is contained in:
parent
e615fcfe90
commit
9d32d208b8
@ -33,6 +33,7 @@
|
||||
#include <string_utils.h>
|
||||
#include <kiface_ids.h>
|
||||
#include <kiway.h>
|
||||
#include <lockfile.h>
|
||||
#include <macros.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h>
|
||||
@ -42,6 +43,7 @@
|
||||
#include <settings/settings_manager.h>
|
||||
#include <title_block.h>
|
||||
|
||||
|
||||
PROJECT::PROJECT() :
|
||||
m_readOnly( false ),
|
||||
m_textVarsTicker( 0 ),
|
||||
@ -460,3 +462,15 @@ DESIGN_BLOCK_LIB_TABLE* PROJECT::DesignBlockLibs()
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
|
||||
void PROJECT::SetProjectLock( LOCKFILE* aLockFile )
|
||||
{
|
||||
m_project_lock.reset( aLockFile );
|
||||
}
|
||||
|
||||
|
||||
LOCKFILE* PROJECT::GetProjectLock() const
|
||||
{
|
||||
return m_project_lock.get();
|
||||
}
|
@ -939,13 +939,11 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
|
||||
if( m_projects.count( fullPath ) )
|
||||
return true;
|
||||
|
||||
bool readOnly = false;
|
||||
LOCKFILE lockFile( fullPath );
|
||||
|
||||
if( !lockFile.Valid() )
|
||||
{
|
||||
wxLogTrace( traceSettings, wxT( "Project %s is locked; opening read-only" ), fullPath );
|
||||
readOnly = true;
|
||||
}
|
||||
|
||||
// No MDI yet
|
||||
@ -986,10 +984,10 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
|
||||
|
||||
if( success )
|
||||
{
|
||||
project->SetReadOnly( readOnly || project->GetProjectFile().IsReadOnly() );
|
||||
project->SetReadOnly( !lockFile.Valid() || project->GetProjectFile().IsReadOnly() );
|
||||
|
||||
if( lockFile && aSetActive )
|
||||
m_project_lock.reset( new LOCKFILE( std::move( lockFile ) ) );
|
||||
project->SetProjectLock( new LOCKFILE( std::move( lockFile ) ) );
|
||||
}
|
||||
|
||||
m_projects_list.push_back( std::move( project ) );
|
||||
@ -1048,9 +1046,6 @@ bool SETTINGS_MANAGER::UnloadProject( PROJECT* aProject, bool aSave )
|
||||
// Remove the reference in the environment to the previous project
|
||||
wxSetEnv( PROJECT_VAR_NAME, wxS( "" ) );
|
||||
|
||||
// Release lock on the file, in case we had one
|
||||
m_project_lock = nullptr;
|
||||
|
||||
if( m_kiway )
|
||||
m_kiway->ProjectChanged();
|
||||
}
|
||||
|
@ -127,6 +127,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
LOCKFILE( LOCKFILE&& other ) noexcept :
|
||||
m_originalFile( std::move( other.m_originalFile ) ),
|
||||
m_lockFilename( std::move( other.m_lockFilename ) ),
|
||||
m_username( std::move( other.m_username ) ),
|
||||
m_hostname( std::move( other.m_hostname ) ),
|
||||
m_fileCreated( other.m_fileCreated ),
|
||||
m_status( other.m_status ),
|
||||
m_removeOnRelease( other.m_removeOnRelease ),
|
||||
m_errorMsg( std::move( other.m_errorMsg ) )
|
||||
{
|
||||
// Disable unlock in the moved-from object
|
||||
other.m_fileCreated = false;
|
||||
}
|
||||
|
||||
~LOCKFILE()
|
||||
{
|
||||
UnlockFile();
|
||||
|
@ -52,6 +52,7 @@ class SYMBOL_LIB_TABLE;
|
||||
class FILENAME_RESOLVER;
|
||||
class PROJECT_FILE;
|
||||
class PROJECT_LOCAL_SETTINGS;
|
||||
class LOCKFILE;
|
||||
|
||||
|
||||
/**
|
||||
@ -217,9 +218,9 @@ public:
|
||||
{
|
||||
DOC_PATH,
|
||||
SCH_LIB_PATH,
|
||||
SCH_LIB_SELECT, // eeschema/selpart.cpp
|
||||
SCH_LIB_SELECT, // eeschema/selpart.cpp
|
||||
SCH_LIBEDIT_CUR_LIB,
|
||||
SCH_LIBEDIT_CUR_SYMBOL, // eeschema/libeditframe.cpp
|
||||
SCH_LIBEDIT_CUR_SYMBOL, // eeschema/libeditframe.cpp
|
||||
|
||||
VIEWER_3D_PATH,
|
||||
VIEWER_3D_FILTER_INDEX,
|
||||
@ -270,11 +271,11 @@ public:
|
||||
/**
|
||||
* Clear the _ELEMs and RSTRINGs.
|
||||
*/
|
||||
void Clear() // inline not virtual
|
||||
void Clear() // inline not virtual
|
||||
{
|
||||
elemsClear();
|
||||
|
||||
for( unsigned i = 0; i<RSTRING_COUNT; ++i )
|
||||
for( unsigned i = 0; i < RSTRING_COUNT; ++i )
|
||||
SetRString( RSTRING_T( i ), wxEmptyString );
|
||||
}
|
||||
|
||||
@ -297,6 +298,10 @@ public:
|
||||
*/
|
||||
virtual DESIGN_BLOCK_LIB_TABLE* DesignBlockLibs();
|
||||
|
||||
void SetProjectLock( LOCKFILE* aLockFile );
|
||||
|
||||
LOCKFILE* GetProjectLock() const;
|
||||
|
||||
private:
|
||||
friend class SETTINGS_MANAGER; // so that SM can set project path
|
||||
friend class TEST_NETLISTS_FIXTURE; // TODO(JE) make this not required
|
||||
@ -366,6 +371,9 @@ private:
|
||||
|
||||
/// @see this::Elem() and enum ELEM_T.
|
||||
std::array<_ELEM*,static_cast<unsigned int>( PROJECT::ELEM::COUNT )> m_elems;
|
||||
|
||||
/// Lock
|
||||
std::unique_ptr<LOCKFILE> m_project_lock;
|
||||
};
|
||||
|
||||
|
||||
|
@ -531,9 +531,6 @@ private:
|
||||
/// Loaded project files, mapped according to project full name.
|
||||
std::map<wxString, PROJECT_FILE*> m_project_files;
|
||||
|
||||
/// Lock for loaded project (expand to multiple once we support MDI).
|
||||
std::unique_ptr<LOCKFILE> m_project_lock;
|
||||
|
||||
static wxString backupDateTimeFormat;
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <kiway.h>
|
||||
#include <kiway_express.h>
|
||||
#include <launch_ext.h>
|
||||
#include <lockfile.h>
|
||||
#include <notifications_manager.h>
|
||||
#include <reporter.h>
|
||||
#include <project/project_local_settings.h>
|
||||
@ -68,6 +69,7 @@
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/dnd.h>
|
||||
#include <wx/process.h>
|
||||
#include <wx/snglinst.h>
|
||||
#include <atomic>
|
||||
#include <update_manager.h>
|
||||
#include <jobs/jobset.h>
|
||||
@ -1035,7 +1037,42 @@ void KICAD_MANAGER_FRAME::CommonSettingsChanged( int aFlags )
|
||||
|
||||
void KICAD_MANAGER_FRAME::ProjectChanged()
|
||||
{
|
||||
wxString file = GetProjectFileName();
|
||||
wxString file = GetProjectFileName();
|
||||
|
||||
// empty file string means no project loaded
|
||||
if( !Prj().IsNullProject() &&
|
||||
Prj().GetProjectLock() == nullptr )
|
||||
{
|
||||
LOCKFILE lockFile( file );
|
||||
|
||||
if( !lockFile.Valid() && lockFile.IsLockedByMe() )
|
||||
{
|
||||
// If we cannot acquire the lock but we appear to be the one who
|
||||
// locked it, check to see if there is another KiCad instance running.
|
||||
// If there is not, then we can override the lock. This could happen if
|
||||
// KiCad crashed or was interrupted
|
||||
if( !Pgm().SingleInstance()->IsAnotherRunning() )
|
||||
{
|
||||
lockFile.OverrideLock();
|
||||
}
|
||||
}
|
||||
|
||||
if( !lockFile.Valid() )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Project '%s' is already open by '%s' at '%s'." ), file, lockFile.GetUsername(),
|
||||
lockFile.GetHostname() );
|
||||
|
||||
if( AskOverrideLock( this, msg ) )
|
||||
{
|
||||
lockFile.OverrideLock();
|
||||
}
|
||||
}
|
||||
|
||||
Prj().SetReadOnly( !lockFile.Valid() || Prj().GetProjectFile().IsReadOnly() );
|
||||
Prj().SetProjectLock( new LOCKFILE( std::move( lockFile ) ) );
|
||||
}
|
||||
|
||||
wxString title;
|
||||
|
||||
if( !file.IsEmpty() )
|
||||
|
Loading…
x
Reference in New Issue
Block a user