From cab0b0830a13cf390528cdd701f683330c681981 Mon Sep 17 00:00:00 2001 From: sln Date: Wed, 30 Nov 2011 07:58:42 +0000 Subject: [PATCH] Implementation of GUITHARE External 20547, GUITHARE Internal 790. Automatic backup see "http://doc.nnov.opencascade.com/doku.php?id=projects:guithare:gui_backup" for more info --- src/LightApp/LightApp_Application.cxx | 53 +++- src/LightApp/LightApp_Application.h | 6 + src/LightApp/LightApp_DataModel.cxx | 8 + src/LightApp/LightApp_DataModel.h | 2 + src/LightApp/LightApp_Study.cxx | 200 ++++++++++++++- src/LightApp/LightApp_Study.h | 8 + src/LightApp/resources/LightApp.xml | 1 + src/LightApp/resources/LightApp_msg_en.ts | 4 + src/SUIT/SUIT_Application.cxx | 22 ++ src/SUIT/SUIT_Application.h | 4 + src/SUIT/SUIT_Session.cxx | 289 ++++++++++++++++++++-- src/SUIT/SUIT_Session.h | 14 ++ src/SUIT/SUIT_Study.cxx | 1 + src/SUIT/resources/SUIT_msg_en.ts | 8 + 14 files changed, 594 insertions(+), 26 deletions(-) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index deb77a743..f53fa4f3a 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -290,15 +290,15 @@ LightApp_Application::LightApp_Application() QStringList anAddFamilies = aResMgr->stringValue( "PyConsole", "additional_families" ).split( ";", QString::SkipEmptyParts ); QString aFamily; for ( QStringList::Iterator it = anAddFamilies.begin(); it != anAddFamilies.end(); ++it ) + { + aFamily = *it; + if ( famdb.contains(aFamily) ) { - aFamily = *it; - if ( famdb.contains(aFamily) ) - { - f.setFamily( aFamily ); - aResMgr->setValue( "PyConsole", "font", f ); - break; - } + f.setFamily( aFamily ); + aResMgr->setValue( "PyConsole", "font", f ); + break; } + } } /*!Destructor. @@ -1826,6 +1826,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" ); pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" ); pref->addPreference( tr( "PREF_STORE_POS" ), studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" ); + pref->addPreference( tr( "PREF_BACKUP" ), studyGroup, LightApp_Preferences::DblSpin, "Study", "backup_studies" ); int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab ); QString platform; @@ -2431,6 +2432,9 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString aSStyle->polish(qApp); } } + + double time = resMgr->doubleValue( "Study", "backup_studies", 0. ); + SUIT_Session::session()->setBackupTime( time ); } /*! @@ -2907,6 +2911,10 @@ void LightApp_Application::createEmptyStudy() if ( objectBrowser() ) objectBrowser()->updateTree(); + + LightApp_Study* aStudy = (LightApp_Study*)activeStudy(); + aStudy->setRestoreFolder( myBFolder ); + //myBFolder = ""; } /*! @@ -3229,4 +3237,33 @@ bool LightApp_Application::openAction( const int choice, const QString& aName ) } return res; -} \ No newline at end of file +} + +/*! + * Calls 'backup' method of active study + */ +void LightApp_Application::backup( const QString& fName ) +{ + LightApp_Study* study = dynamic_cast( activeStudy() ); + if ( study ) + study->backup( fName ); +} + +/*! + * Keeps folder to be used for restoring. + */ +void LightApp_Application::setRestoreFolder( const QString& fName ) +{ + myBFolder = fName; +} + +/*! + * Gets backup time from preferences; this method is used by session when backup timer is created. +*/ +double LightApp_Application::getBackupTime() const +{ + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + double res = resMgr->doubleValue( "Study", "backup_studies", 0. ); + return res; +} + diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index ae6522855..3fe5d6ced 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -144,6 +144,10 @@ public: virtual void updateDesktopTitle(); + virtual void backup( const QString& fName ); + virtual void setRestoreFolder( const QString& fName ); + virtual double getBackupTime() const; + signals: void studyOpened(); void studySaved(); @@ -264,6 +268,8 @@ protected: static LightApp_Preferences* _prefs_; static int lastStudyId; + + QString myBFolder; }; #ifdef WIN32 diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx index 0b8b2cef6..e37bd9c88 100644 --- a/src/LightApp/LightApp_DataModel.cxx +++ b/src/LightApp/LightApp_DataModel.cxx @@ -361,3 +361,11 @@ LightApp_DataObject* LightApp_DataModel::findObjectByEntry( SUIT_DataBrowser* th } return NULL; } + +/*! + to do: +*/ +void LightApp_DataModel::backup( const QString& /*fName*/, QStringList& files ) +{ + +} diff --git a/src/LightApp/LightApp_DataModel.h b/src/LightApp/LightApp_DataModel.h index 2148aab41..91da54d4f 100644 --- a/src/LightApp/LightApp_DataModel.h +++ b/src/LightApp/LightApp_DataModel.h @@ -74,6 +74,8 @@ public: LightApp_DataObject* findObjectByEntry( SUIT_DataBrowser* theOB, const QString& theEntry ); + virtual void backup( const QString& fName, QStringList& files ); + signals: void opened(); void saved(); diff --git a/src/LightApp/LightApp_Study.cxx b/src/LightApp/LightApp_Study.cxx index 900f142e8..dda081079 100644 --- a/src/LightApp/LightApp_Study.cxx +++ b/src/LightApp/LightApp_Study.cxx @@ -24,12 +24,14 @@ #include "LightApp_DataModel.h" #include "LightApp_DataObject.h" #include "LightApp_HDFDriver.h" +#include "LightApp_Module.h" #include "SUIT_ResourceMgr.h" #include "SUIT_DataObjectIterator.h" #include #include +#include /*! Constructor. @@ -73,8 +75,17 @@ bool LightApp_Study::openDocument( const QString& theFileName ) { myDriver->ClearDriverContents(); // create files for models from theFileName - if( !openStudyData(theFileName)) - return false; + + if ( myRestFolder.isEmpty() ) + { + if( !openStudyData(theFileName)) + return false; + } + else + { + // Case when study is restored from backup + openBackupData(); + } setRoot( new LightApp_RootObject( this ) ); // create myRoot @@ -92,6 +103,13 @@ bool LightApp_Study::openDocument( const QString& theFileName ) bool res = CAM_Study::openDocument( theFileName ); emit opened( this ); + + if ( !myRestFolder.isEmpty() ) + { + setIsSaved( false ); + //myRestFolder = ""; + } + return res; } @@ -458,3 +476,181 @@ void LightApp_Study::components( QStringList& comp ) const comp.append( obj->entry() ); } } + +/*! + * Keeps folder to be used for restoring. + */ +void LightApp_Study::setRestoreFolder( const QString& folder ) +{ + myRestFolder = folder; +} + +/*! + * - Call LightApp_DataModel::backup() for each data model + * - Creates "data" file in backup folder; this file contains name of opened + * HDF-file if study was stored or opened, name of temporary folder used + * by LightApp_Driver for study opening, list of backup files created by each model + */ +void LightApp_Study::backup( const QString& fName ) +{ + QList list; + dataModels( list ); + + QListIterator itList( list ); + while ( itList.hasNext() ) + { + LightApp_DataModel* model = (LightApp_DataModel*)itList.next(); + if ( model && model->getModule() ) + { + // writes location of hdf-file + QString hdfName = QString( "HDF:" ) + studyName() + "\n"; + + //QString tmpName = QString( " ) + GetTmpDir( "", false ).c_str() + "\n"; + QString tmpName( "TMP:" ); + + LightApp_Driver::ListOfFiles files = + myDriver->GetListOfFiles( model->getModule()->name().toLatin1().constData() ); + if ( files.size() > 0 ) + tmpName += files.front().c_str(); + else + { + // New (not saved study). Use backup folder as default + tmpName += fName; + } + tmpName += '\n'; + + QString dataName = Qtx::addSlash( fName ) + "data"; + FILE* f = fopen( dataName.toLatin1().constData(), "w" ); + if ( f ) + { + fputs( hdfName.toLatin1().constData(), f ); + fputs( tmpName.toLatin1().constData(), f ); + + // backup model + QStringList backupFiles; + model->backup( fName, backupFiles ); + + // module data string + CAM_Module* mod = model->module(); + { + QString modStr = mod->name(); + QStringList::iterator it; + for ( it = backupFiles.begin(); it != backupFiles.end(); ++it ) + { + const QString& curr = * it; + modStr += QString( "*" ) + curr; + } + fputs( modStr.toLatin1().constData(), f ); + } + fclose( f ); + } + } + } +} + +/*! + * Prepare files to be used by data models for restoring; these files are + * created from backup files and files of previously opened study. + */ +bool LightApp_Study::openBackupData() +{ + // Case when study is restored from backup + // Here: + // tmpFolder - folder where temporary files of previously opened study was saved (ex. D:\temp\84623) + // hdfName – name of HDF-file of previous study, if exists. + // backupFolder – folder with backup files. + + // Main idea: + // - Parse “data” file and gets file names, Fill driver with files of results tmpFolder. + // - Move all files from backup to tmp. + // - Open study using this files. + // - Redirect name of opened study to previous hdfName. + + // Parse “data” + + // data-file - something like this + // HDF:D:/sln/CATHARE/Data/1.hdf + // TMP:d:\temp\84623\ + // CATHAREGUI*1.cbf + QString dataName = Qtx::addSlash( myRestFolder ) + "data"; + FILE* f = fopen( dataName.toLatin1().constData(), "r" ); + if ( !f ) + return false; + + char buff[ 1024 ]; + + // hdf-name + memset( buff, 0, 1024 ); + fgets( buff, 1024, f ); + QString hdfName( buff ); + hdfName.remove( '\n' ); + hdfName.remove( "HDF:" ); + + // name of temporary file + memset( buff, 0, 1024 ); + fgets( buff, 1024, f ); + QString tmpFolder( buff ); + tmpFolder.remove( '\n' ); + tmpFolder.remove( "TMP:" ); + + // list of files + QString modName; + LightApp_Driver::ListOfFiles modFiles; + while( !feof( f ) ) + { + modName = ""; + modFiles.clear(); + + memset( buff, 0, 1024 ); + fgets( buff, 1024, f ); + QString modStr( buff ); + + QStringList lst = modStr.split( "*" ); + QStringList::iterator it = lst.begin(); + for ( int i = 0; it != lst.end(); ++it, ++i ) + { + const QString& curr = *it; + if ( i == 0 ) + { + modName = curr; + modFiles.push_back( Qtx::addSlash( tmpFolder ).toLatin1().constData() ); + continue; + } + else + modFiles.push_back( curr.toLatin1().constData() ); + } + + // fill driver + myDriver->SetListOfFiles( modName.toLatin1().constData(), modFiles ); + } + + fclose( f ); + + // Move all files from backup to tmp + + if ( !QFileInfo( tmpFolder ).exists() ) + QDir().mkdir( tmpFolder ); + + if ( !QFileInfo( tmpFolder ).exists() ) + return false; + + QDir restDir( myRestFolder ); + QStringList restList = restDir.entryList ( QDir::AllEntries ); + QStringList::iterator it; + for ( it = restList.begin(); it != restList.end(); ++it ) + { + const QString& locName = *it; + if ( locName == "." || locName == ".." || locName == "data" ) + continue; + + QString oldName = QDir::convertSeparators( Qtx::addSlash( myRestFolder ) + locName ); + QString newName = QDir::convertSeparators( Qtx::addSlash( tmpFolder ) + locName ); + if ( oldName != newName ) // oldName == newName for non-saved study + { + QFile::remove( newName ); + QFile::copy( oldName, newName ); + } + } + return true; +} + diff --git a/src/LightApp/LightApp_Study.h b/src/LightApp/LightApp_Study.h index 3e307ceea..142bdbcc6 100644 --- a/src/LightApp/LightApp_Study.h +++ b/src/LightApp/LightApp_Study.h @@ -66,6 +66,9 @@ public: virtual void children( const QString&, QStringList& ) const; virtual void components( QStringList& ) const; + void backup( const QString& fName); + void setRestoreFolder( const QString& folder ); + protected: virtual void saveModuleData ( QString theModuleName, QStringList theListOfFiles ); virtual void openModuleData ( QString theModuleName, QStringList& theListOfFiles ); @@ -87,9 +90,14 @@ signals: void closed ( SUIT_Study* ); void created( SUIT_Study* ); +private: + + bool openBackupData(); + private: LightApp_Driver* myDriver; + QString myRestFolder; friend class LightApp_Application; }; diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index 80011cfaf..06cd5bff4 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -87,6 +87,7 @@
+
diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 97a13a8bf..29985e9ea 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -81,6 +81,10 @@ CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITASPREF_STORE_POS Store positions of windows + + PREF_BACKUP + Backup every N minutes + PREF_PROJECTION_MODE Projection mode: diff --git a/src/SUIT/SUIT_Application.cxx b/src/SUIT/SUIT_Application.cxx index c9ef2a243..0a7b9ecf3 100755 --- a/src/SUIT/SUIT_Application.cxx +++ b/src/SUIT/SUIT_Application.cxx @@ -694,3 +694,25 @@ void SUIT_Application::setLastUsedPrinter( const QString& thePrinterName ) if( SUIT_ResourceMgr* aResMgr = resourceMgr() ) aResMgr->setValue( "Printer", "last_used_printer", thePrinterName ); } + +/*! + * Curent implementation does nothing; calls 'backup' method of active study in LightApp_Application + */ +void SUIT_Application::backup( const QString& /*fName*/ ) +{ +} + +/*! + * SUIT_Application does nothing; LightApp_Application keeps folder to be used for restoring. + */ +void SUIT_Application::setRestoreFolder( const QString& /*fName*/ ) +{ +} + +/*! + * Gets backup time from preferences; this method is used by session when backup timer is created. + */ +double SUIT_Application::getBackupTime() const +{ + return 0; +} diff --git a/src/SUIT/SUIT_Application.h b/src/SUIT/SUIT_Application.h index 7bf04f5a5..4d81b4f42 100755 --- a/src/SUIT/SUIT_Application.h +++ b/src/SUIT/SUIT_Application.h @@ -109,6 +109,10 @@ public: //! Sets a name of the last used printer void setLastUsedPrinter( const QString& ); + virtual void backup( const QString& fName ); + virtual void setRestoreFolder( const QString& fName ); + virtual double getBackupTime() const; + signals: void applicationClosed( SUIT_Application* ); void activated( SUIT_Application* ); diff --git a/src/SUIT/SUIT_Session.cxx b/src/SUIT/SUIT_Session.cxx index a11ea26a6..2da346c8c 100755 --- a/src/SUIT/SUIT_Session.cxx +++ b/src/SUIT/SUIT_Session.cxx @@ -18,6 +18,12 @@ // #include "SUIT_Session.h" +#ifdef WIN32 +#include +#else +#include +#endif + #include "SUIT_Study.h" #include "SUIT_Tools.h" #include "SUIT_MessageBox.h" @@ -25,12 +31,10 @@ #include "SUIT_ResourceMgr.h" #include - -#ifdef WIN32 -#include -#else -#include -#endif +#include +#include +#include +#include SUIT_Session* SUIT_Session::mySession = 0; @@ -42,7 +46,9 @@ SUIT_Session::SUIT_Session() myActiveApp( 0 ), myHandler( 0 ), myExitStatus( NORMAL ), - myExitFlags ( 0 ) + myExitFlags ( 0 ), + myBTimer( 0 ), + myBFile( 0 ) { SUIT_ASSERT( !mySession ) @@ -63,6 +69,12 @@ SUIT_Session::~SUIT_Session() myResMgr = 0; } mySession = 0; + + // remove backup + if ( myBFile ) + fclose( myBFile ); + if ( !myBFolder.isEmpty() ) + Qtx::rmDir( myBFolder ); } /*! \retval return mySession */ @@ -119,17 +131,17 @@ SUIT_Application* SUIT_Session::startApplication( const QString& name, int /*arg myResMgr->loadLanguage(); } - //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv ); - SUIT_Application* anApp = crtInst(); - if ( !anApp ) + //jfa 22.06.2005:SUIT_Application* app = crtInst( args, argv ); + SUIT_Application* app = crtInst(); + if ( !app ) { SUIT_MessageBox::warning( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ) ); return 0; } - anApp->setObjectName( appName ); + app->setObjectName( appName ); - insertApplication( anApp ); + insertApplication( app ); if ( !myHandler ) { @@ -143,13 +155,21 @@ SUIT_Application* SUIT_Session::startApplication( const QString& name, int /*arg myHandler = crtHndlr(); } - anApp->start(); + app->start(); // Application can be closed during starting (not started). - if ( !myAppList.contains( anApp ) ) - anApp = 0; + if ( !myAppList.contains( app ) ) + app = 0; + + if ( !myBTimer ) + { + myBTimer = (QTimer*)1; // block reation on creation of new application + restoreBackup(); + myBTimer = 0; + createBTimer(); + } - return anApp; + return app; } /*! @@ -355,3 +375,240 @@ void SUIT_Session::onApplicationActivated( SUIT_Application* app ) { myActiveApp = app; } + +/*! + Gets prefix to be used for creating backup copies +*/ +QString SUIT_Session::getBPrefix() const +{ + //qint64 pId = QApplication::applicationPid(); +#ifdef WNT + QString usr( getenv( "USERNAME" ) ); +#else + QString usr( getenv( "USER" ) ); +#endif + + // Create folder + QString anAppName; + SUIT_Application* app = activeApplication(); + if ( app ) + anAppName = app->applicationName(); + else + anAppName = "SALOME"; + + QString pref = anAppName + "_" + usr; + + return pref; +} + +/*! + Gets backup interval +*/ +double SUIT_Session::backupTime() const +{ + double res; + if ( myBTimer ) + res = myBTimer->interval() / 60. / 10e-3; + else + res = 0; + return res; +} + +/*! + Sets backup interval; this method is used by application + when the interval is changed in preferences +*/ +void SUIT_Session::setBackupTime( const double val ) const +{ + int newInt = val * 60 * 1e3; + if ( !myBTimer || newInt == myBTimer->interval() ) + return; + + myBTimer->setInterval( newInt ); + if ( val <= 0 ) + myBTimer->stop(); + else + myBTimer->start(); +} + +/*! + Creates timer to be used for backup +*/ +void SUIT_Session::createBTimer() +{ + if ( myBTimer ) + return; + + SUIT_Application* app = activeApplication(); + if ( !app ) + return; + + myBTimer = new QTimer( this ); + connect( myBTimer, SIGNAL( timeout() ), this, SLOT( onBTimer() ) ); + + double mSec = app->getBackupTime() * 60 * 1e3; + if ( mSec > 0 ) + myBTimer->start( mSec ); + + QString pref = QDir::convertSeparators( QDir::tempPath() + "/" + getBPrefix() ); + myBFolder = pref; + int i = 0; + while( QFileInfo( myBFolder ).exists() ) + { + myBFolder = pref + QString( "_%1" ).arg( ++i ); + } + + if ( !QDir().mkdir( myBFolder ) ) + myBFolder = ""; + + if ( !myBFolder.isEmpty() ) + { + QString used = Qtx::addSlash( myBFolder ) + "used"; + myBFile = fopen( used.toLatin1().constData(), "w" ); + } +} + +/*! + Slot, called when backup interval is out, iterates through all opened + applications, creates 'folderName' directories for them and calls app->backup( folderName ); +*/ +void SUIT_Session::onBTimer() +{ + QApplication::setOverrideCursor( Qt::WaitCursor ); + + // clear folder + Qtx::rmDir( myBFolder ); + QDir().mkdir( myBFolder ); + + // create backup + QString aName; + QList aList = applications(); + QList::iterator it; + for ( it = aList.begin(); it != aList.end(); ++it ) + { + SUIT_Application* app = *it; + if ( app && app->activeStudy() ) + { + aName = app->activeStudy()->studyName(); + aName.replace( ":", "%" ); + aName.replace( "/", "+" ); + aName.replace( "\\", "+" ); + QString aFName = QDir::convertSeparators( myBFolder + "/" + aName ); + QDir().mkdir( aFName ); + QFileInfo fi( aFName ); + if ( fi.exists() &&fi.isDir() ) + app->backup( aFName ); + } + } + + QApplication::restoreOverrideCursor(); +} + +/*! + Restores crashed studies from backup +*/ +void SUIT_Session::restoreBackup() +{ + QString pref = getBPrefix(); + + // checks whether temp folder contains old backups + QDir tmpDir( QDir::tempPath() ); + + QStringList filt; + filt.append( pref + "*" ); + tmpDir.setNameFilters( filt ); + + QStringList sess = tmpDir.entryList ( QDir::Dirs ); + if ( sess.count() == 0 ) + return; + + QSet stdSet; + QList toRestore; + QList toRemove; + + // iterate through temp folder + QStringList::iterator sessIter; + for ( sessIter = sess.begin(); sessIter != sess.end(); ++sessIter ) + { + // iterate through session folder + const QString& stdRoot = Qtx::addSlash( QDir::tempPath() ) + *sessIter; + + // checks whether folder is not currently used + QString testFile = Qtx::addSlash( stdRoot ) + "used"; + QFileInfo fi( testFile ); + if ( fi.exists() && !QFile( testFile ).remove() ) + continue; + + toRemove.append( stdRoot ); + + QDir sessDir( stdRoot ); + QStringList stdList = sessDir.entryList ( QDir::Dirs ); + + QStringList::iterator stdIt; + for ( stdIt = stdList.begin(); stdIt != stdList.end(); ++stdIt ) + { + const QString& locName = *stdIt; + if ( *stdIt == "." || *stdIt == ".." ) + continue; + + const QString& study = Qtx::addSlash( stdRoot ) + *stdIt; + QDir stdDir( study ); + QStringList fList = sessDir.entryList ( QDir::AllEntries ); + if ( fList.count() > 2 && !stdSet.contains( locName ) ) + { + stdSet.insert( locName ); + toRestore.append( study ); + } + } + } + + // restore study if necessary + if ( !toRestore.isEmpty() ) + { + QWidget* p = activeApplication() ? (QWidget*)activeApplication()->desktop() : 0; + + int aBtn = SUIT_MessageBox::warning( p, tr( "WRN_WARNING" ), tr( "WANT_TO_RESTORE" ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::Yes ); + if ( aBtn == SUIT_MessageBox::Yes ) + { + QStringList::iterator it; + bool isFirst = true; + for ( it = toRestore.begin(); it != toRestore.end(); ++it ) + { + SUIT_Application* app = activeApplication(); + if ( !app ) + return; + + if ( !isFirst ) + app = startApplication( app->objectName(), 0, 0 ); + + isFirst = false; + + if ( !app ) + continue; + + app->setRestoreFolder( *it ); + + QString fName = *it; + int ind = fName.lastIndexOf( "\\" ); + if ( ind == -1 ) + ind = fName.lastIndexOf( "/" ); + if ( ind >= 0 ) + fName = fName.right( fName.length() - ind -1 ); + fName.replace( "%", ":" ); + fName.replace( "+", "/" ); + fName.replace( "+", QDir::separator() ); + if ( !app->useFile( fName ) ) + app->closeApplication(); + } + } + } + + // remove all backup folders + QStringList::iterator it; + for ( it = toRemove.begin(); it != toRemove.end(); ++it ) + { + Qtx::rmDir( *it ); + } +} + diff --git a/src/SUIT/SUIT_Session.h b/src/SUIT/SUIT_Session.h index bc3ca3486..70147565f 100755 --- a/src/SUIT/SUIT_Session.h +++ b/src/SUIT/SUIT_Session.h @@ -37,6 +37,7 @@ #endif class SUIT_ResourceMgr; +class QTimer; class SUIT_ExceptionHandler; #ifdef WIN32 @@ -77,6 +78,9 @@ public: void insertApplication( SUIT_Application* ); + double backupTime() const; + void setBackupTime( const double val ) const; + signals: void applicationClosed( SUIT_Application* ); @@ -86,6 +90,12 @@ protected: private slots: void onApplicationClosed( SUIT_Application* ); void onApplicationActivated( SUIT_Application* ); + void onBTimer(); + +private: + QString getBPrefix() const; + void createBTimer(); + void restoreBackup(); private: typedef QList AppList; @@ -107,6 +117,10 @@ private: int myExitStatus; int myExitFlags; + + QString myBFolder; + QTimer* myBTimer; + FILE* myBFile; }; #endif diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx index ea1262d41..91ec41e40 100755 --- a/src/SUIT/SUIT_Study.cxx +++ b/src/SUIT/SUIT_Study.cxx @@ -530,3 +530,4 @@ bool SUIT_Study::hasTransaction() const void SUIT_Study::restoreState(int /*savePoint*/) { } + diff --git a/src/SUIT/resources/SUIT_msg_en.ts b/src/SUIT/resources/SUIT_msg_en.ts index 466cbaf44..507dd8d1e 100644 --- a/src/SUIT/resources/SUIT_msg_en.ts +++ b/src/SUIT/resources/SUIT_msg_en.ts @@ -131,4 +131,12 @@ Do you want to overwrite it? All files (*) + + SUIT_Session + + WANT_TO_RESTORE + Application crashed and one or several studies was unsaved. +Do you want to restore them? + + -- 2.39.2