X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FLightApp%2FLightApp_Application.cxx;h=e6970b23f1ab05c57bb867e79a67664ae00294f8;hb=8d54f199bd9ead3c2f0c704322975198e65264d6;hp=0ba2a8bac43428ab6b85784b799f3da49283b2c3;hpb=233152eb5cb05a1b296bdb96bbd6b3133128770f;p=modules%2Fgui.git diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 0ba2a8bac..e6970b23f 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -1,90 +1,198 @@ +// Copyright (C) 2007-2014 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + // File: LightApp_Application.cxx // Created: 6/20/2005 18:39:45 PM // Author: Natalia Donis -// Copyright (C) CEA 2005 -#include "PythonConsole_PyInterp.h" // WARNING! This include must be the first! +#ifdef WIN32 +// E.A. : On windows with python 2.6, there is a conflict +// E.A. : between pymath.h and Standard_math.h which define +// E.A. : some same symbols : acosh, asinh, ... + #include + #ifndef DISABLE_PYCONSOLE + #include + #endif +#endif + +#ifndef DISABLE_PYCONSOLE + #include "LightApp_PyInterp.h" // WARNING! This include must be the first! + #include +#endif #include "LightApp_Application.h" -#include "LightApp_WidgetContainer.h" #include "LightApp_Module.h" #include "LightApp_DataModel.h" +#include "LightApp_DataOwner.h" #include "LightApp_Study.h" #include "LightApp_Preferences.h" #include "LightApp_PreferencesDlg.h" #include "LightApp_ModuleDlg.h" #include "LightApp_AboutDlg.h" - -#include "LightApp_OBFilter.h" - -#include "LightApp_GLSelector.h" +#include "LightApp_ModuleAction.h" +// temporary commented +#include "LightApp_EventFilter.h" #include "LightApp_OBSelector.h" -#include "LightApp_OCCSelector.h" -#include "LightApp_VTKSelector.h" #include "LightApp_SelectionMgr.h" +#include "LightApp_DataObject.h" +#include "LightApp_WgViewModel.h" +#include "LightApp_FullScreenHelper.h" + + +#include +#include + +#include + +#include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include +#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include #include -#include -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include +#ifndef DISABLE_GLVIEWER + #include + #include + #include "LightApp_GLSelector.h" +#endif + +#ifndef DISABLE_PLOT2DVIEWER + #include + #include + #include + #include + #include "LightApp_Plot2dSelector.h" +#ifndef DISABLE_SALOMEOBJECT + #include +#else + #include +#endif +#endif + +#ifndef DISABLE_OCCVIEWER + #include + #include +#ifndef DISABLE_SALOMEOBJECT + #include +#else + #include +#endif + #include "LightApp_OCCSelector.h" +#endif + +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + #include + #include + #include "LightApp_VTKSelector.h" +#else + #include + #include +#endif + #include +#endif + +#ifndef DISABLE_QXGRAPHVIEWER + #include + #include + #include +#endif + +#ifndef DISABLE_GRAPHICSVIEW + #include "GraphicsView_Viewer.h" + #include "GraphicsView_ViewManager.h" + #include "LightApp_GVSelector.h" +#endif + +#define VISIBILITY_COLUMN_WIDTH 25 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define OBJECT_BROWSER_WIDTH 300 -#define OBJECT_COLUMN_WIDTH 150 +#define FIRST_HELP_ID 1000000 -#define DEFAULT_BROWSER "mozilla" +#ifndef DISABLE_SALOMEOBJECT + #include + #include +#endif -#define FIRST_HELP_ID 1000000 +#include -#include "SALOME_InteractiveObject.hxx" -#include "SALOME_ListIO.hxx" +#define ToolBarMarker 0 +#define DockWidgetMarker 1 static const char* imageEmptyIcon[] = { "20 20 1 1", -". c None", +". c None", "....................", "....................", "....................", @@ -106,69 +214,194 @@ static const char* imageEmptyIcon[] = { "....................", "...................."}; +int LightApp_Application::lastStudyId = 0; + + +// Markers used to parse array with dockable windows and toolbars state. +// For more details please see the qdockarealayout.cpp && qtoolbararealayout.cpp +// in the Qt source code. + +#define QDockWidgetMarker 0xfd // = DockWidgetStateMarker +#define QToolBarMarker 0xfc // = ToolBarStateMarkerEx + +// Format of the Byte array with the windows and toolbar state is: +// VersionMarker|version|DockWidgetStateMarker|nbDockWidgetLines|...DocWidgetData...|ToolBarStateMarkerEx|nbToolBarLines|...ToolBarData... + +//Find toolbar marker position in the array in the following way: +//since the 'toolbar marker' is not unique, find index of first occurrence of the +//'toolbar marker' in the array and check that next string is name of the toolbar + +int getToolbarMarkerIndex(QByteArray input, const QStringList& aFlags) { + int aResult = -1,tmp = 0; + int inputLen = input.length(); + QDataStream anInputData(&input, QIODevice::ReadOnly); + while(tmp < inputLen) { + tmp = input.indexOf(QToolBarMarker, tmp + 1); + if(tmp < 0 ) + break; + anInputData.device()->seek(tmp); + uchar mark; + anInputData>>mark; + int lines; + anInputData >> lines; + + if(lines == 0 && anInputData.atEnd()){ + //Case then array doesn't contain information about toolbars, + aResult = tmp; + break; + } + + int pos; + anInputData >> pos; + int cnt; + anInputData >> cnt; + QString str; + anInputData>>str; + if(aFlags.contains(str)) { + aResult = tmp; + break; + } + } + return aResult; +} + +/*! + \return last global id of study +*/ +int LightApp_Application::studyId() +{ + return LightApp_Application::lastStudyId; +} + /*!Create new instance of LightApp_Application.*/ extern "C" LIGHTAPP_EXPORT SUIT_Application* createApplication() { return new LightApp_Application(); } +/*! \var global preferences of LightApp */ LightApp_Preferences* LightApp_Application::_prefs_ = 0; -/* - Class : LightApp_Application - Description : Application containing LightApp module + +/*! + \class LightApp_Application + Application containing LightApp module */ /*!Constructor.*/ LightApp_Application::LightApp_Application() : CAM_Application( false ), -myPrefs( 0 ) + myPrefs( 0 ), + myScreenHelper(new LightApp_FullScreenHelper()) { + Q_INIT_RESOURCE( LightApp ); + STD_TabDesktop* desk = new STD_TabDesktop(); + desk->setFullScreenAllowed(false); + desk->setMinimizeAllowed(false); setDesktop( desk ); + // initialize auto save timer + myAutoSaveTimer = new QTimer( this ); + myAutoSaveTimer->setSingleShot( true ); + connect( myAutoSaveTimer, SIGNAL( timeout() ), this, SLOT( onSaveDoc() ) ); + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ); - desktop()->setIcon( aLogo ); - desktop()->setDockableMenuBar( true ); + QtxWebBrowser::setResourceManager( aResMgr ); + QtxWebBrowser::setData("browser:icon", aResMgr->loadPixmap( "LightApp", tr( "BROWSER_ICON" ) ) ); + QtxWebBrowser::setData("browser:title", tr( "BROWSER_TITLE" ) ); + QtxWebBrowser::setData("toolbar:title", tr( "BROWSER_TOOLBAR_TITLE" ) ); + QtxWebBrowser::setData("menu:file:title", tr( "BROWSER_FILEMENU" ) ); + QtxWebBrowser::setData("action:close:title", tr( "BROWSER_CLOSE" ) ); + QtxWebBrowser::setData("action:close:icon", aResMgr->loadPixmap( "LightApp", tr( "BROWSER_CLOSE_ICON" ) ) ); + QtxWebBrowser::setData("action:back:title", tr( "BROWSER_BACK" ) ); + QtxWebBrowser::setData("action:forward:title", tr( "BROWSER_FORWARD" ) ); + QtxWebBrowser::setData("action:find:title", tr( "BROWSER_FIND" ) ); + QtxWebBrowser::setData("action:findnext:title", tr( "BROWSER_FINDNEXT" ) ); + QtxWebBrowser::setData("action:findprev:title", tr( "BROWSER_FINDPREV" ) ); + + desktop()->setWindowIcon( aLogo ); + desktop()->setDockableMenuBar( false ); desktop()->setDockableStatusBar( false ); // base logo (salome itself) - desktop()->addLogo( "_app_base", aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) ); + desktop()->logoInsert( "_app_base", aResMgr->loadPixmap( "LightApp", tr( "APP_BASE_LOGO" ), false ) ); // extra logo (salome-based application) - desktop()->addLogo( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) ); + desktop()->logoInsert( "_app_extra", aResMgr->loadPixmap( "LightApp", tr( "APP_EXTRA_LOGO" ), false ) ); clearViewManagers(); mySelMgr = new LightApp_SelectionMgr( this ); - myAccel = new SUIT_Accel( desktop() ); - myAccel->setActionKey( SUIT_Accel::PanLeft, CTRL+Key_Left, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanRight, CTRL+Key_Right, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanUp, CTRL+Key_Up, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanDown, CTRL+Key_Down, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomIn, CTRL+Key_Plus, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomOut, CTRL+Key_Minus, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomFit, CTRL+Key_Asterisk, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateLeft, ALT+Key_Left, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateUp, ALT+Key_Up, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateDown, ALT+Key_Down, OCCViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanLeft, CTRL+Key_Left, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanRight, CTRL+Key_Right, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanUp, CTRL+Key_Up, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::PanDown, CTRL+Key_Down, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomIn, CTRL+Key_Plus, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomOut, CTRL+Key_Minus, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::ZoomFit, CTRL+Key_Asterisk, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateLeft, ALT+Key_Left, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateRight, ALT+Key_Right, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateUp, ALT+Key_Up, VTKViewer_Viewer::Type() ); - myAccel->setActionKey( SUIT_Accel::RotateDown, ALT+Key_Down, VTKViewer_Viewer::Type() ); + myAccel = SUIT_Accel::getAccel(); + +#ifndef DISABLE_OCCVIEWER + myAccel->setActionKey( SUIT_Accel::PanLeft, Qt::CTRL+Qt::Key_Left, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanRight, Qt::CTRL+Qt::Key_Right, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanUp, Qt::CTRL+Qt::Key_Up, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanDown, Qt::CTRL+Qt::Key_Down, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomIn, Qt::CTRL+Qt::Key_Plus, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomOut, Qt::CTRL+Qt::Key_Minus, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::CTRL+Qt::Key_Asterisk, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::Key_Space, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateLeft, Qt::ALT+Qt::Key_Left, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateUp, Qt::ALT+Qt::Key_Up, OCCViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateDown, Qt::ALT+Qt::Key_Down, OCCViewer_Viewer::Type() ); +#endif +#ifndef DISABLE_VTKVIEWER + myAccel->setActionKey( SUIT_Accel::PanLeft, Qt::CTRL+Qt::Key_Left, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanRight, Qt::CTRL+Qt::Key_Right, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanUp, Qt::CTRL+Qt::Key_Up, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanDown, Qt::CTRL+Qt::Key_Down, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomIn, Qt::CTRL+Qt::Key_Plus, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomOut, Qt::CTRL+Qt::Key_Minus, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::CTRL+Qt::Key_Asterisk, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::Key_Space, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateLeft, Qt::ALT+Qt::Key_Left, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateRight, Qt::ALT+Qt::Key_Right, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateUp, Qt::ALT+Qt::Key_Up, VTKViewer_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::RotateDown, Qt::ALT+Qt::Key_Down, VTKViewer_Viewer::Type() ); +#endif +#ifndef DISABLE_PLOT2DVIEWER + myAccel->setActionKey( SUIT_Accel::PanLeft, Qt::CTRL+Qt::Key_Left, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanRight, Qt::CTRL+Qt::Key_Right, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanUp, Qt::CTRL+Qt::Key_Up, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::PanDown, Qt::CTRL+Qt::Key_Down, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomIn, Qt::CTRL+Qt::Key_Plus, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomOut, Qt::CTRL+Qt::Key_Minus, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::CTRL+Qt::Key_Asterisk, Plot2d_Viewer::Type() ); + myAccel->setActionKey( SUIT_Accel::ZoomFit, Qt::Key_Space, Plot2d_Viewer::Type() ); +#endif connect( mySelMgr, SIGNAL( selectionChanged() ), this, SLOT( onSelection() ) ); + + // Set existing font for the python console in resources + if( !aResMgr->hasValue( "PyConsole", "font" ) ) + return; + + QFont f = aResMgr->fontValue( "PyConsole", "font" ); + QFontDatabase fdb; + QStringList famdb = fdb.families(); + + if ( famdb.contains(f.family()) || !aResMgr->hasValue( "PyConsole", "additional_families" ) ) + return; + + QStringList anAddFamilies = aResMgr->stringValue( "PyConsole", "additional_families" ).split( ";", QString::SkipEmptyParts ); + QString aFamily; + for ( QStringList::Iterator it = anAddFamilies.begin(); it != anAddFamilies.end(); ++it ) + { + aFamily = *it; + if ( famdb.contains(aFamily) ) + { + f.setFamily( aFamily ); + aResMgr->setValue( "PyConsole", "font", f ); + break; + } + } } /*!Destructor. @@ -179,40 +412,31 @@ myPrefs( 0 ) */ LightApp_Application::~LightApp_Application() { - saveWindowsGeometry(); - - if ( resourceMgr() ) - { - if ( desktop() ) - desktop()->saveGeometry( resourceMgr(), "desktop" ); - resourceMgr()->save(); - } delete mySelMgr; + delete myScreenHelper; } /*!Start application.*/ void LightApp_Application::start() { - if ( desktop() ) - desktop()->loadGeometry( resourceMgr(), "desktop" ); - CAM_Application::start(); - QAction* a = action( ViewWindowsId ); - if ( a && a->inherits( "QtxDockAction" ) ) - ((QtxDockAction*)a)->setAutoPlace( true ); - updateWindows(); updateViewManagers(); putInfo( "" ); - desktop()->statusBar()->message( "" ); + desktop()->statusBar()->showMessage( "" ); + + LightApp_EventFilter::Init(); } /*!Gets application name.*/ QString LightApp_Application::applicationName() const { - return tr( "APP_NAME" ); + static QString _app_name; + if ( _app_name.isEmpty() ) + _app_name = tr( "APP_NAME" ); + return _app_name; } /*!Gets application version.*/ @@ -229,37 +453,16 @@ QString LightApp_Application::applicationVersion() const } else { - QString path( ::getenv( "GUI_ROOT_DIR" ) ); - if ( !path.isEmpty() ) - path += QDir::separator(); - path += QString( "bin/salome/VERSION" ); - - QFile vf( path ); - if ( vf.open( IO_ReadOnly ) ) - { - QString line; - vf.readLine( line, 1024 ); - vf.close(); - - if ( !line.isEmpty() ) - { - while ( !line.isEmpty() && line.at( line.length() - 1 ) == QChar( '\n' ) ) - line.remove( line.length() - 1, 1 ); - - int idx = line.findRev( ":" ); - if ( idx != -1 ) - _app_version = line.mid( idx + 1 ).stripWhiteSpace(); - } - } + _app_version = GUI_VERSION_STR; } } - return _app_version; + return _app_version; } /*!Load module by \a name.*/ -CAM_Module* LightApp_Application::loadModule( const QString& name ) +CAM_Module* LightApp_Application::loadModule( const QString& name, const bool showMsg ) { - CAM_Module* mod = CAM_Application::loadModule( name ); + CAM_Module* mod = CAM_Application::loadModule( name, showMsg ); if ( mod ) { connect( this, SIGNAL( studyOpened() ), mod, SLOT( onModelOpened() ) ); @@ -281,15 +484,15 @@ bool LightApp_Application::activateModule( const QString& modName ) if ( actName == modName ) return true; - putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) ); + putInfo( tr( "ACTIVATING_MODULE" ).arg( modName ) ); - saveWindowsGeometry(); + saveDockWindowsState(); bool status = CAM_Application::activateModule( modName ); updateModuleActions(); - putInfo( "" ); + putInfo( "" ); if ( !status ) return false; @@ -300,80 +503,146 @@ bool LightApp_Application::activateModule( const QString& modName ) return true; } -bool LightApp_Application::useStudy(const QString& theName) -{ - createEmptyStudy(); - LightApp_Study* aStudy = dynamic_cast(activeStudy()); - bool res = false; - if (aStudy) - res = aStudy->loadDocument( theName ); - updateDesktopTitle(); - updateCommandsStatus(); - return res; -} - /*!Gets selection manager.*/ LightApp_SelectionMgr* LightApp_Application::selectionMgr() const { return mySelMgr; } +/*!Creat action "New window" for certain type of viewer:*/ +void LightApp_Application::createActionForViewer( const int id, + const int parentId, + const QString& suffix, + const int accel ) +{ + QString vtlt = tr( QString( "NEW_WINDOW_%1" ).arg( suffix ).toLatin1().constData() ); + QString tip = tr( "CREATING_NEW_WINDOW" ).arg( vtlt.remove( "&" ) ); + QAction* a = createAction( id, // menu action id + tip, // status tip + QIcon(), // icon + vtlt, // menu text + tip, // tooltip + accel, // shortcut + desktop(), // parent + false, // toggle flag + this, // receiver + SLOT( onNewWindow() ) ); // slot + createMenu( a, parentId, -1 ); +} + /*!Create actions:*/ + void LightApp_Application::createActions() { - STD_Application::createActions(); + CAM_Application::createActions(); SUIT_Desktop* desk = desktop(); SUIT_ResourceMgr* resMgr = resourceMgr(); - //! Preferences - createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIconSet(), - tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ), - CTRL+Key_P, desk, false, this, SLOT( onPreferences() ) ); + // Preferences + createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(), + tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ), + Qt::CTRL+Qt::Key_R, desk, false, this, SLOT( onPreferences() ) ); - //! Help for modules - int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 ); - int helpModuleMenu = createMenu( tr( "MEN_DESK_MODULE_HELP" ), helpMenu, -1, 0 ); - createMenu( separator(), helpMenu, -1, 1 ); + // Help menu: + + // - Help for modules + int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 ); + createMenu( separator(), helpMenu, -1, 10 ); QStringList aModuleList; modules( aModuleList, false ); + aModuleList.prepend( "GUI" ); + aModuleList.prepend( "KERNEL" ); int id = LightApp_Application::UserID + FIRST_HELP_ID; - // help for KERNEL and GUI - QCString dir; - QAction* a; - if (dir = getenv("GUI_ROOT_DIR")) { - a = createAction( id, tr( QString("Kernel & GUI Help") ), QIconSet(), - tr( QString("Kernel && GUI Help") ), - tr( QString("Kernel & GUI Help") ), - 0, desk, false, this, SLOT( onHelpContentsModule() ) ); - a->setName( QString("GUI") ); - createMenu( a, helpModuleMenu, -1 ); - id++; - } - // help for other existing modules - QStringList::Iterator it; - for ( it = aModuleList.begin(); it != aModuleList.end(); ++it ) - { - if ( (*it).isEmpty() ) + + QString aModule; + foreach( aModule, aModuleList ) { + if ( aModule.isEmpty() ) // module title (user name) continue; + IMap 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 variable + QString modDir = getenv( rootDir.toLatin1().constData() ); // module root dir + 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", "" ).arg( aModule ); + QStringList listOfParam = resMgr->parameters( docSection ); + foreach( QString paramName, listOfParam ) { + QString valueStr = resMgr->stringValue( docSection, paramName ); + if ( !valueStr.isEmpty() ) { + QFileInfo fi( valueStr ); + if ( fi.isRelative() && !modDir.isEmpty() ) + valueStr = Qtx::addSlash( modDir ) + valueStr; + if ( QFile::exists( valueStr ) ) + helpData.insert( paramName.arg( aModule ), valueStr ); + } + } + } + + 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 fileIt; + for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) { + QString helpFileName = fileIt.key(); + // remove all '//' occurances + while ( helpFileName.contains( "//" ) ) + helpFileName.replace( "//", "" ); + // obtain submenus hierarchy if given + QStringList smenus = helpFileName.split( "/" ); + helpFileName = smenus.last(); + smenus.removeLast(); + QAction* a = createAction( id, helpFileName, + resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ), + helpFileName, helpFileName, + 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, 0 ); + } + createMenu( a, menuId, -1, 0 ); + id++; + } + } + + // - Additional help items - QString modName = moduleName( *it ); - if ( modName.compare("GEOM") == 0 ) { // to be removed when documentation for other modules will be done - QAction* a = createAction( id, tr( moduleTitle(modName) + QString(" Help") ), QIconSet(), - tr( moduleTitle(modName) + QString(" Help") ), - tr( moduleTitle(modName) + QString(" Help") ), - 0, desk, false, this, SLOT( onHelpContentsModule() ) ); - a->setName( modName ); - createMenu( a, helpModuleMenu, -1 ); + createMenu( separator(), helpMenu, -1, 5 ); + + QStringList addHelpItems = resMgr->parameters( "add_help" ); + foreach ( QString addHelpItem, addHelpItems ) { + QString valueStr = resMgr->stringValue( "add_help", addHelpItem ); + if ( !valueStr.isEmpty() && QFile::exists( valueStr ) ) { + QAction* a = createAction( id, addHelpItem, + resMgr->loadPixmap( "STD", tr( "ICON_HELP" ), false ), + addHelpItem, addHelpItem, + 0, desk, false, this, SLOT( onHelpContentsModule() ) ); + a->setData( valueStr ); + createMenu( a, helpMenu, -1, 5 ); id++; } } //! MRU - QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), desk ); - connect( mru, SIGNAL( activated( QString ) ), this, SLOT( onMRUActivated( QString ) ) ); + static QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), 0 ); + connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) ); registerAction( MRUId, mru ); // default icon for neutral point ('SALOME' module) @@ -386,98 +655,120 @@ void LightApp_Application::createActions() if ( modIcon.isNull() ) modIcon = QPixmap( imageEmptyIcon ); - QToolBar* modTBar = new QtxToolBar( true, desk ); - modTBar->setLabel( tr( "INF_TOOLBAR_MODULES" ) ); - - QActionGroup* modGroup = new QActionGroup( this ); - modGroup->setExclusive( true ); - modGroup->setUsesDropDown( true ); - - a = createAction( -1, tr( "APP_NAME" ), defIcon, tr( "APP_NAME" ), - tr( "PRP_APP_MODULE" ), 0, desk, true ); - modGroup->add( a ); - myActions.insert( QString(), a ); - - QMap iconMap; - moduleIconNames( iconMap ); - - const int iconSize = 20; - - modGroup->addTo( modTBar ); - modTBar->addSeparator(); - QStringList modList; modules( modList, false ); - for ( it = modList.begin(); it != modList.end(); ++it ) + if ( modList.count() > 1 ) { - if ( (*it).isEmpty() ) - continue; + LightApp_ModuleAction* moduleAction = + new LightApp_ModuleAction( tr( "APP_NAME" ), defIcon, desk ); - QString iconName; - if ( iconMap.contains( *it ) ) - iconName = iconMap[*it]; + QMap iconMap; + moduleIconNames( iconMap ); - QString modName = moduleName( *it ); + const int iconSize = 20; - QPixmap icon = resMgr->loadPixmap( modName, iconName, false ); - if ( icon.isNull() ) - icon = modIcon; + QStringList::Iterator it; + for ( it = modList.begin(); it != modList.end(); ++it ) + { + if ( !isLibExists( *it ) ) + continue; - icon.convertFromImage( icon.convertToImage().smoothScale( iconSize, iconSize, QImage::ScaleMin ) ); + QString modName = moduleName( *it ); - QAction* a = createAction( -1, *it, icon, *it, tr( "PRP_MODULE" ).arg( *it ), 0, desk, true ); - a->addTo( modTBar ); - modGroup->add( a ); + if ( !isModuleAccessible( *it ) ) + continue; - myActions.insert( *it, a ); - } + QString iconName; + if ( iconMap.contains( *it ) ) + iconName = iconMap[*it]; - SUIT_Tools::simplifySeparators( modTBar ); + QPixmap icon = resMgr->loadPixmap( modName, iconName, false ); + if ( icon.isNull() ) + { + icon = modIcon; + INFOS ( "\n****************************************************************" << std::endl + << "* Icon for " << (*it).toLatin1().constData() + << " not found. Using the default one." << std::endl + << "****************************************************************" << std::endl ); + } - // New window - int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, 100 ); - int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 ); - createMenu( separator(), windowMenu, -1, 1 ); + icon = Qtx::scaleIcon( icon, iconSize ); - QMap accelMap; - accelMap[NewGLViewId] = ALT+Key_G; - accelMap[NewPlot2dId] = ALT+Key_P; - accelMap[NewOCCViewId] = ALT+Key_O; - accelMap[NewVTKViewId] = ALT+Key_K; + moduleAction->insertModule( *it, icon ); + } - for ( id = NewGLViewId; id <= NewVTKViewId; id++ ) - { - QAction* a = createAction( id, tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), QIconSet(), - tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), - tr( QString( "NEW_WINDOW_%1" ).arg( id - NewGLViewId ) ), - accelMap.contains( id ) ? accelMap[id] : 0, desk, false, this, SLOT( onNewWindow() ) ); - createMenu( a, newWinMenu, -1 ); + connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ), + this, SLOT( onModuleActivation( const QString& ) ) ); + registerAction( ModulesListId, moduleAction ); } - connect( modGroup, SIGNAL( selected( QAction* ) ), this, SLOT( onModuleActivation( QAction* ) ) ); + // New window + int windowMenu = createMenu( tr( "MEN_DESK_WINDOW" ), -1, MenuWindowId, 100 ); + int newWinMenu = createMenu( tr( "MEN_DESK_NEWWINDOW" ), windowMenu, -1, 0 ); + + createAction( CloseId, tr( "TOT_CLOSE" ), QIcon(), tr( "MEN_DESK_CLOSE" ), tr( "PRP_CLOSE" ), + Qt::CTRL+Qt::Key_F4, desk, false, this, SLOT( onCloseWindow() ) ); + createAction( CloseAllId, tr( "TOT_CLOSE_ALL" ), QIcon(), tr( "MEN_DESK_CLOSE_ALL" ), tr( "PRP_CLOSE_ALL" ), + 0, desk, false, this, SLOT( onCloseAllWindow() ) ); + createAction( GroupAllId, tr( "TOT_GROUP_ALL" ), QIcon(), tr( "MEN_DESK_GROUP_ALL" ), tr( "PRP_GROUP_ALL" ), + 0, desk, false, this, SLOT( onGroupAllWindow() ) ); + + createMenu( CloseId, windowMenu, 0, -1 ); + createMenu( CloseAllId, windowMenu, 0, -1 ); + createMenu( GroupAllId, windowMenu, 0, -1 ); + createMenu( separator(), windowMenu, -1, 0 ); + +#ifndef DISABLE_GLVIEWER + createActionForViewer( NewGLViewId, newWinMenu, QString::number( 0 ), Qt::ALT+Qt::Key_G ); +#endif +#ifndef DISABLE_PLOT2DVIEWER + createActionForViewer( NewPlot2dId, newWinMenu, QString::number( 1 ), Qt::ALT+Qt::Key_P ); +#endif +#ifndef DISABLE_OCCVIEWER + createActionForViewer( NewOCCViewId, newWinMenu, QString::number( 2 ), Qt::ALT+Qt::Key_O ); +#endif +#ifndef DISABLE_VTKVIEWER + createActionForViewer( NewVTKViewId, newWinMenu, QString::number( 3 ), Qt::ALT+Qt::Key_K ); +#endif +#ifndef DISABLE_QXGRAPHVIEWER + createActionForViewer( NewQxSceneViewId, newWinMenu, QString::number( 4 ), Qt::ALT+Qt::Key_S ); +#endif +#ifndef DISABLE_GRAPHICSVIEW + createActionForViewer( NewGraphicsViewId, newWinMenu, QString::number( 5 ), Qt::ALT+Qt::Key_R ); +#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( RenameId, windowMenu, -1 ); int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 ); - createMenu( PreferencesId, fileMenu, 15, -1 ); - createMenu( separator(), fileMenu, -1, 15, -1 ); + createMenu( PreferencesId, fileMenu, 50, -1 ); + createMenu( separator(), fileMenu, -1, 50, -1 ); - /* createMenu( separator(), fileMenu, -1, 100, -1 ); createMenu( MRUId, fileMenu, 100, -1 ); createMenu( separator(), fileMenu, -1, 100, -1 ); - */ + + createAction( StyleId, tr( "TOT_THEME" ), QIcon(), tr( "MEN_DESK_THEME" ), tr( "PRP_THEME" ), + 0, desk, false, this, SLOT( onStylePreferences() ) ); + + createAction( FullScreenId, tr( "TOT_FULLSCREEN" ), QIcon(), tr( "MEN_DESK_FULLSCREEN" ), tr( "PRP_FULLSCREEN" ), + Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) ); + + + int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1 ); + createMenu( separator(), viewMenu, -1, 20, -1 ); + createMenu( StyleId, viewMenu, 20, -1 ); + createMenu( FullScreenId, viewMenu, 20, -1 ); + + int modTBar = createTool( tr( "INF_TOOLBAR_MODULES" ) ); + createTool( ModulesListId, modTBar ); } /*!On module activation action.*/ -void LightApp_Application::onModuleActivation( QAction* a ) +void LightApp_Application::onModuleActivation( const QString& modName ) { - if ( !a ) - return; - - QString modName = a->menuText(); - if ( modName == tr( "APP_NAME" ) ) - modName = QString::null; - // Force user to create/open a study before module activation QMap iconMap; moduleIconNames( iconMap ); @@ -486,24 +777,26 @@ void LightApp_Application::onModuleActivation( QAction* a ) icon = resourceMgr()->loadPixmap( "LightApp", tr( "APP_MODULE_BIG_ICO" ), false ); // default icon for any module bool cancelled = false; + while ( !modName.isEmpty() && !activeStudy() && !cancelled ){ LightApp_ModuleDlg aDlg( desktop(), modName, icon ); - int res = aDlg.exec(); + QMap opmap = activateModuleActions(); + for ( QMap::ConstIterator it = opmap.begin(); it != opmap.end(); ++it ) + aDlg.addButton( it.value(), it.key() ); - switch ( res ){ - case 1: - onNewDoc(); - break; - case 2: - onOpenDoc(); - break; - case 3: - //onLoadStudy(); - //break; - case 0: - default: + int res = aDlg.exec(); + if ( res ) { + // some operation is selected + moduleActionSelected( res ); + } + else { + // cancelled putInfo( tr("INF_CANCELLED") ); - myActions[QString()]->setOn( true ); + + LightApp_ModuleAction* moduleAction = + qobject_cast( action( ModulesListId ) ); + if ( moduleAction ) + moduleAction->setActiveModule( QString() ); cancelled = true; } } @@ -533,51 +826,61 @@ void LightApp_Application::onNewWindow() int id = actionId( (QAction*)obj ); switch ( id ) { +#ifndef DISABLE_GLVIEWER case NewGLViewId: type = GLViewer_Viewer::Type(); break; +#endif +#ifndef DISABLE_PLOT2DVIEWER case NewPlot2dId: type = Plot2d_Viewer::Type(); break; +#endif +#ifndef DISABLE_OCCVIEWER case NewOCCViewId: type = OCCViewer_Viewer::Type(); break; +#endif +#ifndef DISABLE_VTKVIEWER case NewVTKViewId: type = VTKViewer_Viewer::Type(); break; +#endif +#ifndef DISABLE_QXGRAPHVIEWER + case NewQxSceneViewId: + type = QxScene_Viewer::Type(); + break; +#endif +#ifndef DISABLE_GRAPHICSVIEW + case NewGraphicsViewId: + type = GraphicsView_Viewer::Type(); + break; +#endif } if ( !type.isEmpty() ) createViewManager( type ); } -//======================================================================= -// name : onNewDoc -/*! Purpose : SLOT. Create new document*/ -//======================================================================= +/*! + SLOT: Creates new document +*/ void LightApp_Application::onNewDoc() { - SUIT_Study* study = activeStudy(); - - saveWindowsGeometry(); + //asl: fix for 0020515 + if ( activeStudy() ) + saveDockWindowsState(); CAM_Application::onNewDoc(); - - if ( !study ) // new study will be create in THIS application - { - updateWindows(); - updateViewManagers(); - } } -//======================================================================= -// name : onOpenDoc -/*! Purpose : SLOT. Open new document*/ -//======================================================================= +/*! + SLOT: Opens new document +*/ void LightApp_Application::onOpenDoc() { SUIT_Study* study = activeStudy(); - saveWindowsGeometry(); + saveDockWindowsState(); CAM_Application::onOpenDoc(); @@ -588,66 +891,19 @@ void LightApp_Application::onOpenDoc() } } -#include "SUIT_MessageBox.h" -/*! Purpose : SLOT. Open new document with \a aName.*/ +/*! + SLOT: Opens new document. + \param aName - name of file +*/ bool LightApp_Application::onOpenDoc( const QString& aName ) { - bool isAlreadyOpen = false; - - // Look among opened studies - if (activeStudy()) { // at least one study is opened - SUIT_Session* aSession = SUIT_Session::session(); - QPtrList aAppList = aSession->applications(); - QPtrListIterator it (aAppList); - SUIT_Application* aApp = 0; - // iterate on all applications - for (; (aApp = it.current()) && !isAlreadyOpen; ++it) { - if (aApp->activeStudy()->studyName() == aName) { - isAlreadyOpen = true; // Already opened, ask user what to do - - // The document ... is already open. - // Do you want to reload it? - int aAnswer = SUIT_MessageBox::warn2(desktop(), tr("WRN_WARNING"), - tr("QUE_DOC_ALREADYOPEN").arg(aName), - tr("BUT_YES"), tr("BUT_NO"), 1, 2, 2); - if (aAnswer == 1) { // reload - if (activeStudy()->studyName() == aName && aAppList.count() > 1) { - // Opened in THIS (active) application. - STD_Application* app1 = (STD_Application*)aAppList.at(0); - STD_Application* app2 = (STD_Application*)aAppList.at(1); - if (!app1 || !app2) { - // Error - return false; - } - if (app1->activeStudy()->studyName() == aName) { - // app1 is this application, we need another one - app1 = app2; - } - // Close document of this application. This application will be destroyed. - onCloseDoc(/*ask = */false); - // Open the file with another application, as this one will be destroyed. - return app1->onOpenDoc(aName); - } else { - // Opened in another application. - STD_Application* app = (STD_Application*)aApp; - if (app) - app->onCloseDoc(/*ask = */false); - } - } else { // do not reload - // OK, the study will not be reloaded, but we call - // CAM_Application::onOpenDoc( aName ) all the same. - // It will activate a desktop of the study . - } - } - } - } + // We should take mru action first because this application instance can be deleted later. + QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); bool res = CAM_Application::onOpenDoc( aName ); - QAction* a = action( MRUId ); - if ( a && a->inherits( "QtxMRUAction" ) ) + if ( mru ) { - QtxMRUAction* mru = (QtxMRUAction*)a; if ( res ) mru->insert( aName ); else @@ -656,35 +912,19 @@ bool LightApp_Application::onOpenDoc( const QString& aName ) return res; } -//======================================================================= -// name : onHelpAbout -/*! Purpose : SLOT. Display "About" message box*/ -//======================================================================= +/*! + SLOT: Displays "About" message box +*/ void LightApp_Application::onHelpAbout() { - LightApp_AboutDlg* dlg = new LightApp_AboutDlg( applicationName(), applicationVersion(), desktop() ); - dlg->exec(); - delete dlg; -} - -/*!SLOT. Load document with \a aName.*/ -bool LightApp_Application::onLoadDoc( const QString& aName ) -{ - bool res = CAM_Application::onLoadDoc( aName ); - - /*jfa tmp:QAction* a = action( MRUId ); - if ( a && a->inherits( "QtxMRUAction" ) ) - { - QtxMRUAction* mru = (QtxMRUAction*)a; - if ( res ) - mru->insert( aName ); - else - mru->remove( aName ); - }*/ - return res; + LightApp_AboutDlg dlg( applicationName(), applicationVersion(), desktop() ); + dlg.exec(); } -/*!Private SLOT. Selection.*/ +/*! + Private SLOT: Called on selection is changed + Dispatchs active module that selection is changed +*/ void LightApp_Application::onSelection() { onSelectionChanged(); @@ -693,144 +933,253 @@ void LightApp_Application::onSelection() ((LightApp_Module*)activeModule())->selectionChanged(); } -/*!Set active study. - *\param study - SUIT_Study. - */ +/*! + Sets active study. + \param study - SUIT_Study. +*/ void LightApp_Application::setActiveStudy( SUIT_Study* study ) { CAM_Application::setActiveStudy( study ); - - activateWindows(); } -//======================================================================= -// name : updateCommandsStatus -/*! Purpose : Enable/Disable menu items and toolbar buttons. Rebuild menu*/ -//======================================================================= +/*! + Enables/Disables menu items and toolbar buttons. Rebuild menu +*/ void LightApp_Application::updateCommandsStatus() { CAM_Application::updateCommandsStatus(); - - for ( int id = NewGLViewId; id <= NewVTKViewId; id++ ) - { - QAction* a = action( id ); - if ( a ) - a->setEnabled( activeStudy() ); - } + QAction* a = 0; + +#ifndef DISABLE_GLVIEWER + a = action( NewGLViewId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + +#ifndef DISABLE_PLOT2DVIEWER + a = action( NewPlot2dId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + +#ifndef DISABLE_OCCVIEWER + a = action( NewOCCViewId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + +#ifndef DISABLE_VTKVIEWER + a = action( NewVTKViewId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + +#ifndef DISABLE_QXGRAPHVIEWER + a = action( NewQxSceneViewId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif + +#ifndef DISABLE_GRAPHICSVIEW + a = action( NewGraphicsViewId ); + if( a ) + a->setEnabled( activeStudy() ); +#endif } -// Helps to execute command -class RunBrowser: public QThread { +/*! + \class RunBrowser + Runs system command in separate thread +*/ +class RunBrowser: public QThread +{ public: - - RunBrowser(QString theApp, QString theParams, QString theHelpFile, QString theContext=NULL): - myApp(theApp), myParams(theParams), myHelpFile("file:" + theHelpFile + theContext), myStatus(0) {}; + RunBrowser( LightApp_Application* app, + const QString& theApp, + const QString& theParams, + const QString& theHelpFile, + const QString& theContext = QString() ) + : myApp( theApp ), + myParams( theParams ), + myContext( theContext ), + myStatus(0), + myLApp( app ) + { + //For the external browser always specify 'file://' protocol, + //because some WEB browsers (for example Mozilla Firefox) can't open local file without protocol. + myHelpFile = QString("file://%1").arg( QFileInfo( theHelpFile ).canonicalFilePath() ); + } virtual void run() { - QString aCommand; + if ( !myApp.isEmpty() && !myHelpFile.isEmpty()) { + QString aCommand = QString( "%1 %2 \"%3%4\"" ).arg( myApp, myParams, myHelpFile, myContext.isEmpty() ? QString("") : QString( "#%1" ).arg( myContext ) ); - if ( !myApp.isEmpty()) - { - aCommand.sprintf("%s %s %s",myApp.latin1(),myParams.latin1(),myHelpFile.latin1()); - myStatus = system(aCommand); - if(myStatus != 0) - { - QCustomEvent* ce2000 = new QCustomEvent (2000); - postEvent (qApp, ce2000); - } - } + QProcess* proc = new QProcess(); - if( myStatus != 0 || myApp.isEmpty()) - { - myParams = ""; - aCommand.sprintf("%s %s %s", QString(DEFAULT_BROWSER).latin1(),myParams.latin1(), myHelpFile.latin1()); - myStatus = system(aCommand); - if(myStatus != 0) - { - QCustomEvent* ce2001 = new QCustomEvent (2001); - postEvent (qApp, ce2001); - } + proc->start( aCommand ); + if ( !proc->waitForStarted() ) { + SALOME_CustomEvent* ce2000 = new SALOME_CustomEvent( 2000 ); + QString* msg = new QString( QObject::tr( "EXTERNAL_BROWSER_CANNOT_SHOW_PAGE" ).arg( myApp, myHelpFile ) ); + ce2000->setData( msg ); + QApplication::postEvent( myLApp, ce2000 ); } + } } private: - QString myApp; - QString myParams; - QString myHelpFile; - int myStatus; - + QString myApp; + QString myParams; + QString myHelpFile; + QString myContext; + int myStatus; + LightApp_Application* myLApp; }; -//======================================================================= -// name : onHelpContentsModule -/*! Purpose : SLOT. Display help contents for choosen module*/ -//======================================================================= +/*! + SLOT: Displays help contents for choosen module +*/ void LightApp_Application::onHelpContentsModule() { - const QAction* obj = (QAction*) sender(); + const QAction* a = (QAction*) sender(); + QString helpFile = a->data().toString(); + if ( helpFile.isEmpty() ) return; - QString aComponentName = obj->name(); - QString aFileName = aComponentName + "_index.html"; - - QCString dir; - QString root; - QString homeDir; - if (dir = getenv( aComponentName + "_ROOT_DIR")) { - root = Qtx::addSlash( Qtx::addSlash(dir) + Qtx::addSlash("doc") + Qtx::addSlash("salome") ); - if ( QFileInfo( root + aFileName ).exists() ) { - homeDir = root; - } else { - SUIT_MessageBox::warn1( desktop(), tr("WRN_WARNING"), - QString( "%1"+ aFileName + " doesn't exist." ).arg(root), tr ("BUT_OK") ); - return; - } - } - - QString helpFile = QFileInfo( homeDir + aFileName ).absFilePath(); SUIT_ResourceMgr* resMgr = resourceMgr(); - QString anApp = resMgr->stringValue("ExternalBrowser", "application"); + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + QString anApp = resMgr->stringValue("ExternalBrowser", platform); +#ifdef WIN32 + QString quote("\""); + anApp.prepend( quote ); + anApp.append( quote ); +#endif QString aParams = resMgr->stringValue("ExternalBrowser", "parameters"); + bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ); - RunBrowser* rs = new RunBrowser(anApp, aParams, helpFile); - rs->start(); -} + if( useExtBrowser ) { + if ( !anApp.isEmpty() ) { + RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile ); + rs->start(); + } + else { + if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) -/*!Sets enable or disable some actions on selection changed.*/ -void LightApp_Application::onSelectionChanged() -{ + showPreferences( tr( "PREF_APP" ) ); + } + } + else { +#ifdef WIN32 + // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol + // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol. + QtxWebBrowser::loadUrl(helpFile); +#else + QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile)); +#endif + } } -/*!Return window. - *\param flag - key for window - *\param studyId - study id - * Flag used how identificator of window in windows list. - */ -QWidget* LightApp_Application::window( const int flag, const int studyId ) const +/*! + SLOT: Displays help contents for choosen dialog +*/ +void LightApp_Application::onHelpContextModule( const QString& theComponentName, + const QString& theFileName, + const QString& theContext ) { - QWidget* wid = 0; + QString fileName = theFileName; + QString context = theContext; + if ( !QFile::exists( fileName ) && theContext.isEmpty() ) { + // context might be passed within theFileName argument + QStringList comps = fileName.split("#"); + if ( comps.count() > 1 ) { + context = comps.last(); + comps.removeLast(); + fileName = comps.join("#"); + } + } - int sId = studyId; - if ( sId < 0 ) - { - if ( !activeStudy() ) - return 0; - else - sId = activeStudy()->id(); + QString homeDir = ""; + if ( !theComponentName.isEmpty() ) { + QString dir = getenv( ( theComponentName + "_ROOT_DIR" ).toLatin1().constData() ); + if ( !dir.isEmpty() ) + homeDir = Qtx::addSlash( Qtx::addSlash( dir ) + + Qtx::addSlash( "share" ) + + Qtx::addSlash( "doc" ) + + Qtx::addSlash( "salome" ) + + Qtx::addSlash( "gui" ) + + Qtx::addSlash( theComponentName ) ); + } + + QString helpFile = QFileInfo( homeDir + fileName ).absoluteFilePath(); + SUIT_ResourceMgr* resMgr = resourceMgr(); + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + QString anApp = resMgr->stringValue("ExternalBrowser", platform); +#ifdef WIN32 + QString quote("\""); + anApp.prepend( quote ); + anApp.append( quote ); +#endif + + bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ); + + if(useExtBrowser) { + QString aParams = resMgr->stringValue("ExternalBrowser", "parameters"); + + if ( !anApp.isEmpty() ) { + RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, context ); + rs->start(); + } + else { + if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) + showPreferences( tr( "PREF_APP" ) ); + } } + else { +#ifdef WIN32 + // On Win32 platform QWebKit of the Qt 4.6.3 hang up in case 'file://' protocol + // is defined. On Linux platform QWebKit doesn't work correctly without 'file://' protocol. + QtxWebBrowser::loadUrl(helpFile, context); +#else + QtxWebBrowser::loadUrl(QString("file://%1").arg(helpFile), context); +#endif + + } +} - if ( myWindows.contains( flag ) ) - wid = myWindows[flag]->widget( sId ); +/*! + Sets enable or disable some actions on selection changed. +*/ +void LightApp_Application::onSelectionChanged() +{ + LightApp_Module* m = dynamic_cast( activeModule() ); + bool canCopy = m ? m->canCopy() : false; + bool canPaste = m ? m->canPaste() : false; - return wid; + action( EditCopyId )->setEnabled(canCopy); + action( EditPasteId )->setEnabled(canPaste); } -/*!Adds window to application. - *\param wid - QWidget - *\param flag - key wor window - *\param studyId - study id - * Flag used how identificator of window in windows list. - */ +/*! + Adds window to application. + \param wid - QWidget + \param flag - key for window + \param studyId - study id + Flag used how identificator of window in windows list. +*/ +/* void LightApp_Application::addWindow( QWidget* wid, const int flag, const int studyId ) { if ( !wid ) @@ -852,154 +1201,224 @@ void LightApp_Application::addWindow( QWidget* wid, const int flag, const int st LightApp_WidgetContainer* newWC = new LightApp_WidgetContainer( flag, desktop() ); connect( newWC, SIGNAL( destroyed ( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) ); + // asv: connecting a slot for storing visibility flag of a window + connect( newWC, SIGNAL( visibilityChanged ( bool ) ), SLOT( onVisibilityChanged( bool ) ) ); myWindows.insert( flag, newWC ); - if ( winMap.contains( flag ) ) - desktop()->moveDockWindow( myWindows[flag], (Dock)winMap[flag] ); + if ( winMap.contains( flag ) ) { + //desktop()->removeDockWidget( myWindows[flag] ); + desktop()->addDockWidget( (Qt::DockWidgetArea)winMap[flag], myWindows[flag] ); + } - myWindows[flag]->setResizeEnabled( true ); - myWindows[flag]->setCloseMode( QDockWindow::Always ); - myWindows[flag]->setName( QString( "dock_window_%1" ).arg( flag ) ); + //myWindows[flag]->setResizeEnabled( true ); + myWindows[flag]->setFeatures( QDockWidget::AllDockWidgetFeatures ); + myWindows[flag]->setObjectName( QString( "dock_window_%1" ).arg( flag ) ); + //myWindows[flag]->setFixedExtentWidth( wid->width() ); + //myWindows[flag]->setFixedExtentHeight( wid->height() ); + myWindows[flag]->resize( wid->width(), wid->height() ); } QFont f; - if( wid->inherits( "PythonConsole" ) ) - f = ( ( PythonConsole* )wid )->font(); +#ifndef DISABLE_PYCONSOLE + if( wid->inherits( "PyConsole_Console" ) ) + { + if( resourceMgr()->hasValue( "PyConsole", "font" ) ) + f = resourceMgr()->fontValue( "PyConsole", "font" ); + else + { + f = ( ( PyConsole_Console* )wid )->font(); + resourceMgr()->setValue( "PyConsole", "font", f ); + } + } else +#endif f = wid->font(); myWindows[flag]->insert( sId, wid ); - wid->setFont(f); + wid->setFont( f ); setWindowShown( flag, !myWindows[flag]->isEmpty() ); } +*/ -/*!Remove window from application. - *\param flag - key wor window - *\param studyId - study id - * Flag used how identificator of window in windows list. - */ -void LightApp_Application::removeWindow( const int flag, const int studyId ) +QWidget* LightApp_Application::dockWindow( const int id ) const { - if ( !myWindows.contains( flag ) ) - return; + QWidget* wid = 0; + if ( myWin.contains( id ) ) + wid = myWin[id]; + return wid; +} - int sId = studyId; - if ( sId < 0 ) +QDockWidget* LightApp_Application::windowDock( QWidget* wid ) const +{ + if ( !wid ) + return 0; + + QDockWidget* dock = 0; + QWidget* w = wid->parentWidget(); + while ( w && !dock ) { - if ( !activeStudy() ) - return; - else - sId = activeStudy()->id(); + dock = ::qobject_cast( w ); + w = w->parentWidget(); } + return dock; +} + +void LightApp_Application::insertDockWindow( const int id, QWidget* wid ) +{ + if ( !wid ) + return; - QWidget* wid = myWindows[flag]->widget( sId ); - myWindows[flag]->remove( sId ); - delete wid; + if ( wid != dockWindow( id ) ) + removeDockWindow( id ); - setWindowShown( flag, !myWindows[flag]->isEmpty() ); + myWin.insert( id, wid ); + + QtxDockWidget* dock = new QtxDockWidget( true, desktop() ); + connect( dock, SIGNAL( destroyed( QObject* ) ), this, SLOT( onWCDestroyed( QObject* ) ) ); + + dock->setFeatures( QDockWidget::AllDockWidgetFeatures ); + dock->setObjectName( QString( "window_%1" ).arg( id ) ); + dock->setWidget( wid ); + + QKeySequence accel = wid->property( "shortcut" ).value(); + if ( !accel.isEmpty() ) + dock->toggleViewAction()->setShortcut( accel ); + + dock->show(); } -/*!Gets window. - *\param flag - key wor window - *\param studyId - study id - * Flag used how identificator of window in windows list. - */ -QWidget* LightApp_Application::getWindow( const int flag, const int studyId ) +void LightApp_Application::removeDockWindow( const int id ) { - QWidget* wid = window( flag, studyId ); + QWidget* wid = dockWindow( id ); if ( !wid ) - addWindow( wid = createWindow( flag ), flag, studyId ); + return; - return wid; + myWin.remove( id ); + + QDockWidget* dock = windowDock( wid ); + if ( !dock ) + return; + + dock->setWidget( 0 ); + wid->setParent( 0 ); + wid->setVisible( false ); + delete dock; } -/*!Check is window visible?(with identificator \a type)*/ -bool LightApp_Application::isWindowVisible( const int type ) const +void LightApp_Application::placeDockWindow( const int id, Qt::DockWidgetArea place ) { - bool res = false; - if ( myWindows.contains( type ) ) - { - SUIT_Desktop* desk = ((LightApp_Application*)this)->desktop(); - res = desk && desk->appropriate( myWindows[type] ); + QDockWidget* dock = windowDock( dockWindow( id ) ); + if ( dock && desktop() ) { + desktop()->addDockWidget( place, dock ); + QtxDockAction* a = qobject_cast( action( ViewWindowsId ) ); + if ( a ) a->update(); } - return res; } -/*!Sets window show or hide. - *\param type - window identificator. - *\param on - true/false (window show/hide) - */ -void LightApp_Application::setWindowShown( const int type, const bool on ) +/*! + Gets window. + \param flag - key for window + \param studyId - study id + Flag used how identificator of window in windows list. +*/ +QWidget* LightApp_Application::getWindow( const int flag, const int ) { - if ( !desktop() || !myWindows.contains( type ) ) - return; + QWidget* wid = dockWindow( flag ); + if ( !wid ) + insertDockWindow( flag, wid = createWindow( flag ) ); + + QMap winMap; + currentWindows( winMap ); + if ( winMap.contains( flag ) ) + placeDockWindow( flag, (Qt::DockWidgetArea)winMap[flag] ); - QDockWindow* dw = myWindows[type]; - desktop()->setAppropriate( dw, on ); - on ? dw->show() : dw->hide(); + return wid; } -/*!Gets "ObjectBrowser".*/ -OB_Browser* LightApp_Application::objectBrowser() +/*! + \return Object Browser +*/ +SUIT_DataBrowser* LightApp_Application::objectBrowser() { - OB_Browser* ob = 0; - QWidget* wid = getWindow( WT_ObjectBrowser ); - if ( wid->inherits( "OB_Browser" ) ) - ob = (OB_Browser*)wid; - return ob; + return qobject_cast( dockWindow( WT_ObjectBrowser ) ); } -/*!Gets "LogWindow".*/ +/*! + \return Log Window +*/ LogWindow* LightApp_Application::logWindow() { - LogWindow* lw = 0; - QWidget* wid = getWindow( WT_LogWindow ); - if ( wid->inherits( "LogWindow" ) ) - lw = (LogWindow*)wid; - return lw; + return qobject_cast( dockWindow( WT_LogWindow ) ); } -/*!Get "PythonConsole"*/ -PythonConsole* LightApp_Application::pythonConsole() +#ifndef DISABLE_PYCONSOLE +/*! + This returns the python console integrated to the GUI. Depending + 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. + \param force - if true, the pythonConsole is created if it does not exist yet + \return Python Console +*/ +PyConsole_Console* LightApp_Application::pythonConsole(const bool force) { - PythonConsole* console = 0; - QWidget* wid = getWindow( WT_PyConsole ); - if ( wid->inherits( "PythonConsole" ) ) - console = (PythonConsole*)wid; - return console; + QWidget* wid = dockWindow( WT_PyConsole ); + if ( !wid && force==true) { + wid = getWindow(WT_PyConsole); + } + return qobject_cast( wid ); } +#endif -/*!Update obect browser*/ +/*! + Updates object browser and maybe data models + \param updateModels - if it is true, then data models are updated +*/ void LightApp_Application::updateObjectBrowser( const bool updateModels ) { // update existing data models - if ( updateModels ) + if ( updateModels ) { + const bool isAutoUpdate = objectBrowser() ? objectBrowser()->autoUpdate() : true; + if ( objectBrowser() ) + objectBrowser()->setAutoUpdate( false ); + LightApp_Study* study = dynamic_cast(activeStudy()); if ( study ) { CAM_Study::ModelList dm_list; study->dataModels( dm_list ); - for ( CAM_Study::ModelListIterator it( dm_list ); it.current(); ++it ) { - CAM_DataModel* camDM = it.current(); + QListIterator it( dm_list ); + while ( it.hasNext() ) { + CAM_DataModel* camDM = it.next(); if ( camDM && camDM->inherits( "LightApp_DataModel" ) ) ((LightApp_DataModel*)camDM)->update(); } } + + if( objectBrowser() ) + objectBrowser()->setAutoUpdate( isAutoUpdate ); } - if ( objectBrowser() ) - { + + if ( objectBrowser() ) { objectBrowser()->updateGeometry(); - objectBrowser()->updateTree(); + objectBrowser()->updateTree( 0, false ); } } -/*!Gets preferences.*/ +/*! + \return preferences +*/ LightApp_Preferences* LightApp_Application::preferences() const { return preferences( false ); } -/*!Gets view manager*/ +/*! + \return first view manager of some type + \param vmType - type of view manager + \param create - is it necessary to create view manager in case, when there is no manager of such type +*/ SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, const bool create ) { SUIT_ViewManager* aVM = viewManager( vmType ); @@ -1021,22 +1440,35 @@ SUIT_ViewManager* LightApp_Application::getViewManager( const QString& vmType, c return aVM; } -/*!Create view manager.*/ +/*! + Creates view manager of some type + \param vmType - type of view manager +*/ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType ) { SUIT_ResourceMgr* resMgr = resourceMgr(); SUIT_ViewManager* viewMgr = 0; +#ifndef DISABLE_GLVIEWER if( vmType == GLViewer_Viewer::Type() ) { viewMgr = new GLViewer_ViewManager( activeStudy(), desktop() ); new LightApp_GLSelector( (GLViewer_Viewer2d*)viewMgr->getViewModel(), mySelMgr ); } - else if( vmType == Plot2d_Viewer::Type() ) +#endif +#ifndef DISABLE_PLOT2DVIEWER + if( vmType == Plot2d_Viewer::Type() ) { viewMgr = new Plot2d_ViewManager( activeStudy(), desktop() ); - SPlot2d_Viewer* vm = new SPlot2d_Viewer(); - viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface + Plot2d_Viewer* vm; +#ifndef DISABLE_SALOMEOBJECT + SPlot2d_Viewer* v = new SPlot2d_Viewer(); + vm = v; + new LightApp_Plot2dSelector( v, mySelMgr ); +#else + vm = new Plot2d_Viewer(); +#endif + viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface Plot2d_ViewWindow* wnd = dynamic_cast( viewMgr->getActiveView() ); if( wnd ) { @@ -1044,39 +1476,89 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType frame->setBackgroundColor( resMgr->colorValue( "Plot2d", "Background", frame->backgroundColor() ) ); } } - else if( vmType == SUPERVGraph_Viewer::Type() ) +#endif +#ifndef DISABLE_QXGRAPHVIEWER + if( vmType == QxScene_Viewer::Type() ) + { + viewMgr = new QxScene_ViewManager( activeStudy(), desktop() ); + QxScene_Viewer* vm = new QxScene_Viewer(); + viewMgr->setViewModel( vm ); + //QxScene_ViewWindow* wnd = dynamic_cast( viewMgr->getActiveView() ); + } +#endif +#ifndef DISABLE_GRAPHICSVIEW + if( vmType == GraphicsView_Viewer::Type() ) { - viewMgr = new SUPERVGraph_ViewManager( activeStudy(), desktop() ); - SUPERVGraph_Viewer* vm = new SUPERVGraph_Viewer(); - SUPERVGraph_ViewFrame* view = dynamic_cast( vm->getViewManager()->getActiveView() ); - if( view ) - view->setBackgroundColor( resMgr->colorValue( "SUPERVGraph", "Background", view->backgroundColor() ) ); + viewMgr = new GraphicsView_ViewManager( activeStudy(), desktop() ); + new LightApp_GVSelector( (GraphicsView_Viewer*)viewMgr->getViewModel(), mySelMgr ); } - else if( vmType == OCCViewer_Viewer::Type() ) +#endif +#ifndef DISABLE_OCCVIEWER + if( vmType == OCCViewer_Viewer::Type() ) { viewMgr = new OCCViewer_ViewManager( activeStudy(), desktop() ); - SOCC_Viewer* vm = new SOCC_Viewer(); - vm->setBackgroundColor( resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) ); - vm->setTrihedronSize( resMgr->integerValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ) ); - int u( 1 ), v( 1 ); - vm->isos( u, v ); - u = resMgr->integerValue( "OCCViewer", "iso_number_u", u ); - v = resMgr->integerValue( "OCCViewer", "iso_number_v", v ); - vm->setIsos( u, v ); + OCCViewer_Viewer* vm; +#ifndef DISABLE_SALOMEOBJECT + vm = new SOCC_Viewer(); +#else + vm = new OCCViewer_Viewer( true ); +#endif + vm->setBackground( OCCViewer_ViewFrame::TOP_LEFT, + resMgr->backgroundValue( "OCCViewer", "xz_background", vm->background(OCCViewer_ViewFrame::TOP_LEFT) ) ); + vm->setBackground( OCCViewer_ViewFrame::TOP_RIGHT, + resMgr->backgroundValue( "OCCViewer", "yz_background", vm->background(OCCViewer_ViewFrame::TOP_RIGHT) ) ); + vm->setBackground( OCCViewer_ViewFrame::BOTTOM_LEFT, + resMgr->backgroundValue( "OCCViewer", "xy_background", vm->background(OCCViewer_ViewFrame::BOTTOM_LEFT) ) ); + vm->setBackground( OCCViewer_ViewFrame::BOTTOM_RIGHT, + resMgr->backgroundValue( "OCCViewer", "background", vm->background(OCCViewer_ViewFrame::MAIN_VIEW) ) ); + + vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() )); + vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) ); + vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) ); + vm->enablePreselection( resMgr->booleanValue( "OCCViewer", "enable_preselection", vm->isPreselectionEnabled() ) ); + vm->enableSelection( resMgr->booleanValue( "OCCViewer", "enable_selection", vm->isSelectionEnabled() ) ); + viewMgr->setViewModel( vm );// custom view model, which extends SALOME_View interface new LightApp_OCCSelector( (OCCViewer_Viewer*)viewMgr->getViewModel(), mySelMgr ); } - else if ( vmType == SVTK_Viewer::Type() ) +#endif +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + if ( vmType == SVTK_Viewer::Type() ) +#else + if ( vmType == VTKViewer_Viewer::Type() ) +#endif { +#ifndef DISABLE_SALOMEOBJECT viewMgr = new SVTK_ViewManager( activeStudy(), desktop() ); SVTK_Viewer* vm = dynamic_cast( viewMgr->getViewModel() ); if( vm ) { - vm->setBackgroundColor( resMgr->colorValue( "VTKViewer", "background", vm->backgroundColor() ) ); - vm->setTrihedronSize( resMgr->integerValue( "VTKViewer", "trihedron_size", vm->trihedronSize() ) ); + vm->setProjectionMode( resMgr->integerValue( "VTKViewer", "projection_mode", vm->projectionMode() ) ); + vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) ); + vm->setTrihedronSize( resMgr->doubleValue( "3DViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() ) ); + vm->setStaticTrihedronVisible( resMgr->booleanValue( "3DViewer", "show_static_trihedron", vm->isStaticTrihedronVisible() ) ); + vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) ); + vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) ); + vm->setPreSelectionMode(resMgr->integerValue( "VTKViewer", "preselection", vm->preSelectionMode() ) ); + vm->enableSelection( resMgr->booleanValue( "VTKViewer", "enable_selection", vm->isSelectionEnabled() ) ); + vm->setIncrementalSpeed( resMgr->integerValue( "VTKViewer", "speed_value", vm->incrementalSpeed() ), + resMgr->integerValue( "VTKViewer", "speed_mode", vm->incrementalSpeedMode() ) ); + vm->setSpacemouseButtons( resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", vm->spacemouseBtn(1) ), + resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", vm->spacemouseBtn(2) ), + resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", vm->spacemouseBtn(3) ) ); new LightApp_VTKSelector( vm, mySelMgr ); } +#else + viewMgr = new VTKViewer_ViewManager( activeStudy(), desktop() ); + VTKViewer_Viewer* vm = dynamic_cast( viewMgr->getViewModel() ); + if ( vm ) + vm->setBackground( resMgr->backgroundValue( "VTKViewer", "background", vm->background() ) ); +#endif } +#endif if ( !viewMgr ) return 0; @@ -1084,25 +1566,48 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType addViewManager( viewMgr ); SUIT_ViewWindow* viewWin = viewMgr->createViewWindow(); - if ( viewWin && desktop() ) + if ( viewWin && desktop() ) { viewWin->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) ); - - connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ), - this, SLOT( onCloseView( SUIT_ViewManager* ) ) ); + viewWin->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) ); + } return viewMgr; } -//======================================================================= -// name : onCloseView -/*! Purpose : SLOT. Remove view manager from application*/ -//======================================================================= +SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, QWidget* w ) +{ + SUIT_ResourceMgr* resMgr = resourceMgr(); + + SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), + desktop(), + new LightApp_WgViewModel( vmType, w ) ); + vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) ); + + addViewManager( vm ); + SUIT_ViewWindow* vw = vm->createViewWindow(); + if ( vw && desktop() ) { + vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) ); + vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) ); + } + + if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) ) + myUserWmTypes << vmType; + + return vm; +} + +/*! + SLOT: Removes view manager from application +*/ void LightApp_Application::onCloseView( SUIT_ViewManager* theVM ) { removeViewManager( theVM ); } -/*!Protected SLOT. On study created.*/ +/*! + Protected SLOT: On study created. + \param theStudy - just created study +*/ void LightApp_Application::onStudyCreated( SUIT_Study* theStudy ) { SUIT_DataObject* aRoot = 0; @@ -1111,15 +1616,24 @@ void LightApp_Application::onStudyCreated( SUIT_Study* theStudy ) aRoot = theStudy->root(); //aRoot->setName( tr( "DATA_MODELS" ) ); } - if ( objectBrowser() != 0 ) - objectBrowser()->setRootObject( aRoot ); + + getWindow( WT_ObjectBrowser ); + + loadDockWindowsState(); + + if ( objectBrowser() ) + objectBrowser()->setRoot( aRoot ); activateModule( defaultModule() ); - activateWindows(); + if ( objectBrowser() ) + objectBrowser()->openLevels(); } -/*!Protected SLOT. On study opened.*/ +/*! + Protected SLOT: On study opened. + \param theStudy - just opened study +*/ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy ) { SUIT_DataObject* aRoot = 0; @@ -1128,36 +1642,45 @@ void LightApp_Application::onStudyOpened( SUIT_Study* theStudy ) aRoot = theStudy->root(); //aRoot->dump(); } - if ( objectBrowser() != 0 ) { - objectBrowser()->setRootObject( aRoot ); - } + + getWindow( WT_ObjectBrowser ); + + loadDockWindowsState(); + + if ( objectBrowser() ) + objectBrowser()->setRoot( aRoot ); activateModule( defaultModule() ); - activateWindows(); + if ( objectBrowser() ) + objectBrowser()->openLevels(); emit studyOpened(); } /*!Protected SLOT. On study saved.*/ -void LightApp_Application::onStudySaved( SUIT_Study* ) +void LightApp_Application::onStudySaved( SUIT_Study* s ) { + QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); + if ( mru && s ) + mru->insert( s->studyName() ); + emit studySaved(); } /*!Protected SLOT. On study closed.*/ -void LightApp_Application::onStudyClosed( SUIT_Study* ) +void LightApp_Application::onStudyClosed( SUIT_Study* s ) { - emit studyClosed(); + // stop auto-save timer + myAutoSaveTimer->stop(); - activateModule( "" ); - - // Bug 10396: remove all selectors - //delete mySelMgr; - //mySelMgr = new LightApp_SelectionMgr( this ); + // Bug 10396: clear selection mySelMgr->clearSelected(); - saveWindowsGeometry(); + // Bug 12944: emit signal only after clear selection + emit studyClosed(); + + activateModule( "" ); } /*!Protected SLOT.On desktop activated.*/ @@ -1169,21 +1692,51 @@ void LightApp_Application::onDesktopActivated() aModule->studyActivated(); } +void LightApp_Application::studyOpened( SUIT_Study* s ) +{ + CAM_Application::studyOpened( s ); + + updateWindows(); + updateViewManagers(); +} + +void LightApp_Application::studySaved( SUIT_Study* s ) +{ + CAM_Application::studyOpened( s ); + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + if ( aResMgr && activeStudy() ) { + int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 ); + if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 ); + } +} + +void LightApp_Application::studyCreated( SUIT_Study* s ) +{ + CAM_Application::studyCreated( s ); + + updateWindows(); + updateViewManagers(); +} + /*!Gets file filter. *\retval QString "(*.bin)" */ QString LightApp_Application::getFileFilter() const { - return "(*.bin)"; + //return "(*.bin)"; + // HDF persistence + return "(*.hdf)"; } -/*! Gets file name*/ -QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters, +/*! + Shows file dialog and return user selected file name +*/ +QString LightApp_Application::getFileName( bool open, const QString& initial, const QString& filters, const QString& caption, QWidget* parent ) { if ( !parent ) parent = desktop(); - QStringList fls = QStringList::split( ";;", filters, false ); + QStringList fls = filters.split( ";;", QString::SkipEmptyParts ); return SUIT_FileDlg::getFileName( parent, initial, fls, caption, open, true ); } @@ -1196,12 +1749,12 @@ QString LightApp_Application::getDirectory( const QString& initial, const QStrin } /*! Get open file names*/ -QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters, +QStringList LightApp_Application::getOpenFileNames( const QString& initial, const QString& filters, const QString& caption, QWidget* parent ) { if ( !parent ) parent = desktop(); - QStringList fls = QStringList::split( ";;", filters, false ); + QStringList fls = filters.split( ";;", QString::SkipEmptyParts ); return SUIT_FileDlg::getOpenFileNames( parent, initial, fls, caption, true ); } @@ -1211,10 +1764,28 @@ void LightApp_Application::onRefresh() updateObjectBrowser( true ); } +/*!Private SLOT. Support drag-and-drop operation.*/ +void LightApp_Application::onDropped( const QList& objects, SUIT_DataObject* parent, int row, Qt::DropAction action ) +{ + LightApp_DataObject* parentObj = dynamic_cast( parent ); + if ( !parentObj ) + return; + + LightApp_Module* aModule = dynamic_cast( parentObj->module() ); + if ( aModule ) + aModule->dropObjects( objects, parentObj, row, action ); +} + /*!Private SLOT. On preferences.*/ void LightApp_Application::onPreferences() { - QApplication::setOverrideCursor( Qt::waitCursor ); + showPreferences( activeModule() ? activeModule()->moduleName() : tr( "PREF_CATEGORY_SALOME" ) ); +} + +/*!Private SLOT. On preferences.*/ +void LightApp_Application::showPreferences( const QString& itemText ) +{ + QApplication::setOverrideCursor( Qt::WaitCursor ); LightApp_PreferencesDlg* prefDlg = new LightApp_PreferencesDlg( preferences( true ), desktop()); @@ -1223,7 +1794,17 @@ void LightApp_Application::onPreferences() if ( !prefDlg ) return; - prefDlg->exec(); + preferences()->activateItem( itemText ); + + if ( ( prefDlg->exec() == QDialog::Accepted || prefDlg->isSaved() ) && resourceMgr() ) + { + if ( desktop() ) + resourceMgr()->setValue( "desktop", "geometry", desktop()->storeGeometry() ); + resourceMgr()->save(); + + // Update shortcuts + shortcutMgr()->updateShortcuts(); + } delete prefDlg; } @@ -1240,21 +1821,17 @@ void LightApp_Application::onPreferenceChanged( QString& modName, QString& secti sMod->preferencesChanged( section, param ); else preferencesChanged( section, param ); -} - -/*!Private SLOT. On open document with name \a aName.*/ -void LightApp_Application::onMRUActivated( QString aName ) -{ - onOpenDoc( aName ); + // emit signal to allow additional preferences changing processing + emit preferenceChanged( modName, section, param ); } /*!Remove all windows from study.*/ void LightApp_Application::beforeCloseDoc( SUIT_Study* s ) { - CAM_Application::beforeCloseDoc( s ); + if ( SUIT_DataBrowser* ob = objectBrowser() ) + ob->setModel(0); - for ( WindowMap::ConstIterator itr = myWindows.begin(); s && itr != myWindows.end(); ++itr ) - removeWindow( itr.key(), s->id() ); + CAM_Application::beforeCloseDoc( s ); } /*!Update actions.*/ @@ -1263,12 +1840,13 @@ void LightApp_Application::updateActions() updateCommandsStatus(); } -//======================================================================= -// name : createNewStudy -/*! Purpose : Create new study*/ -//======================================================================= +/*! + Creates new study +*/ SUIT_Study* LightApp_Application::createNewStudy() { + LightApp_Application::lastStudyId++; + LightApp_Study* aStudy = new LightApp_Study( this ); // Set up processing of major study-related events @@ -1280,65 +1858,105 @@ SUIT_Study* LightApp_Application::createNewStudy() return aStudy; } -/*!Create window.*/ +/*! + Creates window by flag. + \param flag - identificator of window type +*/ QWidget* LightApp_Application::createWindow( const int flag ) { QWidget* wid = 0; + + SUIT_ResourceMgr* resMgr = resourceMgr(); + if ( flag == WT_ObjectBrowser ) { - OB_Browser* ob = new OB_Browser( desktop() ); + SUIT_DataBrowser* ob = new SUIT_DataBrowser( new LightApp_DataObject(), desktop() ); + ob->setSortMenuEnabled( true ); ob->setAutoUpdate( true ); - ob->setAutoOpenLevel( 1 ); - ob->setCaption( tr( "OBJECT_BROWSER" ) ); - ob->listView()->setColumnWidth( 0, OBJECT_COLUMN_WIDTH ); - ob->resize( OBJECT_BROWSER_WIDTH, ob->height() ); - ob->setFilter( new LightApp_OBFilter( selectionMgr() ) ); + if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) ) + ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) ); + + //ob->setAutoOpenLevel( 1 ); // commented by ASV as a fix to bug IPAL10107 + ob->setWindowTitle( tr( "OBJECT_BROWSER" ) ); + connect( ob, SIGNAL( requestUpdate() ), this, SLOT( onRefresh() ) ); + + QString EntryCol = QObject::tr( "ENTRY_COLUMN" ); + SUIT_AbstractModel* treeModel = dynamic_cast( ob->model() ); + treeModel->setSearcher( this ); + treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId ); + treeModel->setAppropriate( EntryCol, Qtx::Toggled ); + + // Mantis issue 0020136: Drag&Drop in OB + SUIT_ProxyModel* proxyModel = dynamic_cast(treeModel); + if ( proxyModel ) { + connect( proxyModel, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ), + this, SLOT( onDropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ) ); + } - ob->setNameTitle( tr( "OBJ_BROWSER_NAME" ) ); + // temporary commented + /* + OB_ListView* ob_list = dynamic_cast( const_cast( ob->listView() ) ); + if( ob_list ) + ob_list->setColumnMaxWidth( 0, desktop()->width()/4 ); + */ // Create OBSelector new LightApp_OBSelector( ob, mySelMgr ); + ob->treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed); + ob->treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId); + ob->treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH); + ob->setProperty( "shortcut", QKeySequence( "Alt+Shift+O" ) ); wid = ob; - ob->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) ); } +#ifndef DISABLE_PYCONSOLE else if ( flag == WT_PyConsole ) { - PythonConsole* pyCons = new PythonConsole( desktop() ); - pyCons->setCaption( tr( "PYTHON_CONSOLE" ) ); + PyConsole_Console* pyCons = new PyConsole_EnhConsole( desktop(),new LightApp_PyInterp()); + pyCons->setWindowTitle( tr( "PYTHON_CONSOLE" ) ); + pyCons->setFont(resourceMgr()->fontValue( "PyConsole", "font" )); + pyCons->setIsShowBanner(resourceMgr()->booleanValue( "PyConsole", "show_banner", true )); + pyCons->setProperty( "shortcut", QKeySequence( "Alt+Shift+P" ) ); + wid = pyCons; - // pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) ); + pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) ); } +#endif else if ( flag == WT_LogWindow ) { LogWindow* logWin = new LogWindow( desktop() ); - logWin->setCaption( tr( "LOG_WINDOW" ) ); + logWin->setWindowTitle( tr( "LOG_WINDOW" ) ); + logWin->setProperty( "shortcut", QKeySequence( "Alt+Shift+L" ) ); wid = logWin; logWin->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) ); } return wid; } -/*!Default windows(Object Browser, Python Console). - * Adds to map \a aMap. +/*! + \return default windows( Object Browser, Python Console ) + Adds to map \a aMap. */ void LightApp_Application::defaultWindows( QMap& aMap ) const -{ - aMap.insert( WT_ObjectBrowser, Qt::DockLeft ); - aMap.insert( WT_PyConsole, Qt::DockBottom ); +{ + aMap.insert( WT_ObjectBrowser, Qt::LeftDockWidgetArea ); +#ifndef DISABLE_PYCONSOLE + aMap.insert( WT_PyConsole, Qt::BottomDockWidgetArea ); +#endif // aMap.insert( WT_LogWindow, Qt::DockBottom ); } -/*!Default view manager.*/ +/*!Default view managers*/ void LightApp_Application::defaultViewManagers( QStringList& ) const { /*!Do nothing.*/ } -/*!Gets preferences. - * Create preferences, if \a crt = true. - */ +/*! + \return preferences. + Create preferences, if \a crt = true. +*/ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const { if ( myPrefs ) @@ -1346,7 +1964,8 @@ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const LightApp_Application* that = (LightApp_Application*)this; - if ( !_prefs_ && crt ) + bool toCreate = !_prefs_ && crt; + if ( toCreate ) { _prefs_ = new LightApp_Preferences( resourceMgr() ); that->createPreferences( _prefs_ ); @@ -1354,46 +1973,64 @@ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const that->myPrefs = _prefs_; - QPtrList appList = SUIT_Session::session()->applications(); - for ( QPtrListIterator appIt ( appList ); appIt.current(); ++appIt ) + connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ), + this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) ); + + if ( !crt ) + return myPrefs; + + SUIT_ResourceMgr* resMgr = resourceMgr(); + + QList appList = SUIT_Session::session()->applications(); + for ( QList::iterator appIt = appList.begin(); appIt != appList.end(); ++appIt ) { - if ( !appIt.current()->inherits( "LightApp_Application" ) ) + LightApp_Application* app = ::qobject_cast( *appIt ); + if ( !app ) continue; - LightApp_Application* app = (LightApp_Application*)appIt.current(); - QStringList modNameList; app->modules( modNameList, false ); + + QMap iconMap; + app->moduleIconNames( iconMap ); + for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it ) { - int id = _prefs_->addPreference( *it ); - _prefs_->setItemProperty( id, "info", tr( "PREFERENCES_NOT_LOADED" ).arg( *it ) ); + if ( !app->isLibExists( *it ) || _prefs_->hasModule( *it ) ) + continue; + + int modId = _prefs_->addPreference( *it ); + if ( iconMap.contains( *it ) ) + _prefs_->setItemIcon( modId, Qtx::scaleIcon( resMgr->loadPixmap( moduleName( *it ), iconMap[*it], false ), 20 ) ); } ModuleList modList; app->modules( modList ); - for ( ModuleListIterator itr( modList ); itr.current(); ++itr ) + QListIterator itr( modList ); + while ( itr.hasNext() ) { LightApp_Module* mod = 0; - if ( itr.current()->inherits( "LightApp_Module" ) ) - mod = (LightApp_Module*)itr.current(); + + CAM_Module* anItem = itr.next(); + if ( anItem->inherits( "LightApp_Module" ) ) + mod = (LightApp_Module*)anItem; if ( mod && !_prefs_->hasModule( mod->moduleName() ) ) { - int modCat = _prefs_->addPreference( mod->moduleName() ); - _prefs_->setItemProperty( modCat, "info", QString::null ); - mod->createPreferences(); + _prefs_->addPreference( mod->moduleName() ); + mod->createPreferences(); + that->emptyPreferences( mod->moduleName() ); } } } - - connect( myPrefs, SIGNAL( preferenceChanged( QString&, QString&, QString& ) ), - this, SLOT( onPreferenceChanged( QString&, QString&, QString& ) ) ); + _prefs_->setItemProperty( "info", tr( "PREFERENCES_NOT_LOADED" ) ); return myPrefs; } -/*!Add new module to application.*/ +/*! + Adds new module to application +*/ void LightApp_Application::moduleAdded( CAM_Module* mod ) { CAM_Application::moduleAdded( mod ); @@ -1404,290 +2041,1146 @@ void LightApp_Application::moduleAdded( CAM_Module* mod ) if ( myPrefs && lightMod && !myPrefs->hasModule( lightMod->moduleName() )) { - int modCat = myPrefs->addPreference( mod->moduleName() ); - myPrefs->setItemProperty( modCat, "info", QString::null ); + myPrefs->addPreference( mod->moduleName() ); lightMod->createPreferences(); + emptyPreferences( mod->moduleName() ); } } -/*!Create preferences.*/ +void LightApp_Application::emptyPreferences( const QString& modName ) +{ + QtxPreferenceItem* item = myPrefs->findItem( modName, true ); + if ( !item || !item->isEmpty() ) + return; + + // printf( "---------------------> Modify for empty module.\n" ); + + QtxPagePrefFrameItem* frm = new QtxPagePrefFrameItem( item->title(), item->parentItem() ); + frm->setIcon( item->icon() ); + frm->setStretch( false ); + item->parentItem()->insertItem( frm, item ); + new QtxPagePrefLabelItem( Qt::AlignCenter, tr( "PREFERENCES_NOT_SUPPORTED" ).arg( modName ), frm ); + delete item; +} + +/*! + Create preferences +*/ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) { if ( !pref ) return; + QStringList aValuesList; + QList anIndicesList; + QIntList idList; + QIntList txtList; + + // . Top-level "SALOME" preferences group <> int salomeCat = pref->addPreference( tr( "PREF_CATEGORY_SALOME" ) ); + pref->setItemIcon( salomeCat, Qtx::scaleIcon( resourceMgr()->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ), 20 ) ); + // .. "General" preferences tab <> int genTab = pref->addPreference( tr( "PREF_TAB_GENERAL" ), salomeCat ); - int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab ); - pref->setItemProperty( studyGroup, "columns", 1 ); + // ... "Language" group <> + int langGroup = pref->addPreference( tr( "PREF_GROUP_LANGUAGE" ), genTab ); + pref->setItemProperty( "columns", 2, langGroup ); + // .... -> application language + int curLang = pref->addPreference( tr( "PREF_CURRENT_LANGUAGE" ), langGroup, + LightApp_Preferences::Selector, "language", "language" ); + QStringList aLangs = SUIT_Session::session()->resourceMgr()->stringValue( "language", "languages", "en" ).split( "," ); + QList aIcons; + foreach ( QString aLang, aLangs ) { + aIcons << QPixmap( QString( ":/images/%1" ).arg( aLang ) ); + } + pref->setItemProperty( "strings", aLangs, curLang ); + pref->setItemProperty( "icons", aIcons, curLang ); + // ... "Language" group <> + + // ... "Look and feel" group <> + int lookGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), genTab ); + pref->setItemProperty( "columns", 2, lookGroup ); + // .... -> show splash-screen + 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 + pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), lookGroup, LightApp_Preferences::Bool, "viewers", "drop_down_buttons" ); + // ... "Look and feel" group <> + + // ... "Study properties" group <> + int studyGroup = pref->addPreference( tr( "PREF_GROUP_STUDY" ), genTab ); + pref->setItemProperty( "columns", 2, studyGroup ); + // .... -> multi-file save pref->addPreference( tr( "PREF_MULTI_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "multi_file" ); + // .... -> ascii save mode pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" ); - int undoPref = pref->addPreference( tr( "PREF_UNDO_LEVEL" ), studyGroup, LightApp_Preferences::IntSpin, "Study", "undo_level" ); - pref->setItemProperty( undoPref, "min", 1 ); - pref->setItemProperty( undoPref, "max", 100 ); - - int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab ); - pref->setItemProperty( extgroup, "columns", 1 ); - int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", "application" ); - pref->setItemProperty( apppref, "existing", true ); - pref->setItemProperty( apppref, "flags", QFileInfo::ExeUser ); - + // .... -> store windows geometry + pref->addPreference( tr( "PREF_STORE_POS" ), studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" ); + pref->addPreference( "", studyGroup, LightApp_Preferences::Space ); + pref->addPreference( tr( "PREF_STORE_TOOL_POS" ), studyGroup, LightApp_Preferences::Bool, "Study", "store_tool_positions" ); + // .... -> auto-save + int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ), studyGroup, + LightApp_Preferences::IntSpin, "Study", "auto_save_interval" ); + pref->setItemProperty( "min", 0, autoSaveInterval ); + pref->setItemProperty( "max", 1440, autoSaveInterval ); + pref->setItemProperty( "special", tr( "PREF_AUTO_SAVE_DISABLED" ), autoSaveInterval ); + // ... "Study properties" group <> + + // ... "Help browser" group <> + int extgroup = pref->addPreference( tr( "PREF_GROUP_EXT_BROWSER" ), genTab, LightApp_Preferences::Auto, "ExternalBrowser", "use_external_browser"); +#ifdef WIN32 + QString platform = "winapplication"; +#else + QString platform = "application"; +#endif + // .... -> browser application + int apppref = pref->addPreference( tr( "PREF_APP" ), extgroup, LightApp_Preferences::File, "ExternalBrowser", platform ); + pref->setItemProperty( "mode", Qtx::PT_OpenFile, apppref ); + // .... -> browser parameters pref->addPreference( tr( "PREF_PARAM" ), extgroup, LightApp_Preferences::String, "ExternalBrowser", "parameters" ); + // ... "Help browser" group <> + // ... "Python console properties" group <> int pythonConsoleGroup = pref->addPreference( tr( "PREF_GROUP_PY_CONSOLE" ), genTab ); - pref->setItemProperty( pythonConsoleGroup, "columns", 1 ); + // .... -> font pref->addPreference( tr( "PREF_FONT" ), pythonConsoleGroup, LightApp_Preferences::Font, "PyConsole", "font" ); - - int viewTab = pref->addPreference( tr( "PREF_TAB_VIEWERS" ), salomeCat ); - - int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab ); - - int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab ); - - int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), viewTab ); - - int supervGroup = pref->addPreference( tr( "PREF_GROUP_SUPERV" ), viewTab ); - - pref->setItemProperty( occGroup, "columns", 1 ); - pref->setItemProperty( vtkGroup, "columns", 1 ); - pref->setItemProperty( plot2dGroup, "columns", 1 ); - - int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occGroup, - LightApp_Preferences::IntSpin, "OCCViewer", "trihedron_size" ); - pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup, - LightApp_Preferences::Color, "OCCViewer", "background" ); - - pref->setItemProperty( occTS, "min", 1 ); - pref->setItemProperty( occTS, "max", 150 ); - - int isoU = pref->addPreference( tr( "PREF_ISOS_U" ), occGroup, - LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_u" ); - int isoV = pref->addPreference( tr( "PREF_ISOS_V" ), occGroup, - LightApp_Preferences::IntSpin, "OCCViewer", "iso_number_v" ); - - pref->setItemProperty( isoU, "min", 0 ); - pref->setItemProperty( isoU, "max", 100000 ); - - pref->setItemProperty( isoV, "min", 0 ); - pref->setItemProperty( isoV, "max", 100000 ); - - int vtkTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), vtkGroup, - LightApp_Preferences::IntSpin, "VTKViewer", "trihedron_size" ); - pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGroup, - LightApp_Preferences::Color, "VTKViewer", "background" ); - - pref->setItemProperty( vtkTS, "min", 1 ); - pref->setItemProperty( vtkTS, "max", 150 ); - + // .... -> show banner + pref->addPreference( tr( "PREF_SHOW_BANNER" ), pythonConsoleGroup, LightApp_Preferences::Bool, "PyConsole", "show_banner" ); + // ... "Python console properties" group <> + + // ... "MRU" preferences group <> + int mruGroup = pref->addPreference( tr( "PREF_GROUP_MRU" ), genTab, LightApp_Preferences::Auto, "MRU", "show_mru" ); + pref->setItemProperty( "columns", 4, mruGroup ); + // number of MRU items + int mruVisCount = pref->addPreference( tr( "PREF_MRU_VISIBLE_COUNT" ), mruGroup, LightApp_Preferences::IntSpin, + "MRU", "visible_count" ); + pref->setItemProperty( "min", 0, mruVisCount ); + pref->setItemProperty( "max", 100, mruVisCount ); + // MRU links type + int mruLinkType = pref->addPreference( tr( "PREF_MRU_LINK_TYPE" ), mruGroup, LightApp_Preferences::Selector, + "MRU", "link_type" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_MRU_LINK_AUTO") << tr("PREF_MRU_LINK_SHORT") << tr("PREF_MRU_LINK_FULL"); + anIndicesList << 0 << 1 << 2 ; + pref->setItemProperty( "strings", aValuesList, mruLinkType ); + pref->setItemProperty( "indexes", anIndicesList, mruLinkType ); + // ... "MRU" preferences group <> + // .. "General" preferences tab <> + + // .. "3D viewer" group <> + int Viewer3DGroup = pref->addPreference( tr( "PREF_GROUP_3DVIEWER" ), salomeCat ); + // ... -> navigation mode + int vtkStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), Viewer3DGroup, + LightApp_Preferences::Selector, "3DViewer", "navigation_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_STANDARD_STYLE") << tr("PREF_KEYFREE_STYLE"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, vtkStyleMode ); + pref->setItemProperty( "indexes", anIndicesList, vtkStyleMode ); + // ... -> zooming mode + #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version + int occZoomingStyleMode = pref->addPreference( tr( "PREF_ZOOMING" ), Viewer3DGroup, + LightApp_Preferences::Selector, "3DViewer", "zooming_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_ZOOMING_AT_CENTER") << tr("PREF_ZOOMING_AT_CURSOR"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, occZoomingStyleMode ); + pref->setItemProperty( "indexes", anIndicesList, occZoomingStyleMode ); + #endif + // ... "Trihedron" group <> + int occTriGroup = pref->addPreference( tr( "PREF_TRIHEDRON" ), Viewer3DGroup ); + pref->setItemProperty( "columns", 2, occTriGroup ); + // .... -> trihedron size + int occTS = pref->addPreference( tr( "PREF_TRIHEDRON_SIZE" ), occTriGroup, + LightApp_Preferences::DblSpin, "3DViewer", "trihedron_size" ); + pref->setItemProperty( "min", 1.0E-06, occTS ); + pref->setItemProperty( "max", 1000, occTS ); + // .... -> relative size of trihedron + pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "relative_size" ); + // .... -> show static trihedron + pref->addPreference( tr( "PREF_SHOW_STATIC_TRIHEDRON" ), occTriGroup, LightApp_Preferences::Bool, "3DViewer", "show_static_trihedron" ); + // ... "Trihedron" group <> + // .. "3D viewer" group <> + + QString formats; + int bgId; +#ifndef DISABLE_OCCVIEWER + // .. "OCC viewer" group <> + int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), salomeCat ); + + // ... "Background" group <> + int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup ); + // pref->setItemProperty( "columns", 2, bgGroup ); + aValuesList.clear(); + anIndicesList.clear(); + txtList.clear(); + formats = OCCViewer_Viewer::backgroundData( aValuesList, idList, txtList ); + foreach( int gid, idList ) anIndicesList << gid; + // .... -> 3D viewer background + bgId = pref->addPreference( tr( "PREF_3DVIEWER_BACKGROUND" ), bgGroup, + LightApp_Preferences::Background, "OCCViewer", "background" ); + pref->setItemProperty( "gradient_names", aValuesList, bgId ); + pref->setItemProperty( "gradient_ids", anIndicesList, bgId ); + pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId ); + pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId ); + pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId ); + pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); + pref->setItemProperty( "custom_enabled", false, bgId ); + pref->setItemProperty( "image_formats", formats, bgId ); + // .... -> XZ viewer background + bgId = pref->addPreference( tr( "PREF_XZVIEWER_BACKGROUND" ), bgGroup, + LightApp_Preferences::Background, "OCCViewer", "xz_background" ); + pref->setItemProperty( "gradient_names", aValuesList, bgId ); + pref->setItemProperty( "gradient_ids", anIndicesList, bgId ); + pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId ); + pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId ); + pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId ); + pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); + pref->setItemProperty( "custom_enabled", false, bgId ); + pref->setItemProperty( "image_formats", formats, bgId ); + // .... -> YZ viewer background + bgId = pref->addPreference( tr( "PREF_YZVIEWER_BACKGROUND" ), bgGroup, + LightApp_Preferences::Background, "OCCViewer", "yz_background" ); + pref->setItemProperty( "gradient_names", aValuesList, bgId ); + pref->setItemProperty( "gradient_ids", anIndicesList, bgId ); + pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId ); + pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId ); + pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId ); + pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); + pref->setItemProperty( "custom_enabled", false, bgId ); + pref->setItemProperty( "image_formats", formats, bgId ); + // .... -> XY viewer background + bgId = pref->addPreference( tr( "PREF_XYVIEWER_BACKGROUND" ), bgGroup, + LightApp_Preferences::Background, "OCCViewer", "xy_background" ); + pref->setItemProperty( "gradient_names", aValuesList, bgId ); + pref->setItemProperty( "gradient_ids", anIndicesList, bgId ); + pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId ); + pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId ); + pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId ); + pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); + pref->setItemProperty( "custom_enabled", false, bgId ); + pref->setItemProperty( "image_formats", formats, bgId ); + // ... "Background" group <> + + + // ... "Selection" group <> + int occSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), occGroup ); + pref->setItemProperty( "columns", 2, occSelectionGroup ); + // .... -> enable preselection + pref->addPreference( tr( "PREF_ENABLE_PRESELECTION" ), occSelectionGroup, + LightApp_Preferences::Bool, "OCCViewer", "enable_preselection" ); + // .... -> enable selection + pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), occSelectionGroup, + LightApp_Preferences::Bool, "OCCViewer", "enable_selection" ); + // ... "Selection" group <> + + // ... -> empty frame (for layout) <> + int occGen = pref->addPreference( "", occGroup, LightApp_Preferences::Frame ); + pref->setItemProperty( "margin", 0, occGen ); + pref->setItemProperty( "columns", 2, occGen ); + // ... -> empty frame (for layout) <> + // .. "OCC viewer" group <> +#endif + +#ifndef DISABLE_VTKVIEWER + // .. "VTK viewer" group <> + int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), salomeCat ); //viewTab + + // ... -> empty frame (for layout) <> + int vtkGen = pref->addPreference( "", vtkGroup, LightApp_Preferences::Frame ); + //pref->setItemProperty( "columns", 2, vtkGen ); + // .... -> projection mode + int vtkProjMode = pref->addPreference( tr( "PREF_PROJECTION_MODE" ), vtkGen, + LightApp_Preferences::Selector, "VTKViewer", "projection_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_ORTHOGRAPHIC") << tr("PREF_PERSPECTIVE"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, vtkProjMode ); + pref->setItemProperty( "indexes", anIndicesList, vtkProjMode ); + // .... -> background + aValuesList.clear(); + anIndicesList.clear(); + txtList.clear(); +#ifndef DISABLE_SALOMEOBJECT + formats = SVTK_Viewer::backgroundData( aValuesList, idList, txtList ); +#endif + foreach( int gid, idList ) anIndicesList << gid; + bgId = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), vtkGen, + LightApp_Preferences::Background, "VTKViewer", "background" ); + pref->setItemProperty( "gradient_names", aValuesList, bgId ); + pref->setItemProperty( "gradient_ids", anIndicesList, bgId ); + pref->setItemProperty( "texture_enabled", !txtList.isEmpty(), bgId ); + pref->setItemProperty( "texture_center_enabled", (bool)txtList.contains( Qtx::CenterTexture ), bgId ); + pref->setItemProperty( "texture_tile_enabled", (bool)txtList.contains( Qtx::TileTexture ), bgId ); + pref->setItemProperty( "texture_stretch_enabled", (bool)txtList.contains( Qtx::StretchTexture ), bgId ); + pref->setItemProperty( "custom_enabled", false, bgId ); +#ifndef DISABLE_SALOMEOBJECT + pref->setItemProperty( "image_formats", formats, bgId ); +#endif + // .... -> speed increment + int vtkSpeed = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED" ), vtkGen, + LightApp_Preferences::IntSpin, "VTKViewer", "speed_value" ); + pref->setItemProperty( "min", 1, vtkSpeed ); + pref->setItemProperty( "max", 1000, vtkSpeed ); + // .... -> speed mode + int vtkSpeedMode = pref->addPreference( tr( "PREF_INCREMENTAL_SPEED_MODE" ), vtkGen, + LightApp_Preferences::Selector, "VTKViewer", "speed_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_ARITHMETIC") << tr("PREF_GEOMETRICAL"); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, vtkSpeedMode ); + pref->setItemProperty( "indexes", anIndicesList, vtkSpeedMode ); + + // ... "Selection" group <> + int vtkSelectionGroup = pref->addPreference( tr( "PREF_GROUP_SELECTION" ), vtkGroup ); + pref->setItemProperty( "columns", 2, vtkSelectionGroup ); + // .... -> preselection + int vtkPreselection = pref->addPreference( tr( "PREF_PRESELECTION" ), vtkSelectionGroup, + LightApp_Preferences::Selector, "VTKViewer", "preselection" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_PRESELECTION_STANDARD") << tr("PREF_PRESELECTION_DYNAMIC") << tr("PREF_PRESELECTION_DISABLED"); + anIndicesList << 0 << 1 << 2; + pref->setItemProperty( "strings", aValuesList, vtkPreselection ); + pref->setItemProperty( "indexes", anIndicesList, vtkPreselection ); + // .... -> enable selection + pref->addPreference( tr( "PREF_ENABLE_SELECTION" ), vtkSelectionGroup, LightApp_Preferences::Bool, "VTKViewer", "enable_selection" ); + // ... "Selection" group <> + + // ... -> empty frame (for layout) <> + + // ... space mouse sub-group <> + int vtkSM = pref->addPreference( tr( "PREF_FRAME_SPACEMOUSE" ), vtkGroup, LightApp_Preferences::GroupBox ); + //pref->setItemProperty( "columns", 2, vtkSM ); + // .... -> decrease speed increment + int spacemousePref1 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_1" ), vtkSM, + LightApp_Preferences::Selector, "VTKViewer", + "spacemouse_func1_btn" ); + // .... -> increase speed increment + int spacemousePref2 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_2" ), vtkSM, + LightApp_Preferences::Selector, "VTKViewer", + "spacemouse_func2_btn" ); + // .... -> dominant / combined switch + int spacemousePref3 = pref->addPreference( tr( "PREF_SPACEMOUSE_FUNC_3" ), vtkSM, + LightApp_Preferences::Selector, "VTKViewer", + "spacemouse_func5_btn" ); // + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr( "PREF_SPACEMOUSE_BTN_1" ) << tr( "PREF_SPACEMOUSE_BTN_2" ) << tr( "PREF_SPACEMOUSE_BTN_3" ); + aValuesList << tr( "PREF_SPACEMOUSE_BTN_4" ) << tr( "PREF_SPACEMOUSE_BTN_5" ) << tr( "PREF_SPACEMOUSE_BTN_6" ); + aValuesList << tr( "PREF_SPACEMOUSE_BTN_7" ) << tr( "PREF_SPACEMOUSE_BTN_8" ) << tr( "PREF_SPACEMOUSE_BTN_*" ); + aValuesList << tr( "PREF_SPACEMOUSE_BTN_10" ) << tr( "PREF_SPACEMOUSE_BTN_11" ); + anIndicesList << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11; + pref->setItemProperty( "strings", aValuesList, spacemousePref1 ); + pref->setItemProperty( "indexes", anIndicesList, spacemousePref1 ); + pref->setItemProperty( "strings", aValuesList, spacemousePref2 ); + pref->setItemProperty( "indexes", anIndicesList, spacemousePref2 ); + pref->setItemProperty( "strings", aValuesList, spacemousePref3 ); + pref->setItemProperty( "indexes", anIndicesList, spacemousePref3 ); + // ... space mouse sub-group <> + + // ... avi recording sub-group <> + int vtkRec = pref->addPreference( tr( "PREF_FRAME_RECORDING" ), vtkGroup, LightApp_Preferences::GroupBox ); + pref->setItemProperty( "columns", 2, vtkRec ); + // .... -> recording mode + int modePref = pref->addPreference( tr( "PREF_RECORDING_MODE" ), vtkRec, + LightApp_Preferences::Selector, "VTKViewer", "recorder_mode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr( "PREF_SKIPPED_FRAMES" ) << tr( "PREF_ALL_DISLPAYED_FRAMES" ); + anIndicesList << 0 << 1; + pref->setItemProperty( "strings", aValuesList, modePref ); + pref->setItemProperty( "indexes", anIndicesList, modePref ); + // .... -> fps + int fpsPref = pref->addPreference( tr( "PREF_FPS" ), vtkRec, + LightApp_Preferences::DblSpin, "VTKViewer", "recorder_fps" ); + pref->setItemProperty( "min", 0.1, fpsPref ); + pref->setItemProperty( "max", 100, fpsPref ); + // .... -> quality + int qualityPref = pref->addPreference( tr( "PREF_QUALITY" ), vtkRec, + LightApp_Preferences::IntSpin, "VTKViewer", "recorder_quality" ); + pref->setItemProperty( "min", 1, qualityPref ); + pref->setItemProperty( "max", 100, qualityPref ); + // .... -> progressive mode + pref->addPreference( tr( "PREF_PROGRESSIVE" ), vtkRec, + LightApp_Preferences::Bool, "VTKViewer", "recorder_progressive" ); + // ... avi recording sub-group <> + + // ... group names sub-group <> + int vtkGN = pref->addPreference( tr( "PREF_FRAME_GROUP_NAMES" ), vtkGroup, + LightApp_Preferences::GroupBox, "VTKViewer", "show_group_names" ); + pref->setItemProperty( "columns", 2, vtkGN ); + // .... -> text color + pref->addPreference( tr( "PREF_GROUP_NAMES_TEXT_COLOR" ), vtkGN, + LightApp_Preferences::Color, "VTKViewer", "group_names_text_color" ); + // .... -> transparency + int transPref = pref->addPreference( tr( "PREF_GROUP_NAMES_TRANSPARENCY" ), vtkGN, + LightApp_Preferences::DblSpin, "VTKViewer", "group_names_transparency" ); + pref->setItemProperty( "min", 0.0, transPref ); + pref->setItemProperty( "max", 1.0, transPref ); + pref->setItemProperty( "step", 0.1, transPref ); + // ... -> group names sub-group <> + // .. "VTK viewer" group <> +#endif + + // .. "Plot2d viewer" group <> + int plot2dGroup = pref->addPreference( tr( "PREF_GROUP_PLOT2DVIEWER" ), salomeCat ); //viewTab + //pref->setItemProperty( "columns", 2, plot2dGroup ); + + // ... -> show legend pref->addPreference( tr( "PREF_SHOW_LEGEND" ), plot2dGroup, - LightApp_Preferences::Bool, "Plot2d", "ShowLegend" ); - + LightApp_Preferences::Bool, "Plot2d", "ShowLegend" ); + // ... -> legend position int legendPosition = pref->addPreference( tr( "PREF_LEGEND_POSITION" ), plot2dGroup, - LightApp_Preferences::Selector, "Plot2d", "LegendPos" ); - QStringList aLegendPosList; - aLegendPosList.append( tr("PREF_LEFT") ); - aLegendPosList.append( tr("PREF_RIGHT") ); - aLegendPosList.append( tr("PREF_TOP") ); - aLegendPosList.append( tr("PREF_BOTTOM") ); - - QValueList anIndexesList; - anIndexesList.append(0); - anIndexesList.append(1); - anIndexesList.append(2); - anIndexesList.append(3); - - pref->setItemProperty( legendPosition, "strings", aLegendPosList ); - pref->setItemProperty( legendPosition, "indexes", anIndexesList ); - + LightApp_Preferences::Selector, "Plot2d", "LegendPos" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_LEFT") << tr("PREF_RIGHT") << tr("PREF_TOP") << tr("PREF_BOTTOM"); + anIndicesList << 0 << 1 << 2 << 3 ; + pref->setItemProperty( "strings", aValuesList, legendPosition ); + pref->setItemProperty( "indexes", anIndicesList, legendPosition ); + // ... -> legend font + pref->addPreference( tr( "PREF_LEGEND_FONT" ), plot2dGroup, LightApp_Preferences::Font, "Plot2d", "LegendFont" ); + // ... -> curve type int curveType = pref->addPreference( tr( "PREF_CURVE_TYPE" ), plot2dGroup, - LightApp_Preferences::Selector, "Plot2d", "CurveType" ); - QStringList aCurveTypesList; - aCurveTypesList.append( tr("PREF_POINTS") ); - aCurveTypesList.append( tr("PREF_LINES") ); - aCurveTypesList.append( tr("PREF_SPLINE") ); - - anIndexesList.clear(); - anIndexesList.append(0); - anIndexesList.append(1); - anIndexesList.append(2); - - pref->setItemProperty( curveType, "strings", aCurveTypesList ); - pref->setItemProperty( curveType, "indexes", anIndexesList ); - + LightApp_Preferences::Selector, "Plot2d", "CurveType" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_POINTS") << tr("PREF_LINES") << tr("PREF_SPLINE"); + anIndicesList << 0 << 1 << 2 ; + pref->setItemProperty( "strings", aValuesList, curveType ); + pref->setItemProperty( "indexes", anIndicesList, curveType ); + // ... -> marker size int markerSize = pref->addPreference( tr( "PREF_MARKER_SIZE" ), plot2dGroup, - LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" ); - - pref->setItemProperty( markerSize, "min", 0 ); - pref->setItemProperty( markerSize, "max", 100 ); - - QStringList aScaleModesList; - aScaleModesList.append( tr("PREF_LINEAR") ); - aScaleModesList.append( tr("PREF_LOGARITHMIC") ); - - anIndexesList.clear(); - anIndexesList.append(0); - anIndexesList.append(1); - + LightApp_Preferences::IntSpin, "Plot2d", "MarkerSize" ); + pref->setItemProperty( "min", 0, markerSize ); + pref->setItemProperty( "max", 100, markerSize ); + // ... -> horizontal scaling mode int horScale = pref->addPreference( tr( "PREF_HOR_AXIS_SCALE" ), plot2dGroup, - LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" ); - - pref->setItemProperty( horScale, "strings", aScaleModesList ); - pref->setItemProperty( horScale, "indexes", anIndexesList ); - + LightApp_Preferences::Selector, "Plot2d", "HorScaleMode" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_LINEAR") << tr("PREF_LOGARITHMIC"); + anIndicesList << 0 << 1 ; + pref->setItemProperty( "strings", aValuesList, horScale ); + pref->setItemProperty( "indexes", anIndicesList, horScale ); + // ... -> vertical scaling mode int verScale = pref->addPreference( tr( "PREF_VERT_AXIS_SCALE" ), plot2dGroup, - LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" ); - - pref->setItemProperty( verScale, "strings", aScaleModesList ); - pref->setItemProperty( verScale, "indexes", anIndexesList ); - - pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), plot2dGroup, - LightApp_Preferences::Color, "Plot2d", "Background" ); - + LightApp_Preferences::Selector, "Plot2d", "VerScaleMode" ); + pref->setItemProperty( "strings", aValuesList, verScale ); + pref->setItemProperty( "indexes", anIndicesList, verScale ); + // ... -> background + pref->addPreference( tr( "PREF_VIEWER_BACKGROUND_COLOR" ), plot2dGroup, + LightApp_Preferences::Color, "Plot2d", "Background" ); + // ... -> font color + pref->addPreference( tr( "PREF_FONT_COLOR" ), plot2dGroup, LightApp_Preferences::Color, "Plot2d", "LegendFontColor" ); + // ... -> selection font color + pref->addPreference( tr( "PREF_SELECTED_FONT_COLOR" ), plot2dGroup, LightApp_Preferences::Color, "Plot2d", "SelectedLegendFontColor" ); + // ... -> selection color + pref->addPreference( tr( "PREF_VIEWER_SELECTION" ), plot2dGroup, + LightApp_Preferences::Color, "Plot2d", "SelectionColor" ); + // ... -> errors/deviation colot + pref->addPreference( tr( "PREF_DEVIATION_COLOR" ), plot2dGroup, + LightApp_Preferences::Color, "Plot2d", "DeviationMarkerColor" ); + // ... -> deviation markers line size + int deviationMarkerLw = pref->addPreference( tr( "PREF_DEVIATION_MARKER_LW" ), plot2dGroup, + LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerLineWidth" ); + pref->setItemProperty( "min", 1, deviationMarkerLw ); + pref->setItemProperty( "max", 5, deviationMarkerLw ); + // ... -> deviation markers tick mark size + int deviationMarkerTs = pref->addPreference( tr( "PREF_DEVIATION_MARKER_TS" ), plot2dGroup, + LightApp_Preferences::IntSpin, "Plot2d", "DeviationMarkerTickSize" ); + pref->setItemProperty( "min", 1, deviationMarkerTs ); + pref->setItemProperty( "max", 5, deviationMarkerTs ); + // .. "Plot2d viewer" group <> + + // .. "Directories" preferences tab <> int dirTab = pref->addPreference( tr( "PREF_TAB_DIRECTORIES" ), salomeCat ); + // ... --> quick directories list int dirGroup = pref->addPreference( tr( "PREF_GROUP_DIRECTORIES" ), dirTab ); - pref->setItemProperty( dirGroup, "columns", 1 ); pref->addPreference( tr( "" ), dirGroup, - LightApp_Preferences::DirList, "FileDlg", "QuickDirList" ); - - pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), supervGroup, - LightApp_Preferences::Color, "SUPERVGraph", "Background" ); - pref->addPreference( tr( "PREF_SUPERV_TITLE_COLOR" ), supervGroup, - LightApp_Preferences::Color, "SUPERVGraph", "Title" ); -// pref->addPreference( tr( "PREF_SUPERV_CTRL_COLOR" ), supervGroup, -// LightApp_Preferences::Color, "SUPERVGraph", "Ctrl" ); + LightApp_Preferences::DirList, "FileDlg", "QuickDirList" ); + // .. "Directories" preferences tab <> + + // .. "Object browser" preferences tab <> + int obTab = pref->addPreference( tr( "PREF_TAB_OBJBROWSER" ), salomeCat ); + + // ... "Search tool" group <> + int stGroup = pref->addPreference( tr( "PREF_OBJ_BROWSER_SEARCH_TOOL" ), obTab ); + // .... --> auto-hide + pref->addPreference( tr( "PREF_AUTO_HIDE_SEARCH_TOOL" ), stGroup, LightApp_Preferences::Bool, + "ObjectBrowser", "auto_hide_search_tool" ); + // ... "Search tool" group <> + + // ... "Object browser settings" group <> + int objSetGroup = pref->addPreference( tr( "PREF_GROUP_LOOK_AND_FEEL" ), obTab ); + pref->setItemProperty( "columns", 2, objSetGroup ); + // .... -> auto size first column + pref->addPreference( tr( "PREF_AUTO_SIZE_FIRST" ), objSetGroup, LightApp_Preferences::Bool, + "ObjectBrowser", "auto_size_first" ); + // .... -> auto size other columns + pref->addPreference( tr( "PREF_AUTO_SIZE" ), objSetGroup, LightApp_Preferences::Bool, + "ObjectBrowser", "auto_size" ); + // .... -> resize columns on expand item + pref->addPreference( tr( "PREF_RESIZE_ON_EXPAND_ITEM" ), objSetGroup, LightApp_Preferences::Bool, + "ObjectBrowser", "resize_on_expand_item" ); + // .... -> browse to published object + int browsePublished = pref->addPreference( tr( "PREF_BROWSE_TO_THE_PUBLISHED_OBJECT" ), objSetGroup, LightApp_Preferences::Selector, + "ObjectBrowser", "browse_published_object" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr( "PREF_BROWSE_NEVER" ) << tr( "PREF_BROWSE_AFTER_APPLY_AND_CLOSE_ONLY" ) << tr( "PREF_BROWSE_ALWAYS" ); + anIndicesList << BP_Never << BP_ApplyAndClose << BP_Always; + pref->setItemProperty( "strings", aValuesList, browsePublished ); + pref->setItemProperty( "indexes", anIndicesList, browsePublished ); + // ... "Object browser settings" group <> + // .. "Object browser" preferences tab <> + + // .. "Shortcuts" preferences tab <> + int shortcutTab = pref->addPreference( tr( "PREF_TAB_SHORTCUTS" ), salomeCat ); + // ... "Shortcuts settings" group <> + int shortcutGroup = pref->addPreference( tr( "PREF_GROUP_SHORTCUTS" ), shortcutTab ); + pref->addPreference( tr( "" ), shortcutGroup, + LightApp_Preferences::ShortcutTree, "shortcuts" ); + // ... "Shortcuts settings" group <> + // .. "Shortcuts" preferences tab <> + // . Top-level "SALOME" preferences group <> + + pref->retrieve(); } -/*!Changed preferences */ +/*! + Changes appearance of application according to changed preferences + \param sec - section + \param param - name of changed parameter +*/ void LightApp_Application::preferencesChanged( const QString& sec, const QString& param ) { SUIT_ResourceMgr* resMgr = resourceMgr(); if ( !resMgr ) return; - if ( sec == QString( "OCCViewer" ) && param == QString( "trihedron_size" ) ) + if ( sec == "viewers" && param == "drop_down_buttons" ) + { + ViewManagerList vmlist = viewManagers(); + foreach( SUIT_ViewManager* vm, vmlist ) + { + QVector vwlist = vm->getViews(); + foreach( SUIT_ViewWindow* vw, vwlist ) + if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) ); + } + } + + if ( sec == QString( "3DViewer" ) && (param == QString( "trihedron_size" ) || param == QString( "relative_size" ))) { - int sz = resMgr->integerValue( sec, param, -1 ); - QPtrList lst; + double sz = resMgr->doubleValue( sec, "trihedron_size", -1 ); + bool relative = resMgr->booleanValue( sec, "relative_size", true ); + QList lst; +#ifndef DISABLE_OCCVIEWER viewManagers( OCCViewer_Viewer::Type(), lst ); - for ( QPtrListIterator it( lst ); it.current() && sz >= 0; ++it ) + QListIterator itOCC( lst ); + while ( itOCC.hasNext() && sz >= 0 ) { - SUIT_ViewModel* vm = it.current()->getViewModel(); + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) - continue; + continue; OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; - occVM->setTrihedronSize( sz ); + occVM->setTrihedronSize( sz, relative ); occVM->getAISContext()->UpdateCurrentViewer(); } +#endif +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator itVTK( lst ); + while ( itVTK.hasNext() && sz >= 0 ) + { + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; + + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) + { + vtkVM->setTrihedronSize( sz, relative ); + vtkVM->Repaint(); + } + } +#endif +#endif } - if ( sec == QString( "VTKViewer" ) && param == QString( "trihedron_size" ) ) + if ( sec == QString( "3DViewer" ) && param == QString( "show_static_trihedron" ) ) { - int sz = resMgr->integerValue( sec, param, -1 ); - QPtrList lst; + bool isVisible = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true ); + QList lst; +#ifndef DISABLE_OCCVIEWER + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) + { + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; + + OCCViewer_Viewer* occVM = dynamic_cast( vm ); + if( occVM ) + { + occVM->setStaticTrihedronDisplayed( isVisible ); + } + } +#endif +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT viewManagers( SVTK_Viewer::Type(), lst ); - for ( QPtrListIterator it( lst ); it.current() && sz >= 0; ++it ) + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) { - SUIT_ViewModel* vm = it.current()->getViewModel(); + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) - continue; + continue; SVTK_Viewer* vtkVM = dynamic_cast( vm ); if( vtkVM ) { - vtkVM->setTrihedronSize( sz ); - vtkVM->Repaint(); + vtkVM->setStaticTrihedronVisible( isVisible ); + vtkVM->Repaint(); } } +#endif +#endif } - if ( sec == QString( "OCCViewer" ) && ( param == QString( "iso_number_u" ) || param == QString( "iso_number_v" ) ) ) + if ( sec == QString( "3DViewer" ) && param == QString( "navigation_mode" ) ) { - QPtrList lst; + int mode = resMgr->integerValue( "3DViewer", "navigation_mode", 0 ); + QList lst; +#ifndef DISABLE_OCCVIEWER viewManagers( OCCViewer_Viewer::Type(), lst ); - int u = resMgr->integerValue( sec, "iso_number_u" ); - int v = resMgr->integerValue( sec, "iso_number_v" ); - for ( QPtrListIterator it( lst ); it.current(); ++it ) + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) + { + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; + + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->setInteractionStyle( mode ); + } +#endif +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) { - OCCViewer_ViewManager* mgr = dynamic_cast( it.current() ); - if( mgr && mgr->getOCCViewer() ) - mgr->getOCCViewer()->setIsos( u, v ); + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; + + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setInteractionStyle( mode ); } +#endif +#endif } - if( sec=="ObjectBrowser" ) +#ifndef DISABLE_OCCVIEWER + if ( sec == QString( "OCCViewer" ) && param == QString( "enable_preselection" ) ) { - if( param=="auto_size" ) + bool isToEnablePreselection = resMgr->booleanValue( "OCCViewer", "enable_preselection", true ); + QList lst; + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) { - OB_Browser* ob = objectBrowser(); - if( !ob ) - return; - - bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false ); - ob->setWidthMode( autoSize ? QListView::Maximum : QListView::Manual ); + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; - updateObjectBrowser( false ); + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->enablePreselection( isToEnablePreselection ); } } +#endif - if( sec=="PyConsole" ) +#ifndef DISABLE_OCCVIEWER + if ( sec == QString( "OCCViewer" ) && param == QString( "enable_selection" ) ) { - if( param=="font" ) - if( pythonConsole() ) - pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) ); - } -} + bool isToEnableSelection = resMgr->booleanValue( "OCCViewer", "enable_selection", true ); + QList lst; + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; -/*!Update desktop title.*/ -void LightApp_Application::updateDesktopTitle() { - QString aTitle = applicationName(); - QString aVer = applicationVersion(); - if ( !aVer.isEmpty() ) - aTitle += QString( " " ) + aVer; + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->enableSelection( isToEnableSelection ); + } + } +#endif - desktop()->setCaption( aTitle ); -} + if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) ) + { + int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 ); + QList lst; +#ifndef DISABLE_OCCVIEWER + viewManagers( OCCViewer_Viewer::Type(), lst ); + QListIterator itOCC( lst ); + while ( itOCC.hasNext() ) + { + SUIT_ViewModel* vm = itOCC.next()->getViewModel(); + if ( !vm || !vm->inherits( "OCCViewer_Viewer" ) ) + continue; -/*!Update windows after close document.*/ -void LightApp_Application::afterCloseDoc() -{ - updateWindows(); + OCCViewer_Viewer* occVM = (OCCViewer_Viewer*)vm; + occVM->setZoomingStyle( mode ); + } +#endif +#ifndef DISABLE_VTKVIEWER +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator itVTK( lst ); + while ( itVTK.hasNext() ) + { + SUIT_ViewModel* vm = itVTK.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; - CAM_Application::afterCloseDoc(); -} + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setZoomingStyle( mode ); + } +#endif +#endif + } -/*!Update module action.*/ -void LightApp_Application::updateModuleActions() -{ - QString modName; - if ( activeModule() ) - modName = activeModule()->moduleName(); +#ifndef DISABLE_VTKVIEWER + if ( sec == QString( "VTKViewer" ) && (param == QString( "speed_value" ) || param == QString( "speed_mode" )) ) + { + int speed = resMgr->integerValue( "VTKViewer", "speed_value", 10 ); + int mode = resMgr->integerValue( "VTKViewer", "speed_mode", 0 ); + QList lst; +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; - if ( myActions.contains( modName ) ) - myActions[modName]->setOn( true ); -} + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setIncrementalSpeed( speed, mode ); + } +#endif + } +#endif -/*!Gets current windows. - *\param winMap - output current windows map. - */ -void LightApp_Application::currentWindows( QMap& winMap ) const -{ - winMap.clear(); - if ( !activeStudy() ) - return; +#ifndef DISABLE_VTKVIEWER + if ( sec == QString( "VTKViewer" ) && param == QString( "projection_mode" ) ) + { + int mode = resMgr->integerValue( "VTKViewer", "projection_mode", 0 ); + QList lst; +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; - if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) ) - ((LightApp_Module*)activeModule())->windows( winMap ); - else - defaultWindows( winMap ); -} + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setProjectionMode( mode ); + } +#endif + } +#endif -/*!Gets current view managers. - *\param lst - output current view managers list. - */ -void LightApp_Application::currentViewManagers( QStringList& lst ) const +#ifndef DISABLE_VTKVIEWER + if ( sec == QString( "VTKViewer" ) && param == QString( "preselection" ) ) + { + int mode = resMgr->integerValue( "VTKViewer", "preselection", 0 ); + QList lst; +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; + + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setPreSelectionMode( mode ); + } +#endif + } +#endif + +#ifndef DISABLE_VTKVIEWER + if ( sec == QString( "VTKViewer" ) && param == QString( "enable_selection" ) ) + { + bool isToEnableSelection = resMgr->booleanValue( "VTKViewer", "enable_selection", true ); + QList lst; +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; + + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->enableSelection( isToEnableSelection ); + } +#endif + } +#endif + +#ifndef DISABLE_VTKVIEWER + if ( sec == QString( "VTKViewer" ) && (param == QString( "spacemouse_func1_btn" ) || + param == QString( "spacemouse_func2_btn" ) || + param == QString( "spacemouse_func5_btn" ) ) ) + { + int btn1 = resMgr->integerValue( "VTKViewer", "spacemouse_func1_btn", 1 ); + int btn2 = resMgr->integerValue( "VTKViewer", "spacemouse_func2_btn", 2 ); + int btn3 = resMgr->integerValue( "VTKViewer", "spacemouse_func5_btn", 9 ); + QList lst; +#ifndef DISABLE_SALOMEOBJECT + viewManagers( SVTK_Viewer::Type(), lst ); + QListIterator it( lst ); + while ( it.hasNext() ) + { + SUIT_ViewModel* vm = it.next()->getViewModel(); + if ( !vm || !vm->inherits( "SVTK_Viewer" ) ) + continue; + + SVTK_Viewer* vtkVM = dynamic_cast( vm ); + if( vtkVM ) vtkVM->setSpacemouseButtons( btn1, btn2, btn3 ); + } +#endif + } +#endif + if( sec=="ObjectBrowser" ) + { + SUIT_DataBrowser* ob = objectBrowser(); + if ( !ob ) + return; + + if ( param=="auto_size_first" ) + { + bool autoSizeFirst = resMgr->booleanValue( "ObjectBrowser", "auto_size_first", true ); + ob->setAutoSizeFirstColumn( autoSizeFirst ); + if ( autoSizeFirst ) + ob->adjustFirstColumnWidth(); + } + else if ( param=="auto_size" ) { + bool autoSize = resMgr->booleanValue( "ObjectBrowser", "auto_size", false ); + ob->setAutoSizeColumns(autoSize); + if ( autoSize ) + ob->adjustColumnsWidth(); + } + else if ( param=="resize_on_expand_item" ) { + bool resizeOnExpandItem = resMgr->booleanValue( "ObjectBrowser", "resize_on_expand_item", false ); + ob->setResizeOnExpandItem(resizeOnExpandItem); + } + else if ( param == "auto_hide_search_tool" ) { + ob->searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) ); + } + } + + if( sec=="Study" ) + { + if( param=="auto_save_interval" ) { + myAutoSaveTimer->stop(); + int autoSaveInterval = resMgr->integerValue( "Study", "auto_save_interval", 0 ); + if ( activeStudy() && autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 ); + } + } + +#ifndef DISABLE_PYCONSOLE + if( sec=="PyConsole" && pythonConsole() ) + { + if ( param=="font" ) { + pythonConsole()->setFont( resMgr->fontValue( "PyConsole", "font" ) ); + } + else if ( param=="show_banner" ) { + pythonConsole()->setIsShowBanner( resMgr->booleanValue( "PyConsole", "show_banner", true ) ); + } + } +#endif + + if( sec=="MRU" ) + { + QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); + if ( mru ) { + if ( param == "visible_count" ) + mru->setVisibleCount( resMgr->integerValue( "MRU", "visible_count", 5 ) ); // 5 MRU items by default + else if ( param == "max_count" ) + mru->setHistoryCount( resMgr->integerValue( "MRU", "max_count", -1 ) ); // unlimited history by default + else if ( param == "insert_mode" ) + mru->setInsertMode( resMgr->integerValue( "MRU", "insert_mode", 0 ) ); // QtxMRUAction::MoveFirst by default + else if ( param == "link_type" ) + mru->setLinkType( resMgr->integerValue( "MRU", "link_type", 0 ) ); // QtxMRUAction::LinkAuto by default + else if ( param == "show_clear" ) + mru->setClearPossible( resMgr->booleanValue( "MRU", "show_clear", false ) ); // do not show "Clear" item by default + else if ( param == "show_mru" ) + mru->setVisible( resMgr->booleanValue( "MRU", "show_mru", false ) ); // do not show MRU menu item by default + } + } + if ( sec == "language" && param == "language" ) + { + SUIT_MessageBox::information( desktop(), tr( "WRN_WARNING" ), tr( "LANG_CHANGED" ) ); + } + if ( sec == "desktop" && param == "opaque_resize" ) { + bool opaqueResize = resMgr->booleanValue( "desktop", "opaque_resize", false ); + QMainWindow::DockOptions dopts = desktop()->dockOptions(); + if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks; + else dopts &= ~QMainWindow::AnimatedDocks; + desktop()->setDockOptions( dopts ); + desktop()->setOpaqueResize( opaqueResize ); + if ( dynamic_cast( desktop() ) ) + dynamic_cast( desktop() )->workstack()->setOpaqueResize( opaqueResize ); + } + + if ( sec == "ExternalBrowser" && param == "use_external_browser" ) { + if ( resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ) ) + { + QtxWebBrowser::shutdown(); + } + } + +#ifndef DISABLE_PLOT2DVIEWER + if ( sec == "Plot2d" ) { + if( param == "SelectionColor" ) { + QColor c = resMgr->colorValue( sec, param ); + Plot2d_Object::setSelectionColor(c); + } + else if (param == "SelectedLegendFontColor") { + QColor c = resMgr->colorValue( sec, param ); + Plot2d_Object::setHighlightedLegendTextColor(c); + } + } +#endif +} + +/*! + Loads preferences +*/ +void LightApp_Application::loadPreferences() +{ + CAM_Application::loadPreferences(); + + SUIT_ResourceMgr* aResMgr = resourceMgr(); + + if ( !aResMgr ) + return; + + static bool mru_load = true; + if ( mru_load ) + { + QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); + if ( mru ) { + mru->setVisible( aResMgr->booleanValue( "MRU", "show_mru", false ) ); // do not show MRU menu item by default + mru->setVisibleCount( aResMgr->integerValue( "MRU", "visible_count", 5 ) ); // 5 MRU items by default + mru->setHistoryCount( aResMgr->integerValue( "MRU", "max_count", -1 ) ); // unlimited history by default + mru->setInsertMode( aResMgr->integerValue( "MRU", "insert_mode", 0 ) ); // QtxMRUAction::MoveFirst by default + mru->setLinkType( aResMgr->integerValue( "MRU", "link_type", 0 ) ); // QtxMRUAction::LinkAuto by default + mru->setClearPossible( aResMgr->booleanValue( "MRU", "show_clear", false ) ); // do not show "Clear" item by default + mru->loadLinks( aResMgr, "MRU" ); + } + mru_load = false; + } + + myWinVis.clear(); + QStringList mods = aResMgr->parameters( "windows_visibility" ); + for ( QStringList::const_iterator itr = mods.begin(); itr != mods.end(); ++itr ) + { + QByteArray arr; + if ( aResMgr->value( "windows_visibility", *itr, arr ) ) + myWinVis.insert( *itr, arr ); + } + + if ( desktop() ) { + desktop()->retrieveGeometry( aResMgr->stringValue( "desktop", "geometry" ) ); + bool opaqueResize = aResMgr->booleanValue( "desktop", "opaque_resize", false ); + QMainWindow::DockOptions dopts = desktop()->dockOptions(); + if ( opaqueResize ) dopts |= QMainWindow::AnimatedDocks; + else dopts &= ~QMainWindow::AnimatedDocks; + desktop()->setDockOptions( dopts ); + desktop()->setOpaqueResize( opaqueResize ); + if ( dynamic_cast( desktop() ) ) + dynamic_cast( desktop() )->workstack()->setOpaqueResize( opaqueResize ); + } +} + +/*! + Saves preferences +*/ +void LightApp_Application::savePreferences() +{ + CAM_Application::savePreferences(); + + saveDockWindowsState(); + + SUIT_ResourceMgr* aResMgr = resourceMgr(); + + if ( !aResMgr ) + return; + + QtxMRUAction* mru = ::qobject_cast( action( MRUId ) ); + if ( mru ) + mru->saveLinks( aResMgr, "MRU" ); + + for ( WinVis::const_iterator itr = myWinVis.begin(); itr != myWinVis.end(); ++itr ) + aResMgr->setValue( "windows_visibility", itr.key(), itr.value() ); + + if ( desktop() ) + aResMgr->setValue( "desktop", "geometry", desktop()->storeGeometry() ); + + aResMgr->save(); +} + +/*! + Updates desktop title +*/ +void LightApp_Application::updateDesktopTitle() +{ + QString aTitle = applicationName(); + QString aVer = applicationVersion(); + if ( !aVer.isEmpty() ) + aTitle += QString( " " ) + aVer; + + if ( activeStudy() ) { + QString sName = SUIT_Tools::file( activeStudy()->studyName().trimmed(), false ); + aTitle += QString( " - [%1]" ).arg( sName ); + } + + desktop()->setWindowTitle( aTitle ); +} + +/*! + \brief Get map of the operations which can be performed + on the module activation. + + The method should return the map of the kind \c {:} + where \c is an integer identifier of the operation and + \c is a title for the button to be added to the + dialog box. After user selects the required operation by the + clicking the corresponding button in the dialog box, its identifier + is passed to the moduleActionSelected() method to process + the made choice. + + \return map of the operations + \sa moduleActionSelected() +*/ +QMap LightApp_Application::activateModuleActions() const +{ + QMap opmap; + opmap.insert( NewStudyId, tr( "ACTIVATE_MODULE_OP_NEW" ) ); + opmap.insert( OpenStudyId, tr( "ACTIVATE_MODULE_OP_OPEN" ) ); + return opmap; +} + +/*! + \brief Called when the used selectes required operation chosen + from "Activate module" dialog box. + + Performs the required operation according to the user choice. + + \param id operation identifier + \sa activateModuleActions() +*/ +void LightApp_Application::moduleActionSelected( const int id ) +{ + switch ( id ) { + case NewStudyId: + onNewDoc(); + break; + case OpenStudyId: + onOpenDoc(); + break; + default: + break; + } +} + +/*! + Updates windows after close document +*/ +void LightApp_Application::afterCloseDoc() +{ + updateWindows(); + + CAM_Application::afterCloseDoc(); +} + +/*! + Updates actions of active module +*/ +void LightApp_Application::updateModuleActions() +{ + QString modName; + if ( activeModule() ) { + modName = activeModule()->moduleName(); + if ( !isModuleAccessible( modName ) ) { + QList apps = SUIT_Session::session()->applications(); + foreach( SUIT_Application* app, apps ) { + LightApp_Application* lapp = dynamic_cast( app ); + if ( lapp && lapp != this ) + lapp->removeModuleAction( modName ); + } + } + } + + LightApp_ModuleAction* moduleAction = + qobject_cast( action( ModulesListId ) ); + if ( moduleAction ) + moduleAction->setActiveModule( modName ); +} + +void LightApp_Application::removeModuleAction( const QString& modName ) +{ + LightApp_ModuleAction* moduleAction = + qobject_cast( action( ModulesListId ) ); + if ( moduleAction ) + moduleAction->removeModule( modName ); +} + +/*! + Gets current windows. + \param winMap - output current windows map. +*/ +void LightApp_Application::currentWindows( QMap& winMap ) const +{ + winMap.clear(); + if ( !activeStudy() ) + return; + + if ( activeModule() && activeModule()->inherits( "LightApp_Module" ) ) + ((LightApp_Module*)activeModule())->windows( winMap ); + else + defaultWindows( winMap ); +} + +/*! + Gets current view managers. + \param lst - output current view managers list. +*/ +void LightApp_Application::currentViewManagers( QStringList& lst ) const { lst.clear(); if ( !activeStudy() ) @@ -1699,22 +3192,41 @@ void LightApp_Application::currentViewManagers( QStringList& lst ) const defaultViewManagers( lst ); } -/*!Update windows.*/ +/*! + Updates windows +*/ void LightApp_Application::updateWindows() { QMap winMap; currentWindows( winMap ); - for ( QMap::ConstIterator it = winMap.begin(); it != winMap.end(); ++it ) - getWindow( it.key() ); + if ( activeStudy() ) + { + for ( QMap::ConstIterator it = winMap.begin(); it != winMap.end(); ++it ) + { + if ( !dockWindow( it.key() ) ) + getWindow( it.key() ); + } + } - loadWindowsGeometry(); + for ( WinMap::ConstIterator it = myWin.begin(); it != myWin.end(); ++it ) + { + QWidget* wid = it.value(); + if ( activeStudy() ) + wid->setVisible( winMap.contains( it.key() ) ); + else + delete wid; + } - for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr ) - setWindowShown( itr.key(), !itr.data()->isEmpty() && winMap.contains( itr.key() ) ); + if ( activeStudy() ) + loadDockWindowsState(); + else + myWin.clear(); } -/*!Update view managers.*/ +/*! + Updates view managers +*/ void LightApp_Application::updateViewManagers() { QStringList lst; @@ -1724,65 +3236,211 @@ void LightApp_Application::updateViewManagers() getViewManager( *it, true ); } -/*!Load windows geometry.*/ -void LightApp_Application::loadWindowsGeometry() +/*! + Loads windows geometry +*/ +void LightApp_Application::loadDockWindowsState() { - QtxDockAction* dockMgr = 0; - - QAction* a = action( ViewWindowsId ); - if ( a && a->inherits( "QtxDockAction" ) ) - dockMgr = (QtxDockAction*)a; - - if ( !dockMgr ) + if ( !desktop() ) return; + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + bool storeWin = aResMgr->booleanValue( "Study", "store_positions", true ); + bool storeTb = aResMgr->booleanValue( "Study", "store_tool_positions", true ); QString modName; if ( activeModule() ) - modName = activeModule()->name(""); + modName = activeModule()->name(); + + QtxResourceMgr::WorkingMode prevMode = aResMgr->workingMode(); + aResMgr->setWorkingMode(QtxResourceMgr::IgnoreUserValues); + QByteArray aDefaultState; + aResMgr->value("windows_geometry", modName , aDefaultState ); + QByteArray aDefaultVisibility; + aResMgr->value("windows_visibility", modName , aDefaultVisibility ); + bool hasDefaultVisibility = !aDefaultVisibility.isEmpty(); + aResMgr->setWorkingMode(prevMode); + + if( !storeWin && !storeTb && aDefaultState.isEmpty() && !hasDefaultVisibility) + return; - QString section = QString( "windows_geometry" ); - if ( !modName.isEmpty() ) - section += QString( "." ) + modName; + if ( aResMgr->hasValue("windows_geometry" ,modName ) ) { + QByteArray arr; + aResMgr->value("windows_geometry", modName , arr ); + QByteArray aTargetArray = processState(arr, storeWin, storeTb, true, aDefaultState); + desktop()->restoreState( aTargetArray ); + } - dockMgr->loadGeometry( resourceMgr(), section, false ); - dockMgr->restoreGeometry(); + if ( !myWinVis.contains( modName ) && aDefaultVisibility.isEmpty()) + return; + + QMap *tbMap = 0; + QMap *dwMap = 0; + + QMap userTbMap, userDwMap; + dockWindowsState( myWinVis[modName], userTbMap, userDwMap ); + + QMap defaultTbMap, defaultDwMap; + if(hasDefaultVisibility) { + dockWindowsState( aDefaultVisibility, defaultTbMap, defaultDwMap); + } + + if(storeTb) { + tbMap = &userTbMap; + } else { + if(hasDefaultVisibility){ + tbMap = &defaultTbMap; + } + } + + if(storeWin) { + dwMap = &userDwMap; + } else { + if(hasDefaultVisibility){ + dwMap = &defaultDwMap; + } + } + + if(tbMap) { + QList tbList = findToolBars(); + for ( QList::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) + { + QToolBar* tb = *tit; + if ( tbMap->contains( tb->objectName() ) ) { + tb->setVisible( (*tbMap)[tb->objectName()] ); + } + } + } + + if(dwMap) { + QList dwList = qFindChildren( desktop() ); + for ( QList::iterator dit = dwList.begin(); dit != dwList.end(); ++dit ) + { + QDockWidget* dw = *dit; + + QObject* po = Qtx::findParent( dw, "QMainWindow" ); + if ( po != desktop() ) + continue; + + if ( dwMap->contains( dw->objectName() ) ) + dw->setVisible( (*dwMap)[dw->objectName()] ); + } + } } -/*!Save windows geometry.*/ -void LightApp_Application::saveWindowsGeometry() + +/*! + Saves windows geometry +*/ +void LightApp_Application::saveDockWindowsState() { - QtxDockAction* dockMgr = 0; + if ( !desktop() ) + return; - QAction* a = action( ViewWindowsId ); - if ( a && a->inherits( "QtxDockAction" ) ) - dockMgr = (QtxDockAction*)a; + bool storeWin = resourceMgr()->booleanValue( "Study", "store_positions", true ); + bool storeTb = resourceMgr()->booleanValue( "Study", "store_tool_positions", true ); - if ( !dockMgr ) + if( !storeWin && !storeTb ) return; QString modName; if ( activeModule() ) - modName = activeModule()->name(""); + modName = activeModule()->name(); + + QByteArray arr = desktop()->saveState(); + resourceMgr()->setValue( "windows_geometry", modName, processState(arr, storeWin, storeTb, false) ); + + QByteArray visArr; + if ( myWinVis.contains( modName ) ) + visArr = myWinVis[modName]; + + QMap tbMap, dwMap; + dockWindowsState( visArr, tbMap, dwMap ); + + QList tbList = qFindChildren( desktop() ); + for ( QList::iterator it = tbList.begin(); it != tbList.end(); ++it ) + { + QToolBar* tb = *it; + tbMap.insert( tb->objectName(), tb->toggleViewAction()->isChecked() ); + } + + QList dwList = qFindChildren( desktop() ); + for ( QList::iterator it = dwList.begin(); it != dwList.end(); ++it ) + { + QDockWidget* wid = *it; + dwMap.insert( wid->objectName(), wid->toggleViewAction()->isChecked() ); + } - QString section = QString( "windows_geometry" ); - if ( !modName.isEmpty() ) - section += QString( "." ) + modName; + visArr = dockWindowsState( tbMap, dwMap ); - dockMgr->storeGeometry(); - dockMgr->saveGeometry( resourceMgr(), section, false ); + myWinVis.insert( modName, visArr ); } -/*!Activate windows.*/ -void LightApp_Application::activateWindows() +QByteArray LightApp_Application::dockWindowsState( const QMap& tb, const QMap& dw ) const { - if ( activeStudy() ) + QByteArray visArr; + QDataStream stream( &visArr, QIODevice::WriteOnly ); + + stream << (uchar)ToolBarMarker; + stream << tb.size(); + for ( QMap::const_iterator tit = tb.begin(); tit != tb.end(); ++tit ) + { + stream << tit.key(); + stream << (uchar)( tit.value() ? 1 : 0 ); + } + + stream << (uchar)DockWidgetMarker; + stream << dw.size(); + for ( QMap::const_iterator wit = dw.begin(); wit != dw.end(); ++wit ) { - for ( WindowMap::Iterator itr = myWindows.begin(); itr != myWindows.end(); ++itr ) - itr.data()->activate( activeStudy()->id() ); + stream << wit.key(); + stream << (uchar)( wit.value() ? 1 : 0 ); } + + return visArr; } -/*!Adds icon names for modules.*/ +void LightApp_Application::dockWindowsState( const QByteArray& arr, QMap& tb, QMap& dw ) const +{ + tb.clear(); + dw.clear(); + + QByteArray visArr = arr; + QDataStream stream( &visArr, QIODevice::ReadOnly ); + + uchar marker; + stream >> marker; + if ( marker != ToolBarMarker ) + return; + + int lines; + stream >> lines; + for ( int i = 0; i < lines; ++i ) + { + QString objectName; + stream >> objectName; + uchar shown; + stream >> shown; + tb.insert( objectName, shown ); + } + + stream >> marker; + if ( marker != DockWidgetMarker ) + return; + + stream >> lines; + for ( int j = 0; j < lines; ++j ) + { + QString objectName; + stream >> objectName; + uchar shown; + stream >> shown; + dw.insert( objectName, shown ); + } +} + +/*! + Adds icon names for modules +*/ void LightApp_Application::moduleIconNames( QMap& iconMap ) const { iconMap.clear(); @@ -1798,7 +3456,7 @@ void LightApp_Application::moduleIconNames( QMap& iconMap ) co { QString modName = *it; QString modIntr = moduleName( modName ); - QString modIcon = resMgr->stringValue( modIntr, "icon", QString::null ); + QString modIcon = resMgr->stringValue( modIntr, "icon", QString() ); if ( modIcon.isEmpty() ) continue; @@ -1810,62 +3468,822 @@ void LightApp_Application::moduleIconNames( QMap& iconMap ) co } } -/*!Insert items in popup, which necessary for current application*/ -void LightApp_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title ) +/*! + Inserts items in popup, which necessary for current application +*/ +void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title ) { + //Add "Rename" item + LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr(); + bool cacheIsOn = selMgr->isSelectionCacheEnabled(); + selMgr->setSelectionCacheEnabled( true ); + + SUIT_DataBrowser* ob = objectBrowser(); + CAM_Application::contextMenuPopup( type, thePopup, title ); - OB_Browser* ob = objectBrowser(); - if ( !ob || type != ob->popupClientType() ) - return; + if ( ob && type == ob->popupClientType() ) { + thePopup->addSeparator(); + QAction* a = thePopup->addAction( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) ); + if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) ) + a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) ); + } + +#ifndef DISABLE_SALOMEOBJECT + if ( selMgr && ob ) { + SALOME_ListIO selected; + selMgr->selectedObjects( selected ); + if(selected.Extent() == 1){ + Handle(SALOME_InteractiveObject) anIObject = selected.First(); + SUIT_DataObject* obj = findObject(anIObject->getEntry()); + if(obj && obj->renameAllowed()) { + QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup); + connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) ); + if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ) + a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ); + + QList acts = thePopup->actions(); + QAction* firstAction = acts.count() > 0 ? acts.first() : 0; + thePopup->insertAction(firstAction,a); + } + } + } +#endif - thePopup->insertSeparator(); - thePopup->insertItem( tr( "MEN_REFRESH" ), this, SLOT( onRefresh() ) ); + selMgr->setSelectionCacheEnabled( cacheIsOn ); } -/*!Create empty study.*/ +/*! + Create empty study +*/ void LightApp_Application::createEmptyStudy() { CAM_Application::createEmptyStudy(); + if ( objectBrowser() ) objectBrowser()->updateTree(); + + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + if ( aResMgr && activeStudy() ) { + int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 ); + if ( autoSaveInterval > 0 ) myAutoSaveTimer->start( autoSaveInterval*60000 ); + } } -/*!Activate module \a mod.*/ +/*!Set desktop:*/ +void LightApp_Application::setDesktop( SUIT_Desktop* desk ) +{ + CAM_Application::setDesktop( desk ); + + if ( desk ) { + connect( desk, SIGNAL( message( const QString& ) ), + this, SLOT( onDesktopMessage( const QString& ) ), Qt::UniqueConnection ); + } +} + +/*! + Activates module + \param mod - module to be activated +*/ bool LightApp_Application::activateModule( CAM_Module* mod ) { bool res = CAM_Application::activateModule( mod ); + if ( objectBrowser() ) objectBrowser()->updateTree(); + return res; } -/*!return keyborad accelerators manager object */ +/*! + \return keyborad accelerators manager object +*/ SUIT_Accel* LightApp_Application::accel() const { return myAccel; } -/*! remove dead widget container from map */ +/*! + Removes dead widget container from map +*/ void LightApp_Application::onWCDestroyed( QObject* ob ) { // remove destroyed widget container from windows map - for ( WindowMap::ConstIterator itr = myWindows.begin(); itr != myWindows.end(); ++itr ) + for ( WinMap::ConstIterator itr = myWin.begin(); itr != myWin.end(); ++itr ) { - if ( itr.data() != ob ) + if ( itr.value() != ob ) continue; int key = itr.key(); - myWindows.remove( key ); + myWin.remove( key ); break; } } -/*! redefined to remove view manager from memory */ +void LightApp_Application::onMRUActivated( const QString& name ) +{ + SUIT_Session* s = SUIT_Session::session(); + if ( s && s->activeApplication() == this ) + onOpenDoc( name ); +} + +void LightApp_Application::onStylePreferences() +{ + Style_PrefDlg dlg( desktop() ); + dlg.exec(); + + resourceMgr()->setValue( "Style", "use_salome_style", Style_Salome::isActive() ); +} + +void LightApp_Application::onFullScreen(){ + if(myScreenHelper) { + if(desktop()->isFullScreen()) + myScreenHelper->switchToNormalScreen(); + else + myScreenHelper->switchToFullScreen(); + } +} + +/*! + Connects just added view manager +*/ +void LightApp_Application::addViewManager( SUIT_ViewManager* vm ) +{ + connect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ), + this, SLOT( onCloseView( SUIT_ViewManager* ) ) ); + CAM_Application::addViewManager( vm ); +} + +/*! + Remove view manager from memory +*/ void LightApp_Application::removeViewManager( SUIT_ViewManager* vm ) { disconnect( vm, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ), this, SLOT( onCloseView( SUIT_ViewManager* ) ) ); - STD_Application::removeViewManager( vm ); - delete vm; + LightApp_Study* aStudy = dynamic_cast(activeStudy()); + if (aStudy ) + aStudy->removeViewMgr(vm->getGlobalId()); + + CAM_Application::removeViewManager( vm ); + + LightApp_SelectionMgr* selMgr = selectionMgr(); + QList selectors; + selMgr->selectors( selectors ); + foreach( SUIT_Selector* selector, selectors ) { + if ( selector->owner() == vm->getViewModel() ) { + delete selector; + } + } + + // IPAL22894: Crash on closing OCC view + //delete vm; + vm->deleteLater(); +} + +/*! + Renames active window of desktop +*/ +void LightApp_Application::onRenameWindow() +{ + if( !desktop() ) + return; + + QWidget* w = desktop()->activeWindow(); + if( !w ) + return; + + bool ok; + QString name = QInputDialog::getText( w, tr( "TOT_RENAME" ), tr( "PRP_RENAME" ), QLineEdit::Normal, w->windowTitle(), &ok ); + if( ok && !name.isEmpty() ) + w->setWindowTitle( name ); +} + +/*! + Closes active window of desktop +*/ +void LightApp_Application::onCloseWindow() +{ + if( !desktop() ) + return; + + QWidget* w = desktop()->activeWindow(); + if( !w ) + return; + + w->close(); +} + +/*! + Closes all windows of desktop +*/ +void LightApp_Application::onCloseAllWindow() +{ + STD_TabDesktop* desk = dynamic_cast( desktop() ); + if( !desk ) + return; + + QList wndList = desk->windows(); + SUIT_ViewWindow* wnd; + foreach( wnd, wndList ) + { + if ( wnd ) + wnd->close(); + } +} + +/*! + Groups all windows of desktop +*/ +void LightApp_Application::onGroupAllWindow() +{ + STD_TabDesktop* desk = dynamic_cast( desktop() ); + if( !desk ) + return; + + QtxWorkstack* wgStack = desk->workstack(); + if ( wgStack ) + wgStack->stack(); +} + +/*! + \return if the library of module exists + \param moduleTitle - title of module +*/ +bool LightApp_Application::isLibExists( const QString& moduleTitle ) const +{ + if( moduleTitle.isEmpty() ) + return false; + + QString lib = moduleLibrary( moduleTitle ); + + //abd: changed libSalomePyQtGUI to SalomePyQtGUI for WIN32 + bool isPythonModule = lib.contains("SalomePyQtGUI"); + bool isPythonLightModule = lib.contains("SalomePyQtGUILight"); + + QStringList paths; +#ifdef WIN32 + paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts ); +#else + paths = QString(::getenv( "LD_LIBRARY_PATH" )).split( ":", QString::SkipEmptyParts ); +#endif + + bool isLibFound = false; + QStringList::const_iterator anIt = paths.begin(), aLast = paths.end(); + for( ; anIt!=aLast; anIt++ ) + { + QFileInfo inf( Qtx::addSlash( *anIt ) + lib ); + + if( inf.exists() ) + { + isLibFound = true; + break; + } + } + + if ( !isLibFound ) + { + INFOS( "\n****************************************************************" << std::endl + << "* Warning: library " << lib.toLatin1().constData() << " cannot be found" << std::endl + << "* Module " << moduleTitle.toLatin1().constData() << " will not be available in GUI mode" << std::endl + << "****************************************************************" << std::endl ); + } + else if ( !isPythonModule && !isPythonLightModule) + return true; + + if ( isPythonModule || isPythonLightModule) + { + QString pylib = moduleName( moduleTitle ) + QString(".py"); + QString pylibgui = moduleName( moduleTitle ) + QString("GUI.py"); + + // Check the python library +// #ifdef WIN32 +// paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts ); +// #else + paths = QString(::getenv( "PYTHONPATH" )).split( ":", QString::SkipEmptyParts ); +// #endif + bool isPyLib = false, isPyGuiLib = false; + QStringList::const_iterator anIt = paths.begin(), aLast = paths.end(); + for( ; anIt!=aLast; anIt++ ) + { + QFileInfo inf( Qtx::addSlash( *anIt ) + pylib ); + QFileInfo infgui( Qtx::addSlash( *anIt ) + pylibgui ); + + if(!isPythonLightModule) + if( !isPyLib && inf.exists() ) + isPyLib = true; + + if( !isPyGuiLib && infgui.exists() ) + isPyGuiLib = true; + + if ((isPyLib || isPythonLightModule ) && isPyGuiLib && isLibFound) + return true; + } + + printf( "\n****************************************************************\n" ); + printf( "* Warning: python library for %s cannot be found:\n", moduleTitle.toLatin1().constData() ); + if (!isPyLib) + printf( "* No module named %s\n", moduleName( moduleTitle ).toLatin1().constData() ); + if (!isPyGuiLib) + printf( "* No module named %s\n", (moduleName( moduleTitle ) + QString("GUI")).toLatin1().constData() ); + printf( "****************************************************************\n" ); + return true; + } + return false; +} + +/*! + \return default name for an active study +*/ +void LightApp_Application::setDefaultStudyName( const QString& theName ) +{ + QStringList anInfoList; + modules( anInfoList, false ); + + LightApp_Study* aStudy = (LightApp_Study*)activeStudy(); + if( anInfoList.count() == 1 && // to avoid a conflict between different modules + !aStudy->isSaved() ) + { + aStudy->setStudyName( theName ); + updateDesktopTitle(); + } +} + +/*! + Custom event handler +*/ +bool LightApp_Application::event( QEvent* e ) +{ + if( e && e->type()==2000 ) + { + SALOME_CustomEvent* ce = ( SALOME_CustomEvent* )e; + QString* d = ( QString* )ce->data(); + if( SUIT_MessageBox::question(0, tr("WRN_WARNING"), + d ? *d : "", + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) + showPreferences( tr( "PREF_APP" ) ); + if( d ) + delete d; + return true; + } + return CAM_Application::event( e ); +} + +/*! Check data object */ +bool LightApp_Application::checkDataObject(LightApp_DataObject* theObj) +{ + if (theObj) + { + bool isSuitable = !theObj->entry().isEmpty() && + !theObj->componentDataType().isEmpty() && + !theObj->name().isEmpty(); + return isSuitable; + } + + return false; +} + +int LightApp_Application::openChoice( const QString& aName ) +{ + int choice = CAM_Application::openChoice( aName ); + + if ( choice == OpenExist ) // The document is already open. + { + // Do you want to reload it? + if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYOPEN" ).arg( aName ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes ) + choice = OpenReload; + } + + return choice; +} + +bool LightApp_Application::openAction( const int choice, const QString& aName ) +{ + bool res = false; + switch ( choice ) + { + case OpenReload: + { + STD_Application* app = 0; + SUIT_Session* session = SUIT_Session::session(); + QList appList = session->applications(); + for ( QList::iterator it = appList.begin(); it != appList.end() && !app; ++it ) + { + if ( (*it)->activeStudy() && (*it)->activeStudy()->studyName() == aName ) + app = ::qobject_cast( *it ); + } + + if ( app ) + { + app->onCloseDoc( false ); + appList = session->applications(); + STD_Application* other = 0; + for ( QList::iterator it = appList.begin(); it != appList.end() && !other; ++it ) + other = ::qobject_cast( *it ); + + if ( other ) + res = other->onOpenDoc( aName ); + } + } + break; + default: + res = CAM_Application::openAction( choice, aName ); + break; + } + + return res; +} + +QStringList LightApp_Application::viewManagersTypes() const +{ + QStringList aTypesList; + aTypesList += myUserWmTypes; +#ifndef DISABLE_GLVIEWER + aTypesList< aMgrList; + viewManagers( aMgrList ); + foreach (SUIT_ViewManager* aMgr, aMgrList) { + if (aTypesList.contains(aMgr->getType())) + removeViewManager(aMgr); + } +} + +/*! + Copy of current selection + */ +void LightApp_Application::onCopy() +{ + LightApp_Module* m = dynamic_cast( activeModule() ); + if( m ) + m->copy(); +} + +/*! + Paste of current data in clipboard + */ +void LightApp_Application::onPaste() +{ + LightApp_Module* m = dynamic_cast( activeModule() ); + if( m ) + m->paste(); +} + +/*! + Browse (i.e. set focus on) the published objects + \param theIsApplyAndClose - flag indicating that the dialog for creating objects + has been accepted by Ok (or Apply & Close) button + \param theIsOptimizedBrowsing - flag switching to optimized browsing mode + (to select the first published object only) + \return entry of the selected object + */ +QString LightApp_Application::browseObjects( const QStringList& theEntryList, + const bool theIsApplyAndClose, + const bool theIsOptimizedBrowsing ) +{ + QString aResult; + if( SUIT_ResourceMgr* aResourceMgr = resourceMgr() ) + { + int aBrowsePolicy = aResourceMgr->integerValue( "ObjectBrowser", "browse_published_object", (int)BP_Never ); + switch( aBrowsePolicy ) + { + case BP_Never: + return aResult; + case BP_ApplyAndClose: + if( !theIsApplyAndClose ) + return aResult; + case BP_Always: + default: + break; + } + } + + LightApp_Study* aStudy = dynamic_cast( activeStudy() ); + if( !aStudy ) + return aResult; + + SUIT_DataBrowser* anOB = objectBrowser(); + if( !anOB ) + return aResult; + + SUIT_AbstractModel* aModel = dynamic_cast( anOB->model() ); + if( !aModel ) + return aResult; + + QStringListIterator anIter( theEntryList ); + if( theIsOptimizedBrowsing ) + { + // go to the last entry + anIter.toBack(); + if( anIter.hasPrevious() ) + anIter.previous(); + } + + // scroll to each entry in the list + // (in optimized mode - to the last entry only) + QString anEntry; + LightApp_DataObject* anObject = 0; + while( anIter.hasNext() ) + { + anEntry = anIter.next(); + if( !anEntry.isEmpty() ) + { + anObject = aStudy->findObjectByEntry( anEntry ); + if( anObject ) + { + QModelIndex anIndex = aModel->index( anObject ); + anOB->treeView()->scrollTo( anIndex ); + } + } + } + + // always select the last object + if( anObject && !anEntry.isEmpty() ) + { + QList aSelectorList; + selectionMgr()->selectors( "ObjectBrowser", aSelectorList ); + if( !aSelectorList.isEmpty() ) + { + if( LightApp_OBSelector* aSelector = dynamic_cast( aSelectorList.first() ) ) + { + bool anIsAutoBlock = aSelector->autoBlock(); + + // temporarily disable auto block, to emit LightApp_SelectionMgr::currentSelectionChanged() signal + aSelector->setAutoBlock( false ); + + SUIT_DataOwnerPtrList aList; +#ifndef DISABLE_SALOMEOBJECT + Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject + ( anObject->entry().toLatin1().constData(), + anObject->componentDataType().toLatin1().constData(), + anObject->name().toLatin1().constData() ); + LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj ); +#else + LightApp_DataOwner* owner = new LightApp_DataOwner( anEntry ); +#endif + + aList.append( owner ); + selectionMgr()->setSelected( aList ); + aResult = anEntry; + + // restore auto block flag + aSelector->setAutoBlock( anIsAutoBlock ); + } + } + } + + return aResult; +} + +SUIT_DataObject* LightApp_Application::findObject( const QString& id ) const +{ + LightApp_Study* study = dynamic_cast( activeStudy() ); + return study ? study->findObjectByEntry( id ) : 0; +} + +/*! + Checks that an object can be renamed. + \param entry entry of the object + \brief Return \c true if object can be renamed +*/ +bool LightApp_Application::renameAllowed( const QString& /*entry*/) const { + return false; +} + +/*! + Rename object by entry. + \param entry entry of the object + \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& ) { + return false; +} + +/*! Process standard messages from desktop */ +void LightApp_Application::onDesktopMessage( const QString& message ) +{ + const QString sectionSeparator = "/"; + + if ( message.toLower() == "updateobjectbrowser" || + message.toLower() == "updateobjbrowser" ) { + // update object browser + updateObjectBrowser(); + } + else { + QStringList data = message.split( sectionSeparator ); + if ( data.count() > 1 ) { + QString msgType = data[0].trimmed(); + LightApp_Module* sMod = 0; + CAM_Module* mod = module( msgType ); + if ( !mod ) + mod = module( moduleTitle( msgType ) ); + if ( mod && mod->inherits( "LightApp_Module" ) ) + sMod = (LightApp_Module*)mod; + + if ( msgType.toLower() == "preferences" ) { + // requested preferences change: should be given as "preferences/
//" + // for example "preferences/Study/multi_file_dump/true" + if ( data.count() > 3 ) { + QString section = data[1].trimmed(); + QString param = data[2].trimmed(); + QString value = QStringList( data.mid(3) ).join( sectionSeparator ); + resourceMgr()->setValue( section, param, value ); + } + } + else if ( sMod ) { + // received message for the module + QString msg = QStringList( data.mid(1) ).join( sectionSeparator ); + sMod->message( msg ); + } + } + } +} + +/*! + Internal method. + Returns all top level toolbars. + Note : Result list contains only main window toolbars, not including toolbars from viewers. +*/ +QList LightApp_Application::findToolBars() { + QList aResult; + QList tbList = qFindChildren( desktop() ); + for ( QList::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) { + QToolBar* tb = *tit; + QObject* po = Qtx::findParent( tb, "QMainWindow" ); + if ( po != desktop() ) + continue; + aResult.append(tb); + } + return aResult; +} + +/*! + Internal method to parse toolbars and dockable windows state. + */ +QByteArray LightApp_Application::processState(QByteArray& input, + const bool processWin, + const bool processTb, + const bool isRestoring, + QByteArray defaultState) { + + QByteArray aRes; + bool hasDefaultState = !defaultState.isEmpty(); + bool isDockWinWriten = false; + int nbDocWin = -1; + //Write date from users settings + if(isRestoring){ + QDataStream tmpInputData(&input, QIODevice::ReadOnly); + int marker, version; + uchar dockmarker; + tmpInputData >> marker; + tmpInputData >> version; + tmpInputData >> dockmarker; + tmpInputData >> nbDocWin; + } + if(processWin && processTb && !isRestoring) { + aRes = input; + } else if(!processWin && !processTb ) { + if(hasDefaultState) + aRes = defaultState; + } else { + QDataStream aData(&aRes, QIODevice::WriteOnly); + QList aToolBars = findToolBars(); + + QStringList aNames; + for ( QList::iterator tit = aToolBars.begin(); tit != aToolBars.end(); ++tit ) { + QToolBar* tb = *tit; + aNames.append(tb->objectName()); + } + + int toolBarMarkerIndex = getToolbarMarkerIndex(input,aNames); + QDataStream anInputData(&input, QIODevice::ReadOnly); + if(toolBarMarkerIndex < 0) + return aRes; + + int toolBarMarkerIndexDef; + if(hasDefaultState) { + toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames); + if(toolBarMarkerIndexDef < 0) + return aRes; + } + QDataStream anInputDataDef(&defaultState, QIODevice::ReadOnly); + + QDataStream* aTargetData = 0; + int aTargetIndex = -1; + + QByteArray currentArr = desktop()->saveState(); + QDataStream anInputDataCur(¤tArr, QIODevice::ReadOnly); + bool useInputData = !isRestoring || (isRestoring && nbDocWin > 0); + if(processWin && useInputData) { + aTargetData = &anInputData; + aTargetIndex = toolBarMarkerIndex; + } else { + //Write date from default settings + if(hasDefaultState) { + aTargetData = &anInputDataDef; + aTargetIndex = toolBarMarkerIndexDef; + } else { + //If no default state, write current snapshot of the dockable windows + if(isRestoring) { + aTargetData = &anInputDataCur; + int toolBarMarkerIndexCur = getToolbarMarkerIndex(currentArr, aNames); + aTargetIndex = toolBarMarkerIndexCur; + } + } + } + + if(aTargetData && aTargetIndex >= 0 ) { + aTargetData->device()->seek(0); + while( aTargetData->device()->pos() < aTargetIndex ) { + uchar ch; + *aTargetData >> ch; + aData<= 0) { + int index; + if(!isDockWinWriten ) { + //Write version marker + int marker, version; + aTargetData->device()->seek(0); + *aTargetData >> marker; + *aTargetData >> version; + aData << marker; + aData << version; + aData << (uchar) QDockWidgetMarker; + aData << (int) 0; + int shift = 4*sizeof(int) + sizeof(QSize); + index = aTargetIndex - shift; + } else { + index = aTargetIndex; + } + + aTargetData->device()->seek(index); + while(!aTargetData->atEnd()) { + uchar ch; + *aTargetData >> ch; + aData << ch; + } + } else { // Not treat toolbars + aData << (uchar) QToolBarMarker; + aData << (int) 0; //Nb toolbars = 0 + } + } + return aRes; +} + +/*! + \brief Emits operationFinished signal. + \param theModuleName the name of the module which perfomed the operation + \param theOperationName the operation name + \param theEntryList the list of the created objects entries +*/ +void LightApp_Application::emitOperationFinished( const QString& theModuleName, + const QString& theOperationName, + const QStringList& theEntryList ) +{ + emit operationFinished( theModuleName, theOperationName, theEntryList ); }