X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSalomeApp%2FSalomeApp_Application.cxx;h=a8300ea62c7789956cb0aa22830b6fc367cd68bf;hb=f2376a3d416ad43c5ad000a92deb0801f71ff4c4;hp=aaf5ad2bf2d60cc734d042e09a6ab296511ff174;hpb=e6450922454677530835b4769b0e0e3eb16ace51;p=modules%2Fgui.git diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index aaf5ad2bf..a8300ea62 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -30,6 +30,7 @@ // E.A. : some same symbols : acosh, asinh, ... #include #ifndef DISABLE_PYCONSOLE + #include #include #endif #endif @@ -71,6 +72,7 @@ #include #include #include +#include #include @@ -80,8 +82,6 @@ //#include -#include -#include #include #include @@ -97,7 +97,9 @@ #include #include +#include #include +#include #include #include @@ -107,9 +109,15 @@ #include #include +#include #include +#include +#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) + +std::unique_ptr SalomeApp_Application::_ns; + /*!Internal class that updates object browser item properties */ // temporary commented /*class SalomeApp_Updater : public OB_Updater @@ -171,20 +179,34 @@ namespace bool myPrevState; bool& myLock; //! External 'Lock state' boolean flag }; -} -/*!Create new instance of SalomeApp_Application.*/ -extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication() -{ - return new SalomeApp_Application(); + /*! + \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 ), - myToIgnoreMessages( 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. @@ -226,9 +248,10 @@ void SalomeApp_Application::start() 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(); @@ -237,7 +260,7 @@ void SalomeApp_Application::start() } 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) { @@ -257,10 +280,12 @@ void SalomeApp_Application::start() 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 @@ -276,23 +301,20 @@ void SalomeApp_Application::start() 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 (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\", \"rb\").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 @@ -322,12 +344,12 @@ void SalomeApp_Application::createActions() //! Dump study createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIcon(), tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ), - Qt::CTRL+Qt::Key_D, desk, false, this, SLOT( onDumpStudy() ) ); + QKeySequence::UnknownKey, desk, false, this, SLOT( onDumpStudy() ), "/PRP_DESK_FILE_DUMP_STUDY" ); //! Load script createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIcon(), tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ), - Qt::CTRL+Qt::Key_T, desk, false, this, SLOT( onLoadScript() ) ); + QKeySequence::UnknownKey, desk, false, this, SLOT( onLoadScript() ), "/PRP_DESK_FILE_LOAD_SCRIPT" ); //! Properties createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIcon(), @@ -337,22 +359,27 @@ void SalomeApp_Application::createActions() //! Catalog Generator createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ), QIcon(), tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ), - Qt::ALT+Qt::SHIFT+Qt::Key_G, desk, false, this, SLOT( onCatalogGen() ) ); + QKeySequence::UnknownKey, desk, false, this, SLOT( onCatalogGen() ), "/PRP_DESK_CATALOG_GENERATOR" ); //! Registry Display createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ), QIcon(), tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ), /*Qt::SHIFT+Qt::Key_D*/0, desk, false, this, SLOT( onRegDisplay() ) ); + //! Find action dialog + createAction( FindActionId, tr( "TOT_DESK_FIND_ACTION" ), QIcon(), + tr( "MEN_DESK_FIND_ACTION" ), tr( "PRP_DESK_FIND_ACTION" ), + QKeySequence::UnknownKey, desk, false, this, SLOT( onFindAction() ), "/PRP_DESK_FIND_ACTION" ); + createAction( ConnectId, tr( "TOT_DESK_CONNECT_STUDY" ), QIcon(), tr( "MEN_DESK_CONNECT" ), tr( "PRP_DESK_CONNECT" ), - Qt::CTRL+Qt::Key_L, desk, false, this, SLOT( onLoadDoc() ) ); + QKeySequence::UnknownKey, desk, false, this, SLOT( onLoadDoc() ), "/PRP_DESK_CONNECT" ); //no need at this action for mono-study application because study is always exists action( ConnectId )->setVisible( false ); createAction( DisconnectId, tr( "TOT_DESK_DISCONNECT_STUDY" ), QIcon(), tr( "MEN_DESK_DISCONNECT" ), tr( "PRP_DESK_DISCONNECT" ), - Qt::CTRL+Qt::Key_U, desk, false, this, SLOT( onUnloadDoc() ) ); + QKeySequence::UnknownKey, desk, false, this, SLOT( onUnloadDoc() ), "/PRP_DESK_DISCONNECT" ); //no need at this action for mono-study application because study is always exists action( DisconnectId )->setVisible( false ); @@ -376,6 +403,7 @@ void SalomeApp_Application::createActions() int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, MenuToolsId, 50 ); createMenu( CatalogGenId, toolsMenu, 10, -1 ); createMenu( RegDisplayId, toolsMenu, 10, -1 ); + createMenu( FindActionId, toolsMenu, 10, -1 ); createMenu( separator(), toolsMenu, -1, 15, -1 ); createExtraActions(); @@ -529,11 +557,10 @@ void SalomeApp_Application::onNewWithScript() { onNewDoc(); - QString command = QString("exec(open(\"%1\", \"rb\").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 @@ -816,6 +843,8 @@ void SalomeApp_Application::onOpenWith() 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(); } @@ -969,6 +998,7 @@ void SalomeApp_Application::onDumpStudy( ) bool res; { SUIT_OverrideCursor wc; + ensureShaperIsActivated(); res = appStudy->dump( aFileName, toPublish, isMultiFile, toSaveGUI ); } if ( !res ) @@ -1001,14 +1031,12 @@ void SalomeApp_Application::onLoadScript( ) if ( !aFile.isEmpty() ) { - - QString command = QString("exec(open(\"%1\", \"rb\").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 } } @@ -1192,7 +1220,7 @@ void SalomeApp_Application::updateDesktopTitle() { desktop()->setWindowTitle( aTitle ); } -int SalomeApp_Application::closeChoice( const QString& docName ) +int SalomeApp_Application::closeChoice( const QString& /*docName*/ ) { QStringList buttons; QMap choices; @@ -1235,6 +1263,7 @@ bool SalomeApp_Application::closeAction( const int choice, bool& closePermanentl onSaveDoc(); else if ( !onSaveAsDoc() ) res = false; + // fall through! case CloseDisconnect: closeActiveDoc( false ); closePermanently = false; @@ -1283,9 +1312,8 @@ bool SalomeApp_Application::openAction( const int aChoice, const QString& aName switch ( choice ) { case OpenRefresh: - { - choice = OpenNew; - } + choice = OpenNew; + // fall through! default: res = LightApp_Application::openAction( choice, aName ); break; @@ -1350,8 +1378,8 @@ CORBA::ORB_var SalomeApp_Application::orb() if ( CORBA::is_nil( _orb ) ) { Qtx::CmdLineArgs args; - ORB_INIT& init = *SINGLETON_::Instance(); - _orb = init( args.argc(), args.argv() ); + SetArgcArgv( args.argc(), args.argv() ); + _orb = KERNEL::GetRefToORB(); } return _orb; @@ -1370,10 +1398,9 @@ _PTR(Study) SalomeApp_Application::getStudy() } /*!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.*/ @@ -1490,9 +1517,14 @@ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePop 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() ) ); + } } } @@ -1551,6 +1583,25 @@ void SalomeApp_Application::onRegDisplay() regWnd->activateWindow(); } +/*!Display Action Search dialog */ +void SalomeApp_Application::onFindAction() +{ + const auto pActiveModule = activeModule(); + if (pActiveModule && pActiveModule->name() == "PARAVIS") { + return; + // ParaViS module has its own action search dialog (Quick Launch dialog). + // Keep this conditional block until ParaViS's actions are not added to ShortcutMgr resource and asset files. + } + + SUIT_FindActionDialog aDlg( desktop() ); + if (pActiveModule) + aDlg.setActiveModuleID(pActiveModule->name()); + else + aDlg.setActiveModuleID(); + + aDlg.exec(); +} + /*!find original object by double click on item */ void SalomeApp_Application::onDblClick( SUIT_DataObject* theObj ) { @@ -1900,7 +1951,7 @@ bool SalomeApp_Application::renameAllowed( const QString& entry) const \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( activeStudy() ); @@ -1953,6 +2004,7 @@ bool SalomeApp_Application::updateStudy() // get unique temporary directory name QString aTmpDir = QString::fromStdString( SALOMEDS_Tool::GetTmpDir() ); + if( aTmpDir.isEmpty() ) return false; @@ -2039,17 +2091,18 @@ bool SalomeApp_Application::onRestoreStudy( const QString& theDumpScript, SalomeApp_Application* app = dynamic_cast( SUIT_Session::session()->activeApplication() ); // load study from the temporary directory - - QString command = QString( "exec(open(\"%1\" ,\"rb\").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*" ) ); @@ -2091,6 +2144,14 @@ void SalomeApp_Application::afterCloseDoc() 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. */ @@ -2104,7 +2165,41 @@ bool SalomeApp_Application::checkExistingDoc() 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(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 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() ); + } +}