-// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022 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 <QtxFontEdit.h>
#include <QtxToolBar.h>
#include <QtxTreeView.h>
+#include <QtxInfoPanel.h>
#include <QtxMRUAction.h>
#include <QtxDockAction.h>
#include <QtxDockWidget.h>
#include <PyViewer_ViewWindow.h>
#endif
+#ifndef DISABLE_PV3DVIEWER
+#ifndef DISABLE_SALOMEOBJECT
+ #include <SPV3D_ViewModel.h>
+ #include <SPV3D_ViewManager.h>
+ #include "LightApp_PV3DSelector.h"
+#else
+ #include <PV3DViewer_ViewModel.h>
+ #include <PV3DViewer_ViewManager.h>
+#endif
+ #include <PV3DViewer_ViewManager.h>
+ #include <PV3DViewer_ViewModel.h>
+ #include "PV3DViewer_ViewWindow.h"
+#endif
+
#define VISIBILITY_COLUMN_WIDTH 25
#include <utilities.h>
#define FIRST_HELP_ID 1000000
+#define HAS_WWW_URL true
+#define HAS_FORUM_URL true
+#define HAS_YOUTUBE_URL true
+#define HAS_TUTORIAL_URL false
#ifndef DISABLE_SALOMEOBJECT
#include <SALOME_InteractiveObject.hxx>
int inputLen = input.length();
QDataStream anInputData( &input, QIODevice::ReadOnly );
while ( tmp < inputLen ) {
- tmp = input.indexOf( QToolBarMarker, tmp + 1 );
+ tmp = input.indexOf( (uchar)QToolBarMarker, tmp + 1 );
if ( tmp < 0 )
break;
anInputData.device()->seek( tmp );
result = QLocale( lang ).nativeLanguageName();
return result;
}
+
+ QString getHelpItem( const QString& section, const QString& parameter, const QString& root = QString() )
+ {
+ SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+ foreach( QString item, resMgr->stringValue( section, parameter ).split( ";;", QString::SkipEmptyParts ) )
+ {
+ if ( item.startsWith( "http", Qt::CaseInsensitive ) )
+ return item;
+ QString path = item;
+ path.remove( QRegExp( "#.*$" ) );
+ QFileInfo fi( path );
+ if ( fi.isRelative() && !root.isEmpty() )
+ path = Qtx::addSlash( root ) + path;
+ if ( QFile::exists( path ) )
+ return item;
+ }
+ return QString();
+ }
+
+ const bool HAS_SALOME_ON_DEMAND =
+#if defined(WITH_SALOME_ON_DEMAND)
+ true;
+#else
+ false;
+#endif
}
/*!Create new instance of LightApp_Application.*/
#ifndef DISABLE_QTXWEBBROWSER
QProcess::startDetached( "HelpBrowser",
QStringList() << QString( "--remove=%1" ).arg( QApplication::instance()->applicationPid() ) );
-#endif
+#endif
CAM_Application::closeApplication();
}
if ( prevMod )
actName = prevMod->moduleName();
- if ( actName == modName )
+ QString name = modName;
+ if ( !name.isEmpty() && !moduleTitle( modName ).isEmpty() )
+ name = moduleTitle( modName );
+
+ if ( actName == name )
return true;
- putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) );
+ putInfo( tr( "ACTIVATING_MODULE" ).arg( name ) );
saveDockWindowsState();
- bool status = CAM_Application::activateModule( modName );
+ if ( infoPanel() )
+ infoPanel()->clear();
+
+ bool status = CAM_Application::activateModule( name );
updateModuleActions();
updateViewManagers();
if ( activeStudy() && activeStudy()->root() && objectBrowser() ) {
- if ( objectBrowser()->root() != activeStudy()->root() )
+ if ( objectBrowser()->root() != activeStudy()->root() )
objectBrowser()->setRoot( activeStudy()->root() );
updateObjectBrowser( true );
}
// Help menu
int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
-
- int id = LightApp_Application::UserID + FIRST_HELP_ID;
+
+ QString url;
// a) Link to web site
- QString url = resMgr->stringValue("GUI", "site_url");
- if ( !url.isEmpty() ) {
- QString title = tr ( "SALOME_SITE" );
- QAction* as = createAction( id, title,
- resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
- title, title,
- 0, desk, false, this, SLOT( onHelpContentsModule() ) );
- as->setData( url );
- createMenu( as, helpMenu, -1, 0 );
- id++;
+ if ( HAS_WWW_URL ) {
+ url = resMgr->stringValue("GUI", "site_url");
+ if ( !url.isEmpty() ) {
+ QString title = tr ( "SALOME_SITE" );
+ QAction* as = createAction( WebSiteId, title,
+ resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
+ title, title,
+ 0, desk, false, this, SLOT( onHelpContentsModule() ) );
+ as->setData( url );
+ createMenu( as, helpMenu, -1, 0 );
+ }
}
// b) Link to Forum
- url = resMgr->stringValue("GUI", "forum_url");
- if ( !url.isEmpty() ) {
- QString title = tr ( "SALOME_FORUM" );
- QAction* af = createAction( helpMenu, title,
- resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
- title, title,
- 0, desk, false, this, SLOT( onHelpContentsModule() ) );
- af->setData( url );
- createMenu( af, helpMenu, -1, 0 );
- id++;
+ if ( HAS_FORUM_URL ) {
+ url = resMgr->stringValue("GUI", "forum_url");
+ if ( !url.isEmpty() ) {
+ QString title = tr ( "SALOME_FORUM" );
+ QAction* af = createAction( ForumId, title,
+ resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
+ title, title,
+ 0, desk, false, this, SLOT( onHelpContentsModule() ) );
+ af->setData( url );
+ createMenu( af, helpMenu, -1, 0 );
+ }
}
// c) Link to YouTube channel
- url = resMgr->stringValue("GUI", "channel_url");
- if ( !url.isEmpty() ) {
- createMenu( separator(), helpMenu, -1, 0 );
- QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
- QAction* av = createAction( helpMenu, title,
- resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
- title, title,
- 0, desk, false, this, SLOT( onHelpContentsModule() ) );
- av->setData( url );
- createMenu( av, helpMenu, -1, 0 );
- id++;
- }
-
- // d) Help for modules
-
- // - First create top-level menus to preserve correct order
- QString userGuide = "User's Guide";
- QString devGuide = "Developer's Guide";
- createMenu( userGuide, helpMenu, -1, 5 );
- createMenu( devGuide, helpMenu, -1, 5 );
+ if ( HAS_YOUTUBE_URL ) {
+ url = resMgr->stringValue("GUI", "channel_url");
+ if ( !url.isEmpty() ) {
+ createMenu( separator(), helpMenu, -1, 0 );
+ QString title = tr ( "SALOME_VIDEO_TUTORIALS" );
+ QAction* av = createAction( VideosId, title,
+ resMgr->loadPixmap( "LightApp", tr( "ICON_LIFE_RIGN" ), false ),
+ title, tr( "PRP_SALOME_VIDEO_TUTORIALS" ),
+ 0, desk, false, this, SLOT( onHelpContentsModule() ) );
+ av->setData( url );
+ createMenu( av, helpMenu, -1, 0 );
+ }
+ }
+
+ // d) Link to Tutorials
+ if ( HAS_TUTORIAL_URL ) {
+ url = resMgr->stringValue("GUI", "tutorials_url");
+ if ( !url.isEmpty() ) {
+ QString title = tr ( "SALOME_TUTORIALS" );
+ QAction* as = createAction( TutorialsId, title,
+ resMgr->loadPixmap( "LightApp", tr( "ICON_WWW" ), false ),
+ title, tr( "PRP_SALOME_TUTORIALS" ),
+ 0, desk, false, this, SLOT( onHelpContentsModule() ) );
+ as->setData( url );
+ createMenu( as, helpMenu, -1, 0 );
+ }
+ }
+
+ // e) Help for modules
QStringList aModuleList;
modules( aModuleList, false );
aModuleList.prepend( "GUI" );
aModuleList.prepend( "KERNEL" );
- QString aModule;
- foreach( aModule, aModuleList ) {
- if ( aModule.isEmpty() ) // module title (user name)
- continue;
- IMap <QString, QString> helpData; // list of help files for the module
- QString helpSubMenu; // help submenu name (empty if not needed)
- QString modName = moduleName( aModule ); // module name
- if ( modName.isEmpty() ) modName = aModule; // for KERNEL and GUI
- QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName ); // module root dir env variable
- QString modDir = Qtx::getenv( rootDir.toUtf8().constData() ); // module root dir path
- QString docSection;
- if (resMgr->hasValue( modName, "documentation" ) )
- docSection = resMgr->stringValue(modName, "documentation");
- else if ( resMgr->hasSection( modName + "_documentation" ) )
- docSection = modName + "_documentation";
- if ( !docSection.isEmpty() ) {
- helpSubMenu = resMgr->stringValue( docSection, "sub_menu", "" );
- if ( helpSubMenu.contains( "%1" ) )
- helpSubMenu = helpSubMenu.arg( aModule );
- QStringList listOfParam = resMgr->parameters( docSection );
- foreach( QString paramName, listOfParam ) {
- QString valueStr = resMgr->stringValue( docSection, paramName );
- if ( !valueStr.isEmpty() ) {
- QStringList valueItems = valueStr.split( ";;", QString::SkipEmptyParts );
- foreach( QString item, valueItems ) {
- if ( item.startsWith( "http", Qt::CaseInsensitive ) ) {
- QString key = paramName.contains( "%1" ) ? paramName.arg( aModule ) : paramName;
- helpData.insert( key, item );
- break;
- }
- else {
- QFileInfo fi( item );
- if ( fi.isRelative() && !modDir.isEmpty() )
- item = Qtx::addSlash( modDir ) + item;
- if ( QFile::exists( item ) ) {
- QString key = paramName.contains( "%1" ) ? paramName.arg( aModule ) : paramName;
- helpData.insert( key, item );
- break;
- }
- }
- }
- }
- }
- }
-
- if ( helpData.isEmpty() && !modDir.isEmpty() ) {
- QStringList idxLst = QStringList() << modDir << "share" << "doc" << "salome" << "gui" << modName << "index.html";
- QString indexFile = idxLst.join( QDir::separator() ); // index file
- if ( QFile::exists( indexFile ) )
- helpData.insert( tr( "%1 module Users's Guide" ).arg( aModule ), indexFile );
- }
-
- IMapConstIterator<QString, QString > fileIt;
- for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) {
- QString helpItemPath = fileIt.key();
- // remove all '//' occurances
- while ( helpItemPath.contains( "//" ) )
- helpItemPath.replace( "//", "" );
- // obtain submenus hierarchy if given
- QStringList smenus = helpItemPath.split( "/" );
- helpItemPath = smenus.takeLast();
- // workaround for User's Guide and Developer's Guide to avoid having single item in module's submenu.
- if ( helpItemPath == userGuide || helpItemPath == devGuide ) {
- QString menuPath = smenus.join( "/" );
- QStringList allKeys = helpData.keys();
- QStringList total = allKeys.filter( QRegExp( QString( "^%1" ).arg( menuPath ) ) );
- if ( total.count() == 1 && smenus.count() > 0 )
- helpItemPath = smenus.takeLast();
- }
- QPixmap helpIcon = fileIt.value().startsWith( "http", Qt::CaseInsensitive ) ?
- resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
- QAction* a = createAction( id, helpItemPath, helpIcon, helpItemPath, helpItemPath,
- 0, desk, false, this, SLOT( onHelpContentsModule() ) );
- a->setData( fileIt.value() );
- if ( !helpSubMenu.isEmpty() ) {
- smenus.prepend( helpSubMenu );
- }
- // create sub-menus hierarchy
- int menuId = helpMenu;
- foreach ( QString subMenu, smenus )
- menuId = createMenu( subMenu, menuId, -1, 5 );
- createMenu( a, menuId, -1, ( menuId != helpMenu && (helpItemPath == userGuide || helpItemPath == devGuide) ) ? 0 : 5 );
- id++;
- }
- }
-
- // - Additional help items
+ foreach( QString aModule, aModuleList )
+ createHelpItems( aModule );
+
+ // f) Additional help items
+ int id = LightApp_Application::UserID + FIRST_HELP_ID + 1000;
createMenu( separator(), helpMenu, -1, 10 );
QStringList addHelpItems = resMgr->parameters( "add_help" );
foreach ( QString paramName, addHelpItems ) {
- QString valueStr = resMgr->stringValue( "add_help", paramName );
- if ( !valueStr.isEmpty() ) {
- QStringList valueItems = valueStr.split( ";;", QString::SkipEmptyParts );
- foreach( QString item, valueItems ) {
- if ( item.startsWith( "http", Qt::CaseInsensitive ) || QFile::exists( item ) ) {
- QPixmap helpIcon = item.startsWith( "http", Qt::CaseInsensitive ) ?
- resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
- QAction* a = createAction( id++, paramName, helpIcon, paramName, paramName,
- 0, desk, false, this, SLOT( onHelpContentsModule() ) );
- a->setData( item );
- createMenu( a, helpMenu, -1, 10 );
- break;
- }
- }
+ QString helpItem = getHelpItem( "add_help", paramName );
+ if ( !helpItem.isEmpty() )
+ {
+ QPixmap helpIcon = helpItem.startsWith( "http", Qt::CaseInsensitive ) ?
+ resMgr->loadPixmap( "STD", tr( "ICON_WWW" ), false ) : resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false );
+ QAction* a = createAction( id++, paramName, helpIcon, paramName, paramName,
+ 0, desk, false, this, SLOT( onHelpContentsModule() ) );
+ a->setData( helpItem );
+ createMenu( a, helpMenu, -1, 10 );
}
}
connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) );
registerAction( MRUId, mru );
- // default icon for neutral point ('SALOME' module)
- QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false );
- if ( defIcon.isNull() )
- defIcon = QPixmap( imageEmptyIcon );
-
- //! default icon for any module
- QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false );
- if ( modIcon.isNull() )
- modIcon = QPixmap( imageEmptyIcon );
-
+ // List of modules
+ LightApp_ModuleAction* moduleAction = new LightApp_ModuleAction( resMgr, desk );
+ registerAction( ModulesListId, moduleAction );
+ // a. here we add regular modules (specified to GUI via --modules cmd line option, or default list from configuration)
+ // b. custom modules are added in customize() method
QStringList modList;
modules( modList, false );
-
- if ( modList.count() > 1 )
- {
- LightApp_ModuleAction* moduleAction =
- new LightApp_ModuleAction( tr( "APP_NAME" ), defIcon, desk );
-
- QMap<QString, QString> iconMap;
- moduleIconNames( iconMap );
-
- const int iconSize = 20;
-
- QStringList::Iterator it;
- for ( it = modList.begin(); it != modList.end(); ++it )
- {
- QString modName = moduleName( *it );
-
- QString iconName;
- if ( iconMap.contains( *it ) )
- iconName = iconMap[*it];
-
- QPixmap icon = resMgr->loadPixmap( modName, iconName, false );
- if ( icon.isNull() )
- {
- icon = modIcon;
- INFOS( std::endl <<
- "****************************************************************" << std::endl <<
- " Warning: icon for " << qPrintable(*it) << " is not found!" << std::endl <<
- " Using the default icon." << std::endl <<
- "****************************************************************" << std::endl);
- }
- icon = Qtx::scaleIcon( icon, iconSize );
-
- moduleAction->insertModule( *it, icon );
- }
-
- connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ),
- this, SLOT( onModuleActivation( const QString& ) ) );
- registerAction( ModulesListId, moduleAction );
- }
+ foreach ( QString aModule, modList )
+ moduleAction->insertModule( aModule, moduleIcon( aModule, 20 ) ); // scale icon to 20x20 pix
+
+ connect( this, SIGNAL( moduleActivated( QString ) ),
+ moduleAction, SLOT( setActiveModule( QString ) ) );
+ connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ),
+ this, SLOT( onModuleActivation( const QString& ) ) );
+ connect( moduleAction, SIGNAL( adding() ),
+ this, SLOT( onModuleAdding() ) );
+ connect( moduleAction, SIGNAL( removing( QString ) ),
+ this, SLOT( onModuleRemoving( QString ) ) );
// New window
int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, MenuWindowId, 100 );
#ifndef DISABLE_PYVIEWER
createActionForViewer( NewPyViewerId, newWinMenu, QString::number( 7 ), Qt::ALT+Qt::Key_Y );
#endif
+#ifndef DISABLE_PV3DVIEWER
+ createActionForViewer( NewPV3DViewId, newWinMenu, QString::number( 8 ), Qt::ALT+Qt::Key_3 );
+#endif
createAction( RenameId, tr( "TOT_RENAME" ), QIcon(), tr( "MEN_DESK_RENAME" ), tr( "PRP_RENAME" ),
Qt::ALT+Qt::SHIFT+Qt::Key_R, desk, false, this, SLOT( onRenameWindow() ) );
createMenu( StyleId, viewMenu, 20, -1 );
#endif // USE_SALOME_STYLE
createMenu( FullScreenId, viewMenu, 20, -1 );
+ createMenu( separator(), viewMenu, -1, 20, -1 );
+ createMenu( ModulesListId, viewMenu );
int modTBar = createTool( tr( "INF_TOOLBAR_MODULES" ), // title (language-dependant)
QString( "SalomeModules" ) ); // name (language-independant)
createTool( ModulesListId, modTBar );
}
+/*!
+ Customize actions.
+*/
+void LightApp_Application::customize()
+{
+ // List of modules
+ LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
+ // a. regular modules were added in createActions() method
+ // b. here we add custom modules (manually added by the user)
+ if ( HAS_SALOME_ON_DEMAND )
+ {
+ QStringList modList = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts );
+ foreach ( QString aModule, modList )
+ addUserModule( aModule, resourceMgr()->stringValue( "user_modules", aModule ) );
+ }
+ else
+ {
+ moduleAction->setModeEnabled( LightApp_ModuleAction::AddRemove, false );
+ }
+}
+
/*!On module activation action.*/
-void LightApp_Application::onModuleActivation( const QString& modName )
+void LightApp_Application::onModuleActivation( const QString& modTitle )
{
// Force user to create/open a study before module activation
- QMap<QString, QString> iconMap;
- moduleIconNames( iconMap );
- QPixmap icon = resourceMgr()->loadPixmap( moduleName( modName ), iconMap[ modName ], false );
- if ( icon.isNull() )
- icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module
-
+ QPixmap icon = moduleIcon( modTitle );
bool cancelled = false;
- while ( !modName.isEmpty() && !activeStudy() && !cancelled ){
- LightApp_ModuleDlg aDlg( desktop(), modName, icon );
+ while ( !modTitle.isEmpty() && !activeStudy() && !cancelled ){
+ LightApp_ModuleDlg aDlg( desktop(), modTitle, icon );
QMap<int, QString> opmap = activateModuleActions();
for ( QMap<int, QString>::ConstIterator it = opmap.begin(); it != opmap.end(); ++it )
aDlg.addButton( it.value(), it.key() );
else {
// cancelled
putInfo( tr("INF_CANCELLED") );
-
- LightApp_ModuleAction* moduleAction =
- qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
- if ( moduleAction )
- moduleAction->setActiveModule( QString() );
+ emit moduleActivated( QString() );
cancelled = true;
}
}
if ( !cancelled )
- activateModule( modName );
+ activateModule( modTitle );
+}
+
+/*!On module adding action.*/
+void LightApp_Application::onModuleAdding()
+{
+ // show dialog to browse configuration file
+ QStringList filters = ( QStringList() << tr( "Config files") + " (*.salomex)" << tr( "All files" ) + " (*)" );
+ QStringList paths = getOpenFileNames( QString(), filters.join( ";;" ), QString(), desktop() );
+ if ( paths.isEmpty() ) // cancelled
+ return;
+
+ // loop via selected configuration files
+ foreach( QString path, paths )
+ {
+ // read description file (.salomex) and check it's OK
+ QtxResourceMgr resMgr;
+ if ( !resMgr.addResource( path ) )
+ {
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_BAD_SALOMEX_FILE" ).arg( path ) );
+ continue;
+ }
+ // retrieve module name
+ QString name = resMgr.stringValue( "General", "name" ).trimmed();
+ if ( name.isEmpty() )
+ {
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_EMPTY_NAME" ).arg( path ) );
+ continue;
+ }
+ // retrieve root directory
+ QString root = resMgr.stringValue( "General", "root" ).trimmed();
+ if ( root.isEmpty() )
+ {
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_EMPTY_ROOT" ).arg( path ) );
+ continue;
+ }
+ addUserModule( name, root, true );
+ }
+}
+
+/*Add user module.*/
+bool LightApp_Application::addUserModule( const QString& name, const QString& root, bool interactive )
+{
+ if ( name.isEmpty() || root.isEmpty() )
+ return false;
+
+ if ( !moduleTitle( name ).isEmpty() ) // module alread in current session
+ {
+ if ( interactive )
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_DUPLICATED" ).arg( name ) );
+ return false;
+ }
+ if ( !QFileInfo( root ).exists() ) // root directory does not exist
+ {
+ if ( interactive )
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_ROOT_DOES_NOT_EXIST" ).arg( root ) );
+ return false;
+ }
+ // resources directory
+ QString resDir = Qtx::joinPath( QStringList() << root << "share" << "salome" << "resources" << name.toLower() );
+ if ( !QFileInfo( resDir ).exists() ) // resources directory does not exist
+ {
+ if ( interactive )
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_BAD_RESDIR" ).arg( resDir ) );
+ return false;
+ }
+ // read XML configuration file
+ resourceMgr()->setConstant( QString( "%1_ROOT_DIR" ).arg( name ), root );
+ if ( !resourceMgr()->addResource( resDir ) ) // cannot read configuration
+ {
+ if ( interactive )
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_CANNOT_READ_CFG" ).arg( resDir ) );
+ return false;
+ }
+ // fill in information about module
+ if ( !appendModuleInfo( name ) ) // cannot append module information to internal table
+ {
+ if ( interactive )
+ SUIT_MessageBox::warning( desktop(), tr( "WRN_WARNING" ), tr( "WRN_MODULE_BAD_CFG_FILE" ).arg( name ) );
+ return false;
+ }
+ // load translations
+ resourceMgr()->loadLanguage( name );
+ // append module to the menu / toolbar
+ LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
+ if ( moduleAction )
+ moduleAction->insertModule( moduleTitle( name ), moduleIcon( moduleTitle( name ), 20 ), true ); // scale icon to 20x20 pix
+ // add empty page to Preferences dialog
+ LightApp_Preferences* prefs = preferences();
+ if ( prefs && !prefs->hasModule( moduleTitle( name ) ) )
+ {
+ int prefId = prefs->addPreference( moduleTitle( name ) );
+ prefs->setItemIcon( prefId, moduleIcon( moduleTitle( name ), 20 ) ); // scale icon to 20x20 pix
+ LightApp_Module* m = qobject_cast<LightApp_Module*>( module( moduleTitle( name ) ) );
+ if ( m )
+ {
+ m->createPreferences();
+ emptyPreferences( moduleTitle( name ) );
+ }
+ }
+ // add Help items
+ createHelpItems( moduleTitle( name ) );
+ // extend module catalog
+ QString catalogue = QDir( resDir ).filePath( QString( "%1Catalog.xml" ).arg( name ) );
+ addCatalogue( name, catalogue );
+ // update windows (in particular, Info panel)
+ updateWindows();
+ // save module in the resource manager
+ if ( interactive )
+ {
+ QStringList customModules = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts );
+ customModules << name;
+ customModules.removeDuplicates();
+ resourceMgr()->setValue( "launch", "user_modules", customModules.join( ";" ) );
+ resourceMgr()->setValue( "user_modules", name, root );
+ }
+ return true;
+}
+
+/*!On module removing action.*/
+void LightApp_Application::onModuleRemoving( const QString& title )
+{
+ QString root = resourceMgr()->stringValue( "user_modules", moduleName( title ) );
+ QDir rootDirectory = QDir( root );
+
+ if ( rootDirectory.exists() )
+ {
+ int answer = SUIT_MessageBox::question( desktop(),
+ tr( "TLT_REMOVE_MODULE" ),
+ tr( "QUE_REMOVE_MODULE_DIR" ).arg( root ),
+ SUIT_MessageBox::Yes | SUIT_MessageBox::No | SUIT_MessageBox::Cancel,
+ SUIT_MessageBox::No );
+ if ( answer == SUIT_MessageBox::Cancel )
+ return; // cancelled
+ if ( answer == SUIT_MessageBox::Yes )
+ {
+ if ( activeStudy() && activeStudy()->isModified() && !onSaveDoc() )
+ // doc is not saved, or saving cancelled
+ return;
+ if ( !rootDirectory.removeRecursively() )
+ {
+ // canont remove directory
+ if ( SUIT_MessageBox::question( desktop(),
+ tr( "WRN_WARNING" ),
+ tr( "WRN_CANNOT_REMOVE_DIR" ).arg( root ),
+ SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+ SUIT_MessageBox::No ) == SUIT_MessageBox::No )
+ return; // removal is cancelled
+ }
+ }
+ }
+
+ if ( activeModule() && activeModule()->moduleName() == title )
+ activateModule( "" );
+
+ // remove from "Modules" menu and toolbar
+ LightApp_ModuleAction* moduleAction = qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
+ if ( moduleAction )
+ {
+ moduleAction->removeModule( title );
+ }
+ // remove Help menu items
+ removeHelpItems( title );
+ // remove Preferences
+ LightApp_Preferences* prefs = preferences();
+ if ( prefs )
+ prefs->removeModule( title );
+ // remove settings
+ QStringList customModules = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts );
+ customModules.removeAll( moduleName( title ) );
+ resourceMgr()->setValue( "launch", "user_modules", customModules.join( ";" ) );
+ removeModuleInfo( moduleName( title ) );
+ // update windows (in particular, Info panel)
+ updateWindows();
}
/*!Default module activation.*/
case NewPyViewerId:
type = PyViewer_Viewer::Type();
break;
+#endif
+#ifndef DISABLE_PV3DVIEWER
+ case NewPV3DViewId:
+ type = PV3DViewer_ViewModel::Type();
+ break;
#endif
}
//asl: fix for 0020515
saveDockWindowsState();
-
+
CAM_Application::onNewDoc();
}
if ( aName.isNull() ) //Cancel
return;
- closeDoc(false);
onOpenDoc( aName );
if ( !study ) // new study will be create in THIS application
}
}
+bool LightApp_Application::canOpenDoc( const QString& )
+{
+ return true;
+}
+
/*!
SLOT: Opens new document.
\param aName - name of file
*/
bool LightApp_Application::onOpenDoc( const QString& aName )
{
+ if ( !canOpenDoc(aName)) {
+ bool showError = !property("open_study_from_command_line").isValid() ||
+ !property("open_study_from_command_line").toBool();
+
+ putInfo( tr("OPEN_DOCUMENT_PROBLEM") );
+ if ( showError )
+ SUIT_MessageBox::critical( desktop(), tr("ERR_ERROR"), tr("OPEN_DOCUMENT_PROBLEM"));
+
+ return false;
+ }
+
+ closeDoc(false);
+
if ( !checkExistingDoc() )
return false;
// We should take mru action first because this application instance can be deleted later.
QtxMRUAction* mru = ::qobject_cast<QtxMRUAction*>( action( MRUId ) );
-
+
bool res = CAM_Application::onOpenDoc( aName );
if ( mru )
if( a )
a->setEnabled( activeStudy() );
#endif
+
+#ifndef DISABLE_PV3DVIEWER
+ a = action( NewPV3DViewId );
+ if( a )
+ a->setEnabled( activeStudy() );
+#endif
}
/*!
{
// normalize path
if ( myUrl.startsWith( "file://", Qt::CaseInsensitive ) )
- myUrl = myUrl.remove( 0, QString( "file://" ).count() );
+ myUrl = myUrl.remove( 0, QString( "file://" ).count() );
// For the external browser we always specify 'file://' protocol,
// because some web browsers (e.g. Mozilla Firefox) can't open local file without protocol.
myUrl = myUrl.prepend( "file://" );
{
if ( !myBrowser.isEmpty() && !myUrl.isEmpty() )
{
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
#ifdef WIN32
QString cmdLine = QString( "\"%1\" %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
#else
QString cmdLine = QString( "%1 %2 \"%3\"" ).arg( myBrowser, myParameters, myUrl );
+ // remove LD_LIBRARY_PATH from the environement before starting launcher to avoid bad interactions.
+ // (especially in the case of universal binaries)
+ env.remove("LD_LIBRARY_PATH");
#endif
QProcess* proc = new QProcess();
+ proc->setProcessEnvironment(env);
proc->start( cmdLine );
if ( !proc->waitForStarted() )
{
#if DISABLE_QTXWEBBROWSER
bool useExternalBrowser = true;
-#else
+#else
bool useExternalBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false );
#endif
QString browser = resMgr->stringValue( "ExternalBrowser", "application" );
#endif
QString parameters = resMgr->stringValue("ExternalBrowser", "parameters");
-
+
if ( !browser.isEmpty() )
{
RunBrowser::execute( this, browser, parameters, path );
QString rootDir = Qtx::getenv( (component + "_ROOT_DIR").toLatin1().constData() );
if ( !rootDir.isEmpty() )
{
- path = (QStringList() << rootDir << "share" << "doc" << "salome" << "gui" << component << url).join( QDir::separator() );
+ path = (QStringList() << rootDir << "share" << "doc" << "salome" << "gui" << component << url).join( QDir::separator() );
}
}
}
myWin.insert( id, wid );
QtxDockWidget* dock = new QtxDockWidget( true, desktop() );
+ if ( id == WT_InfoPanel ) {
+ // Info panel's position is strongly limited to the right area;
+ // It is not movable and not floatable.
+ dock->setAllowedAreas( Qt::RightDockWidgetArea );
+ dock->setFeatures( QDockWidget::DockWidgetClosable );
+ connect( dock, SIGNAL( aboutToShow()), this, SLOT( onInfoPanelShown() ) );
+ }
+ else {
+ dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
+ }
connect( dock, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) );
- dock->setFeatures( QDockWidget::AllDockWidgetFeatures );
dock->setObjectName( wid->objectName().isEmpty() ? QString( "window_%1" ).arg( id ) :
QString( "%1Dock" ).arg( wid->objectName() ) );
dock->setWidget( wid );
return qobject_cast<SUIT_DataBrowser*>( dockWindow( WT_ObjectBrowser ) );
}
+QtxInfoPanel* LightApp_Application::infoPanel()
+{
+ return qobject_cast<QtxInfoPanel *>( dockWindow( WT_InfoPanel ));
+}
+
/*!
\return Log Window
*/
when you request the python console, this function could return
null. Then the optional parameter force (default to false) can be
set to force the creation of the python console if it is not done
- already.
+ already.
\param force - if true, the pythonConsole is created if it does not exist yet
\return Python Console
*/
resMgr->doubleValue( "OCCViewer", "focus_value", vm->stereographicFocusValue() ));
vm->setInterocularDistance( resMgr->integerValue( "OCCViewer", "iod_type", vm->interocularDistanceType() ),
resMgr->doubleValue( "OCCViewer", "iod_value", vm->interocularDistanceValue() ));
- vm->setSelectionStyle( resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) );
+ vm->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle) resMgr->integerValue( "OCCViewer", "adv_selection_mode", vm->selectionStyle() ) );
vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) );
vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) );
}
#endif
+#ifndef DISABLE_PV3DVIEWER
+# ifndef DISABLE_SALOMEOBJECT
+ if ( vmType == SPV3D_ViewModel::Type() )
+# else
+ if ( vmType == PV3DViewer_ViewModel::Type() )
+# endif
+ {
+ viewMgr = new SPV3D_ViewManager( activeStudy(), desktop() );
+ SPV3D_ViewModel* vm = dynamic_cast<SPV3D_ViewModel*>( viewMgr->getViewModel() );
+ if ( vm )
+ {
+ // vm->setBackground(...); //NYI
+ // vm->...
+
+ new LightApp_PV3DSelector( vm, mySelMgr );
+ }
+#else
+ viewMgr = new PV3DViewer_ViewManager( activeStudy(), desktop() );
+ PV3DViewer_ViewModel* vm = dynamic_cast<PV3DViewer_ViewModel*>( viewMgr->getViewModel() );
+ if ( vm )
+ {
+ // vm->setBackground(...); //NYI
+ }
+#endif
+ }
+
if ( !viewMgr )
return 0;
}
getWindow( WT_ObjectBrowser );
+ getWindow( WT_InfoPanel );
loadDockWindowsState();
}
getWindow( WT_ObjectBrowser );
+ getWindow( WT_InfoPanel );
loadDockWindowsState();
}
/*!Protected SLOT. On study closed.*/
-void LightApp_Application::onStudyClosed( SUIT_Study* s )
+void LightApp_Application::onStudyClosed( SUIT_Study* /*s*/ )
{
/*
disconnect( this, SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
wid = ob;
ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
}
+ else if ( flag == WT_InfoPanel)
+ {
+ QtxInfoPanel* ipanel = new QtxInfoPanel( desktop() );
+ ipanel->setObjectName( "infoPanel" );
+ ipanel->setWindowTitle( tr( "INFO_PANEL" ) );
+ wid = ipanel;
+ }
#ifndef DISABLE_PYCONSOLE
else if ( flag == WT_PyConsole )
{
#endif
if ( activeStudy() ) {
aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+ aMap.insert( WT_InfoPanel, Qt::RightDockWidgetArea );
// aMap.insert( WT_LogWindow, Qt::DockBottom );
}
}
if ( !crt )
return myPrefs;
- SUIT_ResourceMgr* resMgr = resourceMgr();
-
QList<SUIT_Application*> appList = SUIT_Session::session()->applications();
for ( QList<SUIT_Application*>::iterator appIt = appList.begin(); appIt != appList.end(); ++appIt )
{
QStringList names;
app->modules( names, false );
- // icons of modules
- QMap<QString, QString> icons;
- app->moduleIconNames( icons );
-
// step 1: iterate through list of all available modules
// and add empty preferences page
for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
if ( !_prefs_->hasModule( *it ) ) // prevent possible duplications
{
int modId = _prefs_->addPreference( *it ); // add empty page
- if ( icons.contains( *it ) ) // set icon
- _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ),
- icons[*it], false ), 20 ) );
+ _prefs_->setItemIcon( modId, moduleIcon( *it, 20 ) ); // scale icon to 20x20 pix
}
}
}
}
+void LightApp_Application::moduleDeactivated( CAM_Module* /*mod*/ )
+{
+ if ( infoPanel() )
+ infoPanel()->clear();
+}
+
void LightApp_Application::emptyPreferences( const QString& modName )
{
QtxPreferenceItem* item = myPrefs->findItem( modName, true );
pref->addPreference( tr( "PREF_SHOW_SPLASH" ), lookGroup, LightApp_Preferences::Bool, "launch", "splash" );
// .... -> opaque resize
pref->addPreference( tr( "PREF_OPAQUE_RESIZE" ), lookGroup, LightApp_Preferences::Bool, "desktop", "opaque_resize" );
- // .... -> drop-down buttons
+ // .... -> drop-down buttons
pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" );
// .... -> Notification timeout
int delay = pref->addPreference( tr( "PREF_NOTIFY_TIMEOUT" ), lookGroup, LightApp_Preferences::IntSpin, "notification", "timeout" );
pref->setItemProperty( "step", 0.1, light_dz );
// ... "Light source" group <<end>>
+ // ... "View cube" group <<start>>
+ int occViewCubeGroup = pref->addPreference( tr( "PREF_GROUP_VIEWCUBE" ), occGroup );
+ pref->setItemProperty( "columns", 2, occViewCubeGroup );
+ // .... -> show view cube on viewer start
+ pref->addPreference( tr( "PREF_VIEWCUBE_SHOW" ), occViewCubeGroup,
+ LightApp_Preferences::Bool, "OCCViewer", "viewcube_show" );
+ // .... -> view cube duration of animation (sec)
+ int viewcube_dur = pref->addPreference( tr( "PREF_VIEWCUBE_DURATION" ), occViewCubeGroup,
+ LightApp_Preferences::DblSpin, "OCCViewer", "viewcube_duration" );
+ pref->setItemProperty( "min", 0.1, viewcube_dur );
+ pref->setItemProperty( "max", 10.0, viewcube_dur );
+ pref->setItemProperty( "step", 0.1, viewcube_dur );
+ // .... -> show view cube axes
+ pref->addPreference( tr( "PREF_VIEWCUBE_AXES" ), occViewCubeGroup,
+ LightApp_Preferences::Bool, "OCCViewer", "viewcube_axes" );
+ // ... "View cube" group <<end>>
+
+ // ... "View cube default (OCCT) attributes" group <<start>>
+ int occViewCubeAttrsGroup = pref->addPreference( tr( "PREF_VIEWCUBE_CUSTOM" ), occGroup,
+ LightApp_Preferences::Auto, "OCCViewer", "viewcube_custom" );
+ pref->setItemProperty( "columns", 2, occViewCubeAttrsGroup );
+ // .... -> box color
+ pref->addPreference( tr( "PREF_VIEWCUBE_COLOR" ), occViewCubeAttrsGroup,
+ LightApp_Preferences::Color, "OCCViewer", "viewcube_color" );
+ // .... -> view cube size
+ int viewcube_size = pref->addPreference( tr( "PREF_VIEWCUBE_SIZE" ), occViewCubeAttrsGroup,
+ LightApp_Preferences::DblSpin, "OCCViewer", "viewcube_size" );
+ pref->setItemProperty( "min", 30.0, viewcube_size );
+ pref->setItemProperty( "max", 100.0, viewcube_size );
+ pref->setItemProperty( "step", 10.0, viewcube_size );
+ // .... -> text color
+ pref->addPreference( tr( "PREF_VIEWCUBE_TEXTCOLOR" ), occViewCubeAttrsGroup,
+ LightApp_Preferences::Color, "OCCViewer", "viewcube_text_color" );
+ // ... "View cube" group <<end>>
+
// ... -> empty frame (for layout) <<start>>
int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame );
pref->setItemProperty( "margin", 0, occGen );
continue;
OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
- occVM->setSelectionStyle(mode);
+ occVM->setSelectionStyle((OCCViewer_ViewWindow::SelectionStyle)mode);
}
}
#endif
}
#endif
+#ifndef DISABLE_OCCVIEWER
+ if ( sec == QString( "OCCViewer" ) && param.contains( "viewcube" ) )
+ {
+ QList<SUIT_ViewManager*> lst;
+ viewManagers( OCCViewer_Viewer::Type(), lst );
+ QListIterator<SUIT_ViewManager*> it( lst );
+ while ( it.hasNext() )
+ {
+ SUIT_ViewModel* vm = it.next()->getViewModel();
+ if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) )
+ continue;
+
+ OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm;
+ occVM->setViewCubeParamsFromPreferences();
+ }
+ }
+#endif
+
if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) )
{
int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 );
*/
void LightApp_Application::updateModuleActions()
{
- QString modName;
- if ( activeModule() )
- modName = activeModule()->moduleName();
-
- LightApp_ModuleAction* moduleAction =
- qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
- if ( moduleAction )
- moduleAction->setActiveModule( modName );
-}
-
-void LightApp_Application::removeModuleAction( const QString& modName )
-{
- LightApp_ModuleAction* moduleAction =
- qobject_cast<LightApp_ModuleAction*>( action( ModulesListId ) );
- if ( moduleAction )
- moduleAction->removeModule( modName );
+ emit moduleActivated( activeModule() ? activeModule()->moduleName() : QString() );
}
bool LightApp_Application::checkModule( const QString& title )
for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it )
{
QWidget* wid = it.value();
+ if ( !wid )
+ continue;
if ( winMap.contains( it.key() ) )
wid->setVisible( true );
- else
+ else if ( !activeStudy() )
delete wid;
+ else
+ wid->setVisible( false );
}
loadDockWindowsState();
+
+ if ( !activeModule() && infoPanel() )
+ {
+ infoPanel()->clear();
+ infoPanel()->setTitle( tr( "INFO_WELCOME_TO_SALOME" ) );
+
+ int grp = infoPanel()->addGroup( tr( "INFO_GETTING_STARTED" ) );
+ infoPanel()->addAction( action( FileNewId ), grp );
+ infoPanel()->addLabel( action( FileNewId )->statusTip(), grp );
+ infoPanel()->addAction( action( FileOpenId ), grp );
+ infoPanel()->addLabel( action( FileOpenId )->statusTip(), grp );
+ if ( HAS_TUTORIAL_URL ) {
+ infoPanel()->addAction( action( TutorialsId ), grp );
+ infoPanel()->addLabel( action( TutorialsId )->statusTip(), grp );
+ }
+ infoPanel()->addAction( action( VideosId ), grp );
+ infoPanel()->addLabel( action( VideosId )->statusTip(), grp );
+
+ LightApp_ModuleAction* ma = qobject_cast<LightApp_ModuleAction*>(action(ModulesListId));
+ if ( ma && ma->count() > 0 )
+ {
+ grp = infoPanel()->addGroup( tr( "INFO_AVAILABLE_MODULES" ) );
+ foreach ( QString mname, ma->modules() )
+ {
+ infoPanel()->addAction( ma->moduleAction( mname ), grp );
+ if ( !moduleDescription( mname ).isEmpty() )
+ infoPanel()->addLabel( moduleDescription( mname ), grp );
+ }
+ }
+ }
}
/*!
}
}
-/*!
- Adds icon names for modules
-*/
-void LightApp_Application::moduleIconNames( QMap<QString, QString>& iconMap ) const
+QPixmap LightApp_Application::moduleIcon( const QString& moduleTitle, const int size ) const
{
- iconMap.clear();
-
- SUIT_ResourceMgr* resMgr = resourceMgr();
- if ( !resMgr )
- return;
-
- QStringList modList;
- modules( modList, false );
-
- for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
+ QPixmap icon;
+ if ( resourceMgr() )
{
- QString modName = *it;
- QString modIntr = moduleName( modName );
- QString modIcon = resMgr->stringValue( modIntr, "icon", QString() );
-
- if ( modIcon.isEmpty() )
- continue;
-
- if ( SUIT_Tools::extension( modIcon ).isEmpty() )
- modIcon += QString( ".png" );
-
- iconMap.insert( modName, modIcon );
+ QPixmap defaultIcon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), QPixmap( imageEmptyIcon ) );
+ QString iconName = resourceMgr()->stringValue( moduleName( moduleTitle ), "icon", QString() );
+ icon = resourceMgr()->loadPixmap( moduleName( moduleTitle ), iconName, defaultIcon );
+ if ( size > 0 )
+ icon = Qtx::scaleIcon( icon, size );
}
+ return icon;
}
/*!
#else
aTypesList<<VTKViewer_Viewer::Type();
#endif
+#endif
+#ifndef DISABLE_PV3DVIEWER
+ aTypesList<<PV3DViewer_ViewModel::Type();
#endif
return aTypesList;
}
\param name new name of the object
\brief Return \c true if rename operation finished successfully, \c false otherwise.
*/
-bool LightApp_Application::renameObject( const QString& entry, const QString& ) {
+bool LightApp_Application::renameObject( const QString& /*entry*/, const QString& /*name*/ ) {
return false;
}
if ( !vtype.isEmpty() )
getViewManager( vtype, true );
}
+ else if ( message.toLower().startsWith("register_module_in_study" ) ) {
+ QString moduleName = message.split( sectionSeparator ).last();
+ // Check name of current activating module name in order to avoid ciclik
+ // call because of messages
+ if (!property("activateModule").toBool()) {
+ CAM_Module* mod = module(moduleName);
+ if (!mod)
+ mod = module(moduleTitle(moduleName));
+ if (!mod) {
+ mod = loadModule(moduleName);
+ if (!mod)
+ mod = loadModule(moduleTitle(moduleName));
+ if (mod) {
+ addModule(mod);
+ }
+ }
+ if (mod) {
+ CAM_Study* anActiveStudy = dynamic_cast<CAM_Study*>(activeStudy());
+ if (anActiveStudy) {
+ mod->connectToStudy(anActiveStudy);
+ LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>(mod->dataModel());
+ if(aDM) {
+ aDM->initRootObject();
+ }
+ }
+ }
+ }
+ }
else {
QStringList data = message.split( sectionSeparator );
if ( data.count() > 1 ) {
}
}
+void LightApp_Application::onInfoPanelShown()
+{
+ if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) )
+ ((LightApp_Module*)activeModule())->updateInfoPanel();
+}
+
/*!
Internal method.
Returns all top level toolbars.
return aRes;
QDataStream anInputData(&input, QIODevice::ReadOnly);
- int toolBarMarkerIndexDef;
+ int toolBarMarkerIndexDef = 0;
if(hasDefaultState) {
toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
if(toolBarMarkerIndexDef < 0)
Update visibility state of given objects
*/
void LightApp_Application::updateVisibilityState( DataObjectList& theList,
- SUIT_ViewModel* theViewModel )
+ SUIT_ViewModel* theViewModel )
{
if ( !theViewModel || theList.isEmpty() ) return;
if ( !obj || aStudy->isComponent( obj->entry() ) )
continue;
- LightApp_Module* anObjModule = dynamic_cast<LightApp_Module*>(obj->module());
- if ( anObjModule ) {
- LightApp_Displayer* aDisplayer = anObjModule->displayer();
- if ( aDisplayer ) {
- Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
- if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
- if ( aView && aDisplayer->IsDisplayed( obj->entry(), aView ) )
- anObjState = Qtx::ShownState;
- else
- anObjState = Qtx::HiddenState;
+ QString mname = aStudy->componentDataType(obj->entry());
+ LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(mname, false);
+ if ( aDisplayer ) {
+ Qtx::VisibilityState anObjState = Qtx::UnpresentableState;
+ if ( aDisplayer->canBeDisplayed( obj->entry(), theViewModel->getType() ) ) {
+ if ( aDisplayer->IsDisplayed( obj->entry(), aView ) )
+ anObjState = Qtx::ShownState;
+ else
+ anObjState = Qtx::HiddenState;
+ }
+ aStudy->setVisibilityState( obj->entry(), anObjState );
+ }
+ }
+}
+
+/*!
+ Update presentations of all displayed objects of theComponent in specified viewers
+*/
+void LightApp_Application::updatePresentations( const QString& theComponent,
+ const QStringList& theViewManagerTypes )
+{
+ LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(theComponent, false);
+ if ( aDisplayer ) {
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(activeStudy());
+ DataObjectList aComps;
+ bool isFound = false;
+ aStudy->root()->children( aComps );
+ DataObjectList::const_iterator aCompsIt = aComps.begin();
+ for ( ; aCompsIt != aComps.end() && !isFound; aCompsIt++ ) {
+ LightApp_DataObject* aComp = dynamic_cast<LightApp_DataObject*>( *aCompsIt );
+ if ( aComp && aComp->componentDataType() == theComponent) {
+ isFound = true;
+ DataObjectList anObjs;
+ aComp->children(anObjs, true);
+
+ QList<SUIT_ViewManager*> aViewMgrs;
+ QStringList::const_iterator itVMTypes = theViewManagerTypes.begin();
+ for ( ; itVMTypes != theViewManagerTypes.end(); ++itVMTypes )
+ viewManagers( *itVMTypes, aViewMgrs );
+
+ DataObjectList::const_iterator itObjs = anObjs.begin();
+ for ( ; itObjs != anObjs.end(); itObjs++ ) {
+ LightApp_DataObject* anObj = dynamic_cast<LightApp_DataObject*>( *itObjs );
+ QString anEntry = anObj->entry();
+
+ QListIterator<SUIT_ViewManager*> itViewMgrs( aViewMgrs );
+ while ( itViewMgrs.hasNext()) {
+ SUIT_ViewModel* aVM = itViewMgrs.next()->getViewModel();
+ if ( aVM ) {
+ SALOME_View* aView = dynamic_cast<SALOME_View*>(aVM);
+ if ( aView ) {
+ bool isDisp = aDisplayer->IsDisplayed( anEntry, aView );
+ aDisplayer->Erase( anEntry, true, false, aView );
+ if ( isDisp ) {
+ aDisplayer->Display( anEntry, false, aView );
+ }
+ }
+ }
+ }
}
- aStudy->setVisibilityState( obj->entry(), anObjState );
}
}
}
if( activeStudy() ) {
int answer = !activeStudy()->isModified() ? 1 :
SUIT_MessageBox::question( desktop(),
- tr( "APPCLOSE_CAPTION" ),
- tr( "STUDYCLOSE_DESCRIPTION" ),
- tr( "APPCLOSE_SAVE" ),
- tr( "APPCLOSE_CLOSE" ),
- tr( "APPCLOSE_CANCEL" ), 0 );
+ tr( "APPCLOSE_CAPTION" ),
+ tr( "STUDYCLOSE_DESCRIPTION" ),
+ tr( "APPCLOSE_SAVE" ),
+ tr( "APPCLOSE_CLOSE" ),
+ tr( "APPCLOSE_CANCEL" ), 0 );
if(answer == 0) {
if ( activeStudy()->isSaved() ) {
onSaveDoc();
- if (closeExistingDoc) {
- closeDoc(false);
- }
+ if (closeExistingDoc) {
+ closeDoc(false);
+ }
} else if ( onSaveAsDoc() ) {
if (closeExistingDoc) {
if( !closeDoc( false ) ) {
}
else if( answer == 1 ) {
if (closeExistingDoc) {
- closeDoc( false );
+ closeDoc( false );
}
} else if( answer == 2 ) {
result = false;
}
#endif // DISABLE_PYCONSOLE
+
+void LightApp_Application::createHelpItems( const QString& modTitle )
+{
+ if ( modTitle.isEmpty() )
+ return;
+
+ QString userGuide = "User's Guide";
+ QString devGuide = "Developer's Guide";
+
+ int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
+
+ createMenu( userGuide, helpMenu, -1, 5 );
+ createMenu( devGuide, helpMenu, -1, 5 );
+
+ IMap <QString, QString> helpData; // list of help files for the module
+ QString helpSubMenu; // help submenu name (empty if not needed)
+ QString modName = moduleName( modTitle ); // module name
+ if ( modName.isEmpty() ) modName = modTitle; // for KERNEL and GUI
+ QString rootDir = QString( "%1_ROOT_DIR" ).arg( modName ); // module root dir env variable
+ QString modDir = Qtx::getenv( rootDir.toUtf8().constData() ); // module root dir path
+ QString docSection;
+ if ( resourceMgr()->hasValue( modName, "documentation" ) )
+ docSection = resourceMgr()->stringValue( modName, "documentation" );
+ else if ( resourceMgr()->hasSection( modName + "_documentation" ) )
+ docSection = modName + "_documentation";
+ if ( !docSection.isEmpty() )
+ {
+ helpSubMenu = resourceMgr()->stringValue( docSection, "sub_menu", "" );
+ if ( helpSubMenu.contains( "%1" ) )
+ helpSubMenu = helpSubMenu.arg( modTitle );
+ foreach( QString paramName, resourceMgr()->parameters( docSection ) )
+ {
+ QString key = paramName.contains( "%1" ) ? paramName.arg( modTitle ) : paramName;
+ QString helpItem = getHelpItem( docSection, paramName );
+ if ( !helpItem.isEmpty() )
+ helpData.insert( key, helpItem );
+ }
+ }
+
+ if ( helpData.isEmpty() && !modDir.isEmpty() )
+ {
+ QStringList idxLst = QStringList() << modDir << "share" << "doc" << "salome" << "gui" << modName << "index.html";
+ QString indexFile = idxLst.join( QDir::separator() ); // index file
+ if ( QFile::exists( indexFile ) )
+ helpData.insert( tr( "%1 module Users's Guide" ).arg( modTitle ), indexFile );
+ }
+
+ IMapConstIterator<QString, QString > fileIt;
+ for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ )
+ {
+ QString helpItemPath = fileIt.key();
+ // remove all '//' occurances
+ while ( helpItemPath.contains( "//" ) )
+ helpItemPath.replace( "//", "" );
+ // obtain submenus hierarchy if given
+ QStringList smenus = helpItemPath.split( "/" );
+ helpItemPath = smenus.takeLast();
+ // workaround for User's Guide and Developer's Guide to avoid having single item in module's submenu.
+ if ( helpItemPath == userGuide || helpItemPath == devGuide )
+ {
+ QString menuPath = smenus.join( "/" );
+ QStringList allKeys = helpData.keys();
+ QStringList total = allKeys.filter( QRegExp( QString( "^%1" ).arg( menuPath ) ) );
+ if ( total.count() == 1 && smenus.count() > 0 )
+ helpItemPath = smenus.takeLast();
+ }
+ QPixmap helpIcon = fileIt.value().startsWith( "http", Qt::CaseInsensitive ) ?
+ resourceMgr()->loadPixmap( "STD", tr( "ICON_WWW" ), false ) :
+ resourceMgr()->loadPixmap( "STD", tr( "ICON_HELP" ), false );
+ QAction* a = createAction( -1, helpItemPath, helpIcon, helpItemPath, helpItemPath,
+ 0, desktop(), false, this, SLOT( onHelpContentsModule() ) );
+ a->setData( fileIt.value() );
+ if ( !helpSubMenu.isEmpty() )
+ smenus.prepend( helpSubMenu );
+ // create sub-menus hierarchy
+ int menuId = helpMenu;
+ foreach ( QString subMenu, smenus )
+ menuId = createMenu( subMenu, menuId, -1, 5 );
+ createMenu( a, menuId, -1, ( menuId != helpMenu && ( helpItemPath == userGuide || helpItemPath == devGuide ) ) ? 0 : 5 );
+ if ( !myHelpItems.contains( modName ) )
+ myHelpItems[modName] = IdList();
+ myHelpItems[modName].append( actionId( a ) );
+ }
+}
+
+void LightApp_Application::removeHelpItems( const QString& modTitle )
+{
+ QString modName = moduleName( modTitle );
+ if ( myHelpItems.contains( modName ) )
+ {
+ foreach( int id, myHelpItems[modName] )
+ setMenuShown( id, false );
+ myHelpItems.remove( modName );
+ }
+}