From: mbs Date: Sat, 9 Dec 2023 22:21:12 +0000 (+0000) Subject: [bos#35161][EDF](2023-T1) Automatic backup X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=2552d2251f14a4220b86309f1e8a24be93a3c11e;p=modules%2Fgui.git [bos#35161][EDF](2023-T1) Automatic backup Added temporary debug files. To be removed again when task is finished. restore study flags after backup always restore its URL after having backed up a study removed DEBUG macros --- diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index b1cb7e3bb..d86509cc7 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -2251,8 +2251,9 @@ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy ) void LightApp_Application::onStudySaved( SUIT_Study* s ) { QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); - if ( mru && s ) + if ( mru && s ) { mru->insert( s->studyName() ); + } emit studySaved(); } diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx index b85099392..3c2f50c54 100644 --- a/src/LightApp/LightApp_DataModel.cxx +++ b/src/LightApp/LightApp_DataModel.cxx @@ -34,6 +34,7 @@ #include #include + /*! Constructor */ @@ -73,9 +74,10 @@ bool LightApp_DataModel::save( QStringList& ) /*! Emit saved() */ -bool LightApp_DataModel::saveAs( const QString&, CAM_Study*, QStringList& ) +bool LightApp_DataModel::saveAs( const QString&, CAM_Study*, QStringList&, bool isBackup/*=false*/ ) { - emit saved(); + if (!isBackup) + emit saved(); return true; } diff --git a/src/LightApp/LightApp_DataModel.h b/src/LightApp/LightApp_DataModel.h index 859d1d0d7..882a8486d 100644 --- a/src/LightApp/LightApp_DataModel.h +++ b/src/LightApp/LightApp_DataModel.h @@ -53,7 +53,7 @@ public: virtual bool open( const QString&, CAM_Study*, QStringList ); virtual bool save( QStringList& ); - virtual bool saveAs( const QString&, CAM_Study*, QStringList& ); + virtual bool saveAs( const QString&, CAM_Study*, QStringList&, bool isBackup=false ); virtual bool close(); virtual bool dumpPython( const QString&, CAM_Study*, diff --git a/src/LightApp/LightApp_Study.cxx b/src/LightApp/LightApp_Study.cxx index 9aa940331..48bef22a8 100644 --- a/src/LightApp/LightApp_Study.cxx +++ b/src/LightApp/LightApp_Study.cxx @@ -36,6 +36,7 @@ #include + /*! Constructor. */ @@ -134,7 +135,7 @@ bool LightApp_Study::loadDocument( const QString& theStudyName ) /*! Saves document */ -bool LightApp_Study::saveDocumentAs( const QString& theFileName ) +bool LightApp_Study::saveDocumentAs( const QString& theFileName, bool isBackup/*=false*/ ) { SUIT_ResourceMgr* resMgr = application()->resourceMgr(); if( !resMgr ) @@ -190,7 +191,7 @@ bool LightApp_Study::saveDocumentAs( const QString& theFileName ) bool res = saveStudyData(theFileName, 0); // 0 means persistence file res = res && CAM_Study::saveDocumentAs( theFileName ); //SRN: BugID IPAL9377, removed usage of uninitialized variable - if ( res ) + if ( res && !isBackup) emit saved( this ); return res; diff --git a/src/LightApp/LightApp_Study.h b/src/LightApp/LightApp_Study.h index a51e5904d..1da4d7717 100644 --- a/src/LightApp/LightApp_Study.h +++ b/src/LightApp/LightApp_Study.h @@ -76,10 +76,12 @@ public: virtual bool loadDocument( const QString& ); virtual bool saveDocument(); - virtual bool saveDocumentAs( const QString& ); + virtual bool saveDocumentAs( const QString& , bool isBackup=false ); virtual void closeDocument(bool permanently = true); + virtual bool dump( const QString&, bool, bool, bool ) { return false; } + virtual bool isSaved() const; virtual bool isModified() const; diff --git a/src/SUIT/MBDebug.h b/src/SUIT/MBDebug.h new file mode 100644 index 000000000..800d81246 --- /dev/null +++ b/src/SUIT/MBDebug.h @@ -0,0 +1,313 @@ +#ifndef MBDebug_HeaderFile +#define MBDebug_HeaderFile + +//--------------------------------------------------------------- +// Usage of the logging facilities: +// +// (1) At the beginning of each class file to be debugged, there +// should be a static string variable defined with the name +// of the class. Then, include the "MBDebug.h" header file. +// +// //--------------------------------------------------------- +// #define USE_DEBUG +// //#define MB_IGNORE_QT +// //#define MB_FULL_DUMP +// #define MBCLASSNAME "ClassName" +// #include "MBDebug.h" +// // <-- insert includes for addtional debug headers here! +// //--------------------------------------------------------- +// +// (2) At the beginning of each class method, call the DBG_FUN +// macro. +// +// int ClassName::MyMethod(int x) +// { +// DBG_FUN(); +// ... +// } +// +// NOTE: For static methods, call the DBG_FUNC() macro!! +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// This debugging/logging class is a "header-only" solution and +// does NOT require any additional implementation (.cpp) file! +//--------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef MB_IGNORE_QT +# include +# include +#endif + +static std::mutex mtx; + +//--------------------------------------------------------------- +// Set the debug flags dependent on the preprocessor definitions +//--------------------------------------------------------------- +#ifdef USE_DEBUG +# define MBS_DEBUG_FLAG MBDebug::DF_DEBUG +#else +# define MBS_DEBUG_FLAG 0 +#endif /*DEBUG*/ + +#define MBS_DBG_FLAGS (MBS_DEBUG_FLAG) + + +//--------------------------------------------------------------- +// Define the global debug macros +//--------------------------------------------------------------- +#define DLOG MBDebug::LogPrint() +#define RETURN(var) { RET(var); return (var); } + +#ifdef USE_DEBUG + +# define DBG_FUN() MBDebug _dbg(MBCLASSNAME, __FUNCTION__, MBS_DBG_FLAGS, (void*)this) +# define DBG_FUNC() MBDebug _dbg(MBCLASSNAME, __FUNCTION__, MBS_DBG_FLAGS) +# define DBG_FUNB(blk) MBDebug _dbg(MBCLASSNAME, blk, MBS_DBG_FLAGS) +# define MSGEL(txt) MBDebug::LogPrint() << ":" << txt << std::endl +# define PRINT(txt) MBDebug::LogPrint() << txt +# define SHOW2(var,typ) do { PRINT(std::this_thread::get_id()); DumpVar(#var,(typ)(var)); } while (0) +# define SHOW(var) do { PRINT(std::this_thread::get_id()); DumpVar(#var,var); } while (0) +# define ARG(var) do { PRINT(std::this_thread::get_id() << ":in:"); DumpVar(#var,var); } while (0) +# define ARG2(var,typ) do { PRINT(std::this_thread::get_id() << ":in:"); DumpVar(#var,(typ)(var)); } while (0) +# define RET(var) do { PRINT(std::this_thread::get_id() << ":out:"); DumpVar(#var,var); } while (0) +# define MSG(txt) MBDebug::LogPrint() << std::this_thread::get_id() << ":" << txt + +#else /*!USE_DEBUG*/ + +# define DBG_FUN() +# define DBG_FUNC() +# define DBG_FUNB(blk) +# define MSGEL(txt) +# define PRINT(txt) +# define SHOW2(var,typ) +# define SHOW(var) +# define ARG(var) +# define ARG2(var,typ) +# define RET(var) +# define MSG(txt) + +#endif /*USE_DEBUG*/ + + +//--------------------------------------------------------------- +// Declare the debugging and profiling class +//--------------------------------------------------------------- +class MBDebug +{ +public: + enum { + DF_NONE = 0x00, // no debug + DF_DEBUG = 0x01 // debug a function + }; + + MBDebug(const char* aClassName, const char* aFuncName, const short aFlag, void* aThis=NULL) + :mClassName(aClassName),mFuncName(aFuncName),mThis(aThis),mFlags((unsigned char)aFlag) + { + if (mFlags & (DF_DEBUG)) + { + std::lock_guard lck(mtx); + std::cout << std::this_thread::get_id() << ":{ENTER: " << mClassName + "::" + mFuncName; + if (mThis) std::cout << "(this=" << mThis << ")"; + std::cout << std::endl; + } + } + virtual ~MBDebug() + { + if (mFlags & (DF_DEBUG)) + { + std::lock_guard lck(mtx); + std::cout << std::this_thread::get_id() << ":}LEAVE: " << mClassName << "::" << mFuncName << std::endl; + } + } + + // Log file output management + static std::ostream& LogPrint() { return std::cout; } + +private: + std::string mClassName; // Name of class to be debugged + std::string mFuncName; // Name of function to be debugged + void* mThis; // The "this" pointer to the class being debugged + unsigned char mFlags; // Debug mode flags +}; + + + +#define YesNo(b) (b ? "Yes" : "No") + + + +inline std::string w2s(std::wstring ws) +{ + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + return(converterX.to_bytes(ws)); +} + +// Primitive types +inline void DumpVar(const char *szName, char value) +{ + std::lock_guard lck(mtx); + DLOG << "[chr]: " << szName << "='" << value << "'" << std::endl; +} + +inline void DumpVar(const char *szName, bool value) +{ + std::lock_guard lck(mtx); + DLOG << "[bool]: " << szName << "=" << (value ? "true" : "false") << std::endl; +} + +inline void DumpVar(const char *szName, short value) +{ + std::lock_guard lck(mtx); + DLOG << "[shrt]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, int value) +{ + std::lock_guard lck(mtx); + DLOG << "[int]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, long value) +{ + std::lock_guard lck(mtx); + DLOG << "[long]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, double value) +{ + std::lock_guard lck(mtx); + DLOG << "[dbl]: " << szName << "=" << value << std::endl; +} + +inline void DumpVar(const char *szName, unsigned char value) +{ + std::lock_guard lck(mtx); + DLOG << "[byte]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned short value) +{ + std::lock_guard lck(mtx); + DLOG << "[word]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned int value) +{ + std::lock_guard lck(mtx); + DLOG << "[uint]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, unsigned long value) +{ + std::lock_guard lck(mtx); + DLOG << "[dword]: " << szName << "=0x" << std::hex << value << std::dec << std::endl; +} + +inline void DumpVar(const char *szName, const char* value) +{ + std::lock_guard lck(mtx); + DLOG << "[str]: " << szName << "=\"" << (value ? value : "") << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::string &value) +{ + std::lock_guard lck(mtx); + DLOG << "[Str]: " << szName << "=\"" << value << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const std::wstring &value) +{ + std::lock_guard lck(mtx); + DLOG << "[WStr]: " << szName << "=\"" << w2s(value) << "\"" << std::endl; +} + +#ifndef MB_IGNORE_QT +inline void DumpVar(const char *szName, const QString &value) +{ + std::lock_guard lck(mtx); + DLOG << "[QStr]: " << szName << "=\"" << value.toStdString() << "\"" << std::endl; +} + +inline void DumpVar(const char *szName, const QStringList &value) +{ + std::lock_guard lck(mtx); + DLOG << "[QStrLst]: " << szName << "=[len=" << value.length() << "] {"; + bool first = true; + QStringList::const_iterator it = value.constBegin(); + for ( ; it != value.constEnd(); ++it) + { + DLOG << (first ? "" : ",") << "\"" << (*it).toStdString() << "\""; + first = false; + } + DLOG << "}" << std::endl; +} +#endif + +inline void DumpVar(const char *szName, const void* value) +{ + std::lock_guard lck(mtx); + DLOG << "[ptr]: " << szName << "=" << value << std::endl; +} + + +// Collection of primitive types +inline void DumpVar(const char *szName, const std::set &values) +{ + std::lock_guard lck(mtx); + DLOG << "[intSet]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) { + DLOG << (bFirst ? "" : ",") << *it; + bFirst = false; + } + DLOG << "]" << std::endl; +} + +inline void DumpVar(const char *szName, const std::vector &values) +{ + std::lock_guard lck(mtx); + DLOG << "[intVect]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) { + DLOG << (bFirst ? "" : ",") << *it; + bFirst = false; + } + DLOG << "]" << std::endl; +} + +inline void DumpVar(const char *szName, const std::list& values) +{ + std::lock_guard lck(mtx); + DLOG << "[boolList]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) { + DLOG << (bFirst ? "" : ",") << (*it ? "Y" : "N"); + bFirst = false; + } + DLOG << "]" << std::endl; +} + +inline void DumpVar(const char *szName, const std::list &values) +{ + std::lock_guard lck(mtx); + DLOG << "[strLst]: " << szName << "={" << values.size() << "}["; + bool bFirst = true; + for (auto it=values.cbegin(); it!=values.cend(); ++it) { + DLOG << (bFirst ? "\"" : ", \"") << *it << "\""; + bFirst = false; + } + DLOG << "]" << std::endl; +} + +#endif // MBDebug_HeaderFile + diff --git a/src/SUIT/SUIT_Study.cxx b/src/SUIT/SUIT_Study.cxx index 5f62d04be..04cebe761 100644 --- a/src/SUIT/SUIT_Study.cxx +++ b/src/SUIT/SUIT_Study.cxx @@ -28,6 +28,15 @@ #include "SUIT_MessageBox.h" #include "SUIT_Application.h" +//--------------------------------------------------------- +#define USE_DEBUG +//#define MB_IGNORE_QT +//#define MB_FULL_DUMP +#define MBCLASSNAME "SUIT_Study" +#include "MBDebug.h" +// <-- insert includes for addtional debug headers here! +//--------------------------------------------------------- + /*!\class SUIT_Study * Support study management. Object management. Operation management. */ @@ -41,9 +50,11 @@ myIsSaved( false ), myIsModified( false ), myBlockChangeState( false ) { + DBG_FUN(); static int _id = 0; myId = ++_id; + SHOW(myId); myRoot = new SUIT_DataObject(); } @@ -51,6 +62,7 @@ myBlockChangeState( false ) /*!Destructor.*/ SUIT_Study::~SUIT_Study() { + DBG_FUN(); delete myRoot; myRoot = 0; } @@ -142,11 +154,19 @@ bool SUIT_Study::openDocument( const QString& fileName ) /*! * Save document as \a fileName. Set file name. */ -bool SUIT_Study::saveDocumentAs( const QString& fileName ) -{ - myName = fileName; - myIsSaved = true; - myIsModified = false; +bool SUIT_Study::saveDocumentAs( const QString& fileName, bool isBackup/*=false*/ ) +{ + DBG_FUN(); + ARG(fileName); + ARG(isBackup); + if (!isBackup) { + myName = fileName; + myIsSaved = true; + myIsModified = false; + } + SHOW(myName); + SHOW(myIsSaved); + SHOW(myIsModified); return true; } @@ -156,6 +176,7 @@ bool SUIT_Study::saveDocumentAs( const QString& fileName ) */ bool SUIT_Study::saveDocument() { + DBG_FUN(); return saveDocumentAs( myName ); } diff --git a/src/SUIT/SUIT_Study.h b/src/SUIT/SUIT_Study.h index 40cc14732..fb9b7c25c 100644 --- a/src/SUIT/SUIT_Study.h +++ b/src/SUIT/SUIT_Study.h @@ -60,7 +60,7 @@ public: virtual bool createDocument( const QString& ); bool saveDocument(); - virtual bool saveDocumentAs( const QString& ); + virtual bool saveDocumentAs( const QString& , bool isBackup=false ); virtual void update(); diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index d7f15aacc..d610ff9fb 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -60,6 +60,7 @@ #include #include CORBA_SERVER_HEADER(SALOME_Exception) + //#define NOTIFY_BY_EVENT class ObserverEvent : public QEvent @@ -595,10 +596,14 @@ bool SalomeApp_Study::loadDocument( const QString& theStudyName ) Saves document \param theFileName - name of file */ -bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) +bool SalomeApp_Study::saveDocumentAs( const QString& theFileName, bool isBackup/*=false*/ ) { + bool wasSaved = isSaved(); + bool wasModified = isModified(); + std::string oldName = (studyDS() ? studyDS()->Name() : ""); + std::string oldURL = (studyDS() ? studyDS()->URL() : ""); bool store = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", false ); - if ( store ) + if ( store && !isBackup ) SalomeApp_VisualState( (SalomeApp_Application*)application() ).storeState(); ModelList list; dataModels( list ); @@ -611,7 +616,7 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) if ( LightApp_DataModel* aModel = dynamic_cast( it.next() ) ) { listOfFiles.clear(); - aModel->saveAs( theFileName, this, listOfFiles ); + aModel->saveAs( theFileName, this, listOfFiles, isBackup ); if ( !listOfFiles.isEmpty() ) saveModuleData(aModel->module()->name(), 0, // 0 means persistence file listOfFiles); @@ -626,13 +631,26 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); bool isAscii = resMgr->booleanValue( "Study", "ascii_file", false ); bool res = studyDS()->SaveAs( theFileName.toUtf8().data(), isMultiFile, isAscii ) - && CAM_Study::saveDocumentAs( theFileName ); + && CAM_Study::saveDocumentAs( theFileName, isBackup ); res = res && saveStudyData(theFileName, 0); // 0 means persistence file - if ( res ) + if ( res && !isBackup) emit saved( this ); + if (isBackup) + { + // Restore the isSaved and isModified flag after having done backup + setIsSaved(wasSaved); + setIsModified(wasModified); + // If the document hasn't been saved before, reset here its name and URL + if (studyDS()) + { + studyDS()->URL(oldURL); + studyDS()->Name(oldName); + } + } + return res; } diff --git a/src/SalomeApp/SalomeApp_Study.h b/src/SalomeApp/SalomeApp_Study.h index 39cee0aae..d14f9295b 100644 --- a/src/SalomeApp/SalomeApp_Study.h +++ b/src/SalomeApp/SalomeApp_Study.h @@ -50,7 +50,7 @@ public: virtual bool loadDocument( const QString& ); virtual bool saveDocument(); - virtual bool saveDocumentAs( const QString& ); + virtual bool saveDocumentAs( const QString& , bool isBackup=false ); virtual void closeDocument(bool permanently = true);