Currently KiCad applications allow opening the same file more than once,
and they don't check if the files have changed in disk before saving. As
a consequence, there can be situations where the user loses some data
without notice.
This patch uses wxSingleInstanceChecker to create a lock on the open
file. It is checked every time Eeschema tries to open a file. We can
distinguish two situations:
* Open a file when the application is started. In this case, if the lock
is unsuccessful the application closes, it doesn't even show the alert
about other instances running.
* Open another file from the menu (file -> open or tool bar). In this
case, if the lock is unsuccessful the application remains open with its
contents unchanged.
Finally, this patch is a starting point to implement similar checks in
other KiCad applications.
--
Jacobo
=== modified file 'common/edaappl.cpp'
--- common/edaappl.cpp 2012-11-09 06:58:00 +0000
+++ common/edaappl.cpp 2013-01-03 17:22:08 +0000
@@ -273,6 +273,7 @@
EDA_APP::EDA_APP()
{
m_Checker = NULL;
+ m_oneInstancePerFileChecker = NULL;
m_HtmlCtrl = NULL;
m_settings = NULL;
m_LanguageId = wxLANGUAGE_DEFAULT;
@@ -298,6 +299,9 @@
if( m_Checker )
delete m_Checker;
+ if( m_oneInstancePerFileChecker )
+ delete m_oneInstancePerFileChecker;
+
delete m_Locale;
}
@@ -1124,3 +1128,23 @@
}
}
}
+
+bool EDA_APP::LockFile( const wxString& fileName )
+{
+ // semaphore to protect the edition of the file by more than one instance
+ if( m_oneInstancePerFileChecker != NULL )
+ {
+ // it means that we had an open file and we are opening a different one
+ delete m_oneInstancePerFileChecker;
+ }
+ wxString lockFileName = fileName + wxT( ".lock" );
+ lockFileName.Replace( wxT( "/" ), wxT( "_" ) );
+ m_oneInstancePerFileChecker = new wxSingleInstanceChecker( lockFileName );
+ if( m_oneInstancePerFileChecker &&
+ m_oneInstancePerFileChecker->IsAnotherRunning() )
+ {
+ return false;
+ }
+
+ return true;
+}
=== modified file 'eeschema/eeschema.cpp'
--- eeschema/eeschema.cpp 2012-10-31 20:27:31 +0000
+++ eeschema/eeschema.cpp 2013-01-03 17:22:08 +0000
@@ -89,18 +89,33 @@
{
wxFileName filename;
SCH_EDIT_FRAME* frame = NULL;
+ bool fileReady = false;
InitEDA_Appl( wxT( "Eeschema" ), APP_EESCHEMA_T );
- if( m_Checker && m_Checker->IsAnotherRunning() )
- {
- if( !IsOK( NULL, _( "Eeschema is already running, Continue?" ) ) )
- return false;
- }
-
if( argc > 1 )
filename = argv[1];
+ if( filename.IsOk() )
+ {
+ if( filename.GetExt() != SchematicFileExtension )
+ filename.SetExt( SchematicFileExtension );
+
+ if( !wxGetApp().LockFile( filename.GetFullPath() ) )
+ {
+ DisplayError( NULL, _( "This file is already open." ) );
+ return false;
+ }
+
+ fileReady = true;
+ }
+
+ if( m_Checker && m_Checker->IsAnotherRunning() )
+ {
+ if( !IsOK( NULL, _( "Eeschema is already running, Continue?" ) ) )
+ return false;
+ }
+
// Give a default colour for all layers
// (actual color will beinitialized by config)
for( int ii = 0; ii < MAX_LAYERS; ii++ )
@@ -130,11 +145,8 @@
frame->Zoom_Automatique( true );
/* Load file specified in the command line. */
- if( filename.IsOk() )
+ if( fileReady )
{
- if( filename.GetExt() != SchematicFileExtension )
- filename.SetExt( SchematicFileExtension );
-
wxSetWorkingDirectory( filename.GetPath() );
if( frame->LoadOneEEProject( filename.GetFullPath(), false ) )
=== modified file 'eeschema/files-io.cpp'
--- eeschema/files-io.cpp 2012-09-28 17:47:41 +0000
+++ eeschema/files-io.cpp 2013-01-03 17:22:08 +0000
@@ -32,6 +32,7 @@
#include <confirm.h>
#include <gestfich.h>
#include <wxEeschemaStruct.h>
+#include <appl_wxstruct.h>
#include <general.h>
#include <protos.h>
@@ -204,6 +205,21 @@
FullFileName = dlg.GetPath();
}
+ wxFileName fn = FullFileName;
+
+ if( fn.IsRelative() )
+ {
+ fn.MakeAbsolute();
+ FullFileName = fn.GetFullPath();
+ }
+
+ if( !wxGetApp().LockFile( FullFileName ) )
+ {
+ DisplayError( this, _( "This file is already open." ) );
+ return false;
+ }
+
+ // Clear the screen before open a new file
if( g_RootSheet )
{
SAFE_DELETE( g_RootSheet );
@@ -212,14 +228,6 @@
CreateScreens();
screen = GetScreen();
- wxFileName fn = FullFileName;
-
- if( fn.IsRelative() )
- {
- fn.MakeAbsolute();
- FullFileName = fn.GetFullPath();
- }
-
wxLogDebug( wxT( "Loading schematic " ) + FullFileName );
wxSetWorkingDirectory( fn.GetPath() );
=== modified file 'include/appl_wxstruct.h'
--- include/appl_wxstruct.h 2012-08-02 07:47:30 +0000
+++ include/appl_wxstruct.h 2013-01-03 17:22:08 +0000
@@ -67,6 +67,9 @@
/// Used to prevent multiple instances of an application from being run at the same time.
wxSingleInstanceChecker* m_Checker;
+ /// Used to prevent opening the same file multiple times.
+ wxSingleInstanceChecker* m_oneInstancePerFileChecker;
+
wxString m_Project;
/// The application specific configuration settings.
@@ -410,6 +413,13 @@
*/
void InsertLibraryPath( const wxString& aPaths, size_t aIndex );
+ /**
+ * Function LockFile
+ * Locks the access to a file.
+ * @param fileName = full path to the file.
+ * @return false if the file was already locked, true otherwise.
+ */
+ bool LockFile( const wxString& fileName );
};
/*
_______________________________________________
Mailing list: https://launchpad.net/~kicad-developers
Post to : [email protected]
Unsubscribe : https://launchpad.net/~kicad-developers
More help : https://help.launchpad.net/ListHelp