-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//#include <OB_ListItem.h>
-#include <Utils_ORB_INIT.hxx>
-#include <Utils_SINGLETON.hxx>
#include <SALOME_LifeCycleCORBA.hxx>
#include <QApplication>
#include <QtDebug>
#include <SALOMEDSClient_ClientFactory.hxx>
+#include <ArgvKeeper.hxx>
#include <Basics_Utils.hxx>
+#include <OpUtil.hxx>
#include <SALOME_ListIO.hxx>
#include <SALOME_Prs.h>
#include <SALOMEDS_Tool.hxx>
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+
+std::unique_ptr<SALOME_NamingService_Abstract> SalomeApp_Application::_ns;
+
/*!Internal class that updates object browser item properties */
// temporary commented
/*class SalomeApp_Updater : public OB_Updater
//}
}*/
-/*!Create new instance of SalomeApp_Application.*/
-extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
+namespace
{
- return new SalomeApp_Application();
+ /*!
+ \brief Flag locker.
+ */
+ class MessageLocker
+ {
+ public:
+ //! Constructor. Sets passed boolean flag to \c true.
+ MessageLocker( bool& Lock ) : myPrevState( Lock ), myLock( Lock ) { myLock = true; }
+ //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+ ~MessageLocker() { myLock = myPrevState; }
+ private:
+ bool myPrevState;
+ bool& myLock; //! External 'Lock state' boolean flag
+ };
+
+ /*!
+ \brief Dynamic property manager
+ */
+ class PropertyMgr
+ {
+ QObject* myObject;
+ QString myProperty;
+ public:
+ PropertyMgr(QObject* object, const QString& property, const QVariant& value)
+ : myObject(object), myProperty(property)
+ {
+ myObject->setProperty(qPrintable(myProperty), value);
+ }
+ ~PropertyMgr()
+ {
+ myObject->setProperty(qPrintable(myProperty), QVariant());
+ }
+ };
}
/*!Constructor.*/
-SalomeApp_Application::SalomeApp_Application()
- : LightApp_Application(),
- myIsCloseFromExit( false )
+SalomeApp_Application::SalomeApp_Application(SALOME_NamingService_Abstract *ns):myIsCloseFromExit( false ),myToIgnoreMessages( false )
{
+ if(!ns)
+ _ns.reset(new SALOME_NamingService(orb()));
+ else
+ _ns.reset(ns);
}
/*!Destructor.
QString hdffile;
QStringList pyfiles;
- for (int i = 1; i < qApp->arguments().size(); i++) {
+ QStringList args = QApplication::arguments();
+ for (int i = 1; i < args.count(); i++) {
QRegExp rxs ("--study-hdf=(.+)");
- if ( rxs.indexIn( qApp->arguments()[i] ) >= 0 && rxs.capturedTexts().count() > 1 ) {
+ if ( rxs.indexIn( args[i] ) >= 0 && rxs.capturedTexts().count() > 1 ) {
QString file = rxs.capturedTexts()[1];
QFileInfo fi ( file );
QString extension = fi.suffix().toLower();
}
else {
QRegExp rxp ("--pyscript=\\[(.+)\\]");
- if ( rxp.indexIn( qApp->arguments()[i] ) >= 0 && rxp.capturedTexts().count() > 1 ) {
+ if ( rxp.indexIn( args[i] ) >= 0 && rxp.capturedTexts().count() > 1 ) {
// pyscript
QStringList dictList = rxp.capturedTexts()[1].split("},", QString::SkipEmptyParts);
for (int k = 0; k < dictList.count(); ++k) {
LightApp_Application::start();
SALOME_EventFilter::Init();
- setProperty("open_study_from_command_line", true);
- if ( !hdffile.isEmpty() ) // open hdf file given as parameter
+ if ( !hdffile.isEmpty() )
+ {
+ // open hdf file given as parameter
+ PropertyMgr propm( this, "open_study_from_command_line", true );
onOpenDoc( hdffile );
- setProperty("open_study_from_command_line", QVariant());
+ }
#ifndef DISABLE_PYCONSOLE
// import/execute python scripts
if ( !getStudy()->GetProperties()->IsLocked() ) {
// pyfiles[j] is a dictionary: {"/absolute/path/to/script.py": [script_args]}
// Path is absolute, script has .py extension
- for (uint j = 0; j < pyfiles.count(); j++ ) {
+ for (int j = 0; j < pyfiles.count(); j++ ) {
// Extract scripts and their arguments, if any
QRegExp rxp ("\"(.+)\":[\\s]*\\[(.*)\\]");
if ( rxp.indexIn( pyfiles[j] ) >= 0 && rxp.capturedTexts().count() == 3 ) {
QString script = rxp.capturedTexts()[1];
- QString args = "";
+ QStringList args;
QStringList argList = __getArgsList(rxp.capturedTexts()[2]);
- for (uint k = 0; k < argList.count(); k++ ) {
+ for (int k = 0; k < argList.count(); k++ ) {
QString arg = argList[k].trimmed();
arg.remove( QRegExp("^[\"]") );
arg.remove( QRegExp("[\"]$") );
- args += arg+",";
- }
- args.remove( QRegExp("[,]$") );
- if (!args.isEmpty()) {
- args = "args:"+args;
+ args << QString("\"%1\"").arg(arg);
}
+ if (args.count() == 1)
+ args << "";
script.remove( QRegExp("^python.*[\\s]+") );
- QString cmd = script+" "+args;
- QString command = QString( "exec(open(\"%1\").read())" ).arg(cmd.trimmed());
+ QString command = QString( "exec(open(\"%1\", \"rb\").read(), args=(%2))" ).arg(script).arg(args.join(","));
+ PropertyMgr propm( this, "IsLoadedScript", true );
pyConsole->exec(command);
}
} // end for loop on pyfiles QStringList
*/
void SalomeApp_Application::onExit()
{
+ //MessageLocker ml( myToIgnoreMessages );
+
bool killServers = false;
bool result = true;
}
}
+/*!SLOT. Create a document.*/
+void SalomeApp_Application::onNewDoc()
+{
+ MessageLocker ml( myToIgnoreMessages );
+
+ LightApp_Application::onNewDoc();
+}
+
/*!SLOT. Load document.*/
void SalomeApp_Application::onLoadDoc()
{
+ MessageLocker ml( myToIgnoreMessages );
+
QString studyName;
// rnv: According to the single-study approach on the server side
{
onNewDoc();
- QString command = QString("exec(open(\"%1\").read())").arg(aFile);
-
#ifndef DISABLE_PYCONSOLE
+ QString command = QString("exec(open(\"%1\", \"rb\").read())").arg(aFile);
PyConsole_Console* pyConsole = pythonConsole();
-
+ PropertyMgr propm( this, "IsLoadedScript", true );
if ( pyConsole )
pyConsole->exec( command );
#endif
/*!SLOT. Parse message for desktop.*/
void SalomeApp_Application::onDesktopMessage( const QString& message )
{
+ if ( myToIgnoreMessages )
+ return; // a message from SALOMEDS is caused by GUI action
+
+ MessageLocker ml( myToIgnoreMessages );
+
if (message.indexOf("studyCreated") == 0) {
if (!activeStudy()) {
onNewDoc();
}
}
else if ( message.toLower() == "connect_to_study" ) {
- onLoadDoc();
+ if ( activeStudy() )
+ useStudy( activeStudy()->studyName() );
}
if (message.indexOf("studyNameChanged") == 0) {
updateDesktopTitle();
SUIT_MessageBox::No) == SUIT_MessageBox::No ) return;
}
+ MessageLocker ml( myToIgnoreMessages );
+
LightApp_Application::onCloseDoc( ask );
// reinitialize study to have empty data
- getStudy()->Init();
+ //getStudy()->Init();
+}
+
+/*!SLOT. Reload document from the file.*/
+bool SalomeApp_Application::onReopenDoc()
+{
+ MessageLocker ml( myToIgnoreMessages );
+
+ return LightApp_Application::onReopenDoc();
+}
+
+
+/*!SLOT. Load document.*/
+void SalomeApp_Application::onOpenDoc()
+{
+ MessageLocker ml( myToIgnoreMessages );
+
+ LightApp_Application::onOpenDoc();
+}
+
+/*!SLOT. Load document.*/
+bool SalomeApp_Application::onOpenDoc(const QString& name)
+{
+ MessageLocker ml( myToIgnoreMessages );
+
+ return LightApp_Application::onOpenDoc(name);
}
/*!Sets enable or disable some actions on selection changed.*/
Handle(SALOME_InteractiveObject) aIObj = aList.First();
QString aModuleName(aIObj->getComponentDataType());
QString aModuleTitle = moduleTitle(aModuleName);
+ if (aModuleTitle.isEmpty()) // no gui
+ aModuleTitle = moduleDisplayer(aModuleName);
activateModule(aModuleTitle);
QApplication::restoreOverrideCursor();
}
this, SIGNAL(notebookVarUpdated(QString)) );
#endif
+ getStudy()->Init();
+
return aStudy;
}
bool res;
{
SUIT_OverrideCursor wc;
+ ensureShaperIsActivated();
res = appStudy->dump( aFileName, toPublish, isMultiFile, toSaveGUI );
}
if ( !res )
if ( !aFile.isEmpty() )
{
- QString command = QString("exec(open(\"%1\").read())").arg(aFile);
-
#ifndef DISABLE_PYCONSOLE
+ QString command = QString("exec(compile(open('%1', 'rb').read(), '%1', 'exec'))").arg(aFile);
PyConsole_Console* pyConsole = pythonConsole();
-
+ PropertyMgr propm( this, "IsLoadedScript", true );
if ( pyConsole )
- pyConsole->exec( command );
+ pyConsole->exec(command);
#endif
}
}
desktop()->setWindowTitle( aTitle );
}
-int SalomeApp_Application::closeChoice( const QString& docName )
+int SalomeApp_Application::closeChoice( const QString& /*docName*/ )
{
QStringList buttons;
QMap<int, int> choices;
onSaveDoc();
else if ( !onSaveAsDoc() )
res = false;
+ // fall through!
case CloseDisconnect:
closeActiveDoc( false );
closePermanently = false;
} else { // file is not exist on disk
SUIT_MessageBox::warning( desktop(),
QObject::tr("WRN_WARNING"),
- QObject::tr("WRN_FILE_NOT_EXIST").arg(aName.toLatin1().data()));
+ QObject::tr("WRN_FILE_NOT_EXIST").arg(aName.toUtf8().data()));
return false;
}
switch ( choice )
{
case OpenRefresh:
- {
- choice = OpenNew;
- }
+ choice = OpenNew;
+ // fall through!
default:
res = LightApp_Application::openAction( choice, aName );
break;
if ( CORBA::is_nil( _orb ) ) {
Qtx::CmdLineArgs args;
- ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
- _orb = init( args.argc(), args.argv() );
+ SetArgcArgv( args.argc(), args.argv() );
+ _orb = KERNEL::GetRefToORB();
}
return _orb;
}
/*!Create and return SALOME_NamingService.*/
-SALOME_NamingService* SalomeApp_Application::namingService()
+SALOME_NamingService_Abstract *SalomeApp_Application::namingService()
{
- static SALOME_NamingService _ns(orb());
- return &_ns;
+ return _ns.get();
}
/*!Create and return SALOME_LifeCycleCORBA.*/
if ( !entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) {
QString aModuleName( aIObj->getComponentDataType() );
QString aModuleTitle = moduleTitle( aModuleName );
+ if (aModuleTitle.isEmpty()) {
+ // use displayer module, if given
+ aModuleTitle = moduleDisplayer( aModuleName );
+ }
CAM_Module* currentModule = activeModule();
- if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() )
+ if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() ) {
thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) );
+ }
}
}
// iterate new save points. if DataObject with such ID not found in map - create DataObject
// if in the map - remove it from map.
- for ( int i = 0; i < savePoints.size(); i++ )
+ for ( size_t i = 0; i < savePoints.size(); i++ )
if ( !mapDO.contains( savePoints[i] ) )
new SalomeApp_SavePointObject( guiRootObj, savePoints[i], study );
else
\param name new name of the object
\brief Return \c true if rename operation finished successfully, \c false otherwise.
*/
-bool SalomeApp_Application::renameObject( const QString& entry, const QString& name )
+bool SalomeApp_Application::renameObject( const QString& /*entry*/, const QString& name )
{
SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
// get unique temporary directory name
QString aTmpDir = QString::fromStdString( SALOMEDS_Tool::GetTmpDir() );
+
if( aTmpDir.isEmpty() )
return false;
{
bool ok = true;
+ // create a new study
+ onNewDoc();
+
// get active application
SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
// load study from the temporary directory
- QString command = QString( "exec(open(\"%1\").read())" ).arg( theDumpScript );
+ QFileInfo aScriptInfo = QFileInfo(theDumpScript);
+ QString command = QString( "exec(open(\"%1\" ,\"rb\").read())" ).arg(aScriptInfo.canonicalFilePath());
#ifndef DISABLE_PYCONSOLE
PyConsole_Console* pyConsole = app->pythonConsole();
- if ( pyConsole )
+ if ( pyConsole ) {
+ PropertyMgr propm( this, "IsLoadedScript", true );
pyConsole->execAndWait( command );
+ }
#endif
// remove temporary directory
- QFileInfo aScriptInfo = QFileInfo( theDumpScript );
QString aStudyName = aScriptInfo.baseName();
QDir aDir = aScriptInfo.absoluteDir();
QStringList aFiles = aDir.entryList( QStringList( "*.py*" ) );
LightApp_Application::afterCloseDoc();
}
+bool SalomeApp_Application::canOpenDoc( const QString& url )
+{
+ _PTR(Study) aStudyDS = getStudy();
+ if ( aStudyDS )
+ return aStudyDS->CanOpen( url.toUtf8().data() );
+ return false;
+}
+
/*
Asks to close existing document.
*/
PyConsole_Interp* SalomeApp_Application::createPyInterp()
{
- return new SalomeApp_PyInterp;
+ return new SalomeApp_PyInterp( resourceMgr() );
}
#endif // DISABLE_PYCONSOLE
+
+void SalomeApp_Application::ensureShaperIsActivated()
+{
+ SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+ _PTR(Study) studyDS = getStudy();
+ if ( study && studyDS )
+ {
+ _PTR(SObject) shaper = studyDS->FindObjectByPath("/Shaper"); // non null result if shaper data is present in the study
+ bool shaperIsActive = false;
+ QList<CAM_DataModel*> models;
+ study->dataModels( models );
+ for( int i = 0; i < models.count() && !shaperIsActive; i++ )
+ shaperIsActive = models[i]->module()->moduleName() == "Shaper";
+
+ if (shaper && !shaperIsActive)
+ onDesktopMessage("register_module_in_study/Shaper");
+ }
+}
+
+void SalomeApp_Application::addCatalogue( const QString& moduleName, const QString& catalogue )
+{
+ CORBA::Object_var obj = namingService()->Resolve( "/Kernel/ModulCatalog" );
+ SALOME_ModuleCatalog::ModuleCatalog_var moduleCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
+ QFileInfo fi( catalogue );
+ if ( !CORBA::is_nil( moduleCatalogue ) && fi.isFile() )
+ {
+ SALOME_ModuleCatalog::ListOfComponents_var known = moduleCatalogue->GetComponentList();
+ bool loaded = false;
+ for ( int i = 0; i < (int)known->length() && !loaded; i++ )
+ loaded = QString( known[i].in() ) == moduleName;
+ if ( !loaded )
+ moduleCatalogue->ImportXmlCatalogFile( catalogue.toUtf8().constData() );
+ }
+}