Salome HOME
Merge Python 3 porting.
authorrnv <rnv@opencascade.com>
Thu, 22 Jun 2017 14:32:06 +0000 (17:32 +0300)
committerrnv <rnv@opencascade.com>
Thu, 22 Jun 2017 14:32:06 +0000 (17:32 +0300)
114 files changed:
CMakeLists.txt
SalomeGUIConfig.cmake.in
doc/salome/gui/input/howtos_and_best_practives.doc
doc/salome/gui/input/text_user_interface.doc
doc/salome/gui/input/using_pluginsmanager.doc
doc/salome/gui/static/footer.html
doc/salome/tui/static/footer.html
src/CAM/CAM_Module.cxx
src/CAM/CAM_Study.cxx
src/GUI_PY/helper.py
src/GuiHelpers/SALOME_AppStudyEditor.cxx
src/GuiHelpers/SALOME_AppStudyEditor.hxx
src/GuiHelpers/SALOME_GuiServices.cxx
src/GuiHelpers/SALOME_GuiServices.hxx
src/GuiHelpers/StandardApp_Module.cxx
src/GuiHelpers/StandardApp_Module.hxx
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Application.h
src/LightApp/LightApp_Study.cxx
src/LightApp/resources/LightApp.xml
src/LightApp/resources/LightApp_msg_en.ts
src/LightApp/resources/LightApp_msg_fr.ts
src/LightApp/resources/LightApp_msg_ja.ts
src/OCCViewer/OCCViewer_ViewModel.cxx
src/OCCViewer/OCCViewer_ViewModel.h
src/OCCViewer/OCCViewer_ViewWindow.cxx
src/PyViewer/CMakeLists.txt
src/PyViewer/PyViewer_Settings.cxx
src/PyViewer/PyViewer_ViewWindow.cxx
src/PyViewer/PyViewer_ViewWindow.h
src/PyViewer/resources/PyViewer_images.ts
src/PyViewer/resources/PyViewer_msg_en.ts
src/PyViewer/resources/PyViewer_msg_fr.ts
src/PyViewer/resources/PyViewer_msg_ja.ts
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.h
src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx
src/SALOME_PYQT/SalomePyQt/SalomePyQt.h
src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip
src/SALOME_SWIG/SALOMEGUI_Swig.cxx
src/SALOME_SWIG/SALOMEGUI_Swig.hxx
src/SALOME_SWIG/SALOMEGUI_Swig.i
src/SALOME_SWIG/test_big_table.py
src/SALOME_SWIG/test_many_objects.py
src/SALOME_SWIG/test_table.py
src/SOCC/SOCC_ViewModel.cxx
src/SPlot2d/SPlot2d_ViewModel.cxx
src/STD/STD_Application.cxx
src/SUIT/SUIT_Application.cxx
src/SVTK/SVTK_ViewModel.cxx
src/SalomeApp/SalomeApp_Application.cxx
src/SalomeApp/SalomeApp_Application.h
src/SalomeApp/SalomeApp_DataModel.cxx
src/SalomeApp/SalomeApp_DataObject.cxx
src/SalomeApp/SalomeApp_DoubleSpinBox.cxx
src/SalomeApp/SalomeApp_Engine_i.cxx
src/SalomeApp/SalomeApp_Engine_i.h
src/SalomeApp/SalomeApp_IntSpinBox.cxx
src/SalomeApp/SalomeApp_NoteBook.cxx
src/SalomeApp/SalomeApp_NoteBook.h
src/SalomeApp/SalomeApp_PyInterp.cxx
src/SalomeApp/SalomeApp_Study.cxx
src/SalomeApp/SalomeApp_Study.h
src/SalomeApp/SalomeApp_StudyPropertiesDlg.cxx
src/SalomeApp/SalomeApp_StudyPropertiesDlg.h
src/SalomeApp/SalomeApp_TypeFilter.cxx
src/SalomeApp/pluginsdemo/minmax_plugin.py
src/SalomeApp/pluginsdemo/salome_plugins.py
src/SalomeApp/pluginsdemo/trihedron.py
src/SalomeApp/pluginsdemo/tubebuilder.py
src/SalomeApp/pluginsdemo/xalome.py
src/SalomeApp/resources/SalomeApp_msg_en.ts
src/SalomeApp/resources/SalomeApp_msg_fr.ts
src/SalomeApp/resources/SalomeApp_msg_ja.ts
src/SalomeApp/salome_pluginsmanager.py
src/Session/Session_ServerCheck.cxx
src/Session/Session_ServerThread.cxx
src/Session/Session_Session_i.cxx
src/Session/Session_Session_i.hxx
src/TOOLSGUI/CMakeLists.txt
src/TOOLSGUI/ToolsGUI.cxx
src/TOOLSGUI/ToolsGUI.h
tools/PyEditor/src/CMakeLists.txt
tools/PyEditor/src/PyEditor.cxx
tools/PyEditor/src/PyEditor_Completer.cxx [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Completer.h [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Editor.cxx
tools/PyEditor/src/PyEditor_Editor.h
tools/PyEditor/src/PyEditor_FindTool.cxx [new file with mode: 0644]
tools/PyEditor/src/PyEditor_FindTool.h [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Keywords.cxx [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Keywords.h [new file with mode: 0644]
tools/PyEditor/src/PyEditor_PyHighlighter.cxx
tools/PyEditor/src/PyEditor_PyHighlighter.h
tools/PyEditor/src/PyEditor_Settings.cxx
tools/PyEditor/src/PyEditor_Settings.h
tools/PyEditor/src/PyEditor_SettingsDlg.cxx
tools/PyEditor/src/PyEditor_SettingsDlg.h
tools/PyEditor/src/PyEditor_StdSettings.cxx
tools/PyEditor/src/PyEditor_Widget.cxx [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Widget.h [new file with mode: 0644]
tools/PyEditor/src/PyEditor_Window.cxx
tools/PyEditor/src/PyEditor_Window.h
tools/PyEditor/src/python/PyEditorPy.sip
tools/PyEditor/src/resources/PyEditor.qrc
tools/PyEditor/src/resources/about.txt
tools/PyEditor/src/resources/images/py_find.png [new file with mode: 0644]
tools/PyEditor/src/resources/images/py_find_next.png [new file with mode: 0644]
tools/PyEditor/src/resources/images/py_find_previous.png [new file with mode: 0644]
tools/PyEditor/src/resources/images/py_replace.png [new file with mode: 0644]
tools/PyEditor/src/resources/images/py_search.png [new file with mode: 0644]
tools/PyEditor/src/resources/translations/PyEditor_msg_en.ts
tools/PyEditor/src/resources/translations/PyEditor_msg_fr.ts
tools/PyEditor/src/resources/translations/PyEditor_msg_ja.ts

index 9a6313fb76cdb5427326e456555362135b5f4a2d..087ee04b91d480514bdc65e8d8dd4cd5e240f501 100755 (executable)
@@ -37,7 +37,7 @@ SET(${PROJECT_NAME_UC}_MINOR_VERSION 3)
 SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
-SET(${PROJECT_NAME_UC}_VERSION_DEV 0)
+SET(${PROJECT_NAME_UC}_VERSION_DEV 1)
 
 # Common CMake macros
 # ===================
@@ -89,12 +89,10 @@ OPTION(SALOME_USE_PVVIEWER "Enable ParaView visualization (Mandatory in classic
 
 CMAKE_DEPENDENT_OPTION(SALOME_USE_SALOMEOBJECT "Enable Salome Object (Mandatory in classic configurations)" ON
                        "SALOME_LIGHT_ONLY" ON)
-OPTION(SALOME_USE_SINGLE_DESKTOP "Enable multiple document interface" ON)
 
 MARK_AS_ADVANCED(SALOME_LIGHT_ONLY SALOME_USE_VTKVIEWER SALOME_USE_GRAPHICSVIEW SALOME_USE_PVVIEWER)
 MARK_AS_ADVANCED(SALOME_USE_SALOMEOBJECT SALOME_USE_OCCVIEWER SALOME_USE_GLVIEWER SALOME_USE_PLOT2DVIEWER)
 MARK_AS_ADVANCED(SALOME_USE_PYCONSOLE SALOME_USE_QXGRAPHVIEWER SALOME_USE_PYVIEWER)
-MARK_AS_ADVANCED(SALOME_USE_SINGLE_DESKTOP)
 
 # Prerequisites
 # =============
@@ -146,11 +144,6 @@ IF(SALOME_GUI_USE_OBSERVERS)
   ADD_DEFINITIONS(-DWITH_SALOMEDS_OBSERVER)
 ENDIF()
 
-# Single-study GUI
-IF(SALOME_USE_SINGLE_DESKTOP)
-  ADD_DEFINITIONS(-DSINGLE_DESKTOP)
-ENDIF()
-
 # OCCT
 FIND_PACKAGE(SalomeCAS REQUIRED)
 
index 74af926403192301270c2d3906ea3719b9d352fb..bcd7e3c247329d57e9720a2d67d0299b667f95aa 100644 (file)
@@ -63,16 +63,12 @@ SET(SALOME_USE_PVVIEWER       @SALOME_USE_PVVIEWER@)
 SET(SALOME_USE_PYVIEWER       @SALOME_USE_PYVIEWER@)
 SET(SALOME_USE_PYCONSOLE      @SALOME_USE_PYCONSOLE@)
 SET(SALOME_USE_SALOMEOBJECT   @SALOME_USE_SALOMEOBJECT@)
-SET(SALOME_USE_SINGLE_DESKTOP @SALOME_USE_SINGLE_DESKTOP@)
 SET(SALOME_GUI_USE_OBSERVERS  @SALOME_GUI_USE_OBSERVERS@)
 SET(SALOME_GUI_USE_OPENGL2    @SALOME_GUI_USE_OPENGL2@)
 
 IF(SALOME_GUI_LIGHT_ONLY)
   LIST(APPEND GUI_DEFINITIONS "-DGUI_DISABLE_CORBA")
 ENDIF() 
-IF(SALOME_USE_SINGLE_DESKTOP)
-  LIST(APPEND GUI_DEFINITIONS "-DSINGLE_DESKTOP")
-ENDIF()
 IF(SALOME_GUI_USE_OBSERVERS)
   LIST(APPEND GUI_DEFINITIONS "-DWITH_SALOMEDS_OBSERVER")
 ENDIF()
index e064bf28103208760d60d0a0a92a867fee842e19..bb32f91cb8bca6e486c4e68e33940148f1eee31f 100644 (file)
@@ -159,12 +159,12 @@ useCaseIter->UnRegister();
 useCaseBuilder->UnRegister();
 \endcode
 
-\section use_case_compatibility Remark about compatibility with existing studies
+\section use_case_compatibility Remark about compatibility with existing study
 
 If you decide to switch your module to the use case builder approach to provide
 customization for the data tree representation, you must take care of compatibility
 with existing SALOME studies. Basically it means that you have to add
-a simple code to  \c Load() (and \c LoadASCII() if necessary) method
+a simple code to  \c Load() method
 of your module, which adds tree node attributes to all data entities
 in the data tree of your module. The simplest way to do
 this is to iterate through all data items and recursively add them to
@@ -416,7 +416,7 @@ void MyModule::copyOrMove( const MYMODULE_ORB::object_list& what,
 {
   if ( CORBA::is_nil( where ) ) return; // bad parent
 
-  SALOMEDS::Study_var study = where->GetStudy();                               // study
+  SALOMEDS::Study_var study = GUI::getStudyServant();                          // study
   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();               // study builder
   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();    // use case builder
   SALOMEDS::SComponent_var father = where->GetFatherComponent();               // father component
index 5501c21ceb5489060f256edc548e49e867c866b4..0e9984bfa990f138c8e4e1f0eaf9b34b9d6b7f20 100644 (file)
@@ -12,10 +12,7 @@ console (since SWIG library is linked directly to the GUI library).
 The example of usage:
 \code
 # update Object browser contents
-salome.sg.updateObjBrowser(True)
-
-# get the active study ID
-studyId = salome.sg.getActiveStudyId() 
+salome.sg.updateObjBrowser()
 
 # get the active study name
 studyName = salome.sg.getActiveStudyName()
index bff116f05798a74618b601190418d2226e0f6218..71302d2bbdddf567d70841708fa9f3c50109026b 100644 (file)
@@ -100,7 +100,7 @@ training course):
 import salome
 import GEOM
 from salome.geom import geomBuilder
-geompy = geomBuilder.New(salome.myStudy)
+geompy = geomBuilder.New()
 
 # Create the objects
 Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
@@ -122,10 +122,10 @@ import salome_pluginsmanager
 def trihedron(context):
     import GEOM
     from salome.geom import geomBuilder
-    geompy = geomBuilder.New(salome.myStudy)
+    geompy = geomBuilder.New()
     # Intialize the geompy factory with the active study
     activeStudy = context.study
-    geompy.init_geom(activeStudy)
+    geompy.init_geom()
     # Create the objects
     Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
     Vy = geompy.MakeVectorDXDYDZ(0, 10, 0)
index 91afd6cc8ab252063767ab204030ae63dd6ee52b..7cf11feba01a088027958a2e4c7639c64f7adb19 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2007-2016  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+      Copyright &copy; 2007-2017  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
       Copyright &copy; 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS<br>
     </li>
   </ul>
index 91afd6cc8ab252063767ab204030ae63dd6ee52b..7cf11feba01a088027958a2e4c7639c64f7adb19 100755 (executable)
@@ -4,7 +4,7 @@
   <ul>
     $navpath
     <li class="footer">
-      Copyright &copy; 2007-2016  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
+      Copyright &copy; 2007-2017  CEA/DEN, EDF R&amp;D, OPEN CASCADE<br>
       Copyright &copy; 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS<br>
     </li>
   </ul>
index 6a8e49f3628e2d33e76c4d7c649c7ad2d534792a..b886d8f5520bfb725c01f3ab87adb7815a2308ee 100755 (executable)
@@ -1027,7 +1027,9 @@ int CAM_Module::registerAction( const int id, QAction* a )
   if ( toolMgr() )
     toolMgr()->registerAction( a );
 
-  if ( application() && application()->desktop() )
+  if ( application() && application()->desktop() &&
+       a->shortcutContext() != Qt::WidgetShortcut &&
+       a->shortcutContext() != Qt::WidgetWithChildrenShortcut )
     application()->desktop()->addAction( a );
 
   return ident;
index 91aff4c34fc4a7efbe3c89531400760d1b373da6..f252617cbe1acf87264967e749cf5dc735c26187 100755 (executable)
@@ -163,7 +163,7 @@ void CAM_Study::dataModelInserted( const CAM_DataModel* dModel )
 {
   CAM_DataModel* dm = (CAM_DataModel*)dModel;
 
-  if ( isSaved() ) // need to load data model from an exisitng file?
+  if ( isSaved() ) // need to load data model from an existing file?
     openDataModel( studyName(), dm );
   else // no, just need to update data model's connection to study tree 
        //(some application may want to show model's root in a study tree even if a model is empty)
index 670cc5ecbe74f54494fb672d45625f5e9545d4c6..890367e7c384372e8444d8fe51f2e7060ed77759 100644 (file)
@@ -53,23 +53,6 @@ sgPyQt=SalomePyQt.SalomePyQt()
 import libSALOME_Swig
 SalomeGUI = libSALOME_Swig.SALOMEGUI_Swig()
 
-#
-# ==================================================================
-# General helper function for GUI programming actions
-# ==================================================================
-# 
-# Get the active study
-#
-def getActiveStudy():
-    """
-    This returns a study object that corresponds to the active
-    study. The active study is a GUI concept: it's the study currently
-    active on the desktop.
-    """
-    studyId = sgPyQt.getStudyId()
-    study = services.getStudyManager().GetStudyByID( studyId )
-    return study
-
 #
 # ==================================================================
 # Functions to manipulate the objects in the browser (generic)
@@ -84,7 +67,7 @@ def getSObjectSelected():
     '''
     sobj = None
     entry = None
-    study = getActiveStudy()
+    study = salome.myStudy
     if SalomeGUI.SelectedCount() == 1:
         # We only considere the first element of the list. If you need
         # something else, create another function in your own context.
@@ -112,10 +95,10 @@ def deleteSObjectSelected():
     '''
     sobj, entry = getSObjectSelected()
     if ( sobj ):
-        study = getActiveStudy()
+        study = salome.myStudy
         builder = study.NewBuilder()
         builder.RemoveObject( sobj )
-        SalomeGUI.updateObjBrowser(True)
+        SalomeGUI.updateObjBrowser()
     pass
 
 #
@@ -130,7 +113,7 @@ def deleteSObjectSelected():
 
 #
 # Definitions:
-# - the SObject is an item in the active study (Study Object).
+# - the SObject is an item in the study (Study Object).
 # - the entry is the identifier of an item.
 # - the object (geom object or smesh object) is a CORBA servant
 #   embedded in the SALOME component container and with a reference in
index 1252bc431f766e0bc2a3ad0196ce92df172926cb..d024287ff59232fcfb7709b4e926dd5666b4f5e8 100644 (file)
@@ -20,6 +20,7 @@
 // Author: Guillaume Boulant (EDF/R&D)
 
 #include "SALOME_AppStudyEditor.hxx"
+#include "SALOME_GuiServices.hxx"
 
 #include <SalomeApp_Study.h>
 #include <SALOME_ListIO.hxx>
@@ -29,34 +30,12 @@ SALOME_AppStudyEditor::SALOME_AppStudyEditor(SalomeApp_Application * salomeApp)
   : SALOME_StudyEditor()
 {
   _salomeApp = salomeApp;
-  updateActiveStudy();
-}
-
-/**
- * This updates the editor with the current active study. If the
- * active study id is identical to the study id currently associated
- * to this object, then no update is performed.
- */
-int SALOME_AppStudyEditor::updateActiveStudy() {
-  int activeStudyId = SALOME_AppStudyEditor::getActiveStudyId(_salomeApp);
-  if ( activeStudyId != this->getStudyId() ) {
-    this->setStudyById(activeStudyId);
-  }
-  return activeStudyId;
-}
-
-// GUI context only
-int SALOME_AppStudyEditor::getActiveStudyId(SalomeApp_Application * salomeApp) {
-  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*> (salomeApp->activeStudy());
-  _PTR(Study) aCStudy = appStudy->studyDS();
-  int studyId = aCStudy->StudyId();
-  return studyId;
 }
 
 SALOMEDS::SObject_ptr SALOME_AppStudyEditor::IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject) {
   if (!iobject.IsNull()) {
     if (iobject->hasEntry()) {
-      SALOMEDS::SObject_var sobject = _study->FindObjectID(iobject->getEntry());
+      SALOMEDS::SObject_var sobject = GUI::getStudyServant()->FindObjectID(iobject->getEntry());
       return sobject._retn();
     }
   }
index 19ceb182cecaa6acd18f91a1acacf72c23357e94..804ad6df1711bcc307f1424d7ac8cc8af08d06a3 100644 (file)
 class SALOMEGUIHELPERS_EXPORT SALOME_AppStudyEditor: public SALOME_StudyEditor {
 public:
   SALOME_AppStudyEditor(SalomeApp_Application * salomeApp);
-  int updateActiveStudy();
   
   SALOMEDS::SObject_ptr IObjectToSObject(const Handle(SALOME_InteractiveObject)& iobject);
   SALOME_StudyEditor::SObjectList * getSelectedObjects();
 
-  static int getActiveStudyId(SalomeApp_Application * salomeApp);
-
 private:
   SalomeApp_Application * _salomeApp;
 
index 76d1dc0812aa422370a3c93542b8d3481394dbb3..59d77362e5612dc8028a498cd8780b54c8c5f00c 100644 (file)
@@ -68,31 +68,14 @@ namespace GUI {
   // SALOME application using the resourceMgr() method:
   // 
 
-  /**
-   * This returns the current active study id if an active study is
-   * defined in the SALOME session, returns -1 otherwise. Note that
-   * the active study doesn't make sense outside of the GUI SALOME
-   * process, i.e. the SALOME_SessionServer embedding the
-   * SalomeApp_Application.
-   */
-  int getActiveStudyId() {
-    SALOME::Session_var aSession = KERNEL::getSalomeSession();
-    if ( CORBA::is_nil(aSession) ) {
-      INFOS("ERR: can't request for active study because the session is NULL");
-      return -1;
-    }
-    return aSession->GetActiveStudyId();
-  }
-
   /**
    * This returns the current active study if an active study is
    * defined in the SALOME session, returns null otherwise.
    */
-  SALOMEDS::Study_ptr getActiveStudy() {
-    return KERNEL::getStudyById(getActiveStudyId());
+  SALOMEDS::Study_ptr getStudyServant() {
+    return SALOMEDS::Study::_duplicate(KERNEL::getStudyServant());
   }
 
-
   // __GBO__ Question: what is the difference between a
   // SALOMEDS::Study and a SalomeApp_Study?
   SalomeApp_Study* getSalomeAppActiveStudy() {
@@ -120,9 +103,7 @@ namespace GUI {
           // retrieve the SALOMEDS::Study servant first and the to
           // request this servant to get the SObject given its entry.
           //
-          _PTR(Study) studyClient = appStudy->studyDS();
-          SALOMEDS::Study_var study = KERNEL::getStudyManager()->GetStudyByID(studyClient->StudyId());
-          SALOMEDS::SObject_ptr sobject = study->FindObjectID(iobject->getEntry());
+          SALOMEDS::SObject_ptr sobject = KERNEL::getStudyServant()->FindObjectID(iobject->getEntry());
           return sobject;
         }
       }
index 73661bb988b34cb03f247f120b7512e92c0bc136..a7565ff9d2e45aa55d8de3fa7597f323a72c6d6e 100644 (file)
@@ -58,8 +58,7 @@ namespace GUI {
   // depends of the SALOME module technical choices). In general, on
   // of the attribute of a SObject is a CORBA servant that handles the
   // data to work with
-  SALOMEGUIHELPERS_EXPORT SALOMEDS::Study_ptr getActiveStudy();
-  SALOMEGUIHELPERS_EXPORT int                 getActiveStudyId();
+  SALOMEGUIHELPERS_EXPORT SALOMEDS::Study_ptr getStudyServant();
 
   // Another way to get the active study (to be converted in
   // SALOMEDS::Study):
index e969ed113f4c57b8a652cb5b4b696e4509c341de..051958daa3fb7e333336c939e3576384dfce6a01 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "StandardApp_Module.hxx"
 
+#include "SALOME_GuiServices.hxx"
+
 #include <SUIT_Desktop.h>
 #include <SUIT_Study.h>
 #include <SalomeApp_Application.h>
@@ -279,7 +281,7 @@ bool StandardApp_Module::activateModule( SUIT_Study* theStudy )
   setToolShown( true );
 
   if ( this->createStudyComponentAtActivation() ) {
-    this->createStudyComponent(theStudy);
+    this->createStudyComponent();
   }
 
   return bOk;
@@ -301,12 +303,9 @@ bool StandardApp_Module::createStudyComponentAtActivation() {
  * the module. This component is associated to the engine (return by
  * getEngine()) if the engine is a SALOMEDS::Driver.
  */
-void StandardApp_Module::createStudyComponent(SUIT_Study* theStudy) {
+void StandardApp_Module::createStudyComponent() {
 
-  SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
-  CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager");
-  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
-  SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id());
+  SALOMEDS::Study_var aDSStudy = GUI::getStudyServant();
 
   SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent(QCHARSTAR(moduleName()));
   if (aFather->_is_nil())
index 62dad7d0ed40abceeb4ada556b4769890672a2fa..acf1a4c19377378bea7493751267e02218366aa0 100644 (file)
@@ -103,7 +103,7 @@ protected:
   virtual void createModuleActions();
 
   /* Use this to create a root entry in the study for this module */
-  void createStudyComponent(SUIT_Study*);
+  void createStudyComponent();
   /* Implement this to say if study component entry should be created
      at activation step */
   virtual bool createStudyComponentAtActivation();
index 24c8f40ffd465c62eda29adc7b5da33f60e9c370..afda2bbefd6cf356435f613426f1a58b4d502a26 100644 (file)
@@ -230,8 +230,6 @@ 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.
@@ -295,14 +293,6 @@ namespace
   }
 }
 
-/*!
-  \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()
 {
@@ -454,6 +444,8 @@ void LightApp_Application::start()
   desktop()->statusBar()->showMessage( "" );
 
   LightApp_EventFilter::Init();
+
+  onNewDoc();
 }
 
 /*!Closeapplication.*/
@@ -932,10 +924,8 @@ void LightApp_Application::onNewWindow()
 */
 void LightApp_Application::onNewDoc()
 {
-#ifdef SINGLE_DESKTOP
   if ( !checkExistingDoc() )
     return;
-#endif
 
   //asl: fix for 0020515
   saveDockWindowsState();
@@ -950,10 +940,8 @@ void LightApp_Application::onOpenDoc()
 {
   SUIT_Study* study = activeStudy();
   
-#ifdef SINGLE_DESKTOP
   if ( !checkExistingDoc() )
     return;
-#endif
   
   CAM_Application::onOpenDoc();
   
@@ -970,10 +958,8 @@ void LightApp_Application::onOpenDoc()
 */
 bool LightApp_Application::onOpenDoc( const QString& aName )
 {
-#ifdef SINGLE_DESKTOP
   if ( !checkExistingDoc() )
     return false;
-#endif
 
   saveDockWindowsState();
 
@@ -1357,10 +1343,9 @@ void LightApp_Application::placeDockWindow( const int id, Qt::DockWidgetArea pla
 /*!
   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 )
+QWidget* LightApp_Application::getWindow( const int flag)
 {
   QWidget* wid = dockWindow( flag );
   if ( !wid )
@@ -1999,8 +1984,6 @@ void LightApp_Application::updateActions()
 */
 SUIT_Study* LightApp_Application::createNewStudy()
 {
-  LightApp_Application::lastStudyId++;
-
   LightApp_Study* aStudy = new LightApp_Study( this );
 
   // Set up processing of major study-related events
@@ -2932,6 +2915,20 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref )
   pref->addPreference( tr( "PREF_PY_LINE_NUMBS_AREA" ), pyDispGroup,
     LightApp_Preferences::Bool, "PyEditor", "LineNumberArea" );
   // ... "Display settings" group <<end>>
+
+  // ... "Editor settings" group <<start>>
+  int pyEditGroup = pref->addPreference( tr( "PREF_GROUP_PY_EDITOR" ), pyeditTab );
+  // ... -> navigation mode
+  int pyCompletion = pref->addPreference( tr( "PREF_PY_COMPLETION_MODE" ), pyEditGroup,
+                                          LightApp_Preferences::Selector, "PyEditor", "CompletionPolicy" );
+  aValuesList.clear();
+  anIndicesList.clear();
+  aValuesList   << tr("PREF_PY_NONE") << tr("PREF_PY_AUTO") << tr("PREF_PY_MANUAL") << tr("PREF_PY_ALWAYS");
+  anIndicesList << 0                  << 1                  << 2                    << 3                   ;
+  pref->setItemProperty( "strings", aValuesList, pyCompletion );
+  pref->setItemProperty( "indexes", anIndicesList, pyCompletion );
+  // ... "Editor settings" group <<end>>
+
   // ... "Tab settings" group <<start>>
   int pyTabGroup = pref->addPreference( tr( "PREF_GROUP_PY_TAB" ), pyeditTab );
   pref->setItemProperty( "columns", 2, pyTabGroup );
@@ -5133,19 +5130,20 @@ bool LightApp_Application::checkExistingDoc()
 {
   bool result = true;
   if( activeStudy() ) {
-    int answer = SUIT_MessageBox::question( desktop(),
-                                            tr( "APPCLOSE_CAPTION" ),
-                                            tr( "STUDYCLOSE_DESCRIPTION" ),
-                                            tr( "APPCLOSE_SAVE" ),
-                                            tr( "APPCLOSE_CLOSE" ),
-                                            tr( "APPCLOSE_CANCEL" ), 0 );
+    int answer = !activeStudy()->isModified() ? 1 :
+                 SUIT_MessageBox::question( desktop(),
+                                           tr( "APPCLOSE_CAPTION" ),
+                                           tr( "STUDYCLOSE_DESCRIPTION" ),
+                                           tr( "APPCLOSE_SAVE" ),
+                                           tr( "APPCLOSE_CLOSE" ),
+                                           tr( "APPCLOSE_CANCEL" ), 0 );
     if(answer == 0) {
       if ( activeStudy()->isSaved() ) {
         onSaveDoc();
         closeDoc( false );
       } else if ( onSaveAsDoc() ) {
-        if( !closeDoc( false ) ) {
-          result = false;
+         if( !closeDoc( false ) ) {
+           result = false;
         }
       } else {
         result = false;
index 4d26aef25136332b08dce9e20443b3e313f4af2a..767509dfe5925175675ce83f7366817b022bde52 100644 (file)
@@ -135,7 +135,7 @@ public:
   virtual SUIT_ViewManager*           createViewManager( const QString& vmType, QWidget* w );
   virtual SUIT_ViewManager*           createViewManager( SUIT_ViewModel* );
 
-  QWidget*                            getWindow( const int, const int = -1 );
+  QWidget*                            getWindow( const int );
   QWidget*                            dockWindow( const int ) const;
   void                                removeDockWindow( const int );
   void                                insertDockWindow( const int, QWidget* );
@@ -154,8 +154,6 @@ public:
 
   void                                setDefaultStudyName( const QString& theName );
 
-  static int                          studyId();
-
   virtual bool                        event( QEvent* );
 
   virtual bool                        checkDataObject( LightApp_DataObject* theObj );
@@ -248,7 +246,7 @@ protected slots:
   virtual void                        onWindowActivated( SUIT_ViewWindow* theViewWindow );
 
   void                                onNewWindow();
-  void                                onModuleActivation( const QString& );
+  virtual void                        onModuleActivation( const QString& );
   void                                onCloseView( SUIT_ViewManager* );
 
   virtual void                        onStudyCreated( SUIT_Study* );
@@ -341,7 +339,6 @@ protected:
 
   static LightApp_Preferences*        _prefs_;
 
-  static int                          lastStudyId;
   QStringList                         myUserWmTypes;
 };
 
index 9a3d5dfb7718f1dc48644eadbfb52149e626bbfe..debdb25b4d3eafdfdef8c7ac3f0c14a9955b7f0f 100644 (file)
@@ -60,8 +60,6 @@ LightApp_Study::~LightApp_Study()
 */
 bool LightApp_Study::createDocument( const QString& theStr )
 {
-  setStudyName( QString( "Study%1" ).arg( LightApp_Application::studyId() ) );
-
   // create myRoot
   setRoot( new LightApp_RootObject( this ) );
 
index ace4c880f822f02be8c06593a352322910866a24..3f74985a9951e75808b6eee8d134f1bc0598571d 100644 (file)
     <parameter name="TabSize"              value="4" />
     <parameter name="VerticalEdge"         value="true" />
     <parameter name="NumberColumns"        value="90" />
+    <parameter name="CompletionPolicy"     value="3" />
   </section>
   <section name="GUI" >
     <parameter name="documentation"     value="gui_help"/>
index 63fc8258bffca77cb055797600c87d3a9745002e..62c8b8d1e9cc00546f26dcd474485b65fe9c934e 100644 (file)
@@ -9,7 +9,7 @@
     </message>
     <message>
         <source>ABOUT_COPYRIGHT</source>
-        <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&amp;D, OPEN CASCADE
+        <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&amp;D, OPEN CASCADE
 
 Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
 CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translation>
@@ -56,15 +56,15 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
     </message>
     <message>
         <source>STUDYCLOSE_DESCRIPTION</source>
-        <translation>You already have an active study in your session. It has to be closed before working with another study.</translation>
+        <translation>The current study has unsaved changes. Would you like to save before closing it?</translation>
     </message>
     <message>
         <source>APPCLOSE_SAVE</source>
-        <translation>&amp;Save &amp;&amp; Close</translation>
+        <translation>&amp;Yes</translation>
     </message>
     <message>
         <source>APPCLOSE_CLOSE</source>
-        <translation>Close &amp;w/o saving</translation>
+        <translation>&amp;No</translation>
     </message>
     <message>
         <source>APPCLOSE_CANCEL</source>
@@ -1041,6 +1041,30 @@ File does not exist</translation>
     <source>PREF_PY_LINE_NUMBS_AREA</source>
     <translation>Display line numbers area</translation>
   </message>
+  <message>
+    <source>PREF_GROUP_PY_EDITOR</source>
+    <translation>Editor settings</translation>
+  </message>
+  <message>
+    <source>PREF_PY_COMPLETION_MODE</source>
+    <translation>Completion mode</translation>
+  </message>
+  <message>
+    <source>PREF_PY_NONE</source>
+    <translation>None</translation>
+  </message>
+  <message>
+    <source>PREF_PY_AUTO</source>
+    <translation>Auto</translation>
+  </message>
+  <message>
+    <source>PREF_PY_MANUAL</source>
+    <translation>Manual</translation>
+  </message>
+  <message>
+    <source>PREF_PY_ALWAYS</source>
+    <translation>Always</translation>
+  </message>
   <message>
     <source>PREF_GROUP_PY_TAB</source>
     <translation>Tab settings</translation>
index 88a208a03a216cbdb593050ae27206c0860dfb10..6cd92b3d473eea26202ebc7727a79e4d704d5a2b 100755 (executable)
@@ -9,7 +9,7 @@
     </message>
     <message>
         <source>ABOUT_COPYRIGHT</source>
-        <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&amp;D, OPEN CASCADE
+        <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&amp;D, OPEN CASCADE
 
 Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
 CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translation>
@@ -56,15 +56,15 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
     </message>
     <message>
         <source>STUDYCLOSE_DESCRIPTION</source>
-        <translation>Une étude est déjà ouverte. Elle doit être fermée avant d&apos;en ouvrir une autre.</translation>
+        <translation>Une étude a des modifications non enregistrées. Voulez-vous les sauvegarder avant de fermer?</translation>
     </message>
     <message>
         <source>APPCLOSE_SAVE</source>
-        <translation>&amp;Sauvegarder &amp;&amp; Fermer</translation>
+        <translation>&amp;Oui</translation>
     </message>
     <message>
         <source>APPCLOSE_CLOSE</source>
-        <translation>&amp;Fermer sans sauvegarder</translation>
+        <translation>&amp;Non</translation>
     </message>
     <message>
         <source>APPCLOSE_CANCEL</source>
@@ -1041,6 +1041,30 @@ Le fichier n&apos;existe pas</translation>
         <source>PREF_PY_LINE_NUMBS_AREA</source>
         <translation>Affiche les numéros de ligne</translation>
     </message>
+    <message>
+        <source>PREF_GROUP_PY_EDITOR</source>
+       <translation type="unfinished">Editor settings</translation>
+    </message>
+    <message>
+        <source>PREF_PY_COMPLETION_MODE</source>
+       <translation type="unfinished">Completion mode</translation>
+    </message>
+    <message>
+        <source>PREF_PY_NONE</source>
+       <translation type="unfinished">None</translation>
+    </message>
+    <message>
+        <source>PREF_PY_AUTO</source>
+       <translation type="unfinished">Auto</translation>
+    </message>
+    <message>
+        <source>PREF_PY_MANUAL</source>
+       <translation type="unfinished">Manual</translation>
+    </message>
+    <message>
+        <source>PREF_PY_ALWAYS</source>
+       <translation type="unfinished">Always</translation>
+    </message>
     <message>
         <source>PREF_GROUP_PY_TAB</source>
         <translation>Indentation</translation>
index b294bed045d46062e9b78cb4752e4e20c09993cb..21df7e3660dee743cc3f1f1fd547c192d42ffa2f 100644 (file)
@@ -9,7 +9,7 @@
     </message>
     <message>
       <source>ABOUT_COPYRIGHT</source>
-      <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&amp;D, OPEN CASCADE
+      <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&amp;D, OPEN CASCADE
 
 Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
 CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translation>
@@ -56,16 +56,15 @@ CEA/DEN, CEDRAT, EDF R&amp;D, LEG, PRINCIPIA R&amp;D, BUREAU VERITAS</translatio
     </message>
     <message>
       <source>STUDYCLOSE_DESCRIPTION</source>
-      <translation>既存のスタディを閉じる必要があります。閉じますか?
-</translation>
+      <translation type="unfinished">The current study has unsaved changes. Would you like to save before closing it?</translation>
     </message>
     <message>
       <source>APPCLOSE_SAVE</source>
-      <translation>保存して閉じる(&amp;S)</translation>
+      <translation>はい(&amp;Y)</translation>
     </message>
     <message>
       <source>APPCLOSE_CLOSE</source>
-      <translation>保存せずに閉じる(&amp;C)</translation>
+      <translation>いいえ(&amp;N)</translation>
     </message>
     <message>
       <source>APPCLOSE_CANCEL</source>
@@ -1040,6 +1039,30 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて
       <source>PREF_PY_LINE_NUMBS_AREA</source>
       <translation>ライン数エリアの表示</translation>
     </message>
+    <message>
+        <source>PREF_GROUP_PY_EDITOR</source>
+       <translation type="unfinished">Editor settings</translation>
+    </message>
+    <message>
+        <source>PREF_PY_COMPLETION_MODE</source>
+       <translation type="unfinished">Completion mode</translation>
+    </message>
+    <message>
+        <source>PREF_PY_NONE</source>
+       <translation type="unfinished">None</translation>
+    </message>
+    <message>
+        <source>PREF_PY_AUTO</source>
+       <translation type="unfinished">Auto</translation>
+    </message>
+    <message>
+        <source>PREF_PY_MANUAL</source>
+       <translation type="unfinished">Manual</translation>
+    </message>
+    <message>
+        <source>PREF_PY_ALWAYS</source>
+       <translation type="unfinished">Always</translation>
+    </message>
     <message>
       <source>PREF_GROUP_PY_TAB</source>
       <translation>設定タブ</translation>
index 3285f015edb5c3f80f7d8009e1102150c7fe6fbb..0b0ce6a972ce90068697e07fc09bdc8d91d5bb4a 100644 (file)
@@ -120,7 +120,8 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron)
   myIsRelative(true),
   myTopLayerId( 0 ),
   myTrihedronSize(100),
-  myClippingDlg (NULL)
+  myClippingDlg (NULL),
+  myIsUseLocalSelection(false)
 {
   // init CasCade viewers
   myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() );
@@ -454,7 +455,7 @@ void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEven
     break;
   case  Qt::Key_N:
     if ( isPreselectionEnabled() ) {
-      if ( getAISContext()->HasOpenedContext() )
+      if ( useLocalSelection() )
        getAISContext()->HilightNextDetected( aView->getViewPort()->getView() );
     }
     break;
@@ -1355,6 +1356,27 @@ OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow()
   return new OCCViewer_ViewWindow(0,  this);
 }
 
+/*!
+  Sets using local selection state
+  \param theIsUseLocalSelection - state
+*/
+void OCCViewer_Viewer::setUseLocalSelection(bool theIsUseLocalSelection)
+{
+  myIsUseLocalSelection = theIsUseLocalSelection;
+}
+
+/* 
+ * Returns true if local context is opened or view model local state is set
+ */
+bool OCCViewer_Viewer::useLocalSelection() const
+{
+  if (myIsUseLocalSelection)
+    return true;
+
+  Handle(AIS_InteractiveContext) ic = getAISContext();
+  return !ic.IsNull() && ic->HasOpenedContext();
+}
+
 // obsolete  
 QColor OCCViewer_Viewer::backgroundColor( int theViewId ) const
 {
index 63db7700b2b4dec9694189bbdc6a2f121da08fd1..329bb05bd9702c905daf3c8f9859078771af65a2 100755 (executable)
@@ -132,6 +132,9 @@ public:
 
   virtual OCCViewer_ViewWindow*   createSubWindow();
 
+  void                            setUseLocalSelection(bool theIsUseLocalSelection);
+  bool                            useLocalSelection() const;
+
 public:
   Handle(V3d_Viewer)              getViewer3d()    const { return myV3dViewer;}
   Handle(AIS_InteractiveContext)  getAISContext()  const { return myAISContext; }
@@ -279,7 +282,7 @@ protected:
   QString                         myClippingTexture;
   bool                            myTextureModulated;
   double                          myClippingTextureScale;
-
+  bool                            myIsUseLocalSelection;
 };
 
 #ifdef WIN32
index a4bce4220b4e3d0040794c9f2ae7b8446b4b8331..b7d38eab49be69f63253aab47394ac671d7f5760 100644 (file)
@@ -393,7 +393,7 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
 
         if ( aEvent->modifiers().testFlag(Qt::ControlModifier) ) {
           Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
-          if ( isPreselectionEnabled() && ic->HasOpenedContext() ) {
+          if ( isPreselectionEnabled() && myModel->useLocalSelection() ) {
             if ( aEvent->delta() > 0 ) {
               ic->HilightNextDetected( myViewPort->getView() );
             } else {
index bc4fbe352241854562a013b552301d359d78f50b..85bcc87ee1c72240ec0ab185f3a261d58270bc1b 100644 (file)
@@ -69,12 +69,14 @@ SET(_other_RESOURCES
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_copy.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_cut.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_delete.png
+  ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_find.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_help.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_new.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_open.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_paste.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_preferences.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_redo.png
+  ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_replace.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_save.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_save_as.png
   ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_select_all.png
index d86c8373e8779035e95592bb14fd33cfe14eb18a..90259e380abe6222cf90b6f2ba1a393566d95ee8 100644 (file)
@@ -50,6 +50,8 @@ void PyViewer_Settings::load()
   setTabSpaceVisible( myResMgr->booleanValue( group, option( snTabSpaceVisible ), tabSpaceVisible() ) );
   setTabSize( myResMgr->integerValue( group, option( snTabSize ), tabSize() ) );
   setFont( myResMgr->fontValue( group, option( snFont ), font() ) );
+  setCompletionPolicy( myResMgr->integerValue( group, option( snCompletionPolicy ),
+                                              completionPolicy() ) );
 }
 
 void PyViewer_Settings::save()
@@ -65,4 +67,5 @@ void PyViewer_Settings::save()
   myResMgr->setValue( group, option( snTabSpaceVisible ), tabSpaceVisible() );
   myResMgr->setValue( group, option( snTabSize ), tabSize() );
   myResMgr->setValue( group, option( snFont ), font() );
+  myResMgr->setValue( group, option( snCompletionPolicy ), completionPolicy() );
 }
index f7c37be7ef38db8dbe6a9ed786a4a63d812f0276..a9e6c79c2a040c9690c827ecd7595f818f9f0b92 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "PyViewer_ViewWindow.h"
 
-#include "PyEditor_Editor.h"
+#include "PyEditor_Widget.h"
 #include "PyEditor_SettingsDlg.h"
 
 #include "SUIT_Session.h"
 #include "QtxActionToolMgr.h"
 
 #include <QApplication>
+#include <QCloseEvent>
 #include <QFileDialog>
 #include <QMessageBox>
 #include <QTextStream>
+#include <QVBoxLayout>
 
 /*!
   \class PyViewer_ViewWindow
@@ -48,9 +50,9 @@
 PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
   SUIT_ViewWindow( desktop )
 {
-  // Create editor and set it as a central widget.
-  myTextEditor = new PyEditor_Editor( this );
-  setCentralWidget( myTextEditor );
+  // Create central widget.
+  myEditor = new PyEditor_Widget( this );
+  setCentralWidget( myEditor );
 
   // Create actions.
   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
@@ -82,7 +84,7 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
   action->setShortcut( QKeySequence::Save );
   connect( action, SIGNAL( triggered( bool ) ), this, SLOT( onSave() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ),
+  connect( myEditor, SIGNAL( modificationChanged( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, SaveId );
   
@@ -101,9 +103,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_UNDO" ), 0, this );
   action->setStatusTip( tr( "DSC_UNDO" ) );
   action->setShortcut( QKeySequence::Undo );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( undo() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( undo() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( undoAvailable( bool ) ),
+  connect( myEditor, SIGNAL( undoAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, UndoId );
 
@@ -113,9 +115,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_REDO" ), 0, this );
   action->setStatusTip( tr( "DSC_REDO" ) );
   action->setShortcut( QKeySequence::Redo );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( redo() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( redo() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( redoAvailable( bool ) ),
+  connect( myEditor, SIGNAL( redoAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, RedoId );
 
@@ -125,9 +127,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_CUT" ), 0, this );
   action->setStatusTip( tr( "DSC_CUT" ) );
   action->setShortcut( QKeySequence::Cut );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( cut() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( cut() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, CutId );
 
@@ -137,9 +139,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_COPY" ), 0, this );
   action->setStatusTip( tr( "DSC_COPY" ) );
   action->setShortcut( QKeySequence::Copy );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( copy() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, CopyId );
 
@@ -149,7 +151,7 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_PASTE" ), 0, this );
   action->setStatusTip( tr( "DSC_PASTE" ) );
   action->setShortcut( QKeySequence::Paste );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( paste() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
   toolMgr()->registerAction( action, PasteId );
 
   // . Delete
@@ -158,9 +160,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_DELETE" ), 0, this );
   action->setStatusTip( tr( "DSC_DELETE" ) );
   action->setShortcut( QKeySequence::Delete );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( deleteSelected() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( deleteSelected() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   toolMgr()->registerAction( action, DeleteId );
 
@@ -170,9 +172,29 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
                           tr( "ACT_SELECT_ALL" ), 0, this );
   action->setStatusTip( tr( "DSC_SELECT_ALL" ) );
   action->setShortcut( QKeySequence::SelectAll );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( selectAll() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
   toolMgr()->registerAction( action, SelectAllId );
 
+  // . Find
+  action = new QtxAction( tr( "TTP_FIND" ),
+                          resMgr->loadPixmap( "PyViewer", tr( "ICON_FIND" ) ),
+                          tr( "ACT_FIND" ), 0, this );
+  action->setStatusTip( tr( "DSC_FIND" ) );
+  action->setShortcut( QKeySequence::Find );
+  action->setShortcutContext( Qt::WidgetShortcut );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( find() ) );
+  toolMgr()->registerAction( action, FindId );
+
+  // . Replace
+  action = new QtxAction( tr( "TTP_REPLACE" ),
+                          resMgr->loadPixmap( "PyViewer", tr( "ICON_REPLACE" ) ),
+                          tr( "ACT_REPLACE" ), 0, this );
+  action->setStatusTip( tr( "DSC_REPLACE" ) );
+  action->setShortcut( QKeySequence::Replace );
+  action->setShortcutContext( Qt::WidgetShortcut );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) );
+  toolMgr()->registerAction( action, ReplaceId );
+
   // . Preferences
   action = new QtxAction( tr( "TTP_PREFERENCES" ),
                           resMgr->loadPixmap( "PyViewer", tr( "ICON_PREFERENCES" ) ),
@@ -205,6 +227,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) :
   toolMgr()->append( DeleteId, idTB );
   toolMgr()->append( SelectAllId, idTB );
   toolMgr()->append( toolMgr()->separator(), idTB );
+  toolMgr()->append( FindId, idTB );
+  toolMgr()->append( ReplaceId, idTB );
+  toolMgr()->append( toolMgr()->separator(), idTB );
   toolMgr()->append( PreferencesId, idTB );
   toolMgr()->append( toolMgr()->separator(), idTB );
   toolMgr()->append( HelpId, idTB );
@@ -239,7 +264,7 @@ void PyViewer_ViewWindow::onNew()
 {
   if ( whetherSave() )
   {
-    myTextEditor->clear();
+    myEditor->clear();
     setCurrentFile( QString() );
   }
 }
@@ -299,7 +324,7 @@ bool PyViewer_ViewWindow::onSaveAs()
 */
 void PyViewer_ViewWindow::onPreferences()
 {
-  PyEditor_SettingsDlg dlg( myTextEditor, true, this );
+  PyEditor_SettingsDlg dlg( myEditor->editor(), true, this );
   connect( &dlg, SIGNAL( help() ), this, SLOT( onHelp() ) );
   dlg.exec();
 }
@@ -311,7 +336,7 @@ void PyViewer_ViewWindow::onPreferences()
 void PyViewer_ViewWindow::setCurrentFile( const QString& filePath )
 {
   myURL = filePath;
-  myTextEditor->document()->setModified( false );
+  myEditor->setModified( false );
 }
 
 /*!
@@ -321,7 +346,7 @@ void PyViewer_ViewWindow::setCurrentFile( const QString& filePath )
 */
 bool PyViewer_ViewWindow::whetherSave()
 {
-  if ( myTextEditor->document()->isModified() )
+  if ( myEditor->isModified() )
   {
     QMessageBox::StandardButton answer =  QMessageBox::warning( this,
                                                                 tr( "NAME_PYEDITOR" ),
@@ -358,7 +383,7 @@ void PyViewer_ViewWindow::loadFile( const QString& filePath )
 
   QTextStream anInput( &aFile );
   QApplication::setOverrideCursor( Qt::WaitCursor );
-  myTextEditor->setPlainText( anInput.readAll() );
+  myEditor->setText( anInput.readAll() );
   QApplication::restoreOverrideCursor();
 
   setCurrentFile( filePath );
@@ -382,7 +407,7 @@ bool PyViewer_ViewWindow::saveFile( const QString& filePath )
 
   QTextStream anOutput( &aFile );
   QApplication::setOverrideCursor( Qt::WaitCursor );
-  anOutput << myTextEditor->toPlainText();
+  anOutput << myEditor->text();
   QApplication::restoreOverrideCursor();
 
   setCurrentFile( filePath );
index b96ea8b2c307f7000118566beb8ef4214f6936ac..229721d682a099edc3bed733e87b522d5661c1af 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <SUIT_ViewWindow.h>
 
-class PyEditor_Editor;
+class PyEditor_Widget;
 
 class PYVIEWER_EXPORT PyViewer_ViewWindow : public SUIT_ViewWindow
 {
@@ -36,6 +36,7 @@ class PYVIEWER_EXPORT PyViewer_ViewWindow : public SUIT_ViewWindow
 public:
   enum { NewId, OpenId, SaveId, SaveAsId,
          UndoId, RedoId, CutId, CopyId, PasteId, DeleteId, SelectAllId,
+         FindId, ReplaceId,
          PreferencesId, HelpId };
 
   PyViewer_ViewWindow( SUIT_Desktop* = 0 );
@@ -61,7 +62,7 @@ private:
   QString     defaultName() const;
 
 private:
-  PyEditor_Editor*  myTextEditor;
+  PyEditor_Widget*  myEditor;
   QString           myURL;
 };
 
index 639f1b5847dea025c6c58f91e7632765087ed098..6ac464e6c6cc25eabec3b4f499195a0a51e98a36 100644 (file)
         <source>ICON_SELECT_ALL</source>
         <translation>py_select_all.png</translation>
     </message>
+    <message>
+        <source>ICON_FIND</source>
+        <translation>py_find.png</translation>
+    </message>
+    <message>
+        <source>ICON_REPLACE</source>
+        <translation>py_replace.png</translation>
+    </message>
     <message>
         <source>ICON_PREFERENCES</source>
         <translation>py_preferences.png</translation>
index 0f4355ee35de0d23aea0a39317411a14a157fa0a..20e989a1a3299521100b800ec36d898702e52424 100644 (file)
       <source>DSC_SELECT_ALL</source>
       <translation>Select all the contents</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation>Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation>Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation>Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation>Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation>Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation>Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>Pre&amp;ferences</translation>
index c0fc973cd1417ceb345c47f9f241d585ccde4e21..7a52883c0318cccda83f0e597cddf8d777ef6a3a 100644 (file)
       <source>DSC_SELECT_ALL</source>
       <translation>Sélectionne tout le contenu</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation type="unfinished">Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation type="unfinished">Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation type="unfinished">Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>Préférences</translation>
index 6b8691da33a4be694cabaa9913f50bb2322e6cb1..35c4e054e10ce35cfbfb5cb8120e67775105a298 100644 (file)
       <source>DSC_SELECT_ALL</source>
       <translation>全選択</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation type="unfinished">Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation type="unfinished">Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation type="unfinished">Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>環境設定 (&amp;f)</translation>
index 459839a9b74c549636310023d832868e505a5644..4264610e4a729b1ce54f23a7ed61ff541cccfa14 100644 (file)
@@ -609,7 +609,6 @@ void PyModuleHelper::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu*
   SALOME GUI modules.
 */
 
-PyModuleHelper::InterpMap PyModuleHelper::myInterpMap;
 LightApp_Module*          PyModuleHelper::myInitModule = 0;
 
 /*!
@@ -1731,31 +1730,15 @@ QString PyModuleHelper::engineIOR() const
 /*!
   \brief Initialize python subinterpreter (one per study).
   \internal
-  \param studyId study ID
 */
-void PyModuleHelper::initInterp( int studyId )
+void PyModuleHelper::initInterp()
 {
   FuncMsg fmsg( "--- PyModuleHelper::initInterp()" );
 
-  // check study Id
-  if ( !studyId ) {
-    // Error! Study Id must not be 0!
-    myInterp = 0;
-    return;
-  }
-
   QMutexLocker ml( &myInitMutex );
 
-  // try to find the subinterpreter
-  if ( myInterpMap.contains( studyId ) ) {
-    // found!
-    myInterp = myInterpMap[ studyId ];
-    return;
-  }
-
   myInterp = new SALOME_PYQT_PyInterp();
   myInterp->initialize();
-  myInterpMap[ studyId ] = myInterp;
   
 #ifndef GUI_DISABLE_CORBA
   if ( !SUIT_PYTHON::initialized ) {
@@ -1772,7 +1755,7 @@ void PyModuleHelper::initInterp( int studyId )
     }
     // ... then call a method
     int embedded = 1;
-    PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"ii", studyId, embedded ) );
+    PyObjWrapper aRes( PyObject_CallMethod( aMod, (char*)"salome_init", (char*)"i", embedded ) );
     if ( !aRes ) {
       // Error!
       PyErr_Print();
@@ -1905,10 +1888,9 @@ void PyModuleHelper::internalInitialize( CAM_Application* app )
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( app->activeStudy() );
   if ( !aStudy )
     return;
-  int aStudyId = aStudy ? aStudy->id() : 0;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp )
     return; // Error
 
@@ -2006,10 +1988,11 @@ void PyModuleHelper::internalActivate( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp ) {
     myLastActivateStatus = false;
     return; // Error
@@ -2058,10 +2041,11 @@ void PyModuleHelper::internalCustomize( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( aStudyId );
+  initInterp();
   if ( !myInterp ) {
     myLastActivateStatus = false;
     return; // Error
@@ -2134,7 +2118,8 @@ void PyModuleHelper::internalClosedStudy( SUIT_Study* theStudy )
   // Get study Id
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
-  int aStudyId = aStudy ? aStudy->id() : 0;
+  if ( !aStudy )
+    return;
 
   // check that Python subinterpreter is initialized and Python module is imported
   if ( !myInterp || !myPyModule ) {
@@ -2143,7 +2128,7 @@ void PyModuleHelper::internalClosedStudy( SUIT_Study* theStudy )
   }
   // then call Python module's deactivate() method
   if ( PyObject_HasAttrString( myPyModule , (char*)"closeStudy" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"closeStudy", (char*)"i", aStudyId ) );
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"closeStudy", (char*)"i" ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -2202,12 +2187,11 @@ void PyModuleHelper::internalStudyChanged( SUIT_Study* study )
 
   // get study Id
   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( study );
-  int id = aStudy ? aStudy->id() : 0;
-
-  fmsg.message( QString( "study id = %1" ).arg( id ) );
+  if ( !aStudy )
+    return;
 
   // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
-  initInterp( id );
+  initInterp();
   if ( !myInterp )
     return; // Error
 
@@ -2224,7 +2208,7 @@ void PyModuleHelper::internalStudyChanged( SUIT_Study* study )
 
   // call Python module's activeStudyChanged() method
   if ( PyObject_HasAttrString( myPyModule, (char*)"activeStudyChanged" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"activeStudyChanged", (char*)"i", id ) );
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"activeStudyChanged", (char*)"i" ) );
     if( !res ) {
       PyErr_Print();
     }
index e25fc9ab00a61f9445a7978a52568e5f53bf995b..c4d1ca9fec257779c4ba153f7ae08079ca289c40 100644 (file)
@@ -54,9 +54,6 @@ private:
   class XmlHandler;
   class InitLocker;
 
-  typedef QMap<int, PyInterp_Interp*> InterpMap;
-
-  static InterpMap           myInterpMap;          //!< study to Python subinterpreter map
   static LightApp_Module*    myInitModule;         //!< Python GUI being initialized (not zero only during the initialization)
 
   LightApp_Module*           myModule;             //!< GUI module
@@ -110,7 +107,7 @@ public slots:
   void                       onObjectBrowserClicked(SUIT_DataObject*, int);
 
 private:
-  void                       initInterp( int );
+  void                       initInterp();
   void                       importModule();
   void                       setWorkSpace();
 
index 4748bde6982715b6c778880625545e9b1a41ccf9..aea4aa2d5f8cfb7bf1ed395bdc04177df7197937 100644 (file)
 #include <QApplication>
 #include <QPaintEvent>
 #include <QCoreApplication>
+#include <QVBoxLayout>
 
 #include <utilities.h>
+
 namespace
 {
   /*!
@@ -329,6 +331,90 @@ void SALOME_Selection::ClearFilters()
   ProcessVoidEvent( new TEvent( mySelMgr ) );
 }
 
+/*!
+  \class UserDefinedContent
+  \brief The class represents base class for user defined widget that
+  can be inserted to the Preferences dialog.
+*/
+
+/*!
+  \brief Constructor
+*/
+UserDefinedContent::UserDefinedContent()
+  : QWidget()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+*/
+void UserDefinedContent::store()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+*/
+void UserDefinedContent::retrieve()
+{
+}
+
+/*!
+  \class SgPyQtUserDefinedContent
+  \brief A Wrapper for UserDefinedContent class.
+  \internal
+*/
+class SgPyQtUserDefinedContent: public QtxUserDefinedContent
+{
+public:
+  SgPyQtUserDefinedContent(UserDefinedContent*);
+  virtual ~SgPyQtUserDefinedContent();
+
+  void store( QtxResourceMgr*, QtxPreferenceMgr* );
+  void retrieve( QtxResourceMgr*, QtxPreferenceMgr* );
+
+private:
+  UserDefinedContent* myContent;
+};
+
+/*!
+  \brief Create custom item for Preferences dialog wrapping widget passed from Python.
+  \internal
+*/
+SgPyQtUserDefinedContent::SgPyQtUserDefinedContent(UserDefinedContent* content)
+  : QtxUserDefinedContent( 0 ), myContent( content )
+{
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setContentsMargins( 0, 0, 0, 0 );
+  l->addWidget( myContent );
+}
+
+/*!
+  \brief Destructor.
+  \internal
+*/
+SgPyQtUserDefinedContent::~SgPyQtUserDefinedContent()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::store( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->store();
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::retrieve( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->retrieve();
+}
+
 /*!
   \class SalomePyQt
   \brief The class provides utility functions which can be used in the Python
@@ -512,30 +598,6 @@ QTreeView* SalomePyQt::getObjectBrowser()
   return ProcessEvent( new TGetObjectBrowserEvent() );
 }
 
-/*!
-  \fn int SalomePyQt::getStudyId();
-  \brief Get active study's identifier.
-  \return active study ID or 0 if there is no active study
-*/
-
-class TGetStudyIdEvent: public SALOME_Event
-{
-public:
-  typedef int TResult;
-  TResult myResult;
-  TGetStudyIdEvent() : myResult( 0 ) {}
-  virtual void Execute()
-  {
-    if ( LightApp_Study* aStudy = getActiveStudy() ) {
-      myResult = aStudy->id();
-    }
-  }
-};
-int SalomePyQt::getStudyId()
-{
-  return ProcessEvent( new TGetStudyIdEvent() );
-}
-
 /*!
   \fn SALOME_Selection* SalomePyQt::getSelection();
   \brief Get the selection object for the current study.
@@ -738,37 +800,23 @@ bool SalomePyQt::activateModule( const QString& modName )
 }
 
 /*!
-  \brief Update an Object Browser of the specified (by identifier) study.
-
-  If \a studyId <= 0 the active study's object browser is updated.
-  The \a updateSelection parameter is obsolete and currently is not used. 
-  This parameter will be removed in future, so try to avoid its usage in 
-  your code.
-
-  \brief studyId study identifier
-  \brief updateSelection update selection flag (not used)
-  \sa getActiveStudy()
+  \brief Update an Object Browser of the study.
 */
-void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
+void SalomePyQt::updateObjBrowser()
 {  
   class TEvent: public SALOME_Event
   {
-    int  myStudyId;
-    bool myUpdateSelection;
   public:
-    TEvent( const int studyId, bool updateSelection ) 
-      : myStudyId( studyId ), myUpdateSelection( updateSelection ) {}
+    TEvent() {}
     virtual void Execute()
     {
       if ( SUIT_Session::session() ) {
-        if ( getActiveStudy() && myStudyId <= 0 )
-          myStudyId = getActiveStudy()->id();
-        if ( myStudyId > 0 ) {
+        if ( getActiveStudy() ) {
           QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
           QList<SUIT_Application*>::Iterator it;
           for( it = apps.begin(); it != apps.end(); ++it ) {
             LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
-            if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId ) {
+            if ( anApp && anApp->activeStudy() ) {
               anApp->updateObjectBrowser();
               return;
             }
@@ -777,7 +825,7 @@ void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
       }
     }
   };
-  ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
+  ProcessVoidEvent( new TEvent() );
 }
 
 
@@ -2440,7 +2488,39 @@ void SalomePyQt::setPreferenceProperty( const int id,
       }
     }
   };
-  ProcessVoidEvent( new TEvent( id, prop, var) );
+  ProcessVoidEvent( new TEvent( id, prop, var ) );
+}
+
+/*!
+  \brief Set specific widget as a custom preferences item.
+  \param id preferences identifier
+  \param prop preferences property name
+  \param widget custom widget
+*/
+void SalomePyQt::setPreferencePropertyWg( const int id, 
+                                          const QString& prop,
+                                          UserDefinedContent* widget )
+{
+  class TEvent: public SALOME_Event
+  {
+    int      myId;
+    QString  myProp;
+    UserDefinedContent* myWidget;
+  public:
+    TEvent( const int id, const QString& prop, UserDefinedContent* widget ) 
+      : myId( id ), myProp( prop ), myWidget( widget ) {}
+    virtual void Execute() 
+    {
+      LightApp_Module* module = getActiveModule();
+      if ( module ) {
+       LightApp_Preferences* pref = module->getApp()->preferences();
+       if ( pref ) {
+         pref->setItemProperty( myProp, (qint64) new SgPyQtUserDefinedContent( myWidget ), myId );
+        }
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, prop, widget ) );
 }
 
 /*!
index d31a8600fcee4365ef0f0ff845b9534a6afbb556..8b749800e43e65a1c97403608efa0bcdd9f4c55b 100644 (file)
@@ -114,6 +114,23 @@ enum {
   PT_Font     = LightApp_Preferences::Font, 
   PT_DirList  = LightApp_Preferences::DirList, 
   PT_File     = LightApp_Preferences::File, 
+  PT_Slider       = LightApp_Preferences::Slider, 
+  PT_Shortcut     = LightApp_Preferences::Shortcut, 
+  PT_ShortcutTree = LightApp_Preferences::ShortcutTree, 
+  PT_BiColor      = LightApp_Preferences::BiColor, 
+  PT_Background   = LightApp_Preferences::Background, 
+  PT_UserDefined  = LightApp_Preferences::UserDefined, 
+};
+
+class UserDefinedContent: public QWidget
+{
+  Q_OBJECT
+
+public:
+  explicit UserDefinedContent();
+
+  virtual void store();
+  virtual void retrieve();
 };
 
 //! Orientation
@@ -172,12 +189,11 @@ public:
   static void              disableSelector();
   static SALOME_Selection* getSelection();
   static void              setSelection( const QStringList& );
-  static int               getStudyId();
   static void              putInfo( const QString&, const int = 0 );
   static const QString     getActiveComponent();
   static PyObject*         getActivePythonModule();
   static bool              activateModule( const QString& );
-  static void              updateObjBrowser( const int = 0, bool = true );
+  static void              updateObjBrowser();
 
   static bool              isModified();
   static void              setModified( bool );
@@ -277,6 +293,7 @@ public:
                                           const QString& = QString() );
   static QVariant          preferenceProperty( const int, const QString& );
   static void              setPreferenceProperty( const int, const QString&, const QVariant& );
+  static void              setPreferencePropertyWg( const int, const QString&, UserDefinedContent* );
   static void              addPreferenceProperty( const int, const QString&, const int, const QVariant& );
 
   static void              message( const QString&, bool = true );
index 59309bcfdb0481a4edcd55f08717c6f53a83b678..a80a8403a63f65db4e7b63bd989b01e263f028e6 100644 (file)
@@ -102,6 +102,12 @@ enum PrefType {
   PT_Font, 
   PT_DirList, 
   PT_File, 
+  PT_Slider,
+  PT_Shortcut,
+  PT_ShortcutTree,
+  PT_BiColor,
+  PT_Background,
+  PT_UserDefined
 };
 
 enum Orientation {
@@ -237,6 +243,26 @@ private:
   QtxTreeView( const QtxTreeView& );
 };
 
+class UserDefinedContent : public QWidget
+{
+%TypeHeaderCode
+#include <SalomePyQt.h>
+%End
+
+%ConvertToSubClassCode
+    if ( qobject_cast<UserDefinedContent*>( sipCpp ) )
+      sipClass = sipClass_UserDefinedContent;
+    else
+      sipClass = NULL;
+%End
+
+public:
+  explicit UserDefinedContent();
+
+  virtual void store();
+  virtual void retrieve();
+};
+
 enum VisibilityState 
 {
   ShownState,
@@ -273,13 +299,11 @@ public:
   static void              enableSelector() /ReleaseGIL/ ;
   static void              disableSelector() /ReleaseGIL/ ;
   static SALOME_Selection* getSelection() /Factory,ReleaseGIL/ ;
-  static void              setSelection( const QStringList& ) /ReleaseGIL/ ;
-  static int               getStudyId() /ReleaseGIL/ ;
   static void              putInfo( const QString&, const int = 0 ) /ReleaseGIL/ ;
   static const QString     getActiveComponent() /ReleaseGIL/ ;
   static SIP_PYOBJECT      getActivePythonModule() /ReleaseGIL/ ;
   static bool              activateModule( const QString& ) /ReleaseGIL/ ;
-  static void              updateObjBrowser( const int = 0, bool =  true ) /ReleaseGIL/ ;
+  static void              updateObjBrowser() /ReleaseGIL/ ;
   
   static bool              isModified() /ReleaseGIL/ ;
   static void              setModified( bool ) /ReleaseGIL/ ;
@@ -391,6 +415,9 @@ public:
   static void              setPreferenceProperty( const int, 
                                                   const QString&,
                                                   const QVariant& ) /ReleaseGIL/ ;
+  static void              setPreferencePropertyWg( const int, 
+                                                    const QString&,    
+                                                    UserDefinedContent* ) /ReleaseGIL/ ;
   static void              addPreferenceProperty( const int, 
                                                   const QString&, 
                                                  const int, 
index bcd1e54adb8368ae41521dcacf05f8860f04e6da..184ad8f6316dcb82c72326e2b5747bf75db6e38b 100644 (file)
@@ -71,7 +71,7 @@
   This module provides an access to the SALOME GUI implementing set of functions
   which can be used from Python. This module is implemented using SWIG wrappings
   for some GUI functionality:
-  - getActiveStudyId(), getActiveStudyName() : get active study identifier and name
+  - getActiveStudyName() : get active study name
   - updateObjBrowser() : update contents of the Object Browser
   - SelectedCount() : get number of currently selected items
   - getSelected() : get entry of the speicified selected item
@@ -173,9 +173,8 @@ bool SALOMEGUI_Swig::hasDesktop()
 
 /*!
   \brief Update active study's Object Browser.
-  \param updateSelection this parameter is obsolete
 */
-void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
+void SALOMEGUI_Swig::updateObjBrowser()
 {
   class TEvent: public SALOME_Event
   {
@@ -192,30 +191,6 @@ void SALOMEGUI_Swig::updateObjBrowser( bool /*updateSelection*/ )
   ProcessVoidEvent( new TEvent() );
 }
 
-/*!
-  \fn int SALOMEGUI_Swig::getActiveStudyId()
-  \brief Get active study identifier
-  \return active study's ID or 0 if there is no active study
-*/
-
-class TGetActiveStudyIdEvent: public SALOME_Event
-{
-public:
-  typedef int TResult;
-  TResult myResult;
-  TGetActiveStudyIdEvent() : myResult( 0 ) {}
-  virtual void Execute()
-  {
-    if ( LightApp_Study* aStudy = getActiveStudy() ) {
-      myResult = aStudy->id();
-    }
-  }
-};
-int SALOMEGUI_Swig::getActiveStudyId()
-{
-  return ProcessEvent( new TGetActiveStudyIdEvent() );
-}
-
 /*!
   \fn const char* SALOMEGUI_Swig::getActiveStudyName()
   \brief Get active study name
index 6b537c8c993d36ee9c9441d80f5dbcb673947504..f5d2227ee3e886f44115e3231db1d1bf8559544a 100644 (file)
@@ -35,9 +35,8 @@ public:
 
   bool             hasDesktop();
 
-  void             updateObjBrowser( bool );
+  void             updateObjBrowser();
 
-  int              getActiveStudyId();
   const char*      getActiveStudyName();
 
   const char*      getComponentName( const char* );
index 10631d8810232ab643ce9b2dd737a515e7924bd2..c77f14a6ae476cb928fd41f974bacd5442078bb1 100644 (file)
@@ -57,10 +57,9 @@ public:
   bool hasDesktop();
 
   /* update object browser*/
-  void updateObjBrowser(bool);
+  void updateObjBrowser();
 
   /* get active study */
-  int getActiveStudyId();
   const char *getActiveStudyName();
 
   /* get component name/username */
index 73a881a10e21221f039f427b3e0bf8e225674c1a..a2b032fd8621d93cea342266098910905502504d 100755 (executable)
@@ -66,6 +66,6 @@ for i in range(1,myVerNb+1):
 ARealTable.SetTitle("Very useful data")
 
 # >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
 
 # ============================================================================
index 94df01f83fdc9e7ddd60f72873c791b7590fb9f8..42897dace99d7e9d89522de7c07a11a3334071c1 100755 (executable)
@@ -84,7 +84,7 @@ for i in range(0,myNb1):
                 myBuilder.Addreference(myRefObject,myObject3);
 
 # >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
 
 # ============================================================================
 
index 21b934e9e47afaf361a659aea897edd8607fe984..812b21e47327882c71add2835798f5617e89f89c 100755 (executable)
@@ -109,7 +109,7 @@ ACmt = myBuilder.FindOrCreateAttribute(myCmtObject, "AttributeComment")
 ACmt.SetValue("Just a comment")
 
 # >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
 
 # ============================================================================
 
index 03825c7a4e84f665ad3847cdc24192f498152445..3981d50cb38a676e4053c042453ff10450085f09 100755 (executable)
 #include <SALOME_InteractiveObject.hxx>
 #include <SALOME_ListIO.hxx>
 
-// Temporarily commented to avoid awful dependecy on SALOMEDS
-// TODO: better mechanism of storing display/erse status in a study
-// should be provided...
-//#include <Utils_ORB_INIT.hxx>
-//#include <Utils_SINGLETON.hxx>
-//#include <SALOME_ModuleCatalog_impl.hxx>
-//#include <SALOME_NamingService.hxx>
-
-//#include "SALOMEDSClient.hxx"
-//#include "SALOMEDS_StudyManager.hxx"
-
 #include <AIS_TypeOfIso.hxx>
 #include <Precision.hxx>
 
 #include <algorithm>
 
-// in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
-// SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from 
-// SALOMEDS::StudyManager - no linkage with SalomeApp. 
-
-// Temporarily commented to avoid awful dependecy on SALOMEDS
-// TODO: better mechanism of storing display/erse status in a study
-// should be provided...
-//static _PTR(Study) getStudyDS() 
-//{
-//  SALOMEDSClient_Study* aStudy = NULL;
-//  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
-
-  // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
-  //    id of its underlying SALOMEDS::Study
-//  SUIT_Application* app = SUIT_Session::session()->activeApplication();
-//  if ( !app )  return _PTR(Study)(aStudy);
-//  SUIT_Study* stud = app->activeStudy();
-//  if ( !stud ) return _PTR(Study)(aStudy);  
-//  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
-  // get SALOMEDS_Study with this id from StudyMgr
-//  return aMgr->GetStudyByID( id );
-//}
-
 /*!
   Constructor
   \param DisplayTrihedron - is trihedron displayed
@@ -320,12 +286,6 @@ void SOCC_Viewer::Display( const SALOME_OCCPrs* prs )
   if ( !anOCCPrs || anOCCPrs->IsNull() )
     return;
 
-  // get SALOMEDS Study
-  // Temporarily commented to avoid awful dependecy on SALOMEDS
-  // TODO: better mechanism of storing display/erse status in a study
-  // should be provided...
-  //  _PTR(Study) study(getStudyDS());
-
   // get context
   Handle (AIS_InteractiveContext) ic = getAISContext();
 
@@ -401,8 +361,7 @@ void SOCC_Viewer::Display( const SALOME_OCCPrs* prs )
       //  Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
       //if ( !anObj.IsNull() && anObj->hasEntry() )
       //{
-      //  if ( study  )
-      //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
+      //  ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
       //}
 
       // Deactivate object if necessary
@@ -426,12 +385,6 @@ void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
   if ( !anOCCPrs || anOCCPrs->IsNull() )
     return;
 
-  // get SALOMEDS Study
-  // Temporarily commented to avoid awful dependecy on SALOMEDS
-  // TODO: better mechanism of storing display/erse status in a study
-  // should be provided...
-  //  _PTR(Study) study(getStudyDS());
-
   // get context
   Handle(AIS_InteractiveContext) ic = getAISContext();
 
@@ -455,8 +408,7 @@ void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
       //    Handle(SALOME_InteractiveObject)::DownCast( anAIS->GetOwner() );
       //  if ( !anObj.IsNull() && anObj->hasEntry() )
       //  {
-      //  if ( study )
-      //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
+      //    ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
       //  }
       //}
     }
@@ -471,12 +423,6 @@ void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced )
 */
 void SOCC_Viewer::EraseAll( SALOME_Displayer* d, const bool forced )
 {
-  // get SALOMEDS Study
-  // Temporarily commented to avoid awful dependecy on SALOMEDS
-  // TODO: better mechanism of storing display/erse status in a study
-  // should be provided...
-  //  _PTR(Study) study(getStudyDS());
-
   // get context
   Handle(AIS_InteractiveContext) ic = getAISContext();
 
@@ -504,8 +450,7 @@ void SOCC_Viewer::EraseAll( SALOME_Displayer* d, const bool forced )
     //  Handle(SALOME_InteractiveObject)::DownCast( anIO->GetOwner() );
 
     //  if ( !anObj.IsNull() && anObj->hasEntry() ) {
-    //  if ( study )
-    //    ToolsGUI::SetVisibility( study, anObj->getEntry(), true, this );
+    //    ToolsGUI::SetVisibility( anObj->getEntry(), true, this );
     //  }
     //}
   }
index abe70294adee40e01c8229c491146ffe94437e9d..f890ca74cf19fe2622e92832d55414e857670587 100644 (file)
 #include <qwt_plot_curve.h>
 #include <stdlib.h>
 
-//ASL: Temporary commented in order to avoir dependency on SALOMEDS
-
-//#include "SALOMEDSClient.hxx"
-//#include "SALOMEDS_StudyManager.hxx"
-
-// in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
-// SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from
-// SALOMEDS::StudyManager - no linkage with SalomeApp.  
-
-/*static _PTR(Study) getStudyDS()
-{
-  SALOMEDSClient_Study* aStudy = NULL;
-  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
-
-  // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
-  //    id of its underlying SALOMEDS::Study
-  SUIT_Application* app = SUIT_Session::session()->activeApplication();
-  if ( !app )  return _PTR(Study)(aStudy);
-  SUIT_Study* stud = app->activeStudy();
-  if ( !stud ) return _PTR(Study)(aStudy);
-  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
-  // get SALOMEDS_Study with this id from StudyMgr
-  return aMgr->GetStudyByID( id );
-} */               
-
 /*!
   Constructor
 */
index d5751cf34375739c676065e273484fb79e720913..1dcd838cfdc53e86202571cd4c08e6aadab5ff59 100755 (executable)
@@ -156,6 +156,8 @@ void STD_Application::createActions()
                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_NEW" ) ),
                 tr( "MEN_DESK_FILE_NEW" ), tr( "PRP_DESK_FILE_NEW" ),
                 Qt::CTRL+Qt::Key_N, desk, false, this, SLOT( onNewDoc() ) );
+  //no need at this action for mono-study application because study is always exists
+  action( FileNewId )->setVisible( false );
 
   createAction( FileOpenId, tr( "TOT_DESK_FILE_OPEN" ),
                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
@@ -367,16 +369,11 @@ bool STD_Application::onReopenDoc()
     // post closing actions
     afterCloseDoc();
 
-    int aNbStudies = 0;
-    QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
-    for ( int i = 0; i < apps.count(); i++ )
-      aNbStudies += apps.at( i )->getNbStudies();
-
     // reload study from the file
     res = useFile( studyName ) && activeStudy();
 
     // if reloading is failed, close the desktop
-    if ( aNbStudies && !res )
+    if ( activeStudy() && !res )
       closeApplication();
     else
     {
index 75d32cfc62397d7cb5ab859886bed5ab0f15e958..06d9180ed8138cd4a388437a8f8014578d1d4de2 100644 (file)
@@ -693,7 +693,8 @@ int SUIT_Application::registerAction( const int id, QAction* a )
   if ( desktop() && desktop()->toolMgr() )
     desktop()->toolMgr()->registerAction( a );
 
-  if ( desktop() )
+  if ( desktop() && a->shortcutContext() != Qt::WidgetShortcut &&
+       a->shortcutContext() != Qt::WidgetWithChildrenShortcut )
     desktop()->addAction( a );
 
   return ident;
index 28bc07177cc4b7979a05a8d4d885bae60918a659..eb5c339a89db0eb93bccbfac324acb081ee3081a 100644 (file)
 // VSR: Uncomment below line to allow texture background support in VTK viewer
 #define VTK_ENABLE_TEXTURED_BACKGROUND
 
-
-// in order NOT TO link with SalomeApp, here the code returns SALOMEDS_Study.
-// SalomeApp_Study::studyDS() does it as well, but -- here it is retrieved from 
-// SALOMEDS::StudyManager - no linkage with SalomeApp. 
-
-// Temporarily commented to avoid awful dependecy on SALOMEDS
-// TODO: better mechanism of storing display/erse status in a study
-// should be provided...
-//static _PTR(Study) getStudyDS() 
-//{
-//  SALOMEDSClient_Study* aStudy = NULL;
-//  _PTR(StudyManager) aMgr( new SALOMEDS_StudyManager() );
-  // get id of SUIT_Study, if it's a SalomeApp_Study, it will return
-  //    id of its underlying SALOMEDS::Study
-//  SUIT_Application* app = SUIT_Session::session()->activeApplication();
-//  if ( !app )  return _PTR(Study)(aStudy); 
-//  SUIT_Study* stud = app->activeStudy();
-//  if ( !stud ) return _PTR(Study)(aStudy);  
-//  const int id = stud->id(); // virtual method, must return SALOMEDS_Study id
-  // get SALOMEDS_Study with this id from StudyMgr
-//  return aMgr->GetStudyByID( id );
-//}
-
 /*!
   Constructor
 */
@@ -688,11 +665,6 @@ void SVTK_Viewer::Display( const SALOME_VTKPrs* prs )
     if(aPrs->IsNull())
       return;
     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){
-      // get SALOMEDS Study
-      // Temporarily commented to avoid awful dependecy on SALOMEDS
-      // TODO: better mechanism of storing display/erse status in a study
-      // should be provided...
-      // _PTR(Study) aStudy(getStudyDS());
       anActorCollection->InitTraversal();
       while(vtkActor* anActor = anActorCollection->GetNextActor()){
         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){
@@ -703,8 +675,8 @@ void SVTK_Viewer::Display( const SALOME_VTKPrs* prs )
           // TODO: better mechanism of storing display/erse status in a study
           // should be provided...
           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
-          //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){
-          //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),true,this);
+          //if(!anObj.IsNull() && anObj->hasEntry()){
+          //  ToolsGUI::SetVisibility(anObj->getEntry(),true,this);
           //}
           // just display the object
           QVector<SUIT_ViewWindow*> aViews = myViewManager->getViews();
@@ -737,11 +709,6 @@ void SVTK_Viewer::Erase( const SALOME_VTKPrs* prs, const bool forced )
     if(aPrs->IsNull())
       return;
     if(vtkActorCollection* anActorCollection = aPrs->GetObjects()){
-      // get SALOMEDS Study
-      // Temporarily commented to avoid awful dependecy on SALOMEDS
-      // TODO: better mechanism of storing display/erase status in a study
-      // should be provided...
-      //_PTR(Study) aStudy(getStudyDS());
       anActorCollection->InitTraversal();
       while(vtkActor* anActor = anActorCollection->GetNextActor())
         if(SALOME_Actor* anAct = SALOME_Actor::SafeDownCast(anActor)){
@@ -750,8 +717,8 @@ void SVTK_Viewer::Erase( const SALOME_VTKPrs* prs, const bool forced )
           // TODO: better mechanism of storing display/erase status in a study
           // should be provided...
           //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
-          //if(!anObj.IsNull() && anObj->hasEntry() && aStudy){
-          //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);
+          //if(!anObj.IsNull() && anObj->hasEntry()){
+          //  ToolsGUI::SetVisibility(anObj->getEntry(),false,this);
           //}
           // just display the object
           QVector<SUIT_ViewWindow*> aViews = myViewManager->getViews();
@@ -776,10 +743,6 @@ void SVTK_Viewer::Erase( const SALOME_VTKPrs* prs, const bool forced )
 */
 void SVTK_Viewer::EraseAll( SALOME_Displayer* d, const bool forced )
 {
-  // Temporarily commented to avoid awful dependecy on SALOMEDS
-  // TODO: better mechanism of storing display/erse status in a study
-  // should be provided...
-  //_PTR(Study) aStudy(getStudyDS());
   QVector<SUIT_ViewWindow*> aViews = myViewManager->getViews();
   for(int i = 0, iEnd = aViews.size(); i < iEnd; i++){
     if(SVTK_ViewWindow* aViewWindow = dynamic_cast<SVTK_ViewWindow*>(aViews.at(i)))
@@ -795,8 +758,8 @@ void SVTK_Viewer::EraseAll( SALOME_Displayer* d, const bool forced )
             // TODO: better mechanism of storing display/erse status in a study
             // should be provided...
             //Handle(SALOME_InteractiveObject) anObj = anAct->getIO();
-            //if(!anObj.IsNull() && anObj->hasEntry() && aStudy)
-            //  ToolsGUI::SetVisibility(aStudy,anObj->getEntry(),false,this);
+            //if(!anObj.IsNull() && anObj->hasEntry())
+            //  ToolsGUI::SetVisibility(anObj->getEntry(),false,this);
             if(forced){
               if(SVTK_Renderer* aRnd = aView->GetRenderer())
                 aRnd->RemoveActor(anAct);
index 70646990ff82c781655a0ed9b82d00033a64bd11..2dec0819855955b2435cb3abdad9e360e75bb22f 100644 (file)
@@ -206,7 +206,6 @@ void SalomeApp_Application::start()
 
     QString hdffile;
     QStringList pyfiles;
-    QString loadStudy;
 
     for (int i = 1; i < qApp->arguments().size(); i++) {
       QRegExp rxs ("--study-hdf=(.+)");
@@ -240,14 +239,8 @@ void SalomeApp_Application::start()
     SALOME_EventFilter::Init();
 
     setProperty("open_study_from_command_line", true);
-    if ( !hdffile.isEmpty() )       // open hdf file given as parameter
+    if ( !hdffile.isEmpty() ) // open hdf file given as parameter
       onOpenDoc( hdffile );
-    else if ( pyfiles.count() > 0 ) // create new study
-      onNewDoc();
-    else if (!loadStudy.isEmpty()) {// load study by name
-      if (onLoadDoc(loadStudy))
-        updateObjectBrowser(true);
-    }
     setProperty("open_study_from_command_line", QVariant());
 
 #ifndef DISABLE_PYCONSOLE
@@ -256,8 +249,7 @@ void SalomeApp_Application::start()
       SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
       PyConsole_Console* pyConsole = pythonConsole();
       if ( appStudy && pyConsole ) {
-        _PTR(Study) aStudy = appStudy->studyDS();
-        if ( !aStudy->GetProperties()->IsLocked() ) {
+        if ( !getStudy()->GetProperties()->IsLocked() ) {
           // pyfiles[j] is a dictionary: {"/absolute/path/to/script.py": [script_args]}
           // Path is absolute, script has .py extension
           for (uint j = 0; j < pyfiles.count(); j++ ) {
@@ -335,10 +327,14 @@ void SalomeApp_Application::createActions()
   createAction( ConnectId, tr( "TOT_DESK_CONNECT_STUDY" ), QIcon(),
                 tr( "MEN_DESK_CONNECT" ), tr( "PRP_DESK_CONNECT" ),
                 Qt::CTRL+Qt::Key_L, desk, false, this, SLOT( onLoadDoc() ) );
+  //no need at this action for mono-study application because study is always exists
+  action( ConnectId )->setVisible( false );
 
   createAction( DisconnectId, tr( "TOT_DESK_DISCONNECT_STUDY" ), QIcon(),
                 tr( "MEN_DESK_DISCONNECT" ), tr( "PRP_DESK_DISCONNECT" ),
                 Qt::CTRL+Qt::Key_U, desk, false, this, SLOT( onUnloadDoc() ) );
+  //no need at this action for mono-study application because study is always exists
+  action( DisconnectId )->setVisible( false );
 
 
   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1 );
@@ -406,8 +402,6 @@ void SalomeApp_Application::onLoadDoc()
 {
   QString studyName;
 
-  std::vector<std::string> List = studyMgr()->GetOpenStudies();
-
   // rnv: According to the single-study approach on the server side
   //      can be only one study. So if it is exists connect to them,
   //      overwise show warning message: "No active study on the server"
@@ -439,14 +433,14 @@ void SalomeApp_Application::onLoadDoc()
     return;
   */
 
-  if(List.size() <= 0) {
+  if(!activeStudy()) {
     SUIT_MessageBox::warning( desktop(),
                               QObject::tr("WRN_WARNING"),
                               QObject::tr("WRN_NO_STUDY_ON SERV") );
     return;
   }
 
-  studyName = List[0].c_str();
+  studyName = activeStudy()->studyName();
 
 #ifndef WIN32
   // this code replaces marker of windows drive and path become invalid therefore
@@ -518,10 +512,9 @@ void SalomeApp_Application::onNewWithScript()
 /*!SLOT. Load document with \a aName.*/
 bool SalomeApp_Application::onLoadDoc( const QString& aName )
 {
-#ifdef SINGLE_DESKTOP
   if ( !LightApp_Application::closeDoc() )
     return false;
-#endif
+
   bool res = true;
   if ( !activeStudy() ) {
     // if no study - load in current desktop
@@ -555,28 +548,40 @@ bool SalomeApp_Application::onLoadDoc( const QString& aName )
 /*!SLOT. Parse message for desktop.*/
 void SalomeApp_Application::onDesktopMessage( const QString& message )
 {
-  if (message.indexOf("studyCreated:") == 0) {
-    // Enable 'Connect' action
-    updateCommandsStatus();
+  if (message.indexOf("studyCreated") == 0) {
+    if (!activeStudy()) {
+      onNewDoc();
+      updateCommandsStatus();
+    }
   }
-  else if (message.indexOf("studyClosed:") == 0) {
-    /* message also contains ID of the closed study,
-       but as soon as SALOME is mono-study application for the moment,
-       this ID is not needed now.*/
-    //long aStudyId = message.section(':', 1).toLong();
+  if (message.indexOf("studyCleared") == 0) {
     // Disconnect GUI from active study, because it was closed on DS side.
-    closeActiveDoc( false );
-    // Disable 'Connect' action
-    QAction* a = action( ConnectId );
-    if ( a )
-      a->setEnabled( false );
+    if (activeStudy()) {
+      closeActiveDoc( false );
+      // Disable 'Connect' action
+      QAction* a = action( ConnectId );
+      if ( a )
+        a->setEnabled( false );
+    }
   }
   else if ( message.toLower() == "connect_to_study" ) {
     onLoadDoc();
   }
+  if (message.indexOf("studyNameChanged") == 0) {
+    updateDesktopTitle();
+  }
   LightApp_Application::onDesktopMessage( message );
 }
 
+/*!On module activation action.*/
+void SalomeApp_Application::onModuleActivation( const QString& modName )
+{
+  if (!activeStudy() && !modName.isEmpty())
+    getStudy()->Init();
+
+  LightApp_Application::onModuleActivation( modName );
+}
+
 /*!SLOT. Copy objects to study maneger from selection maneger..*/
 void SalomeApp_Application::onCopy()
 {
@@ -587,7 +592,7 @@ void SalomeApp_Application::onCopy()
   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
   if(study == NULL) return;
 
-  _PTR(Study) stdDS = study->studyDS();
+  _PTR(Study) stdDS = getStudy();
   if(!stdDS) return;
 
   SALOME_ListIteratorOfListIO it( list );
@@ -595,7 +600,7 @@ void SalomeApp_Application::onCopy()
     {
       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
       try {
-        studyMgr()->Copy(so);
+        stdDS->Copy(so);
         onSelectionChanged();
       }
       catch(...) {
@@ -613,7 +618,7 @@ void SalomeApp_Application::onPaste()
   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
   if(study == NULL) return;
 
-  _PTR(Study) stdDS = study->studyDS();
+  _PTR(Study) stdDS = getStudy();
   if(!stdDS) return;
 
   if ( stdDS->GetProperties()->IsLocked() ) {
@@ -628,7 +633,7 @@ void SalomeApp_Application::onPaste()
     {
       _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
       try {
-        studyMgr()->Paste(so);
+        stdDS->Paste(so);
         updateObjectBrowser( true );
         updateActions(); //SRN: BugID IPAL9377, case 3
       }
@@ -648,20 +653,18 @@ bool SalomeApp_Application::isPossibleToClose( bool& closePermanently )
 /*! Check if the study is locked */
 void SalomeApp_Application::onCloseDoc( bool ask )
 {
-  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
-
-  if (study != NULL) {
-    _PTR(Study) stdDS = study->studyDS();
-    if(stdDS && stdDS->IsStudyLocked()) {
-      if ( SUIT_MessageBox::question( desktop(),
-                                      QObject::tr( "WRN_WARNING" ),
-                                      QObject::tr( "CLOSE_LOCKED_STUDY" ),
-                                      SUIT_MessageBox::Yes | SUIT_MessageBox::No,
-                                      SUIT_MessageBox::No) == SUIT_MessageBox::No ) return;
+  if(getStudy()->IsStudyLocked()) {
+    if ( SUIT_MessageBox::question( desktop(),
+                                    QObject::tr( "WRN_WARNING" ),
+                                    QObject::tr( "CLOSE_LOCKED_STUDY" ),
+                                    SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+                                    SUIT_MessageBox::No) == SUIT_MessageBox::No ) return;
 
-    }
   }
   LightApp_Application::onCloseDoc( ask );
+
+  // reinitialize study to have empty data
+  getStudy()->Init();
 }
 
 /*!Sets enable or disable some actions on selection changed.*/
@@ -681,21 +684,14 @@ void SalomeApp_Application::onSelectionChanged()
      canPaste = m->canPaste();
    }
 
-   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
-   if (study) {
-     _PTR(Study) stdDS = study->studyDS();
+   SALOME_ListIteratorOfListIO it ( list );
 
-     if (stdDS) {
-       SALOME_ListIteratorOfListIO it ( list );
+   if (it.More() && list.Extent() == 1) {
+     _PTR(SObject) so = getStudy()->FindObjectID(it.Value()->getEntry());
 
-       if (it.More() && list.Extent() == 1) {
-         _PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
-
-         if ( so ) {
-           canCopy  = canCopy  || studyMgr()->CanCopy(so);
-           canPaste = canPaste || studyMgr()->CanPaste(so);
-         }
-       }
+     if ( so ) {
+       canCopy  = canCopy  || getStudy()->CanCopy(so);
+       canPaste = canPaste || getStudy()->CanPaste(so);
      }
    }
 
@@ -713,8 +709,7 @@ void SalomeApp_Application::onDeleteInvalidReferences()
   if( aList.IsEmpty() )
     return;
 
-  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
-  _PTR(Study) aStudyDS = aStudy->studyDS();
+  _PTR(Study) aStudyDS = getStudy();
   _PTR(StudyBuilder) aStudyBuilder = aStudyDS->NewBuilder();
   _PTR(SObject) anObj;
 
@@ -804,7 +799,7 @@ void SalomeApp_Application::updateCommandsStatus()
   // Connect study menu
   a = action( ConnectId );
   if( a )
-    a->setEnabled( !activeStudy() && studyMgr()->GetOpenStudies().size() > 0 );
+    a->setEnabled( !activeStudy() );
 
   // Disconnect study menu
   a = action( DisconnectId );
@@ -859,7 +854,6 @@ void SalomeApp_Application::onDumpStudy( )
 {
   SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
   if ( !appStudy ) return;
-  _PTR(Study) aStudy = appStudy->studyDS();
 
   QStringList aFilters;
   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
@@ -911,15 +905,11 @@ void SalomeApp_Application::onDumpStudy( )
 /*!Private SLOT. On load script.*/
 void SalomeApp_Application::onLoadScript( )
 {
-  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
-  if ( appStudy ) {
-    _PTR(Study) aStudy = appStudy->studyDS();
-    if ( aStudy->GetProperties()->IsLocked() ) {
-      SUIT_MessageBox::warning( desktop(),
-                                QObject::tr("WRN_WARNING"),
-                                QObject::tr("WRN_STUDY_LOCKED") );
-      return;
-    }
+  if ( getStudy()->GetProperties()->IsLocked() ) {
+    SUIT_MessageBox::warning( desktop(),
+                              QObject::tr("WRN_WARNING"),
+                              QObject::tr("WRN_STUDY_LOCKED") );
+    return;
   }
 
   QStringList filtersList;
@@ -1060,14 +1050,11 @@ QWidget* SalomeApp_Application::createWindow( const int flag )
   }
   else if ( flag == WT_NoteBook )
   {
-    SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
-    if ( appStudy ) {
-      _PTR(Study) aStudy = appStudy->studyDS();
-      setNoteBook( new SalomeApp_NoteBook( desktop(), aStudy ) );
-      //to receive signal in NoteBook that it's variable was modified
-      connect( this, SIGNAL( notebookVarUpdated( QString ) ),
-               getNoteBook(), SLOT( onVarUpdate( QString ) ) );
-    }
+    setNoteBook( new SalomeApp_NoteBook( desktop() ) );
+    //to receive signal in NoteBook that it's variable was modified
+    connect( this, SIGNAL( notebookVarUpdated( QString ) ),
+             getNoteBook(), SLOT( onVarUpdate( QString ) ) );
+
     wid = getNoteBook();
     wid->setObjectName( "noteBook" );
   }
@@ -1116,16 +1103,10 @@ void SalomeApp_Application::updateDesktopTitle() {
   {
     QString sName = SUIT_Tools::file( activeStudy()->studyName().trimmed(), false );
     if ( !sName.isEmpty() ) {
-      SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
-      if ( study ) {
-        _PTR(Study) stdDS = study->studyDS();
-        if(stdDS) {
-          if ( stdDS->GetProperties()->IsLocked() ) {
-            aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
-          } else {
-            aTitle += QString( " - [%1]" ).arg( sName );
-          }
-        }
+      if ( getStudy()->GetProperties()->IsLocked() ) {
+        aTitle += QString( " - [%1 (%2)]").arg( sName ).arg( tr( "STUDY_LOCKED" ) );
+      } else {
+        aTitle += QString( " - [%1]" ).arg( sName );
       }
     }
   }
@@ -1138,9 +1119,9 @@ int SalomeApp_Application::closeChoice( const QString& docName )
   QStringList buttons;
   QMap<int, int> choices;
   int idx = 0;
-  buttons << tr ("APPCLOSE_SAVE");                // Save & Close
+  buttons << tr ("APPCLOSE_SAVE");                // Save & Clear
   choices.insert( idx++, CloseSave );             // ...
-  buttons << tr ("APPCLOSE_CLOSE");               // Close w/o saving
+  buttons << tr ("APPCLOSE_CLOSE");               // Clear w/o saving
   choices.insert( idx++, CloseDiscard );          // ...
   if ( myIsCloseFromExit ) {
     buttons << tr ("APPCLOSE_UNLOAD_SAVE");       // Save & Disconnect
@@ -1151,6 +1132,8 @@ int SalomeApp_Application::closeChoice( const QString& docName )
   buttons << tr ("APPCLOSE_CANCEL");              // Cancel
   choices.insert( idx++, CloseCancel );           // ...
 
+  if( !activeStudy()->isModified() )
+    return CloseCancel;
   int answer = SUIT_MessageBox::question( desktop(), tr( "APPCLOSE_CAPTION" ),
                                           tr( "APPCLOSE_DESCRIPTION" ), buttons, 0 );
   return choices[answer];
@@ -1192,12 +1175,9 @@ int SalomeApp_Application::openChoice( const QString& aName )
   if ( QFileInfo( aName ).exists() ) {
     if ( choice == OpenNew ) { // The document isn't already open.
       bool exist = false;
-      std::vector<std::string> lst = studyMgr()->GetOpenStudies();
-      for ( uint i = 0; i < lst.size() && !exist; i++ ) {
-        if ( aName == QString( lst[i].c_str() ) )
-          exist = true;
-      }
-      // The document already exists in the study manager.
+      if ( aName == getStudy()->Name().c_str() )
+        exist = true;
+      // The document already exists in the study.
       // Do you want to reload it?
       if ( exist ) {
         int answer = SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "QUE_DOC_ALREADYEXIST" ).arg( aName ),
@@ -1226,12 +1206,7 @@ bool SalomeApp_Application::openAction( const int aChoice, const QString& aName
   {
   case OpenRefresh:
     {
-      _PTR(Study) aStudy = studyMgr()->GetStudyByName( aName.toStdString() );
-      if ( aStudy )
-      {
-        studyMgr()->Close( aStudy );
-        choice = OpenNew;
-      }
+      choice = OpenNew;
     }
   default:
     res = LightApp_Application::openAction( choice, aName );
@@ -1304,12 +1279,16 @@ CORBA::ORB_var SalomeApp_Application::orb()
   return _orb;
 }
 
-/*!Create and return SALOMEDS_StudyManager.*/
-SALOMEDSClient_StudyManager* SalomeApp_Application::studyMgr()
+/*!Create and return SALOMEDS_Study.*/
+_PTR(Study) SalomeApp_Application::getStudy()
 {
-  static _PTR(StudyManager) _sm;
-  if(!_sm) _sm = ClientFactory::StudyManager();
-  return _sm.get();
+  static _PTR(Study) _study;
+  if(!_study) {
+    CORBA::Object_var aSObject = namingService()->Resolve("/Study");
+    SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(aSObject);
+    _study = ClientFactory::Study(aStudy);
+  }
+  return _study;
 }
 
 /*!Create and return SALOME_NamingService.*/
@@ -1380,72 +1359,62 @@ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePop
 
   // isInvalidRefs will be true, if at least one of selected objects is invalid reference
   bool isInvalidRefs = false;
-  SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(activeStudy());
-  if ( aStudy ) {
-    _PTR(Study) aStudyDS = aStudy->studyDS();
-    _PTR(SObject) anObj;
 
-    for( SALOME_ListIteratorOfListIO it( aList ); it.More() && !isInvalidRefs; it.Next() )
+  _PTR(SObject) anObj;
+  for( SALOME_ListIteratorOfListIO it( aList ); it.More() && !isInvalidRefs; it.Next() )
+  {
+    if( it.Value()->hasEntry() )
     {
-      if( it.Value()->hasEntry() )
-      {
-        _PTR(SObject) aSObject = aStudyDS->FindObjectID( it.Value()->getEntry() ), aRefObj = aSObject;
-        while( aRefObj && aRefObj->ReferencedObject( anObj ) )
-          aRefObj = anObj;
+      _PTR(SObject) aSObject = getStudy()->FindObjectID( it.Value()->getEntry() ), aRefObj = aSObject;
+      while( aRefObj && aRefObj->ReferencedObject( anObj ) )
+        aRefObj = anObj;
 
-        if( aRefObj && aRefObj!=aSObject && QString( aRefObj->GetName().c_str() ).isEmpty() )
-          isInvalidRefs = true;
-      }
+      if( aRefObj && aRefObj!=aSObject && QString( aRefObj->GetName().c_str() ).isEmpty() )
+        isInvalidRefs = true;
     }
+  }
 
-    // Add "Delete reference" item to popup
-    if ( isInvalidRefs )
-    {
-      thePopup->addSeparator();
-      thePopup->addAction( tr( "MEN_DELETE_INVALID_REFERENCE" ), this, SLOT( onDeleteInvalidReferences() ) );
-      return;
-    }
+  // Add "Delete reference" item to popup
+  if ( isInvalidRefs )
+  {
+    thePopup->addSeparator();
+    thePopup->addAction( tr( "MEN_DELETE_INVALID_REFERENCE" ), this, SLOT( onDeleteInvalidReferences() ) );
+    return;
+  }
 
-    // "Activate module" item should appear only if it's necessary
-    if ( aList.Extent() == 1 ) {
-      aList.Clear();
-      mgr->selectedObjects( aList );
-
-      Handle(SALOME_InteractiveObject) aIObj = aList.First();
-
-      // add extra popup menu (defined in XML)
-      if ( myExtActions.size() > 0 ) {
-        // Use only first selected object
-        SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( activeStudy() );
-        if ( study ) {
-          _PTR(Study) stdDS = study->studyDS();
-          if ( stdDS ) {
-            _PTR(SObject) aSO = stdDS->FindObjectID( aIObj->getEntry() );
-            if ( aSO ) {
-              _PTR( GenericAttribute ) anAttr;
-              std::string auid = "AttributeUserID";
-              auid += Kernel_Utils::GetGUID(Kernel_Utils::ObjectdID);
-              if ( aSO->FindAttribute( anAttr, auid ) ) {
-                _PTR(AttributeUserID) aAttrID = anAttr;
-                QString aId = aAttrID->Value().c_str();
-                if ( myExtActions.contains( aId ) ) {
-                  thePopup->addAction(myExtActions[aId]);
-                }
-              }
-            }
+  // "Activate module" item should appear only if it's necessary
+  if ( aList.Extent() == 1 ) {
+    aList.Clear();
+    mgr->selectedObjects( aList );
+
+    Handle(SALOME_InteractiveObject) aIObj = aList.First();
+
+    // add extra popup menu (defined in XML)
+    if ( myExtActions.size() > 0 ) {
+      // Use only first selected object
+      _PTR(SObject) aSO = getStudy()->FindObjectID( aIObj->getEntry() );
+      if ( aSO ) {
+        _PTR( GenericAttribute ) anAttr;
+        std::string auid = "AttributeUserID";
+        auid += Kernel_Utils::GetGUID(Kernel_Utils::ObjectdID);
+        if ( aSO->FindAttribute( anAttr, auid ) ) {
+          _PTR(AttributeUserID) aAttrID = anAttr;
+          QString aId = aAttrID->Value().c_str();
+          if ( myExtActions.contains( aId ) ) {
+            thePopup->addAction(myExtActions[aId]);
           }
         }
       }
+    }
 
-      // check if item is a "GUI state" item (also a first level object)
-      QString entry( aIObj->getEntry() );
-      if ( !entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) {
-        QString aModuleName( aIObj->getComponentDataType() );
-        QString aModuleTitle = moduleTitle( aModuleName );
-        CAM_Module* currentModule = activeModule();
-        if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() )
-          thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) );
-      }
+    // check if item is a "GUI state" item (also a first level object)
+    QString entry( aIObj->getEntry() );
+    if ( !entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) {
+      QString aModuleName( aIObj->getComponentDataType() );
+      QString aModuleTitle = moduleTitle( aModuleName );
+      CAM_Module* currentModule = activeModule();
+      if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() )
+        thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) );
     }
   }
 
@@ -1462,25 +1431,21 @@ void SalomeApp_Application::updateObjectBrowser( const bool updateModels )
   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
   if ( study )
   {
-    _PTR(Study) stdDS = study->studyDS();
-    if( stdDS )
+    for ( _PTR(SComponentIterator) it ( getStudy()->NewComponentIterator() ); it->More(); it->Next() )
     {
-      for ( _PTR(SComponentIterator) it ( stdDS->NewComponentIterator() ); it->More(); it->Next() )
-      {
-        _PTR(SComponent) aComponent ( it->Value() );
+      _PTR(SComponent) aComponent ( it->Value() );
 
 #ifndef WITH_SALOMEDS_OBSERVER
-        // with GUI observers this check is not needed anymore
-        if ( aComponent->ComponentDataType() == study->getVisualComponentName().toLatin1().constData() )
-          continue; // skip the magic "Interface Applicative" component
+      // with GUI observers this check is not needed anymore
+      if ( aComponent->ComponentDataType() == study->getVisualComponentName().toLatin1().constData() )
+        continue; // skip the magic "Interface Applicative" component
 #endif
-        if ( !objectBrowser() )
-          getWindow( WT_ObjectBrowser );
-        const bool isAutoUpdate = objectBrowser()->autoUpdate();
-        objectBrowser()->setAutoUpdate( false );
-        SalomeApp_DataModel::synchronize( aComponent, study );
-        objectBrowser()->setAutoUpdate( isAutoUpdate );
-      }
+      if ( !objectBrowser() )
+        getWindow( WT_ObjectBrowser );
+      const bool isAutoUpdate = objectBrowser()->autoUpdate();
+      objectBrowser()->setAutoUpdate( false );
+      SalomeApp_DataModel::synchronize( aComponent, study );
+      objectBrowser()->setAutoUpdate( isAutoUpdate );
     }
   }
 
@@ -1908,8 +1873,6 @@ bool SalomeApp_Application::updateStudy()
   myNoteBook->setIsDumpedStudySaved( study->isSaved() );
   myNoteBook->setDumpedStudyName( study->studyName() );
 
-  _PTR(Study) studyDS = study->studyDS();
-
   // get unique temporary directory name
   QString aTmpDir = QString::fromStdString( SALOMEDS_Tool::GetTmpDir() );
   if( aTmpDir.isEmpty() )
@@ -1927,12 +1890,12 @@ bool SalomeApp_Application::updateStudy()
   int savePoint;
   _PTR(AttributeParameter) ap;
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
-  if(ip->isDumpPython(studyDS)) ip->setDumpPython(studyDS); //Unset DumpPython flag.
+  if(ip->isDumpPython()) ip->setDumpPython(); //Unset DumpPython flag.
   if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method
-    ip->setDumpPython(studyDS);
+    ip->setDumpPython();
     savePoint = SalomeApp_VisualState( this ).storeState(); //SRN: create a temporary save point
   }
-  bool ok = studyDS->DumpStudy( aTmpDir.toStdString(), aScriptName.toStdString(), toPublish, isMultiFile );
+  bool ok = getStudy()->DumpStudy( aTmpDir.toStdString(), aScriptName.toStdString(), toPublish, isMultiFile );
   if ( toSaveGUI )
     study->removeSavePoint(savePoint); //SRN: remove the created temporary save point.
 
@@ -1991,9 +1954,6 @@ bool SalomeApp_Application::onRestoreStudy( const QString& theDumpScript,
 {
   bool ok = true;
 
-  // create a new study
-  onNewDoc();
-
   // get active application
   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
 
@@ -2019,9 +1979,8 @@ bool SalomeApp_Application::onRestoreStudy( const QString& theDumpScript,
   if( SalomeApp_Study* newStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
   {
 #ifndef DISABLE_PYCONSOLE
-    _PTR(Study) aStudyDS = newStudy->studyDS();
     if ( app->getNoteBook() )
-      app->getNoteBook()->Init( aStudyDS );
+      app->getNoteBook()->Init();
     newStudy->updateFromNotebook(theStudyName, theIsStudySaved);
     newStudy->Modified();
     updateDesktopTitle();
@@ -2055,18 +2014,7 @@ void SalomeApp_Application::afterCloseDoc()
 */
 bool SalomeApp_Application::checkExistingDoc()
 {
-  bool result = LightApp_Application::checkExistingDoc();
-  if ( result && !activeStudy() ) {
-    SALOMEDSClient_StudyManager* aMgr = studyMgr();
-    if ( aMgr ) {
-      std::vector<std::string> List = studyMgr()->GetOpenStudies();
-      if( List.size() > 0 ) {
-        SUIT_MessageBox::critical( desktop(), tr( "WRN_WARNING" ), tr( "ERR_ACTIVEDOC_LOAD" ));
-        result = false;
-      }
-    }
-  }
-  return result;
+  return LightApp_Application::checkExistingDoc();
 }
 
 
index ae6775ea7962fb721b733ceb93e062aa98736f70..cf112abbfd312686895d7491eda1b26d6eb57279 100644 (file)
@@ -96,7 +96,7 @@ public:
   virtual bool                        checkExistingDoc();
 
   static CORBA::ORB_var               orb();
-  static SALOMEDSClient_StudyManager* studyMgr();
+  static _PTR(Study)                  getStudy();
   static SALOME_NamingService*        namingService();
   static SALOME_LifeCycleCORBA*       lcc();
 
@@ -141,6 +141,8 @@ protected slots:
   void                                onStudyOpened( SUIT_Study* );
   void                                onDesktopMessage( const QString& );
 
+  virtual void                        onModuleActivation( const QString& );
+
 protected:
   virtual void                        createActions();
   virtual SUIT_Study*                 createNewStudy();
index bebd38e644076ba95f340641651230ffb2fc86f2..77a1ea8248d328ac7b45b778bdf60910dbdb9376 100644 (file)
@@ -286,8 +286,7 @@ bool SalomeApp_DataModel::open( const QString& name, CAM_Study* study, QStringLi
   if ( anId.isEmpty() )
     return true; // Probably nothing to load
 
-  _PTR(Study)      aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
-  _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.toLatin1() ) ) );
+  _PTR(SComponent) aSComp ( SalomeApp_Application::getStudy()->FindComponentID( std::string( anId.toLatin1() ) ) );
   if ( aSComp )
     updateTree( aSComp, aDoc );
 
@@ -321,8 +320,7 @@ void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study )
       studyRoot = dynamic_cast<LightApp_RootObject*>( aSStudy->root() );
       QString anId = getRootEntry( aSStudy );
       if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
-        _PTR(Study) aStudy ( aSStudy->studyDS() );
-        sobj = aStudy->FindComponentID( std::string( anId.toLatin1() ) );
+        sobj = SalomeApp_Application::getStudy()->FindComponentID( std::string( anId.toLatin1() ) );
       }
     }
   }
@@ -331,9 +329,8 @@ void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study )
     if ( studyRoot ) {
       aSStudy = dynamic_cast<SalomeApp_Study*>( studyRoot->study() ); // <study> value should not change here theoretically, but just to make sure
       if ( aSStudy ) {
-        _PTR(Study) aStudy ( aSStudy->studyDS() );
         // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
-        sobj = aStudy->FindComponentID( std::string( modelRoot->entry().toLatin1() ) );
+        sobj = SalomeApp_Application::getStudy()->FindComponentID( std::string( modelRoot->entry().toLatin1() ) );
       }
     }
   }
index a6fd9c005752c47b58f5360058d1c8eb3927af8a..ba1afa06889fba0deb77023616d24266422a9d22 100644 (file)
@@ -291,7 +291,7 @@ QString SalomeApp_DataObject::toolTip( const int /*id*/ ) const
       if ( !CORBA::is_nil(aComponent) && aComponent->hasObjectInfo() ) {
         LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() );
         if ( aRoot && aRoot->study() ) {
-          CORBA::String_var data = aComponent->getObjectInfo( aRoot->study()->id(), entry().toLatin1().constData());
+          CORBA::String_var data = aComponent->getObjectInfo( entry().toLatin1().constData());
           QString objInfo = data.in();
           QStringList l;
           l << name();
@@ -405,13 +405,13 @@ bool SalomeApp_DataObject::hasChildren() const
   bool ok = false;
 
   // tmp??
-  _PTR(UseCaseBuilder) aUseCaseBuilder = myObject->GetStudy()->GetUseCaseBuilder();
+  _PTR(UseCaseBuilder) aUseCaseBuilder = SalomeApp_Application::getStudy()->GetUseCaseBuilder();
   if (aUseCaseBuilder->IsUseCaseNode(myObject)) {
     ok = aUseCaseBuilder->HasChildren(myObject);
     // TODO: check name as below?
   }
   else {
-    _PTR(ChildIterator) it ( myObject->GetStudy()->NewChildIterator( myObject ) );
+    _PTR(ChildIterator) it ( SalomeApp_Application::getStudy()->NewChildIterator( myObject ) );
     for ( ; it->More() && !ok; it->Next() ) {
       _PTR(SObject) obj = it->Value();
       if ( obj ) {
@@ -548,36 +548,28 @@ QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const
     QString aStrings = fromUtf8( str );
     
     //Special case to show NoteBook variables in the "Value" column of the OB 
-    if ( LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root() ) )
+    bool ok = false;
+    QStringList aSectionList = aStrings.split( "|" );
+    if ( !aSectionList.isEmpty() )
     {
-      if ( SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() ) )
+      QString aLastSection = aSectionList.last();
+      QStringList aStringList = aLastSection.split( ":" );
+      if ( !aStringList.isEmpty() )
       {
-        _PTR(Study) studyDS( aStudy->studyDS() );
-
-        bool ok = false;
-        QStringList aSectionList = aStrings.split( "|" );
-        if ( !aSectionList.isEmpty() )
+        ok = true;
+        for ( int i = 0, n = aStringList.size(); i < n; i++ )
         {
-          QString aLastSection = aSectionList.last();
-          QStringList aStringList = aLastSection.split( ":" );
-          if ( !aStringList.isEmpty() )
-          {
-            ok = true;
-            for ( int i = 0, n = aStringList.size(); i < n; i++ )
-            {
-              QString aStr = aStringList[i];
-              if ( studyDS->IsVariable( aStr.toStdString() ) )
-                val.append( aStr + ", " );
-            }
-
-            if ( !val.isEmpty() )
-              val.remove( val.length() - 2, 2 );
-          }
+          QString aStr = aStringList[i];
+          if ( SalomeApp_Application::getStudy()->IsVariable( aStr.toStdString() ) )
+            val.append( aStr + ", " );
         }
-        if( !ok )
-          val = aStrings;
+
+        if ( !val.isEmpty() )
+          val.remove( val.length() - 2, 2 );
       }
     }
+    if( !ok )
+      val = aStrings;
   }
   else if ( obj->FindAttribute( attr, "AttributeInteger" ) )
   {
index 9bdda7525743fd458d2b7a8d1ffc8637f7723a7f..216b107cdd0377d86e2fb624c16c7996a63389d5 100644 (file)
@@ -425,38 +425,35 @@ SalomeApp_DoubleSpinBox::SearchState SalomeApp_DoubleSpinBox::findVariable( cons
   value = 0;
   if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
   {
-    if( SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
-    {
-      _PTR(Study) studyDS = study->studyDS();
+    _PTR(Study) studyDS = SalomeApp_Application::getStudy();
 
-      std::string aName = name.toStdString();
-      if( studyDS->IsVariable( aName ) )
+    std::string aName = name.toStdString();
+    if( studyDS->IsVariable( aName ) )
+    {
+      if( studyDS->IsReal( aName ) || studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
       {
-        if( studyDS->IsReal( aName ) || studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
+        if( studyDS->IsString( aName ) )
         {
-          if( studyDS->IsString( aName ) )
-            {
 #ifndef DISABLE_PYCONSOLE
-              PyConsole_Interp* pyInterp = app->getPyInterp();
-              PyLockWrapper aLock; // Acquire GIL
-              std::string command;
-              command  = "import salome_notebook ; ";
-              command += "salome_notebook.notebook.setAsReal(\"";
-              command += aName;
-              command += "\")";
-              bool aResult;
-              aResult = pyInterp->run(command.c_str());
-              if(aResult)
-                {
-                  return IncorrectType;
-                }
+          PyConsole_Interp* pyInterp = app->getPyInterp();
+          PyLockWrapper aLock; // Acquire GIL
+          std::string command;
+          command  = "import salome_notebook ; ";
+          command += "salome_notebook.notebook.setAsReal(\"";
+          command += aName;
+          command += "\")";
+          bool aResult;
+          aResult = pyInterp->run(command.c_str());
+          if(aResult)
+          {
+            return IncorrectType;
+          }
 #endif
-            }
-          value = studyDS->GetReal( aName );
-          return Found;
         }
-        return IncorrectType;
+        value = studyDS->GetReal( aName );
+        return Found;
       }
+      return IncorrectType;
     }
   }
   return NotFound;
index 16c1fcc29fdbebf2f92f01983c0ac65bc9ae8652..108cee699ef84f9262bb889604f18a1f77a5694f 100644 (file)
@@ -65,43 +65,37 @@ SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theCompone
 {
   SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
 
-  if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy()))
+  if (CORBA::is_nil(theComponent))
     return aStreamFile._retn();
 
-  const int studyId = theComponent->GetStudy()->StudyId();
-
   // Get a temporary directory to store a file
   //std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
 
-  if (myMap.count(studyId)) {
-    std::string componentName (theComponent->ComponentDataType());
-
-    // Error somewhere outside - Save() called with
-    // wrong SComponent instance
-    if ( myComponentName != componentName )
-      return aStreamFile._retn();
+  std::string componentName (theComponent->ComponentDataType());
 
-    const ListOfFiles& listOfFiles = myMap[studyId];
+  // Error somewhere outside - Save() called with
+  // wrong SComponent instance
+  if ( myComponentName != componentName )
+    return aStreamFile._retn();
 
-    // listOfFiles must contain temporary directory name in its first item
-    // and names of files (relatively the temporary directory) in the others
-    const int n = listOfFiles.size() - 1;
+  // listOfFiles must contain temporary directory name in its first item
+  // and names of files (relatively the temporary directory) in the others
+  const int n = myListOfFiles.size() - 1;
 
-    if (n > 0) { // there are some files, containing persistent data of the component
-      std::string aTmpDir = listOfFiles[0];
+  if (n > 0) { // there are some files, containing persistent data of the component
+    std::string aTmpDir = myListOfFiles[0];
 
-      // Create a list to store names of created files
-      SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
-      aSeq->length(n);
-      for (int i = 0; i < n; i++)
-        aSeq[i] = CORBA::string_dup(listOfFiles[i + 1].c_str());
+    // Create a list to store names of created files
+    ListOfFiles aSeq;
+    aSeq.reserve(n);
+    for (int i = 0; i < n; i++)
+      aSeq.push_back(CORBA::string_dup(myListOfFiles[i + 1].c_str()));
 
-      // Convert a file to the byte stream
-      aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq.in(), isMultiFile);
+    // Convert a file to the byte stream
+    aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq, isMultiFile);
 
-      // Remove the files and tmp directory, created by the component storage procedure
-      if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
-    }
+    // Remove the files and tmp directory, created by the component storage procedure
+    if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq, true);
   }
 
   return aStreamFile._retn();
@@ -113,7 +107,7 @@ CORBA::Boolean SalomeApp_Engine_i::Load (SALOMEDS::SComponent_ptr theComponent,
                                          bool isMultiFile)
 {
   std::cout << "SalomeApp_Engine_i::Load() isMultiFile = " << isMultiFile << std::endl;
-  if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy()))
+  if (CORBA::is_nil(theComponent))
     return false;
 
   // Error somewhere outside - Load() called with
@@ -122,53 +116,42 @@ CORBA::Boolean SalomeApp_Engine_i::Load (SALOMEDS::SComponent_ptr theComponent,
   if ( myComponentName != componentName )
     return false;
 
-  const int studyId = theComponent->GetStudy()->StudyId();
-
   // Create a temporary directory for the component's data files
   std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
 
   // Convert the byte stream theStream to a files and place them in the tmp directory.
   // The files and temporary directory must be deleted by the component loading procedure.
-  SALOMEDS::ListOfFileNames_var aSeq =
+  ListOfFiles aSeq =
     SALOMEDS_Tool::PutStreamToFiles(theFile, aTmpDir.c_str(), isMultiFile);
 
   // Store list of file names to be used by the component loading procedure
-  const int n = aSeq->length() + 1;
+  const int n = aSeq.size() + 1;
   ListOfFiles listOfFiles (n);
   listOfFiles[0] = aTmpDir;
   for (int i = 1; i < n; i++)
     listOfFiles[i] = std::string(aSeq[i - 1]);
 
-  SetListOfFiles(listOfFiles, studyId);
+  SetListOfFiles(listOfFiles);
 
   return true;
 }
 
-SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int theStudyId)
+SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles()
 {
-  ListOfFiles aListOfFiles;
-
-  if (myMap.find(theStudyId) != myMap.end())
-  {
-    aListOfFiles = myMap[theStudyId];
-  }
-
-  return aListOfFiles;
+  return myListOfFiles;
 }
 
-void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles& theListOfFiles,
-                                         const int          theStudyId)
+void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles& theListOfFiles)
 {
-  myMap[theStudyId] = theListOfFiles;
+  myListOfFiles = theListOfFiles;
 }
 
 /*! 
  *  DumpPython implementation for light modules
  */
-Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy, 
-                                                CORBA::Boolean isPublished, 
-                                                CORBA::Boolean isMultiFile, 
-                                                CORBA::Boolean& isValidScript)
+Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Boolean isPublished,
+                                                                        CORBA::Boolean isMultiFile,
+                                                                        CORBA::Boolean& isValidScript)
 {
   MESSAGE("SalomeApp_Engine_i::DumpPython(): myComponentName = "<<
          myComponentName << ", this = " << this);
@@ -182,24 +165,13 @@ Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy,
   aStreamFile[0] = '\0';
   isValidScript = true;
 
-  if (CORBA::is_nil(theStudy))
-    return aStreamFile._retn();
-
-  SALOMEDS::Study_var studyDS = SALOMEDS::Study::_narrow( theStudy );
-  const int studyId = studyDS->StudyId();
-
-  if (!myMap.count(studyId))
-    return aStreamFile._retn();
-
-  ListOfFiles listOfFiles = myMap[studyId];
-
   // listOfFiles must contain temporary directory name in its first item
   // and names of files (relatively the temporary directory) in the others
-  if ( listOfFiles.size() < 2 ) 
+  if ( myListOfFiles.size() < 2 )
     return aStreamFile._retn();
 
   // there are some files, containing persistent data of the component
-  QString aTmpPath( listOfFiles.front().c_str() );
+  QString aTmpPath( myListOfFiles.front().c_str() );
   QDir aTmpDir( aTmpPath );
   if ( !aTmpDir.exists() )
     return aStreamFile._retn();    
@@ -208,8 +180,8 @@ Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy,
   QStringList aFilePaths;
   QList<qint64> aFileSizes;
   qint64 aBuffSize = 0;
-  ListOfFiles::const_iterator aFIt  = listOfFiles.begin();
-  ListOfFiles::const_iterator aFEnd = listOfFiles.end();
+  ListOfFiles::const_iterator aFIt  = myListOfFiles.begin();
+  ListOfFiles::const_iterator aFEnd = myListOfFiles.end();
   aFIt++;
   for (; aFIt != aFEnd; aFIt++){
     QString aFileName( (*aFIt).c_str() );
index ec2641913840c79fef3740f00033faa38de75ac2..98412512b474d4b69021963bc90e5023fb7e4bbb 100644 (file)
@@ -55,17 +55,15 @@ public:
                                const char* theURL, 
                                bool isMultiFile );
 
-  virtual Engines::TMPFile* DumpPython(CORBA::Object_ptr theStudy,
-                                       CORBA::Boolean isPublished,
+  virtual Engines::TMPFile* DumpPython(CORBA::Boolean isPublished,
                                        CORBA::Boolean isMultiFile,
                                        CORBA::Boolean& isValidScript);
 
 public:
   typedef std::vector<std::string> ListOfFiles;
 
-  ListOfFiles             GetListOfFiles (const int          theStudyId);
-  void                    SetListOfFiles (const ListOfFiles& theListOfFiles,
-                                          const int          theStudyId);
+  ListOfFiles             GetListOfFiles ();
+  void                    SetListOfFiles (const ListOfFiles& theListOfFiles);
 
   static std::string         EngineIORForComponent( const char* theComponentName,
                                                    bool toCreate );
@@ -85,7 +83,7 @@ public:
   char* IORToLocalPersistentID( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean,  CORBA::Boolean )                                                {return 0;}
   char* LocalPersistentIDToIOR( SALOMEDS::SObject_ptr, const char*, CORBA::Boolean,  CORBA::Boolean )                                                {return 0;}
   bool CanPublishInStudy( CORBA::Object_ptr )                                                                                                        {return 0;}
-  SALOMEDS::SObject_ptr PublishInStudy(SALOMEDS::Study_ptr, SALOMEDS::SObject_ptr, CORBA::Object_ptr, const char* ) throw (SALOME::SALOME_Exception) {return 0;}
+  SALOMEDS::SObject_ptr PublishInStudy( SALOMEDS::SObject_ptr, CORBA::Object_ptr, const char* ) throw (SALOME::SALOME_Exception)                     {return 0;}
   CORBA::Boolean CanCopy( SALOMEDS::SObject_ptr )                                                                                                    {return 0;}
   SALOMEDS::TMPFile* CopyFrom( SALOMEDS::SObject_ptr, CORBA::Long& )                                                                                 {return 0;}
   CORBA::Boolean CanPaste( const char*, CORBA::Long )                                                                                                {return 0;}
@@ -98,8 +96,7 @@ private:
   static PortableServer::POA_var     poa();
   static SALOME_NamingService*       namingService();
 private:
-  typedef std::map<int, ListOfFiles> MapOfListOfFiles;
-  MapOfListOfFiles                   myMap;
+  ListOfFiles                        myListOfFiles;
 
   std::string                        myComponentName;
 };
index 64bf5a306b3c3cc08c5f37c912cdbec7aded84ef..bb4e01b880f698f4cf0e42872bdba89a7b27d482 100644 (file)
@@ -373,38 +373,35 @@ SalomeApp_IntSpinBox::SearchState SalomeApp_IntSpinBox::findVariable( const QStr
   value = 0;
   if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
   {
-    if( SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
-    {
-      _PTR(Study) studyDS = study->studyDS();
+    _PTR(Study) studyDS = SalomeApp_Application::getStudy();
 
-      std::string aName = name.toStdString();
-      if( studyDS->IsVariable( aName ) )
+    std::string aName = name.toStdString();
+    if( studyDS->IsVariable( aName ) )
+    {
+      if( studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
       {
-        if( studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
+        if( studyDS->IsString( aName ) )
         {
-          if( studyDS->IsString( aName ) )
-            {
 #ifndef DISABLE_PYCONSOLE
-              PyConsole_Interp* pyInterp = app->getPyInterp();
-              PyLockWrapper aLock; // Acquire GIL
-              std::string command;
-              command  = "import salome_notebook ; ";
-              command += "salome_notebook.notebook.setAsInteger(\"";
-              command += aName;
-              command += "\")";
-              bool aResult;
-              aResult = pyInterp->run(command.c_str());
-              if(aResult)
-                {
-                  return IncorrectType;
-                }
+          PyConsole_Interp* pyInterp = app->getPyInterp();
+          PyLockWrapper aLock; // Acquire GIL
+          std::string command;
+          command  = "import salome_notebook ; ";
+          command += "salome_notebook.notebook.setAsInteger(\"";
+          command += aName;
+          command += "\")";
+          bool aResult;
+          aResult = pyInterp->run(command.c_str());
+          if(aResult)
+          {
+            return IncorrectType;
+          }
 #endif
-            }
-          value = studyDS->GetInteger( aName );
-          return Found;
         }
-        return IncorrectType;
+        value = studyDS->GetInteger( aName );
+        return Found;
       }
+      return IncorrectType;
     }
   }
   return NotFound;
index 749ce3798668a83ef6875d19cd658b77da672908..64d75941f1a2bc7996fd903d6e258720d1c8e282 100644 (file)
@@ -378,7 +378,7 @@ int NoteBook_Table::getUniqueIndex() const
  *  Purpose  : Add variables in the table from theStudy
  */
 //============================================================================
-void NoteBook_Table::Init(_PTR(Study) theStudy)
+void NoteBook_Table::Init()
 {
   isProcessItemChangedSignal = false;
 
@@ -403,10 +403,10 @@ void NoteBook_Table::Init(_PTR(Study) theStudy)
   myVariableMap.clear();
 
   //Add all variables into the table
-  std::vector<std::string> aVariables = theStudy->GetVariableNames();
+  std::vector<std::string> aVariables = SalomeApp_Application::getStudy()->GetVariableNames();
   for(int iVar = 0; iVar < aVariables.size(); iVar++ ) {
     AddRow(QString(aVariables[iVar].c_str()),
-           Variable2String(aVariables[iVar],theStudy));
+           Variable2String(aVariables[iVar]));
   }
 
   //Add empty row
@@ -414,8 +414,6 @@ void NoteBook_Table::Init(_PTR(Study) theStudy)
   isProcessItemChangedSignal = true;
 
   ResetMaps();
-
-  myStudy = theStudy;
 }
 
 //============================================================================
@@ -423,18 +421,18 @@ void NoteBook_Table::Init(_PTR(Study) theStudy)
  *  Purpose  : Convert variable values to QString
  */
 //============================================================================
-QString NoteBook_Table::Variable2String(const std::string& theVarName,
-                                        _PTR(Study) theStudy)
+QString NoteBook_Table::Variable2String(const std::string& theVarName)
 {
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
   QString aResult;
-  if( theStudy->IsReal(theVarName) )
-    aResult = QString::number(theStudy->GetReal(theVarName));
-  else if( theStudy->IsInteger(theVarName) )
-    aResult = QString::number(theStudy->GetInteger(theVarName));
-  else if( theStudy->IsBoolean(theVarName) )
-    aResult = theStudy->GetBoolean(theVarName) ? QString("True") : QString("False");
-  else if( theStudy->IsString(theVarName) )
-    aResult = theStudy->GetString(theVarName).c_str();
+  if( aStudy->IsReal(theVarName) )
+    aResult = QString::number(aStudy->GetReal(theVarName));
+  else if( aStudy->IsInteger(theVarName) )
+    aResult = QString::number(aStudy->GetInteger(theVarName));
+  else if( aStudy->IsBoolean(theVarName) )
+    aResult = aStudy->GetBoolean(theVarName) ? QString("True") : QString("False");
+  else if( aStudy->IsString(theVarName) )
+    aResult = aStudy->GetString(theVarName).c_str();
   
   return aResult;
 }
@@ -566,7 +564,7 @@ void NoteBook_Table::onItemChanged(QTableWidgetItem* theItem)
         if( myVariableMap.contains( anIndex ) )
         {
           const NoteBoox_Variable& aVariable = myVariableMap[ anIndex ];
-          if( !aVariable.Name.isEmpty() && myStudy->IsVariableUsed( std::string( aVariable.Name.toLatin1().constData() ) ) )
+          if( !aVariable.Name.isEmpty() && SalomeApp_Application::getStudy()->IsVariableUsed( std::string( aVariable.Name.toLatin1().constData() ) ) )
           {
             if( QMessageBox::warning( parentWidget(), tr( "WARNING" ),
                                       tr( "RENAME_VARIABLE_IS_USED" ).arg( aVariable.Name ),
@@ -661,6 +659,7 @@ bool NoteBook_Table::IsUniqueName(const NoteBook_TableRow* theRow) const
 //============================================================================
 void NoteBook_Table::RemoveSelected()
 {
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
   isProcessItemChangedSignal = false;
   QList<QTableWidgetItem*> aSelectedItems = selectedItems();
   if( !(aSelectedItems.size() > 0)) {
@@ -678,7 +677,7 @@ void NoteBook_Table::RemoveSelected()
       else {
         int nRow = row(aSelectedItems[i]);
 
-        if( myStudy->IsVariableUsed( std::string( aRow->GetName().toLatin1().constData() ) ) )
+        if( aStudy->IsVariableUsed( std::string( aRow->GetName().toLatin1().constData() ) ) )
         {
           if( QMessageBox::warning( parentWidget(), tr( "WARNING" ),
                                     tr( "REMOVE_VARIABLE_IS_USED" ).arg( aRow->GetName() ),
@@ -696,7 +695,7 @@ void NoteBook_Table::RemoveSelected()
           myVariableMap.remove( index );
         removeRow(nRow);
         myRows.removeAt(nRow);
-        if(myStudy->IsVariable(aVarName.toLatin1().constData()))
+        if(aStudy->IsVariable(aVarName.toLatin1().constData()))
           removedFromStudy = true;
       }
     }
@@ -757,9 +756,8 @@ void NoteBook_Table::ResetMaps()
  *  Purpose  : Constructor
  */
 //============================================================================
-SalomeApp_NoteBook::SalomeApp_NoteBook(QWidget * parent, _PTR(Study) theStudy):
-  QWidget(parent),
-  myStudy(theStudy)
+SalomeApp_NoteBook::SalomeApp_NoteBook(QWidget * parent):
+  QWidget(parent)
 {
   setObjectName("SalomeApp_NoteBook");
   setWindowTitle(tr("NOTEBOOK_TITLE"));
@@ -789,7 +787,7 @@ SalomeApp_NoteBook::SalomeApp_NoteBook(QWidget * parent, _PTR(Study) theStudy):
   connect( myUpdateStudyBtn, SIGNAL(clicked()), this, SLOT(onUpdateStudy()) );
   connect( myRemoveButton, SIGNAL(clicked()), this, SLOT(onRemove()));
   
-  myTable->Init(myStudy);
+  myTable->Init();
 
   myDumpedStudyScript = "";  
   myIsDumpedStudySaved = false;
@@ -808,10 +806,8 @@ SalomeApp_NoteBook::~SalomeApp_NoteBook(){}
  *  Purpose  : init variable table
  */
 //============================================================================
-void SalomeApp_NoteBook::Init(_PTR(Study) theStudy){
-  if(myStudy!= theStudy)
-    myStudy = theStudy;
-  myTable->Init(myStudy);
+void SalomeApp_NoteBook::Init(){
+  myTable->Init();
 }
 
 
@@ -822,7 +818,7 @@ void SalomeApp_NoteBook::Init(_PTR(Study) theStudy){
 //============================================================================
 void SalomeApp_NoteBook::onVarUpdate(QString theVarName)
 {
-  myTable->Init(myStudy);
+  myTable->Init();
 }
 
 //============================================================================
@@ -837,6 +833,7 @@ void SalomeApp_NoteBook::onApply()
     SUIT_MessageBox::warning( this, tr( "WARNING" ), tr( "INCORRECT_DATA" ) );
     return;
   }
+  _PTR(Study) aStudy = SalomeApp_Application::getStudy();
 
   double aDVal;
   int    anIVal;
@@ -852,7 +849,7 @@ void SalomeApp_NoteBook::onApply()
     if( aVariableMapRef.contains( anIndex ) )
     {
       QString aRemovedVariable = aVariableMapRef[ anIndex ].Name;
-      myStudy->RemoveVariable( std::string( aRemovedVariable.toLatin1().constData() ) );
+      aStudy->RemoveVariable( std::string( aRemovedVariable.toLatin1().constData() ) );
     }
   }
 
@@ -874,22 +871,22 @@ void SalomeApp_NoteBook::onApply()
 
         if( !aNameRef.isEmpty() && !aValueRef.isEmpty() && aNameRef != aName )
         {
-          myStudy->RenameVariable( std::string( aNameRef.toLatin1().constData() ),
-                                   std::string( aName.toLatin1().constData() ) );
+          aStudy->RenameVariable( std::string( aNameRef.toLatin1().constData() ),
+                                  std::string( aName.toLatin1().constData() ) );
         }
       }
 
       if( NoteBook_TableRow::IsIntegerValue(aValue,&anIVal) )
-        myStudy->SetInteger(std::string(aName.toLatin1().constData()),anIVal);
+        aStudy->SetInteger(std::string(aName.toLatin1().constData()),anIVal);
 
       else if( NoteBook_TableRow::IsRealValue(aValue,&aDVal) )
-        myStudy->SetReal(std::string(aName.toLatin1().constData()),aDVal);
+        aStudy->SetReal(std::string(aName.toLatin1().constData()),aDVal);
     
       else if( NoteBook_TableRow::IsBooleanValue(aValue,&aBVal) )
-        myStudy->SetBoolean(std::string(aName.toLatin1().constData()),aBVal);
+        aStudy->SetBoolean(std::string(aName.toLatin1().constData()),aBVal);
     
       else
-        myStudy->SetString(std::string(aName.toLatin1().constData()),aValue.toStdString());
+        aStudy->SetString(std::string(aName.toLatin1().constData()),aValue.toStdString());
     }
   }
   myTable->ResetMaps();
@@ -898,7 +895,7 @@ void SalomeApp_NoteBook::onApply()
   if(app)
     app->updateActions();
   
-  myStudy->Modified();
+  aStudy->Modified();
 }
 
 //============================================================================
index ba4e96b25eda3e26ab430a4d74ce9c2bff252d18..4722ee7aace99bffb68561020996c2b0d05709f7 100644 (file)
@@ -95,9 +95,8 @@ class SALOMEAPP_EXPORT NoteBook_Table : public QTableWidget
   NoteBook_Table(QWidget * parent = 0);
   virtual ~NoteBook_Table();
 
-  void Init(_PTR(Study) theStudy);
-  static QString Variable2String(const std::string& theVarName,
-                                 _PTR(Study) theStudy);
+  void Init();
+  static QString Variable2String(const std::string& theVarName);
 
   bool IsValid() const;
 
@@ -137,18 +136,16 @@ class SALOMEAPP_EXPORT NoteBook_Table : public QTableWidget
   QList<int>  myRemovedRows;
   VariableMap myVariableMapRef;
   VariableMap myVariableMap;
-
-  _PTR(Study)      myStudy;
 };
 
 class SALOMEAPP_EXPORT SalomeApp_NoteBook : public QWidget 
 {
   Q_OBJECT
  public:
-  SalomeApp_NoteBook(QWidget * parent , _PTR(Study) theStudy);
+  SalomeApp_NoteBook(QWidget * parent);
   virtual ~SalomeApp_NoteBook();
 
-  void Init(_PTR(Study) theStudy);
+  void Init();
 
   QString getDumpedStudyName() { return myDumpedStudyName; }
   void setDumpedStudyName(QString theName) { myDumpedStudyName = theName; }
@@ -170,7 +167,6 @@ class SALOMEAPP_EXPORT SalomeApp_NoteBook : public QWidget
   QPushButton*     myRemoveButton;
   QPushButton*     myUpdateStudyBtn;
   
-  _PTR(Study)      myStudy;
   QString          myDumpedStudyScript; // path to script of dumped study
   QString          myDumpedStudyName;
   bool             myIsDumpedStudySaved;
index 4db5aff1a717e351f4c332d6114620250fde117d..942aa6da486ea6ede8c60e7798b0efcfdf0016b9 100755 (executable)
@@ -72,7 +72,7 @@ int SalomeApp_PyInterp::beforeRun()
     int ret = simpleRun( "import salome", false );
     if ( ret )
       return ret;
-    ret = simpleRun( "salome.salome_init(0,1)", false );
+    ret = simpleRun( "salome.salome_init(1)", false );
     if ( ret )
       return ret;
   }
index e44ceb9aef65f4662c9eaebc01a7c5f57073386b..71644587752f3507615f5cdebba8e86cb0f8698e 100644 (file)
@@ -82,9 +82,8 @@ class SalomeApp_Study::Observer_i : public virtual POA_SALOMEDS::Observer, QObje
 
 public:
 
-  Observer_i(_PTR(Study) aStudyDS, SalomeApp_Study* aStudy):QObject(aStudy)
+  Observer_i( SalomeApp_Study* aStudy):QObject(aStudy)
   {
-    myStudyDS=aStudyDS;
     myStudy=aStudy;
     fillEntryMap();
   }
@@ -122,7 +121,7 @@ public:
     switch(event) {
     case 1:
       { //Add sobject
-        _PTR(SObject) aSObj = myStudyDS->FindObjectID(theID);
+        _PTR(SObject) aSObj = SalomeApp_Application::getStudy()->FindObjectID(theID);
         _PTR(SComponent) aSComp = aSObj->GetFatherComponent();
 
         if (!aSComp || aSComp->IsNull()) {
@@ -131,7 +130,7 @@ public:
         }
 
         // Mantis issue 0020136: Drag&Drop in OB
-        _PTR(UseCaseBuilder) aUseCaseBuilder = myStudyDS->GetUseCaseBuilder();
+        _PTR(UseCaseBuilder) aUseCaseBuilder = SalomeApp_Application::getStudy()->GetUseCaseBuilder();
         if (aUseCaseBuilder->IsUseCaseNode(aSComp)) { // BEGIN: work with tree nodes structure
           if (!aUseCaseBuilder->IsUseCaseNode(aSObj)) {
             // tree node is not yet set, it is a normal situation
@@ -392,7 +391,6 @@ private:
   }
 
 private:
-  _PTR(Study)      myStudyDS;
   SalomeApp_Study* myStudy;
   EntryMap         entry2SuitObject;
 };
@@ -404,6 +402,7 @@ private:
 SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
 : LightApp_Study( app ), myObserver( 0 )
 {
+  myStudyDS = SalomeApp_Application::getStudy();
 }
 
 /*!
@@ -424,17 +423,6 @@ void SalomeApp_Study::onNoteBookVarUpdate( QString theVarName)
 }
 #endif
 
-/*!
-  Gets study id.
-*/
-int SalomeApp_Study::id() const
-{
-  int id = -1;
-  if ( studyDS() )
-    id = studyDS()->StudyId();
-  return id;
-}
-
 /*!
   Get study name.
 */
@@ -444,7 +432,7 @@ QString SalomeApp_Study::studyName() const
   // it can be changed outside of GUI
   // TEMPORARILY SOLUTION: better to be implemented with help of SALOMEDS observers
   if ( studyDS() ) {
-    QString newName = QString::fromUtf8(studyDS()->Name().c_str());
+    QString newName = QString::fromUtf8(studyDS()->URL().c_str());
     if ( LightApp_Study::studyName() != newName ) {
       SalomeApp_Study* that = const_cast<SalomeApp_Study*>( this );
       that->setStudyName( newName );
@@ -469,35 +457,7 @@ bool SalomeApp_Study::createDocument( const QString& theStr )
 {
   MESSAGE( "createDocument" );
 
-  // initialize myStudyDS, read HDF file
-  QString aName = newStudyName();
-
-  _PTR(Study) study;
-  bool showError = !application()->property("open_study_from_command_line").isValid() || 
-    !application()->property("open_study_from_command_line").toBool();
-  try {
-    study = _PTR(Study)( SalomeApp_Application::studyMgr()->NewStudy( aName.toUtf8().data() ) );
-  }
-  catch(const SALOME_Exception& ex) {
-    application()->putInfo(tr(ex.what()));
-    if ( showError )
-      SUIT_MessageBox::critical( SUIT_Session::session()->activeApplication()->desktop(),
-                                 tr("ERR_ERROR"), tr(ex.what()));
-    return false;
-  } 
-  catch(...) {
-    application()->putInfo(tr("CREATE_DOCUMENT_PROBLEM"));
-    if ( showError )
-      SUIT_MessageBox::critical( SUIT_Session::session()->activeApplication()->desktop(),
-                                 tr("ERR_ERROR"), tr("CREATE_DOCUMENT_PROBLEM"));
-    return false;
-  }
-
-  if ( !study )
-    return false;
-
-  setStudyDS( study );
-  setStudyName( aName );
+  setStudyName( QString::fromUtf8(myStudyDS->URL().c_str()) );
 
   // create myRoot
   SalomeApp_RootObject* aRoot=new SalomeApp_RootObject( this );
@@ -509,7 +469,7 @@ bool SalomeApp_Study::createDocument( const QString& theStr )
   bool aRet = CAM_Study::createDocument( theStr );
 
 #ifdef WITH_SALOMEDS_OBSERVER
-  myObserver = new Observer_i(myStudyDS,this);
+  myObserver = new Observer_i(this);
   //attach an observer to the study with notification of modifications
   myStudyDS->attach(myObserver->_this(),true);
 #endif
@@ -527,12 +487,12 @@ bool SalomeApp_Study::openDocument( const QString& theFileName )
 {
   MESSAGE( "openDocument" );
 
-  // initialize myStudyDS, read HDF file
-  _PTR(Study) study;
-  bool showError = !application()->property("open_study_from_command_line").isValid() || 
+  // read HDF file
+  bool res = false;
+  bool showError = !application()->property("open_study_from_command_line").isValid() ||
     !application()->property("open_study_from_command_line").toBool();
   try {
-    study = _PTR(Study) ( SalomeApp_Application::studyMgr()->Open( theFileName.toUtf8().data() ) );
+    res = myStudyDS->Open( theFileName.toUtf8().data() );
   }
   catch(const SALOME_Exception& ex) {
     application()->putInfo(tr(ex.what()));
@@ -540,7 +500,7 @@ bool SalomeApp_Study::openDocument( const QString& theFileName )
       SUIT_MessageBox::critical( SUIT_Session::session()->activeApplication()->desktop(),
                                  tr("ERR_ERROR"), tr(ex.what()));
     return false;
-  } 
+  }
   catch(...) {
     application()->putInfo(tr("OPEN_DOCUMENT_PROBLEM"));
     if ( showError )
@@ -549,11 +509,9 @@ bool SalomeApp_Study::openDocument( const QString& theFileName )
     return false;
   }
 
-  if ( !study )
+  if ( !res)
     return false;
 
-  setStudyDS( study );
-
   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
 
   // update loaded data models: call open() and update() on them.
@@ -570,15 +528,15 @@ bool SalomeApp_Study::openDocument( const QString& theFileName )
 
 #ifdef WITH_SALOMEDS_OBSERVER
   dynamic_cast<SalomeApp_RootObject*>( root() )->setToSynchronize(false);
-  myObserver = new Observer_i(myStudyDS,this);
+  myObserver = new Observer_i(this);
   //attach an observer to the study with notification of modifications
   myStudyDS->attach(myObserver->_this(),true);
 #endif
 
-  bool res = CAM_Study::openDocument( theFileName );
+  res = CAM_Study::openDocument( theFileName );
 
   emit opened( this );
-  study->IsSaved(true);
+  myStudyDS->IsSaved(true);
 
   bool restore = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", true );
   if ( restore ) {
@@ -592,20 +550,13 @@ bool SalomeApp_Study::openDocument( const QString& theFileName )
 }
 
 /*!
-  Connects GUI study to SALOMEDS one already loaded into StudyManager
+  Connects GUI study to SALOMEDS one
   \param theStudyName - name of study
 */
 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
 {
   MESSAGE( "loadDocument" );
 
-  // obtain myStudyDS from StudyManager
-  _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( theStudyName.toUtf8().data() ) );
-  if ( !study )
-    return false;
-
-  setStudyDS( study );
-
   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
 
   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
@@ -625,7 +576,7 @@ bool SalomeApp_Study::loadDocument( const QString& theStudyName )
 
 #ifdef WITH_SALOMEDS_OBSERVER
   dynamic_cast<SalomeApp_RootObject*>( root() )->setToSynchronize(false);
-  myObserver = new Observer_i(myStudyDS,this);
+  myObserver = new Observer_i(this);
   //attach an observer to the study with notification of modifications
   myStudyDS->attach(myObserver->_this(),true);
 #endif
@@ -681,9 +632,7 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
 
   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
   bool isAscii = resMgr->booleanValue( "Study", "ascii_file", false );
-  bool res = (isAscii ?
-    SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.toUtf8().data(), studyDS(), isMultiFile ) :
-    SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.toUtf8().data(), studyDS(), isMultiFile ))
+  bool res = studyDS()->SaveAs( theFileName.toUtf8().data(), isMultiFile, isAscii )
     && CAM_Study::saveDocumentAs( theFileName );
 
   res = res && saveStudyData(theFileName);
@@ -726,9 +675,7 @@ bool SalomeApp_Study::saveDocument()
 
   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
   bool isAscii = resMgr->booleanValue( "Study", "ascii_file", false );
-  bool res = (isAscii ?
-    SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
-    SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile )) && CAM_Study::saveDocument();
+  bool res = studyDS()->Save( isMultiFile, isAscii ) && CAM_Study::saveDocument();
 
   res = res && saveStudyData(studyName());
   if ( res )
@@ -745,24 +692,18 @@ void SalomeApp_Study::closeDocument(bool permanently)
   LightApp_Study::closeDocument(permanently);
 
   // close SALOMEDS document
-  _PTR(Study) studyPtr = studyDS();
-  if ( studyPtr )
-  {
-    if ( myObserver )
-      myStudyDS->detach( myObserver->_this() );
-    if ( permanently ) {
-      SUIT_Desktop* desk = SUIT_Session::session()->activeApplication()->desktop();
-      bool isBlocked = desk->signalsBlocked();
-      desk->blockSignals( true );
-      SalomeApp_Application::studyMgr()->Close( studyPtr );
-      desk->blockSignals( isBlocked );
+  if ( myObserver )
+    myStudyDS->detach( myObserver->_this() );
+  if ( permanently ) {
+    SUIT_Desktop* desk = SUIT_Session::session()->activeApplication()->desktop();
+    bool isBlocked = desk->signalsBlocked();
+    desk->blockSignals( true );
+    myStudyDS->Clear();
+    desk->blockSignals( isBlocked );
 #ifndef DISABLE_PYCONSOLE
-      SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( application() );
-      app->getPyInterp()->destroy();
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( application() );
+    app->getPyInterp()->destroy();
 #endif
-    }
-    SALOMEDSClient_Study* aStudy = 0;
-    setStudyDS( _PTR(Study)(aStudy) );
   }
 }
 
@@ -789,13 +730,12 @@ bool SalomeApp_Study::dump( const QString& theFileName,
   int savePoint;
   _PTR(AttributeParameter) ap;
   _PTR(IParameters) ip = ClientFactory::getIParameters(ap);
-  _PTR(Study) aStudy = studyDS();
 
-  if( ip->isDumpPython( aStudy ) ) 
-    ip->setDumpPython( aStudy ); //Unset DumpPython flag.
+  if( ip->isDumpPython() )
+    ip->setDumpPython(); //Unset DumpPython flag.
 
   if ( toSaveGUI ) { //SRN: Store a visual state of the study at the save point for DumpStudy method
-    ip->setDumpPython( aStudy );
+    ip->setDumpPython();
     //SRN: create a temporary save point
     savePoint = SalomeApp_VisualState( 
       dynamic_cast<SalomeApp_Application*>( application() ) ).storeState(); 
@@ -825,10 +765,10 @@ bool SalomeApp_Study::dump( const QString& theFileName,
   // Now dump SALOMEDS part that also involves SalomeApp_Engine in case if 
   // any light module is present in the current configuration
   QFileInfo aFileInfo( theFileName );
-  bool res = aStudy->DumpStudy( aFileInfo.absolutePath().toUtf8().data(),
-                                aFileInfo.baseName().toUtf8().data(),
-                                toPublish,
-                                isMultiFile);
+  bool res = myStudyDS->DumpStudy( aFileInfo.absolutePath().toUtf8().data(),
+                                  aFileInfo.baseName().toUtf8().data(),
+                                  toPublish,
+                                  isMultiFile);
   if ( toSaveGUI )
     removeSavePoint( savePoint ); //SRN: remove the created temporary save point.
 
@@ -857,8 +797,7 @@ bool SalomeApp_Study::isModified() const
  */
 void SalomeApp_Study::Modified()
 {
-  if(_PTR(Study) aStudy = studyDS())
-    aStudy->Modified();
+  myStudyDS->Modified();
   LightApp_Study::Modified();
 }
 
@@ -944,14 +883,6 @@ bool SalomeApp_Study::openStudyData( const QString& theFileName )
  return true;
 }
 
-/*!
-  Set studyDS.
-*/
-void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
-{
-  myStudyDS = s;
-}
-
 /*!
   Virtual method re-implemented from LightApp_Study in order to create
   the module object connected to SALOMEDS - SalomeApp_ModuleObject.
@@ -985,11 +916,7 @@ CAM_ModuleObject* SalomeApp_Study::createModuleObject( LightApp_DataModel* theDa
   }
 
   if ( !res ){
-    _PTR(Study) aStudy = studyDS();
-    if ( !aStudy )
-      return res;
-
-    _PTR(SComponent) aComp = aStudy->FindComponent( 
+    _PTR(SComponent) aComp = myStudyDS->FindComponent(
       theDataModel->module()->name().toStdString() );
     if ( !aComp )
       return res;
@@ -1021,16 +948,13 @@ void SalomeApp_Study::addComponent(const CAM_DataModel* dm)
   // 1. aModule == 0 means that this is a light module (no CORBA enigine)
   if (!aModule) {
     // Check SComponent existance
-    _PTR(Study) aStudy = studyDS();
-    if (!aStudy)
-      return;
 
     std::string aCompDataType = dm->module()->name().toStdString();
 
-    _PTR(SComponent) aComp = aStudy->FindComponent(aCompDataType);
+    _PTR(SComponent) aComp = myStudyDS->FindComponent(aCompDataType);
     if (!aComp) {
       // Create SComponent
-      _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
+      _PTR(StudyBuilder) aBuilder = myStudyDS->NewBuilder();
       aComp = aBuilder->NewComponent(aCompDataType);
       aBuilder->SetName(aComp, dm->module()->moduleName().toStdString());
       QString anIconName = dm->module()->iconName();
@@ -1049,7 +973,7 @@ void SalomeApp_Study::addComponent(const CAM_DataModel* dm)
       SalomeApp_DataModel::synchronize( aComp, this );
     }
     else {
-      _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
+      _PTR(StudyBuilder) aBuilder = myStudyDS->NewBuilder();
       aBuilder->SetName(aComp, dm->module()->moduleName().toStdString());
       QString anIconName = dm->module()->iconName();
       if (!anIconName.isEmpty()) {
@@ -1072,7 +996,6 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm
 
   //  SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( dm->module() );
-  _PTR(Study)       aStudy = studyDS(); // shared_ptr cannot be used here
   _PTR(SComponent)  aSComp;
   QString anEngine;
   // 1. aModule == 0 means that this is a light module (no CORBA enigine)
@@ -1080,7 +1003,7 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm
     // Issue 21377 - using separate engine for each type of light module
     std::string aCompDataType = dm->module()->name().toStdString();
     anEngine = SalomeApp_Engine_i::EngineIORForComponent( aCompDataType.c_str(), true ).c_str();
-    aSComp = aStudy->FindComponent( aCompDataType );
+    aSComp = myStudyDS->FindComponent( aCompDataType );
   }
   else {
     SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
@@ -1091,11 +1014,11 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm
       anEngine = aDM->getModule()->engineIOR();
       if ( anEngine.isEmpty() )
         return false;
-      aSComp = aStudy->FindComponentID( std::string( anId.toLatin1() ) );
+      aSComp = myStudyDS->FindComponentID( std::string( anId.toLatin1() ) );
     }
   }
   if ( aSComp ) {
-    _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() );
+    _PTR(StudyBuilder) aBuilder( myStudyDS->NewBuilder() );
     if ( aBuilder ) {
       try {
         aBuilder->LoadWith( aSComp, std::string( anEngine.toLatin1() ) );
@@ -1129,28 +1052,6 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm
   return false;
 }
 
-/*!
-  Create new study name.
-*/
-QString SalomeApp_Study::newStudyName() const
-{
-  std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
-  QString prefix( "Study%1" ), newName, curName;
-  int i = 1, j, n = studies.size();
-  while ( newName.isEmpty() ){
-    curName = prefix.arg( i );
-    for ( j = 0 ; j < n; j++ ){
-      if ( !strcmp( studies[j].c_str(), curName.toLatin1() ) )
-        break;
-    }
-    if ( j == n )
-      newName = curName;
-    else
-      i++;
-  }
-  return newName;
-}
-
 /*!
   Note that this method does not create or activate SalomeApp_Engine_i instance,
   therefore it can be called safely for any kind of module, but for full
@@ -1163,7 +1064,7 @@ std::vector<std::string> SalomeApp_Study::GetListOfFiles( const char* theModuleN
   // Issue 21377 - using separate engine for each type of light module
   SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false );
   if (aDefaultEngine)
-    return aDefaultEngine->GetListOfFiles(id());
+    return aDefaultEngine->GetListOfFiles();
 
   std::vector<std::string> aListOfFiles;
   return aListOfFiles;
@@ -1183,7 +1084,7 @@ void SalomeApp_Study::SetListOfFiles ( const char* theModuleName,
   // Issue 21377 - using separate engine for each type of light module
   SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance( theModuleName, false );
   if (aDefaultEngine)
-    aDefaultEngine->SetListOfFiles(theListOfFiles, id());
+    aDefaultEngine->SetListOfFiles(theListOfFiles);
 }
 
 /*!
@@ -1204,17 +1105,17 @@ void SalomeApp_Study::RemoveTemporaryFiles ( const char* theModuleName, const bo
   if (isMultiFile)
     return;
 
-  std::vector<std::string> aListOfFiles = GetListOfFiles( theModuleName );
+  SALOMEDS_Tool::ListOfFiles aListOfFiles = GetListOfFiles( theModuleName );
   if (aListOfFiles.size() > 0) {
     std::string aTmpDir = aListOfFiles[0];
 
     const int n = aListOfFiles.size() - 1;
-    SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
-    aSeq->length(n);
+    std::vector<std::string> aSeq;
+    aSeq.reserve(n);
     for (int i = 0; i < n; i++)
-      aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str());
+      aSeq.push_back(CORBA::string_dup(aListOfFiles[i + 1].c_str()));
 
-    SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
+    SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq, true);
   }
 }
 
@@ -1226,7 +1127,7 @@ void SalomeApp_Study::RemoveTemporaryFiles ( const char* theModuleName, const bo
 void SalomeApp_Study::updateFromNotebook( const QString& theFileName, bool isSaved )
 {
   setStudyName(theFileName);
-  studyDS()->Name(theFileName.toStdString());
+  studyDS()->URL(theFileName.toStdString());
   setIsSaved( isSaved );
 }
 #endif
index cf93e4056d5126217a114889a4f829e9c6ae650b..2284df8dbff6f083a71a9584c6c6bb737d19ff50 100644 (file)
@@ -43,7 +43,6 @@ public:
   SalomeApp_Study( SUIT_Application* );
   virtual ~SalomeApp_Study();
 
-  virtual int         id() const;
   virtual QString     studyName() const;
 
   virtual bool        createDocument( const QString& );
@@ -103,7 +102,7 @@ protected:
 protected:
   virtual void        dataModelInserted( const CAM_DataModel* );
   virtual bool        openDataModel( const QString&, CAM_DataModel* );
-  void                setStudyDS(const _PTR(Study)& s );
+
   virtual CAM_ModuleObject* createModuleObject( LightApp_DataModel* theDataModel, 
                                                SUIT_DataObject* theParent ) const;
 protected slots:
@@ -112,9 +111,6 @@ protected slots:
   void                onNoteBookVarUpdate( QString theVarName );
 #endif
 
-private:
-  QString             newStudyName() const;
-
 private:
   _PTR(Study)         myStudyDS;
   Observer_i*         myObserver;
index 043a2e30c1ca8ec91647354a1be46fd3f317a3eb..55a4765c71a23aa7b259031b06058b5a8a7d4b8b 100644 (file)
@@ -25,6 +25,7 @@
 //  Author : Roman NIKOLAEV
 
 #include "SalomeApp_StudyPropertiesDlg.h"
+#include "SalomeApp_Application.h"
 #include "SalomeApp_Study.h"
 
 #include "SUIT_Session.h"
@@ -69,12 +70,6 @@ SalomeApp_StudyPropertiesDlg::SalomeApp_StudyPropertiesDlg(QWidget* parent)
 
   setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint );
 
-  // Display study properties
-  SalomeApp_Study* study =
-    dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
-  if (study)
-    myStudyDoc = study->studyDS();
-
   //Author
   QLabel* authorLbl = new QLabel(tr("PRP_AUTHOR"),this);
   myAuthor = new QLineEdit(this);
@@ -173,10 +168,10 @@ SalomeApp_StudyPropertiesDlg::~SalomeApp_StudyPropertiesDlg()
 */
 void SalomeApp_StudyPropertiesDlg::initData()
 {
-  bool hasData = (myStudyDoc != NULL);
+  bool hasData = (SalomeApp_Application::getStudy() != NULL);
   _PTR(AttributeStudyProperties) propAttr;
   if (hasData)
-    propAttr = myStudyDoc->GetProperties();
+    propAttr = SalomeApp_Application::getStudy()->GetProperties();
   hasData = hasData && propAttr;
   
   if (hasData) {
@@ -268,7 +263,7 @@ void SalomeApp_StudyPropertiesDlg::initData()
 */
 void SalomeApp_StudyPropertiesDlg::clickOnOk()
 {
-  _PTR(AttributeStudyProperties) propAttr = myStudyDoc->GetProperties();
+  _PTR(AttributeStudyProperties) propAttr = SalomeApp_Application::getStudy()->GetProperties();
   //Firstly, store locked flag
   if(propAttr) {
     bool bLocked = myLocked->isChecked();
index 7289eb800cc82064e8477e16286d9248e12881b4..a88d54edb64cd4d6b2cac9de9d854fc1842aeb5a 100644 (file)
@@ -60,7 +60,6 @@ private:
  void initData();
   
 private:
- _PTR(Study)          myStudyDoc;
  bool                 myIsChanged;
  QLineEdit*           myAuthor;
  QLabel*              myDate;
index 8d296e815f86f465eb620c478a75a0db7835a01a..d2652792b982b6329980973a64cd7fae5b437730 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "LightApp_DataOwner.h"
 #include "SalomeApp_Study.h"
+#include "SalomeApp_Application.h"
 
 /*!
   Constructor.
@@ -48,20 +49,18 @@ bool SalomeApp_TypeFilter::isOk( const SUIT_DataOwner* sOwner ) const
 {  
   const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*> ( sOwner );
 
-  SalomeApp_Study* aDoc =  getStudy();
-  if (owner && aDoc && aDoc->studyDS())
+  if (owner)
+  {
+    QString entry = owner->entry();
+
+    _PTR(SObject) aSObj( SalomeApp_Application::getStudy()->FindObjectID( entry.toStdString() ) );
+    if (aSObj)
     {
-      _PTR(Study) aStudy = aDoc->studyDS();
-      QString entry = owner->entry();
-      
-      _PTR(SObject) aSObj( aStudy->FindObjectID( entry.toStdString() ) );
-      if (aSObj)
-        {
-          _PTR(SComponent) aComponent(aSObj->GetFatherComponent());
-          if ( aComponent && (aComponent->ComponentDataType() == myKind.toStdString()) )
-            return true;
-        }
+      _PTR(SComponent) aComponent(aSObj->GetFatherComponent());
+      if ( aComponent && (aComponent->ComponentDataType() == myKind.toStdString()) )
+        return true;
     }
+  }
 
   return false;
 }
index 1b0719bb17dda572d2741c9358fab35778a95b18..f1b30c06a038ca9f8f488f2478b90c53eae3dc90 100644 (file)
@@ -22,9 +22,8 @@
 from qtsalome import *
 
 def minmax(context):
-  # get context study, studyId, salomeGui
+  # get context study, salomeGui
   study = context.study
-  studyId = context.studyId
   sg = context.sg
 
   from minmax_ui import Ui_Dialog
@@ -32,7 +31,7 @@ def minmax(context):
   import salome
   import SMESH
   from salome.smesh import smeshBuilder
-  smesh = smeshBuilder.New(salome.myStudy)
+  smesh = smeshBuilder.New()
 
   controls_dict = {
     "Aspect Ratio 3D" :     SMESH.FT_AspectRatio3D,
index eaeb93cbbc8feb5bb15d28b0e78eda01ea72b5be..451b944e445e003d018c5468f72c35435e9b6b53 100755 (executable)
@@ -28,11 +28,11 @@ if DEMO_IS_ACTIVATED:
   try:
     import GEOM
     from salome.geom import geomBuilder
-    geompy = geomBuilder.New(salome.myStudy)
+    geompy = geomBuilder.New()
     
     import SMESH, SALOMEDS
     from salome.smesh import smeshBuilder
-    smesh =  smeshBuilder.New(salome.myStudy)
+    smesh =  smeshBuilder.New()
   except:
     DEMO_IS_ACTIVATED = False
 
@@ -48,8 +48,7 @@ if DEMO_IS_ACTIVATED:
       from salome.geom import geomBuilder
 
       # Intialize the geompy factory with the active study
-      activeStudy = context.study
-      geompy = geomBuilder.New(activeStudy)
+      geompy = geomBuilder.New()
 
       # Create the objects
       Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
@@ -76,8 +75,7 @@ if DEMO_IS_ACTIVATED:
       from salome.geom import geomBuilder
 
       # Intialize the geompy factory with the active study
-      activeStudy = context.study
-      geompy = geomBuilder.New(activeStudy)
+      geompy = geomBuilder.New()
 
       # Create the objects
       Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
@@ -122,7 +120,6 @@ if DEMO_IS_ACTIVATED:
 
   def tube_shapewithgui(context):
       global tubebuilder, xalome, dialog
-      activeStudy = context.study
 
       # Get the parameter values from a gui dialog box. If the dialog is
       # closed using the Ok button, then the data are requested from the
@@ -130,8 +127,8 @@ if DEMO_IS_ACTIVATED:
       dialog.exec_()
       if dialog.wasOk():
           radius, length, width = dialog.getData()
-          shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
-          entry = xalome.addToStudy(activeStudy, shape, "Tube" )
+          shape = tubebuilder.createGeometry(radius, length, width)
+          entry = xalome.addToStudy(shape, "Tube" )
           xalome.displayShape(entry)
 
 
@@ -147,7 +144,6 @@ if DEMO_IS_ACTIVATED:
   #
   def tube_meshwithgui(context):
       global tube, dialog
-      activeStudy = context.study
 
       # Get the parameter values from a gui dialog box. If the dialog is
       # closed using the Ok button, then the data are requested from the
@@ -155,7 +151,7 @@ if DEMO_IS_ACTIVATED:
       dialog.exec_()
       if dialog.wasOk():
           radius, length, width = dialog.getData()
-          mesh = tubebuilder.createModel(activeStudy, radius, length, width)
+          mesh = tubebuilder.createModel(radius, length, width)
 
 
   salome_pluginsmanager.AddFunction('DEMO/Tube mesh from parameters',
@@ -179,7 +175,6 @@ if DEMO_IS_ACTIVATED:
   dialogWithApply.setData(tubebuilder.DEFAULT_RADIUS,
                           tubebuilder.DEFAULT_LENGTH,
                           tubebuilder.DEFAULT_WIDTH)
-  activeStudy = None
   previewShapeEntry = None
 
   DEFAULT_FOLDER_NAME="TubeList"
@@ -189,7 +184,7 @@ if DEMO_IS_ACTIVATED:
   def acceptCallback():
       """Action to be done when click on Ok"""
       global tubebuilder, xalome
-      global dialogWithApply, activeStudy
+      global dialogWithApply
       global previewShapeEntry, deletePreviewShape
       global DEFAULT_FOLDER_NAME,DEFAULT_SHAPE_NAME
 
@@ -199,8 +194,8 @@ if DEMO_IS_ACTIVATED:
           deletePreviewShape()
 
       radius, length, width = dialogWithApply.getData()
-      shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
-      entry = xalome.addToStudy(activeStudy, shape, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME)
+      shape = tubebuilder.createGeometry(radius, length, width)
+      entry = xalome.addToStudy(shape, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME)
       xalome.displayShape(entry)
 
   def rejectCallback():
@@ -218,7 +213,7 @@ if DEMO_IS_ACTIVATED:
   def applyCallback():
       """Action to be done when click on Apply"""
       global tubebuilder, xalome
-      global dialogWithApply, activeStudy
+      global dialogWithApply
       global previewShapeEntry, deletePreviewShape
       global PREVIEW_COLOR, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME, PREVIEW_SHAPE_NAME
 
@@ -228,16 +223,16 @@ if DEMO_IS_ACTIVATED:
 
       # Then we can create the new shape with the new parameter values
       radius, length, width = dialogWithApply.getData()
-      shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+      shape = tubebuilder.createGeometry(radius, length, width)
       # We apply a specific color on the shape for the preview state
       shape.SetColor(PREVIEW_COLOR)
-      previewShapeEntry = xalome.addToStudy(activeStudy, shape, PREVIEW_SHAPE_NAME, DEFAULT_FOLDER_NAME )
+      previewShapeEntry = xalome.addToStudy(shape, PREVIEW_SHAPE_NAME, DEFAULT_FOLDER_NAME )
       xalome.displayShape(previewShapeEntry)
 
   def deletePreviewShape():
       """This delete the shape currently being displayed as a preview"""
-      global activeStudy, previewShapeEntry, xsalome
-      xalome.deleteShape(activeStudy,previewShapeEntry)
+      global previewShapeEntry, xsalome
+      xalome.deleteShape(previewShapeEntry)
       previewShapeEntry = None
 
   # Connection of callback functions to the dialog butoon click signals
@@ -251,8 +246,7 @@ if DEMO_IS_ACTIVATED:
       required callback functions to be associated to the button
       signals.
       """
-      global dialogWithApply, activeStudy
-      activeStudy = context.study
+      global dialogWithApply
       dialogWithApply.open()
 
 
index 3439d0830f556667da8136260aa580e46e154355..95fd3d00105fd55614146393b3cdc5da96898a5d 100644 (file)
@@ -26,7 +26,7 @@ import salome
 
 import GEOM
 from salome.geom import geomBuilder
-geompy = geomBuilder.New(salome.myStudy)
+geompy = geomBuilder.New()
 
 # Create the objects
 Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
index cd231842ef4a8a4163573698260fcf07b4e8c300..44e7ec508f351f8ab9d44114f54b4d2821c48343 100644 (file)
@@ -27,14 +27,13 @@ DEFAULT_WIDTH  = 20
 
 from salome.geom import geomtools
 
-def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+def createGeometry(radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
     '''
     This function creates the geometry on the specified study and with
     given parameters.
     '''
     print("TUBE: creating the geometry ...")
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
+    geompy = geomtools.getGeompy()
 
     radius_ext = radius
     radius_int = radius_ext - width
@@ -44,17 +43,16 @@ def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DE
     Tube = geompy.MakeCut(CylinderExt, CylinderInt)
     return Tube
     
-def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+def createGeometryWithPartition(radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
     '''
     This function create the geometrical shape with a partition so
     that the hexaedric algorithm could be used for meshing.
     '''
-    shape = createGeometry(study,radius,length,width)
+    shape = createGeometry(radius,length,width)
 
     # We have to create a partition so that we can use an hexaedric
     # meshing algorithm.
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
+    geompy = geomtools.getGeompy()
 
     print("TUBE: creating a partition ...")
     toolPlane = geompy.MakeFaceHW(2.1*length,2.1*radius,3)
@@ -62,12 +60,12 @@ def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LEN
     entry = geompy.addToStudy( partition, "TubeWithPartition" )
     return partition
     
-def createMesh(study, shape):
-    '''This function creates the mesh of the specified shape on the specified study'''
+def createMesh(shape):
+    '''This function creates the mesh of the specified shape on the current study'''
     print("TUBE: creating the mesh ...")
     import SMESH
     from salome.smesh import smeshBuilder
-    smesh = smeshBuilder.New(study)
+    smesh = smeshBuilder.New()
 
     mesh = smesh.Mesh(shape)
     Regular_1D = mesh.Segment()
@@ -84,21 +82,21 @@ def createMesh(study, shape):
         smesh.SetName(Nb_Segments, 'Nb. Segments_1')
         smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
         smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
-        salome.sg.updateObjBrowser(False)
+        salome.sg.updateObjBrowser()
 
     return mesh
 
 
-def createModel(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
+def createModel(radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
     '''
     This function create the geomtrical shape AND the associated mesh.
     '''
     # We first create a shape with a partition so that the hexaedric
     # algorithm could be used.
-    shape = createGeometryWithPartition(study,radius,length,width)
+    shape = createGeometryWithPartition(radius,length,width)
 
     # Then the mesh can be defined and computed
-    mesh = createMesh(study,shape)
+    mesh = createMesh(shape)
     
 def exportModel(mesh, filename):
     '''
@@ -116,25 +114,21 @@ def exportModel(mesh, filename):
 #
 def TEST_createGeometry():
     salome.salome_init()
-    theStudy=salome.myStudy
-    createGeometry(theStudy)
+    createGeometry()
 
 def TEST_createMesh():
     salome.salome_init()
-    theStudy=salome.myStudy
-    shape = createGeometryWithPartition(theStudy)
-    mesh  = createMesh(theStudy, shape)
+    shape = createGeometryWithPartition()
+    mesh  = createMesh(shape)
 
 def TEST_createModel():
     salome.salome_init()
-    theStudy=salome.myStudy
-    createModel(theStudy)
+    createModel()
 
 def TEST_exportModel():
     salome.salome_init()
-    theStudy=salome.myStudy
-    shape = createGeometryWithPartition(theStudy)
-    mesh  = createMesh(theStudy, shape)
+    shape = createGeometryWithPartition()
+    mesh  = createMesh(shape)
     exportModel(mesh,"tubemesh.med")
     
 if __name__ == "__main__":
index a2f5343d76afba007c5a11cf8f00196a533f8edc..c2d55be7d63cbf26d8010e87e90040fb7b0fcc66 100644 (file)
@@ -36,7 +36,7 @@ from salome.geom import geomtools
 # Helper functions to add/remove a geometrical shape in/from the study
 # ======================================================================
 
-def addToStudy(study,shape,shapeName,folderName=None):
+def addToStudy(shape,shapeName,folderName=None):
     """
     Add a GEOM shape in the study. It returns the associated entry
     that corresponds to the identifier of the entry in the study. This
@@ -45,8 +45,7 @@ def addToStudy(study,shape,shapeName,folderName=None):
     created in the Geometry part of the study, and the shape study
     object is stored in this folder of the study. 
     """
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
+    geompy = geomtools.getGeompy()
 
     if folderName is None:
         # Insert the shape in the study by the standard way
@@ -55,7 +54,7 @@ def addToStudy(study,shape,shapeName,folderName=None):
         # A folder name has been specified to embed this shape. Find
         # or create a folder with this name in the Geometry study, and
         # then store the shape in this folder.
-        studyEditor = getStudyEditor(studyId)
+        studyEditor = getStudyEditor()
         geomStudyFolder = studyEditor.findOrCreateComponent("GEOM")
         shapeStudyFolder = studyEditor.findOrCreateItem(geomStudyFolder,folderName)
 
@@ -71,17 +70,16 @@ def addToStudy(study,shape,shapeName,folderName=None):
 
     return entry
 
-def removeFromStudy(study,shapeStudyEntry):
+def removeFromStudy(shapeStudyEntry):
     """
     This removes the specified entry from the study. Note that this
     operation does not destroy the underlying GEOM object, neither
     erase the drawing in the viewer.
     The underlying GEOM object is returned (so that it can be destroyed)
     """
-    studyId = study._get_StudyId()
     shape = IDToObject(shapeStudyEntry)    
     studyObject = IDToSObject(shapeStudyEntry)
-    studyEditor = getStudyEditor(studyId)
+    studyEditor = getStudyEditor()
     studyEditor.removeItem(studyObject,True)
     return shape
 
@@ -126,7 +124,7 @@ def eraseShape_version65(shapeStudyEntry):
 # Helper functions for a complete suppression of a shape from the
 # SALOME session.
 # ======================================================================
-def deleteShape(study,shapeStudyEntry):
+def deleteShape(shapeStudyEntry):
     """
     This completly deletes a geom shape.
 
@@ -138,7 +136,7 @@ def deleteShape(study,shapeStudyEntry):
     3. destroy the underlying geom object
     """
     eraseShape(shapeStudyEntry)
-    shape = removeFromStudy(study, shapeStudyEntry)
+    shape = removeFromStudy(shapeStudyEntry)
     if shape is not None:
       shape.Destroy()
     
@@ -162,11 +160,10 @@ def TEST_createAndDeleteShape():
     """
     import salome
     salome.salome_init()
-    study   = salome.myStudy
-    studyId = salome.myStudyId
+    study = salome.myStudy
 
     from salome.geom import geomtools
-    geompy = geomtools.getGeompy(studyId)
+    geompy = geomtools.getGeompy()
 
     # --------------------------------------------------
     # Create a first shape (GEOM object)
@@ -178,7 +175,7 @@ def TEST_createAndDeleteShape():
     # folder. A name must be specified. The register operation
     # (addToStudy) returns an identifier of the entry in the study.
     cylinderName = "cyl.r%s.l%s"%(radius,length)
-    cylinderStudyEntry = addToStudy(study, cylinder, cylinderName)
+    cylinderStudyEntry = addToStudy(cylinder, cylinderName)
 
     # Display the registered shape in a viewer
     displayShape(cylinderStudyEntry)
@@ -188,7 +185,7 @@ def TEST_createAndDeleteShape():
     radius = 10
     sphere = geompy.MakeSphereR(radius)
     sphereName = "sph.r%s"%radius
-    sphereStudyEntry = addToStudy(study, sphere, sphereName)
+    sphereStudyEntry = addToStudy(sphere, sphereName)
     displayShape(sphereStudyEntry)
 
     # --------------------------------------------------
@@ -199,7 +196,7 @@ def TEST_createAndDeleteShape():
     box = geompy.MakeBoxDXDYDZ(length,length,length)
     boxName = "box.l%s"%length
     folderName = "boxset" 
-    boxStudyEntry = addToStudy(study, box, boxName, folderName)
+    boxStudyEntry = addToStudy(box, boxName, folderName)
     displayShape(boxStudyEntry,PreviewColor)
 
     # --------------------------------------------------
@@ -214,7 +211,7 @@ def TEST_createAndDeleteShape():
     # SALOME session (erase from viewer, remove from study and finnaly
     # destroy the object). This is done by a simple call to
     # deleteShape().
-    deleteShape(study,cylinderStudyEntry)
+    deleteShape(cylinderStudyEntry)
 
     # --------------------------------------------------
     # At the end of the executioon of this test, you should have in
index 58fb8acedeb01f3203b83f1eb74a87827c125942..d75e202a2f36ed0a73ae1493c02d7d9b09aa5ab1 100644 (file)
@@ -7,10 +7,6 @@
         <source>WRN_FILE_NOT_EXIST</source>
         <translation>The file %1 does not exist.</translation>
     </message>
-    <message>
-        <source>ERR_ACTIVEDOC_LOAD</source>
-        <translation>A study is already active in your session, but you are not connected to it. Use the Connect button to load it in the interface.</translation>
-    </message>
     <message>
         <source>WRN_STUDY_LOCKED</source>
         <translation>Study is locked.</translation>
@@ -214,7 +210,7 @@ Launch a new session or close the study.</translation>
     </message>
     <message>
         <source>QUE_DOC_ALREADYEXIST</source>
-        <translation>The document %1 already exists in study manager.
+        <translation>The document %1 already exists.
 Do you want to reload it ?</translation>
     </message>
     <message>
index 5709c9727c75adfc75adf614a05e8fe35a1f7d5f..c50fe935531f43abadec163c6baf05a1702970bf 100755 (executable)
@@ -7,10 +7,6 @@
         <source>WRN_FILE_NOT_EXIST</source>
         <translation>Le fichier %1 n&apos;existe pas.</translation>
     </message>
-    <message>
-        <source>ERR_ACTIVEDOC_LOAD</source>
-        <translation>Une étude est déjà chargée dans votre session mais vous n&apos;y êtes pas connectée. Utilisez le bouton &quot;Connecter&quot; pour charger l&apos;étude dans l&apos;interface.</translation>
-    </message>
     <message>
         <source>WRN_STUDY_LOCKED</source>
         <translation>L&apos;étude est verrouillée</translation>
@@ -214,7 +210,7 @@ Lancez une nouvelle session ou fermez l&apos;étude en cours.</translation>
     </message>
     <message>
         <source>QUE_DOC_ALREADYEXIST</source>
-        <translation>Le document %1 existe déjà dans le gestionnaire d&apos;études.
+        <translation>Le document %1 existe déjà.
 Voulez-vous le recharger ?</translation>
     </message>
     <message>
index 1d9a98edb8b613b61d1a692509929afcc8e1ba78..7dab9b3a40afd7c1ddac45f2dfff935641692de2 100644 (file)
@@ -7,11 +7,6 @@
       <source>WRN_FILE_NOT_EXIST</source>
       <translation>ファイル %1 は存在しません。</translation>
     </message>
-    <message>
-      <source>ERR_ACTIVEDOC_LOAD</source>
-      <translation>A study is already active in your session, but you are not connected to it. Use the Connect button to load it in the interface.
-スタディはあなたのセッション内ですでにアクティブになっていますが、接続できません。インターフェイス内でそれをロードするための接続用ボタンを使用してください。</translation>
-    </message>
     <message>
       <source>WRN_STUDY_LOCKED</source>
       <translation>スタディがロックされています</translation>
     </message>
     <message>
       <source>QUE_DOC_ALREADYEXIST</source>
-      <translation>ドキュメント %1 は研究のマネージャーに既に存在します。それを再読み込みしますか。</translation>
+      <translation>ドキュメント %1 はの存在。それを再読み込みしますか。</translation>
     </message>
     <message>
       <source>MEN_RENAME_VS</source>
index 3b5f3d2fafab9dcd505be6f9a112c207ae1c4307..c6bc59f1ecb0cc5207aa4df567daf3709a9c0ad6 100644 (file)
@@ -77,7 +77,6 @@ In short to add a plugin:
 context attributes:
 
   - sg : the SALOME Swig interface
-  - studyId : the SALOME studyId that must be used to execute the plugin
   - study : the SALOME study object that must be used to execute the plugin
 
 """
@@ -118,8 +117,7 @@ def initialize(module,name,basemenuname,menuname):
 class Context:
     def __init__(self,sgpyqt):
         self.sg=sgpyqt
-        self.studyId=salome.sg.getActiveStudyId()
-        self.study= salome.myStudyManager.GetStudyByID(self.studyId)
+        self.study=salome.myStudy
 
 def find_menu(smenu):
   lmenus=smenu.split("|")
@@ -242,12 +240,7 @@ class PluginsManager:
 
     def importPlugins(self):
         """Execute the salome_plugins file that contains plugins definition """
-        studyId=sg.getActiveStudyId()
-        if studyId == 0:
-          self.menu.clear()
-          self.menu.menuAction().setVisible(False)
-          return
-        elif self.lasttime ==0 or salome.myStudy == None:
+        if self.lasttime ==0 or salome.myStudy == None:
           salome.salome_init(embedded=1)
 
         lasttime=0
index 1575acb72239d3b1053d015b2a85a4ec710636e7..3e3e062fe9270c4b55bb877f8d59977daddff970 100644 (file)
@@ -354,12 +354,12 @@ void Session_ServerCheck::run()
       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
       NS.init_orb( orb );
-      CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
-      SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
-      if ( !CORBA::is_nil( studyManager ) ) {
-        MESSAGE( "/myStudyManager is found" );
-        studyManager->ping();
-        MESSAGE( "StudyManager was activated" );
+      CORBA::Object_var obj = NS.Resolve( "/Study" );
+      SALOMEDS::Study_var study = SALOMEDS::Study::_narrow( obj );
+      if ( !CORBA::is_nil( study ) ) {
+        MESSAGE( "/Study is found" );
+        study->ping();
+        MESSAGE( "Study was activated" );
         setStep( ++current * myAttempts );
         break;
       }
index ee1c1f6815f38c0aeaba02ad27afcd449436b96c..753cacaab2cffe66c34f4a8051e12a760fa12ae8 100755 (executable)
@@ -142,7 +142,7 @@ void Session_ServerThread::Init()
         }
       case 4:  // Session
         {
-          NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
+          NamingService_WaitForServerReadiness(_NS,"/Study");
           std::string containerName = "/Containers/";
           containerName = containerName + Kernel_Utils::GetHostname();
           containerName = containerName + "/FactoryServer";
@@ -215,7 +215,7 @@ void Session_ServerThread::ActivateSALOMEDS(int argc,
     // counted objects, they will be deleted by the POA when they are no
     // longer needed.    
     
-    ClientFactory::createStudyManager(_orb,_root_poa);
+    ClientFactory::createStudy(_orb,_root_poa);
   }
   catch(CORBA::SystemException&) {
     INFOS( "Caught CORBA::SystemException." );
index 95103de9ce9e2bdd5ac6421b9e2917bbeea932c7..d82cefc878dd3de20ffbbc648aac222aba8083cc 100755 (executable)
@@ -65,7 +65,6 @@ SALOME_Session_i::SALOME_Session_i(int argc,
   _argc = argc ;
   _argv = argv ;
   _isGUI = false ;
-  _runningStudies= 0 ;
   _orb = CORBA::ORB::_duplicate(orb) ;
   _poa = PortableServer::POA::_duplicate(poa) ;
   _GUIMutex = GUIMutex;
@@ -206,7 +205,7 @@ void SALOME_Session_i::Shutdown()
 
 /*!
   Send a SALOME::StatSession structure (see idl) to the client
-  (number of running studies and presence of GUI)
+  (presence of GUI)
 */
 /*class QtLock
 {
@@ -220,24 +219,23 @@ SALOME::StatSession SALOME_Session_i::GetStatSession()
 {
   // update Session state
   _GUIMutex->lock();
+  int activeStudy = 0;
 
-  _runningStudies = 0;
   {
     //QtLock lock;
     _isGUI = SUIT_Session::session();
     if ( _isGUI && SUIT_Session::session()->activeApplication() )
-      _runningStudies = SUIT_Session::session()->activeApplication()->getNbStudies();
+      activeStudy = SUIT_Session::session()->activeApplication()->getNbStudies();
   }
 
   // getting stat info
-  SALOME::StatSession_var myStats = new SALOME::StatSession ;
-  if (_runningStudies)
+  SALOME::StatSession_var myStats = new SALOME::StatSession;
+  if (activeStudy)
     myStats->state = SALOME::running ;
   else if (_isShuttingDown)
     myStats->state = SALOME::shutdown ;
   else
     myStats->state = SALOME::asleep ;
-  myStats->runningStudies = _runningStudies ;
   myStats->activeGUI = _isGUI ;
 
   _GUIMutex->unlock();
@@ -245,16 +243,6 @@ SALOME::StatSession SALOME_Session_i::GetStatSession()
   return myStats._retn() ;
 }
 
-CORBA::Long SALOME_Session_i::GetActiveStudyId()
-{
-  long aStudyId=-1;
-  if ( SUIT_Session::session() && SUIT_Session::session()->activeApplication() ) {
-    if ( SUIT_Session::session()->activeApplication()->activeStudy() ) // mkr : IPAL12128
-      aStudyId = SUIT_Session::session()->activeApplication()->activeStudy()->id();
-  }
-  return aStudyId;
-}
-
 CORBA::Long SALOME_Session_i::getPID() {
   return (CORBA::Long)
 #ifndef WIN32
index 5a83d5fdf8bc1a50612a90416f82f361fffd3ce1..1fbcc4d42e328f60ce59d3201bd4e8b8a4e91759 100755 (executable)
@@ -68,8 +68,6 @@ public:
   //! Unregister the servant from Naming Service
   void NSunregister();
 
-  CORBA::Long GetActiveStudyId();
-
   void ping(){};
   CORBA::Long getPID();
   char* getHostname();
@@ -94,7 +92,6 @@ protected:
   CORBA::Boolean _isGUI ;
   QMutex* _GUIMutex ;
   QWaitCondition* _GUILauncher;
-  int _runningStudies ;
   CORBA::ORB_var _orb;
   PortableServer::POA_var _poa;
   bool _isShuttingDown;
index d391fc67668282a1c94fc58738feaa673894eae2..91bef71a865df9a02a1871298d96f68e606a24ec 100755 (executable)
@@ -44,8 +44,10 @@ SET(_link_LIBRARIES
   ${CAS_KERNEL}
   ${KERNEL_SalomeIDLKernel}
   ${KERNEL_SALOMELocalTrace}
+  ${KERNEL_SalomeDSClient}
   ${KERNEL_SalomeNS}
   ${KERNEL_OpUtil}
+  ${KERNEL_SalomeKernelHelpers}
   ${OMNIORB_LIBRARIES}
   qtx suit
 )
index aba35802765610ed78db3ba4dc341f50327e0da3..253389ad7bde473b825157135e0003fe6ee6a115 100755 (executable)
@@ -25,6 +25,8 @@
 //  Author : Nicolas REJNERI
 //
 #include "ToolsGUI.h"
+#include <SALOMEDSClient_ClientFactory.hxx>
+#include <SALOME_KernelServices.hxx>
 
 /*!
   \class ToolsGUI
 
 /*!
   \brief Get visibility value of the "AttributeGraphic" attribute.
-  \param theStudy study
   \param theObj object
   \param theId sub-object identifier
   \return \c true if an object (sub-object) is visible
 */
-bool ToolsGUI::GetVisibility( _PTR(Study)   theStudy,
-                              _PTR(SObject) theObj,
+bool ToolsGUI::GetVisibility( _PTR(SObject) theObj,
                               void*         theId )
 {
   _PTR(GenericAttribute) anAttr;
@@ -54,17 +54,16 @@ bool ToolsGUI::GetVisibility( _PTR(Study)   theStudy,
 
 /*!
   \brief Set visibility value of the "AttributeGraphic" attribute.
-  \param theStudy study
   \param theObj object
   \return theValue new visibility value
   \param theId sub-object identifier
 */
-bool ToolsGUI::SetVisibility( _PTR(Study) theStudy,
-                              const char* theEntry,
+bool ToolsGUI::SetVisibility( const char* theEntry,
                               const bool  theValue,
                               void*       theId )
 {
-  _PTR(SObject) anObj ( theStudy->FindObjectID( theEntry ) );
+  _PTR(Study) aStudy = ClientFactory::Study(KERNEL::getStudyServant());
+  _PTR(SObject) anObj ( aStudy->FindObjectID( theEntry ) );
 
   if ( anObj )
   {
@@ -76,7 +75,7 @@ bool ToolsGUI::SetVisibility( _PTR(Study) theStudy,
     }
     else if ( theValue )
     {
-      _PTR(StudyBuilder) aBuilder (theStudy->NewBuilder());
+      _PTR(StudyBuilder) aBuilder (aStudy->NewBuilder());
       _PTR(AttributeGraphic) anAttr (aBuilder->FindOrCreateAttribute(anObj, "AttributeGraphic"));
       anAttr->SetVisibility( (unsigned long)theId, theValue );
     }
index 5a2190d7a84d785b584231ce4bfb5b9588f66b72..05ab648158e307967fb85287b13fd7ccf90632a0 100755 (executable)
 class TOOLSGUI_EXPORT ToolsGUI  
 {
 public :
-  static bool               GetVisibility( _PTR(Study)   theStudy,
-                                           _PTR(SObject) theObj,
+  static bool               GetVisibility( _PTR(SObject) theObj,
                                            void*         theId );
-  static bool               SetVisibility( _PTR(Study) theStudy,
-                                           const char* theEntry,
+  static bool               SetVisibility( const char* theEntry,
                                            const bool  theValue,
                                            void*       theId );
 };
index 94f88dae6efefe83dff84ee03767c69a16d28a70..53f50bbea2934b4e44f3172bc8953bc70382b151 100644 (file)
@@ -43,9 +43,13 @@ SET(_link_LIBRARIES ${PLATFORM_LIBS} ${QT_LIBRARIES})
 # header files / to be processed by moc
 SET(_moc_HEADERS
   PyEditor_Editor.h
+  PyEditor_FindTool.h
   PyEditor_LineNumberArea.h
+  PyEditor_Keywords.h
+  PyEditor_Completer.h
   PyEditor_PyHighlighter.h
   PyEditor_SettingsDlg.h
+  PyEditor_Widget.h
   PyEditor_Window.h
 )
 
@@ -82,11 +86,15 @@ QT_ADD_RESOURCES(_rcc_SOURCES ${_rcc_RESOURCES})
 # sources / static
 SET(_other_SOURCES
   PyEditor_Editor.cxx
+  PyEditor_FindTool.cxx
   PyEditor_LineNumberArea.cxx
+  PyEditor_Keywords.cxx
+  PyEditor_Completer.cxx
   PyEditor_PyHighlighter.cxx
   PyEditor_Settings.cxx
   PyEditor_SettingsDlg.cxx
   PyEditor_StdSettings.cxx
+  PyEditor_Widget.cxx
   PyEditor_Window.cxx
 )
 
index 03a29b8e98f72335d6e81dd017f0d5a94cb9a5af..5a213338de0723da06f0de98c9156078ae83298b 100644 (file)
@@ -24,6 +24,7 @@
 #include "PyEditor_StdSettings.h"
 
 #include <QApplication>
+#include <QCommandLineParser>
 #include <QDir>
 #include <QLibraryInfo>
 #include <QLocale>
@@ -67,11 +68,11 @@ int main( int argc, char *argv[] )
   app.setOrganizationDomain( "www.salome-platform.org" );
   app.setApplicationName( "pyeditor" );
   
+  QLocale locale;
+
   PyEditor_StdSettings* settings = new PyEditor_StdSettings();
   PyEditor_Settings::setSettings( settings );
   
-  QString language = settings->language();
-  
   // Load Qt translations.
   QString qtDirTrSet = QLibraryInfo::location( QLibraryInfo::TranslationsPath );
   QString qtDirTrEnv = qtTrDir();
@@ -85,7 +86,11 @@ int main( int argc, char *argv[] )
   foreach( QString qtTrFile, qtTrFiles ) {
     foreach ( QString qtTrDir, qtTrDirs ) {
       QTranslator* translator = new QTranslator;
-      if ( translator->load( QString("%1_%2").arg( qtTrFile ).arg( language ), qtTrDir ) ) {
+      if ( translator->load( locale, QString("%1").arg( qtTrFile ), "_", qtTrDir ) ) {
+        app.installTranslator( translator );
+        break;
+      }
+      else if ( translator->load( QString("%1_en").arg( qtTrFile ), qtTrDir ) ) {
         app.installTranslator( translator );
         break;
       }
@@ -97,13 +102,27 @@ int main( int argc, char *argv[] )
   
   // Load application's translations.
   QTranslator translator;
-  if ( translator.load( QString( "PyEditor_msg_%1" ).arg( language ), resourceDir() ) )
+  if ( translator.load( locale, QString( "PyEditor_msg" ), "_", resourceDir() ) )
     app.installTranslator( &translator );
-  
+  else if ( translator.load( QString( "PyEditor_msg_en" ), resourceDir() ) )
+    app.installTranslator( &translator );
+
+  QCommandLineParser parser;
+  parser.setApplicationDescription( QApplication::translate( "PyEditor", "PROGRAM_DESCRIPTION" ) );
+  parser.addHelpOption();
+  parser.addPositionalArgument( QApplication::translate( "PyEditor", "FILE_PARAM_NAME" ),
+                                QApplication::translate( "PyEditor", "FILE_PARAM_DESCRIPTION" ) );
+
+  parser.process( app );
+  const QStringList args = parser.positionalArguments();
+
   PyEditor_Window window;
   window.setWindowIcon( QIcon( ":/images/py_editor.png" ) );
   window.resize( 650, 700 );
   window.show();
+
+  if ( args.count() > 0 )
+    window.loadFile( args[0], false );
   
   return app.exec();
 }
diff --git a/tools/PyEditor/src/PyEditor_Completer.cxx b/tools/PyEditor/src/PyEditor_Completer.cxx
new file mode 100644 (file)
index 0000000..bee9d99
--- /dev/null
@@ -0,0 +1,264 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Completer.cxx
+// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com)
+//
+
+#include "PyEditor_Completer.h"
+
+#include "PyEditor_Editor.h"
+#include "PyEditor_Keywords.h"
+
+#include <QSet>
+#include <QTimer>
+#include <QTextBlock>
+#include <QTextCursor>
+#include <QApplication>
+#include <QAbstractItemView>
+#include <QStandardItemModel>
+
+/*!
+  \brief Constructor.
+*/
+PyEditor_Completer::PyEditor_Completer( PyEditor_Editor* editor,
+                                       PyEditor_Keywords* std, PyEditor_Keywords* user )
+  : QCompleter( editor ),
+    myEditor( editor ),
+    myTimer( 0 ),
+    myStdKeywords( std ),
+    myUserKeywords( user )
+{
+  setWidget( editor );
+  setCompletionMode(QCompleter::PopupCompletion);
+
+  connect(this, SIGNAL( activated( const QString& ) ),
+         this, SLOT( onActivated( const QString& ) ) );
+  connect(editor, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) );
+  connect(myStdKeywords, SIGNAL( keywordsChanged() ),
+         this, SLOT( onKeywordsChanged() ) );
+  connect(myUserKeywords, SIGNAL( keywordsChanged() ),
+         this, SLOT( onKeywordsChanged() ) );
+
+  updateKeywords();
+}
+
+/*!
+  \brief Destructor.
+*/
+PyEditor_Completer::~PyEditor_Completer()
+{
+}
+
+/*!
+  \brief Perform the completion if it possible.
+*/
+void PyEditor_Completer::perform()
+{
+  QString prefix = completionText();
+  setCompletionPrefix( prefix );
+
+  if ( !completionPrefix().isEmpty() && 
+       ( completionCount() > 1 || ( completionCount() == 1 && 
+                                   currentCompletion() != completionPrefix() ) ) )
+    complete(completionRect());
+  else
+    uncomplete();
+}
+
+/*!
+  \brief Hide the completer's popup menu.
+*/
+void PyEditor_Completer::uncomplete()
+{
+  if ( popup() )
+    popup()->hide();
+}
+
+/*!
+  \brief Handling 'Enter' key.
+*/
+bool PyEditor_Completer::eventFilter(QObject* o, QEvent* e)
+{
+  bool res = false;
+  if ( e->type() == QEvent::KeyPress && popup()->isVisible() ) {
+    QKeyEvent* ke = (QKeyEvent*)e;
+    if ( ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return ) {
+      res = true;
+      setCurrentRow(popup()->currentIndex().row());
+      onActivated(currentCompletion());
+    }
+  }
+
+  if ( !res )
+    res = QCompleter::eventFilter(o, e);
+
+  return res;
+}
+
+/*!
+  \brief Perform delayed completion.
+*/
+void PyEditor_Completer::onTimeout()
+{
+  perform();
+}
+
+/*!
+  \brief Invoked when text changed in editor.
+*/
+void PyEditor_Completer::onTextChanged()
+{
+  uncomplete();
+  if ( myEditor->completionPolicy() == PyEditor_Editor::Auto ||
+       myEditor->completionPolicy() == PyEditor_Editor::Always )
+    triggerComplete();
+}
+
+/*!
+  \brief Invoked when keywords changed in editor.
+*/
+void PyEditor_Completer::onKeywordsChanged()
+{
+  updateKeywords();
+}
+
+/*!
+  \brief Insert selected completion into editor.
+*/
+void PyEditor_Completer::onActivated( const QString& text)
+{
+  QPoint rng = completionRange();
+  QTextCursor cursor = myEditor->textCursor();
+  cursor.setPosition(cursor.position() - rng.y() + rng.x() - 1,
+                    QTextCursor::KeepAnchor);
+  cursor.insertText(text);
+  uncomplete();
+}
+
+/*!
+  \brief Get the rectangle for completion popup.
+  \return completion popup rect
+*/
+QRect PyEditor_Completer::completionRect() const
+{
+  QRect res = myEditor->cursorRect(myEditor->textCursor());
+  res.setWidth(popup()->sizeHint().width());
+  res.translate(myEditor->document()->documentMargin(),
+               myEditor->document()->documentMargin());
+  return res;
+}
+
+/*!
+  \brief Get the current completion prefix from editor.
+  \return completion prefix string
+*/
+QString PyEditor_Completer::completionText() const
+{
+  QString prefix;
+  if ( myEditor ) {
+    QString txt = myEditor->textCursor().block().text();
+    if ( !txt.isEmpty() ) {
+      QPoint range = completionRange();
+      prefix = txt.mid( range.x(), range.y() - range.x() + 1 );
+    }
+  }
+  return prefix;
+}
+
+/*!
+  \brief Get position of completion prefix in editor.
+  \return begin and end of completion prefix
+*/
+QPoint PyEditor_Completer::completionRange() const
+{
+  QPoint range;
+
+  if ( myEditor ) {
+    QTextCursor cursor = myEditor->textCursor();
+    QString txt = cursor.block().text();
+    int beg = 0;
+    int end = cursor.positionInBlock() - 1;
+
+    QRegExp rx("[A-Za-z]{1}\\w*$");
+    int pos = rx.indexIn(txt.mid(beg, end - beg + 1));
+
+    if ( pos >= 0 )
+      beg = pos;
+
+    range = QPoint(beg, end);
+  }
+
+  return range;
+}
+
+/*!
+  \brief Schedule the delayed completion.
+*/
+void PyEditor_Completer::triggerComplete()
+{
+  if ( !myTimer ) {
+    myTimer = new QTimer( this );
+    myTimer->setSingleShot( true );
+    myTimer->setInterval( 200 );
+
+    connect( myTimer, SIGNAL( timeout() ), this, SLOT( onTimeout() ) );
+  }
+
+  if ( myTimer->isActive() )
+    myTimer->stop();
+  myTimer->start();
+}
+
+/*!
+  \brief Updates the keywords list in completer.
+*/
+void PyEditor_Completer::updateKeywords()
+{
+  QStandardItemModel* model = new QStandardItemModel( this );
+  KeywordMap kwMap = keywords();
+  for ( KeywordMap::const_iterator it = kwMap.begin(); it != kwMap.end(); ++it ) {
+    QStandardItem* item = new QStandardItem( it.key() );
+    if ( it.value().isValid() )
+      item->setForeground( it.value() );
+    model->appendRow( item );
+  }
+  setModel( model );
+}
+
+/*!
+  \brief Gets the keywords list.
+  \return keyword string list
+*/
+PyEditor_Completer::KeywordMap PyEditor_Completer::keywords() const
+{
+  KeywordMap res;
+  QList<PyEditor_Keywords*> kwDicts;
+  kwDicts << myStdKeywords << myUserKeywords;
+
+  for ( QList<PyEditor_Keywords*>::iterator itr = kwDicts.begin(); itr != kwDicts.end(); ++itr ) {
+    PyEditor_Keywords* dict = *itr;
+    QStringList kwList = dict->keywords();
+    for ( QStringList::const_iterator it = kwList.begin(); it != kwList.end(); ++it ) {
+      if ( !res.contains( *it ) ) {
+       res.insert( *it, dict->color( *it ) );
+      }
+    }
+  }
+  return res;
+}
diff --git a/tools/PyEditor/src/PyEditor_Completer.h b/tools/PyEditor/src/PyEditor_Completer.h
new file mode 100644 (file)
index 0000000..01e0f4e
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Completer.h
+// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com)
+//
+
+#ifndef PYEDITOR_COMPLETER_H
+#define PYEDITOR_COMPLETER_H
+
+#include <QCompleter>
+
+class QTimer;
+class PyEditor_Editor;
+class PyEditor_Keywords;
+
+class PyEditor_Completer : public QCompleter
+{
+  Q_OBJECT
+
+public:
+  PyEditor_Completer( PyEditor_Editor*,
+                     PyEditor_Keywords*, PyEditor_Keywords* );
+  virtual ~PyEditor_Completer();
+
+  void               perform();
+
+  void               uncomplete();
+
+  virtual bool       eventFilter(QObject*, QEvent*);
+
+private Q_SLOTS:
+  void               onTimeout();
+  void               onTextChanged();
+  void               onKeywordsChanged();
+  void               onActivated( const QString& );
+
+protected:
+  QRect              completionRect() const;
+  QString            completionText() const;
+  QPoint             completionRange() const;
+
+private:
+  typedef QMap<QString, QColor> KeywordMap;
+
+private:
+  KeywordMap         keywords() const;
+  void               updateKeywords();
+  void               triggerComplete();
+
+private:
+  PyEditor_Editor*   myEditor;
+  QTimer*            myTimer;
+  PyEditor_Keywords* myStdKeywords;
+  PyEditor_Keywords* myUserKeywords;
+};
+
+#endif
index fff2e04254d89b13770fcb7b767597ef27413cd4..6fe34f1960928ee616d6aa81d686922843803007 100644 (file)
 #include "PyEditor_Editor.h"
 #include "PyEditor_LineNumberArea.h"
 #include "PyEditor_PyHighlighter.h"
+#include "PyEditor_Completer.h"
 #include "PyEditor_Settings.h"
+#include "PyEditor_Keywords.h"
 
 #include <QPainter>
 #include <QTextBlock>
 
+#include <iostream>
+
 /*!
   \class PyEditor_Editor
   \brief Widget to show / edit Python scripts.
   \param parent parent widget
 */
 PyEditor_Editor::PyEditor_Editor( QWidget* parent )
-  : QPlainTextEdit( parent )
+  : QPlainTextEdit( parent ),
+    myCompletionPolicy( Always )
 {
+  myStdKeywords = new PyEditor_StandardKeywords( this );
+  myUserKeywords = new PyEditor_Keywords( this );
+  myUserKeywords->append( "print", 0, Qt::red );
+
   // Set up line number area
   myLineNumberArea = new PyEditor_LineNumberArea( this );
   myLineNumberArea->setMouseTracking( true );
 
   // Set up syntax highighter
-  mySyntaxHighlighter = new PyEditor_PyHighlighter( this->document() );
+  mySyntaxHighlighter = new PyEditor_PyHighlighter( this->document(),
+                                                   myStdKeywords, myUserKeywords );
 
   // Set-up settings
   PyEditor_Settings* settings = PyEditor_Settings::settings();
   if ( settings )
     setSettings( *settings );
 
+  myCompleter = new PyEditor_Completer( this, myStdKeywords, myUserKeywords );
+
   // Connect signals
   connect( this, SIGNAL( blockCountChanged( int ) ), this, SLOT( updateLineNumberAreaWidth( int ) ) );
   connect( this, SIGNAL( updateRequest( QRect, int ) ), this, SLOT( updateLineNumberArea( QRect, int ) ) );
@@ -98,6 +110,9 @@ void PyEditor_Editor::setSettings( const PyEditor_Settings& settings )
   // Set size white spaces
   setTabStopWidth( mySettings.tabSize() * 10 );
 
+  // Set completion policy
+  setCompletionPolicy( (CompletionPolicy)mySettings.completionPolicy() );
+
   // Update current line highlight
   updateHighlightCurrentLine();
 
@@ -108,6 +123,54 @@ void PyEditor_Editor::setSettings( const PyEditor_Settings& settings )
   viewport()->update();
 }
 
+/*!
+  \brief Gets the current completion policy
+  \return completion policy
+*/
+PyEditor_Editor::CompletionPolicy PyEditor_Editor::completionPolicy() const
+{
+  return myCompletionPolicy;
+}
+
+/*!
+  \brief Sets the current completion policy
+  \param policy completion policy
+*/
+void PyEditor_Editor::setCompletionPolicy( const CompletionPolicy& policy )
+{
+  myCompletionPolicy = policy;
+}
+
+/*!
+  \brief Gets the all user keywords.
+  \param event key press event
+  \return keyword string list
+*/
+QStringList PyEditor_Editor::keywords() const
+{
+  return myUserKeywords->keywords();
+}
+
+/*!
+  \brief Add the user keywords.
+  \param kws keywords string list
+  \param type keywords type
+  \param color keywords color
+*/
+void PyEditor_Editor::appendKeywords( const QStringList& kws, int type, const QColor& color )
+{
+  myUserKeywords->append( kws, type, color );
+}
+
+/*!
+  \brief Remove the user keywords.
+  \param kws keywords string list
+*/
+void PyEditor_Editor::removeKeywords( const QStringList& kws )
+{
+  myUserKeywords->remove( kws );
+}
+
 /*!
   Delete current selection contents.
 */
@@ -151,6 +214,12 @@ void PyEditor_Editor::keyPressEvent( QKeyEvent* event )
       aCursor.endEditBlock();
       event->accept();
     }
+    else if ( aKey == Qt::Key_Space && aCtrl && !aShift &&
+             ( completionPolicy() == Manual || completionPolicy() == Always ) )
+    {
+      myCompleter->perform();
+      event->accept();
+    }
     else if ( event == QKeySequence::MoveToStartOfLine || event == QKeySequence::SelectStartOfLine )
     {
       QTextCursor aCursor = this->textCursor();
@@ -824,3 +893,21 @@ QString PyEditor_Editor::text() const
 {
   return toPlainText();
 }
+
+/*!
+  \brief Get user keywords dictionary.
+  \return keywords dictionary
+*/
+PyEditor_Keywords* PyEditor_Editor::userKeywords() const
+{
+  return myUserKeywords;
+}
+
+/*!
+  \brief Get standard keywords dictionary.
+  \return keywords dictionary
+*/
+PyEditor_Keywords* PyEditor_Editor::standardKeywords() const
+{
+  return myStdKeywords;
+}
index 0266356739745819a616078748b5463437b0268c..d37c1a86056da70e36382c2ea4b9278727ff4b44 100644 (file)
 
 #include <QPlainTextEdit>
 
+class PyEditor_Keywords;
+class PyEditor_Completer;
 class PyEditor_PyHighlighter;
 
 class PYEDITOR_EXPORT PyEditor_Editor : public QPlainTextEdit
 {
   Q_OBJECT
 
+public:
+  typedef enum { None, Auto, Manual, Always } CompletionPolicy;
+
 public:
   PyEditor_Editor( QWidget* = 0 );
   virtual ~PyEditor_Editor();
   
-  void setSettings( const PyEditor_Settings& );
+  void    setSettings( const PyEditor_Settings& );
   const PyEditor_Settings& settings() const;
   QString text() const;
 
+  QStringList keywords() const;
+  void        appendKeywords( const QStringList&, int, const QColor& = QColor() );
+  void        removeKeywords( const QStringList& );
+
+  CompletionPolicy completionPolicy() const;
+  void             setCompletionPolicy( const CompletionPolicy& );
+
 public Q_SLOTS:
   void deleteSelected();
   void append( const QString& );  
@@ -51,7 +63,10 @@ protected:
   virtual void keyPressEvent( QKeyEvent* );
   virtual void resizeEvent( QResizeEvent* );
   virtual void paintEvent( QPaintEvent* );
-    
+
+  PyEditor_Keywords* userKeywords() const;
+  PyEditor_Keywords* standardKeywords() const;
+
 private Q_SLOTS:
   void updateHighlightCurrentLine();
   void matchParentheses();
@@ -72,13 +87,19 @@ private:
   int  lineIndent();
   void tabIndentation( bool );
   void indentSelection( bool );
-  
+
   int findFirstNonSpace( const QString& );
-  
+
   QWidget*                myLineNumberArea;
   PyEditor_PyHighlighter* mySyntaxHighlighter;
+  PyEditor_Completer*     myCompleter;
   PyEditor_Settings       mySettings;
 
+  PyEditor_Keywords*      myStdKeywords;
+  PyEditor_Keywords*      myUserKeywords;
+
+  CompletionPolicy        myCompletionPolicy;
+
   friend class PyEditor_LineNumberArea;
 };
 
diff --git a/tools/PyEditor/src/PyEditor_FindTool.cxx b/tools/PyEditor/src/PyEditor_FindTool.cxx
new file mode 100644 (file)
index 0000000..b91000a
--- /dev/null
@@ -0,0 +1,612 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_FindTool.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#include "PyEditor_FindTool.h"
+#include "PyEditor_Editor.h"
+
+#include <QAction>
+#include <QCompleter>
+#include <QEvent>
+#include <QGridLayout>
+#include <QIcon>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMenu>
+#include <QSignalMapper>
+#include <QToolButton>
+
+/*!
+  \class PyEditor_FindTool
+  \brief Find / Replace widget for PyEditor
+*/
+
+/*!
+  \brief Constructor.
+  \param editor Python editor widget.
+  \param parent Parent widget.
+*/
+PyEditor_FindTool::PyEditor_FindTool( PyEditor_Editor* editor, QWidget* parent )
+  : QWidget( parent ), myEditor( editor )
+{
+  QLabel* findLabel = new QLabel( tr( "FIND_LABEL" ), this );
+  myFindEdit = new QLineEdit( this );
+  myFindEdit->setClearButtonEnabled( true );
+  myFindEdit->installEventFilter( this );
+  connect( myFindEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( find( const QString& ) ) );
+  connect( myFindEdit, SIGNAL( returnPressed() ), this, SLOT( findNext() ) );
+  myFindEdit->setCompleter( new QCompleter( myFindEdit ) );
+  myFindEdit->completer()->setModel( &myFindCompletion );
+
+  QLabel* replaceLabel = new QLabel( tr( "REPLACE_LABEL" ), this );
+  myReplaceEdit = new QLineEdit( this );
+  myReplaceEdit->setClearButtonEnabled( true );
+  myReplaceEdit->installEventFilter( this );
+  myReplaceEdit->setCompleter( new QCompleter( myReplaceEdit ) );
+  myReplaceEdit->completer()->setModel( &myReplaceCompletion );
+
+  myInfoLabel = new QLabel( this );
+  myInfoLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight );
+
+  QToolButton* prevBtn = new QToolButton( this );
+  prevBtn->setIcon( QIcon( ":images/py_find_previous.png" ) );
+  prevBtn->setAutoRaise( true );
+  connect( prevBtn, SIGNAL( clicked() ), this, SLOT( findPrevious() ) );
+
+  QToolButton* nextBtn = new QToolButton( this );
+  nextBtn->setIcon( QIcon( ":images/py_find_next.png" ) );
+  nextBtn->setAutoRaise( true );
+  connect( nextBtn, SIGNAL( clicked() ), this, SLOT( findNext() ) );
+
+  QToolButton* replaceBtn = new QToolButton();
+  replaceBtn->setText( tr( "REPLACE_BTN" ) );
+  replaceBtn->setAutoRaise( true );
+  connect( replaceBtn, SIGNAL( clicked() ), this, SLOT( replace() ) );
+
+  QToolButton* replaceAllBtn = new QToolButton();
+  replaceAllBtn->setText( tr( "REPLACE_ALL_BTN" ) );
+  replaceAllBtn->setAutoRaise( true );
+  connect( replaceAllBtn, SIGNAL( clicked() ), this, SLOT( replaceAll() ) );
+
+  QHBoxLayout* hl = new QHBoxLayout;
+  hl->setContentsMargins( 0, 0, 0, 0 );
+  hl->setSpacing( 0 );
+  hl->addWidget( prevBtn );
+  hl->addWidget( nextBtn );
+
+  QGridLayout* l = new QGridLayout( this );
+  l->setContentsMargins( 6, 2, 6, 2 );
+  l->setSpacing( 2 );
+  l->addWidget( findLabel, 0, 0 );
+  l->addWidget( myFindEdit, 0, 1 );
+  l->addLayout( hl, 0, 2 );
+  l->addWidget( myInfoLabel, 0, 3 );
+  l->addWidget( replaceLabel, 1, 0 );
+  l->addWidget( myReplaceEdit, 1, 1 );
+  l->addWidget( replaceBtn, 1, 2 );
+  l->addWidget( replaceAllBtn, 1, 3 );
+
+  QAction* menuAction = myFindEdit->addAction( QIcon(":images/py_search.png"), QLineEdit::LeadingPosition );
+  connect( menuAction, SIGNAL( triggered( bool ) ), this, SLOT( showMenu() ) );
+
+  addAction( new QAction( tr( "CASE_SENSITIVE_CHECK" ), this ) );
+  addAction( new QAction( tr( "WHOLE_WORDS_CHECK" ), this ) );
+  addAction( new QAction( tr( "REGEX_CHECK" ), this ) );
+  addAction( new QAction( tr( "Find" ), this ) );
+  addAction( new QAction( tr( "FindPrevious" ), this ) );
+  addAction( new QAction( tr( "FindNext" ), this ) );
+  addAction( new QAction( tr( "Replace" ), this ) );
+
+  foreach ( QAction* action, actions().mid( CaseSensitive, RegExp+1 ) )
+  {
+    action->setCheckable( true );
+    connect( action, SIGNAL( toggled( bool ) ), this, SLOT( update() ) );
+  }
+
+  QSignalMapper* mapper = new QSignalMapper( this );
+  connect( mapper, SIGNAL( mapped( int ) ), this, SLOT( activate( int ) ) );
+
+  for ( int i = Find; i < actions().count(); i++ )
+  {
+    QAction* action = actions()[i];
+    action->setShortcuts( shortcuts( i ) );
+    action->setShortcutContext( Qt::WidgetWithChildrenShortcut );
+    connect( action, SIGNAL( triggered( bool ) ), mapper, SLOT( map() ) );
+    mapper->setMapping( action, i );
+    myEditor->addAction( action );
+  }
+
+  myEditor->installEventFilter( this );
+
+  hide();
+}
+
+/*!
+  \brief Process events for this widget,
+  \param e Event being processed.
+  \return true if event's processing should be stopped; false otherwise.
+*/
+bool PyEditor_FindTool::event( QEvent* e )
+{
+  if ( e->type() == QEvent::EnabledChange )
+  {
+    updateShortcuts();
+  }
+  else if ( e->type() == QEvent::KeyPress )
+  {
+    QKeyEvent* ke = (QKeyEvent*)e;
+    switch ( ke->key() )
+    {
+    case Qt::Key_Escape:
+      hide();
+      return true;
+    default:
+      break;
+    }
+  }
+  else if ( e->type() == QEvent::Hide )
+  {
+    addCompletion( myFindEdit->text(), false );
+    addCompletion( myReplaceEdit->text(), true );
+    myEditor->setFocus();
+  }
+  return QWidget::event( e );
+}
+
+/*!
+  \brief Filter events from watched objects.
+  \param o Object being watched.
+  \param e Event being processed.
+  \return true if event should be filtered out; false otherwise.
+*/
+bool PyEditor_FindTool::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o == myFindEdit )
+  {
+    if ( e->type() == QEvent::KeyPress )
+    {
+      QKeyEvent* keyEvent = (QKeyEvent*)e;
+      if ( keyEvent->key() == Qt::Key_Escape && !myFindEdit->text().isEmpty() )
+      {
+        addCompletion( myFindEdit->text(), false );
+        myFindEdit->clear();
+        return true;
+      }
+    }
+  }
+  else if ( o == myReplaceEdit )
+  {
+    if ( e->type() == QEvent::KeyPress )
+    {
+      QKeyEvent* keyEvent = (QKeyEvent*)e;
+      if ( keyEvent->key() == Qt::Key_Escape && !myReplaceEdit->text().isEmpty() )
+      {
+        myReplaceEdit->clear();
+        return true;
+      }
+    }
+  }
+  else if ( o == myEditor )
+  {
+    if ( e->type() == QEvent::EnabledChange )
+    {
+      setEnabled( myEditor->isEnabled() );
+    }
+    else if ( e->type() == QEvent::Hide )
+    {
+      hide();
+    }
+    else if ( e->type() == QEvent::KeyPress )
+    {
+      QKeyEvent* ke = (QKeyEvent*)e;
+      switch ( ke->key() )
+      {
+      case Qt::Key_Escape:
+        if ( isVisible() )
+          hide();
+        break;
+      default:
+        break;
+      }
+    }
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+/*!
+  \brief Slot: activate 'Find' dialog.
+*/
+void PyEditor_FindTool::activateFind()
+{
+  activate( Find );
+}
+
+/*!
+  \brief Slot: activate 'Replace' dialog.
+*/
+void PyEditor_FindTool::activateReplace()
+{
+  activate( Replace );
+}
+
+/*!
+  \brief Slot: show context menu with search options.
+  \internal
+*/
+void PyEditor_FindTool::showMenu()
+{
+  QMenu::exec( actions().mid( CaseSensitive, RegExp+1 ), QCursor::pos() );
+}
+/*!
+  \brief Slot: find text being typed in the 'Find' control.
+  \param text Text entered by the user.
+  \internal
+*/
+void PyEditor_FindTool::find( const QString& text )
+{
+  find( text, 0 );
+}
+
+/*!
+  \brief Slot: find text entered in the 'Find' control.
+  \internal
+  \overload
+*/
+void PyEditor_FindTool::find()
+{
+  find( myFindEdit->text(), 0 );
+}
+
+/*!
+  \brief Slot: find previous matched item; called when user presses 'Previous' button.
+  \internal
+*/
+void PyEditor_FindTool::findPrevious()
+{
+  find( myFindEdit->text(), -1 );
+}
+
+/*!
+  \brief Slot: find next matched item; called when user presses 'Next' button.
+  \internal
+*/
+void PyEditor_FindTool::findNext()
+{
+  find( myFindEdit->text(), 1 );
+}
+
+/*!
+  \brief Slot: replace currently selected match; called when user presses 'Replace' button.
+  \internal
+*/
+void PyEditor_FindTool::replace()
+{
+  QString text = myFindEdit->text();
+  QString replacement = myReplaceEdit->text();
+
+  QTextCursor editor = myEditor->textCursor();
+  if ( editor.hasSelection() && editor.selectedText() == text )
+  {
+    editor.beginEditBlock();
+    editor.removeSelectedText();
+    editor.insertText( replacement );
+    editor.endEditBlock();
+    find();
+  }
+}
+
+/*!
+  \brief Slot: replace all matches; called when user presses 'Replace All' button.
+  \internal
+*/
+void PyEditor_FindTool::replaceAll()
+{
+  QString text = myFindEdit->text();
+  QString replacement = myReplaceEdit->text();
+  QList<QTextCursor> results = matches( text );
+  if ( !results.isEmpty() )
+  {
+    QTextCursor editor( myEditor->document() );
+    editor.beginEditBlock();
+    foreach ( QTextCursor cursor, results )
+    {
+      editor.setPosition( cursor.anchor() );
+      editor.setPosition( cursor.position(), QTextCursor::KeepAnchor );
+      editor.removeSelectedText();
+      editor.insertText( replacement );
+    }
+    editor.endEditBlock();
+    find();
+  }
+}
+
+/*!
+  \brief Slot: restart search; called when search options are changed.
+  \internal
+*/
+void PyEditor_FindTool::update()
+{
+  find();
+}
+
+/*!
+  \brief Slot: activate action; called when user types corresponding shortcut.
+  \param action Action being activated.
+  \internal
+*/
+void PyEditor_FindTool::activate( int action )
+{
+  QTextCursor cursor = myEditor->textCursor();
+  cursor.movePosition( QTextCursor::StartOfWord );
+  cursor.movePosition( QTextCursor::EndOfWord, QTextCursor::KeepAnchor );
+  QString word = cursor.selectedText();
+
+  switch ( action )
+  {
+  case Find:
+  case Replace:
+    showReplaceControls( action == Replace );
+    show();
+    if ( !word.isEmpty() ) {
+      myFindEdit->setText( word );
+      myEditor->setTextCursor( cursor );
+    }
+    myFindEdit->setFocus();
+    myFindEdit->selectAll();
+    find( myFindEdit->text() );
+    break;
+  case FindPrevious:
+    findPrevious();
+    break;
+  case FindNext:
+    findNext();
+    break;
+  default:
+    break;
+  }
+}
+
+/*!
+  \brief Get shortcuts for given action.
+  \param action Editor's action.
+  \return List of shortcuts.
+  \internal
+*/
+QList<QKeySequence> PyEditor_FindTool::shortcuts( int action ) const
+{
+  QList<QKeySequence> bindings;
+  switch ( action )
+  {
+  case Find:
+    bindings << QKeySequence( QKeySequence::Find );
+    break;
+  case FindPrevious:
+    bindings << QKeySequence( QKeySequence::FindPrevious );
+    break;
+  case FindNext:
+    bindings << QKeySequence( QKeySequence::FindNext );
+    break;
+  case Replace:
+    bindings << QKeySequence( QKeySequence::Replace );
+    bindings << QKeySequence( "Ctrl+H" );
+    break;
+  default:
+    break;
+  }
+  return bindings;
+}
+
+/*!
+  \brief Update shortcuts when widget is enabled / disabled.
+  \internal
+*/
+void PyEditor_FindTool::updateShortcuts()
+{
+  foreach ( QAction* action, actions().mid( Find ) )
+  {
+    action->setEnabled( isEnabled() && myEditor->isEnabled() );
+  }
+}
+
+/*!
+  \brief Show / hide 'Replace' controls.
+  \param on Visibility flag.
+  \internal
+*/
+void PyEditor_FindTool::showReplaceControls( bool on )
+{
+  QGridLayout* l = qobject_cast<QGridLayout*>( layout() );
+  for ( int j = 0; j < l->columnCount(); j++ )
+  {
+    if ( l->itemAtPosition( 1, j )->widget() )
+      l->itemAtPosition( 1, j )->widget()->setVisible( on );
+  }
+}
+
+/*!
+  \brief Set palette for 'Find' tool depending on results of search.
+  \param found Search result: true in case of success; false otherwise.
+  \internal
+*/
+void PyEditor_FindTool::setSearchResult( bool found )
+{
+  QPalette pal = myFindEdit->palette();
+  QPalette ref = myReplaceEdit->palette();
+  pal.setColor( QPalette::Active, QPalette::Text,
+                found ? ref.color( QPalette::Active, QPalette::Text ) : QColor( 255, 0, 0 ) );
+  myFindEdit->setPalette( pal );
+}
+
+/*!
+  \brief Get 'Use regular expression' search option.
+  \return true if option is switched on; false otherwise.
+  \internal
+*/
+bool PyEditor_FindTool::isRegExp() const
+{
+  return actions()[RegExp]->isChecked();
+}
+
+/*!
+  \brief Get 'Case sensitive search' search option.
+  \return true if option is switched on; false otherwise.
+  \internal
+*/
+bool PyEditor_FindTool::isCaseSensitive() const
+{
+  return actions()[CaseSensitive]->isChecked();
+}
+
+/*!
+  \brief Get 'Whole words only' search option.
+  \return true if option is switched on; false otherwise.
+  \internal
+*/
+bool PyEditor_FindTool::isWholeWord() const
+{
+  return actions()[WholeWord]->isChecked();
+}
+
+/*!
+  \brief Get search options.
+  \param back Search direction: backward if false; forward otherwise.
+  \return List of options
+  \internal
+*/
+QTextDocument::FindFlags PyEditor_FindTool::searchFlags( bool back ) const
+{
+  QTextDocument::FindFlags flags = 0;
+  if ( isCaseSensitive() )
+    flags |= QTextDocument::FindCaseSensitively;
+  if ( isWholeWord() )
+    flags |= QTextDocument::FindWholeWords;
+  if ( back )
+    flags |= QTextDocument::FindBackward;
+  return flags;
+}
+
+/*!
+  \brief Get all matches from Python editor.
+  \param text Text being searched.
+  \return List of all matches.
+  \internal
+*/
+QList<QTextCursor> PyEditor_FindTool::matches( const QString& text ) const
+{
+  QList<QTextCursor> results;
+
+  QTextDocument* document = myEditor->document();
+
+  QTextCursor cursor( document );
+  while ( !cursor.isNull() )
+  {
+    cursor = isRegExp() ? 
+      document->find( QRegExp( text, isCaseSensitive() ?
+                               Qt::CaseSensitive : Qt::CaseInsensitive ),
+                      cursor, searchFlags() ) : 
+      document->find( text, cursor, searchFlags() );
+    if ( !cursor.isNull() )
+      results.append( cursor );
+  }
+  return results;
+}
+
+/*!
+  \brief Find specified text.
+  \param text Text being searched.
+  \param delta Search direction.
+  \internal
+*/
+void PyEditor_FindTool::find( const QString& text, int delta )
+{
+  QTextCursor cursor = myEditor->textCursor();
+  int position = qMin( cursor.position(), cursor.anchor() ) + delta;
+  cursor.setPosition( position );
+  myEditor->setTextCursor( cursor );
+
+  QList<QTextCursor> results = matches( text );
+
+  int index = -1;
+  if ( !results.isEmpty() )
+  {
+    if ( delta >= 0 )
+    {
+      // search forward
+      if ( position > results.last().anchor() )
+        position = 0;
+      for ( int i = 0; i < results.count() && index == -1; i++ )
+      {
+        QTextCursor result = results[i];
+        if ( result.hasSelection() && position <= result.anchor() )
+        {
+          index = i;
+        }
+      }
+    }
+    else
+    {
+      // search backward
+      if ( position < results.first().position() )
+        position = results.last().position();
+
+      for ( int i = results.count()-1; i >= 0 && index == -1; i-- )
+      {
+        QTextCursor result = results[i];
+        if ( result.hasSelection() && position >= result.position() )
+        {
+          index = i;
+        }
+      }
+    }
+  }
+  if ( index != -1 )
+  {
+    myInfoLabel->setText( tr( "NB_MATCHED_LABEL" ).arg( index+1 ).arg( results.count() ) );
+    myEditor->setTextCursor( results[index] );
+  }
+  else
+  {
+    myInfoLabel->clear();
+    cursor.clearSelection();
+    myEditor->setTextCursor( cursor );
+  }
+
+  setSearchResult( text.isEmpty() || !results.isEmpty() );
+}
+
+/*!
+  \brief Add completion.
+  \param text Completeion being added.
+  \param replace true to add 'Replace' completion; false to add 'Find' completion.
+  \internal
+*/
+void PyEditor_FindTool::addCompletion( const QString& text, bool replace )
+{
+  QStringListModel& model = replace ? myReplaceCompletion : myFindCompletion;
+
+  QStringList completions = model.stringList();
+  if ( !text.isEmpty() and !completions.contains( text ) )
+  {
+    completions.prepend( text );
+    model.setStringList( completions );
+  }
+}
diff --git a/tools/PyEditor/src/PyEditor_FindTool.h b/tools/PyEditor/src/PyEditor_FindTool.h
new file mode 100644 (file)
index 0000000..e650170
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_FindTool.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#ifndef PYEDITOR_FINDTOOL_H
+#define PYEDITOR_FINDTOOL_H
+
+#include "PyEditor.h"
+
+#include <QTextDocument>
+#include <QStringListModel>
+#include <QWidget>
+
+class PyEditor_Editor;
+class QAction;
+class QLabel;
+class QLineEdit;
+
+class PYEDITOR_EXPORT PyEditor_FindTool : public QWidget
+{
+Q_OBJECT
+
+  enum { CaseSensitive, WholeWord, RegExp, Find, FindPrevious, FindNext, Replace };
+
+public:
+  PyEditor_FindTool( PyEditor_Editor*, QWidget* = 0 );
+
+  bool event( QEvent* );
+  bool eventFilter( QObject*, QEvent* );
+
+public slots:
+  void activateFind();
+  void activateReplace();
+
+private slots:
+  void showMenu();
+  void find( const QString& );
+  void find();
+  void findPrevious();
+  void findNext();
+  void replace();
+  void replaceAll();
+  void update();
+  void activate( int );
+
+private:
+  QList<QKeySequence> shortcuts( int ) const;
+  void updateShortcuts();
+
+  void showReplaceControls( bool );
+  void setSearchResult( bool );
+
+  bool isRegExp() const;
+  bool isCaseSensitive() const;
+  bool isWholeWord() const;
+  QTextDocument::FindFlags searchFlags( bool = false ) const;
+
+  QList<QTextCursor> matches( const QString& ) const;
+  void find( const QString&, int );
+
+  void addCompletion( const QString&, bool );
+
+private:
+  PyEditor_Editor* myEditor;
+  QLineEdit* myFindEdit;
+  QLineEdit* myReplaceEdit;
+  QLabel* myInfoLabel;
+  QStringListModel myFindCompletion, myReplaceCompletion;
+};
+
+#endif // PYEDITOR_FINDTOOL_H
diff --git a/tools/PyEditor/src/PyEditor_Keywords.cxx b/tools/PyEditor/src/PyEditor_Keywords.cxx
new file mode 100644 (file)
index 0000000..ecc9fe6
--- /dev/null
@@ -0,0 +1,243 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Keywords.cxx
+// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com)
+//
+
+#include "PyEditor_Keywords.h"
+
+#include <QSet>
+
+/*!
+  \brief PyEditor_Keywords
+*/
+
+/*!
+  \brief Constructor.
+*/
+PyEditor_Keywords::PyEditor_Keywords( QObject* parent )
+  : QObject( parent )
+{
+}
+
+/*!
+  \brief Destructor.
+*/
+PyEditor_Keywords::~PyEditor_Keywords()
+{
+}
+
+
+QList<int> PyEditor_Keywords::types() const
+{
+  QMap<int, bool> map;
+  for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) {
+    map.insert( it.value().type, false );
+  }
+  return map.keys();
+}
+
+/*!
+  \brief Gets the colors list.
+  \return color list
+*/
+QList<QColor> PyEditor_Keywords::colors() const
+{
+  QList<QColor> list;
+  QSet<QRgb> set;
+  for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) {
+    const QColor& color = it.value().color;
+    if ( !set.contains( color.rgba() ) ) {
+      list.append( color );
+      set.insert( color.rgba() );
+    }
+  }
+  return list;
+}
+
+/*!
+  \brief Gets the keyword type.
+  \return type number
+*/
+int PyEditor_Keywords::type( const QString& keyword ) const
+{
+  return myKeywords.contains(keyword) ? myKeywords[keyword].type : -1;
+}
+
+/*!
+  \brief Gets the keyword color.
+  \return color
+*/
+QColor PyEditor_Keywords::color( const QString& keyword ) const
+{
+  return myKeywords.contains(keyword) ? myKeywords[keyword].color : QColor();
+}
+
+/*!
+  \brief Gets all keywords.
+  \return keywords string list
+*/
+QStringList PyEditor_Keywords::keywords() const
+{
+  return myKeywords.keys();
+}
+
+/*!
+  \brief Gets all keywords of specified type.
+  \return keywords string list
+*/
+QStringList PyEditor_Keywords::keywords( int type ) const
+{
+  QStringList keywords;
+  for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) {
+    if ( it.value().type == type )
+      keywords.append( it.key() );
+  }
+  return keywords;
+}
+
+/*!
+  \brief Gets all keywords with specified color.
+  \return keywords string list
+*/
+QStringList PyEditor_Keywords::keywords( const QColor& color ) const
+{
+  QStringList keywords;
+  for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) {
+    if ( it.value().color == color )
+      keywords.append( it.key() );
+  }
+  return keywords;
+}
+
+/*!
+  \brief Append keyword with type and color.
+*/
+void PyEditor_Keywords::append( const QString& keyword,
+                               int type, const QColor& color )
+{
+  append( QStringList() << keyword, type, color );
+}
+
+/*!
+  \brief Append keyword list with type and color.
+*/
+void PyEditor_Keywords::append( const QStringList& keywords,
+                               int type, const QColor& color )
+{
+  bool modif = false;
+  for ( QStringList::const_iterator it = keywords.begin(); it != keywords.end(); ++it ) {
+    const QString& kw = *it;
+    bool changed = false;
+    if ( !myKeywords.contains( kw ) ) {
+      myKeywords.insert( kw, KeywordInfo() );
+      changed = true;
+    }
+    KeywordInfo& info = myKeywords[kw];
+    changed = changed || info.type != type || info.color != color;
+    info.type = type;
+    info.color = color;
+
+    modif = modif || changed;
+  }
+
+  if ( modif )
+    Q_EMIT keywordsChanged();
+}
+
+/*!
+  \brief Remove all keywords with specified type.
+*/
+void PyEditor_Keywords::remove( int type )
+{
+  remove( keywords( type ) );
+}
+
+/*!
+  \brief Remove keyword.
+*/
+void PyEditor_Keywords::remove( const QString& keyword )
+{
+  remove( QStringList() << keyword );
+}
+
+/*!
+  \brief Remove keywords.
+*/
+void PyEditor_Keywords::remove( const QStringList& keywords )
+{
+  bool changed = false;
+  for ( QStringList::const_iterator it = keywords.begin(); it != keywords.end(); ++it ) {
+    if ( myKeywords.contains( *it ) ) {
+      myKeywords.remove( *it );
+      changed = true;
+    }
+  }
+  if ( changed )
+    Q_EMIT keywordsChanged();
+}
+
+/*!
+  \brief Remove all keywords.
+*/
+void PyEditor_Keywords::clear()
+{
+  if ( !myKeywords.isEmpty() ) {
+    myKeywords.clear();
+    Q_EMIT keywordsChanged();
+  }
+}
+
+/*!
+  \brief PyEditor_StandardKeywords
+*/
+
+PyEditor_StandardKeywords::PyEditor_StandardKeywords( QObject* parent )
+  : PyEditor_Keywords( parent )
+{
+  QStringList aBase;
+  aBase << "and" << "as" << "assert" << "break" << "class" << "continue"
+       << "def" << "elif" << "else" << "except" << "exec" << "finally"
+       << "False" << "for" << "from" << "global" << "if" << "import"
+       << "in" << "is" << "lambda" << "None" << "not" << "or" << "pass"
+       << "print" << "raise" << "return" << "True" << "try" << "while"
+       << "with" << "yield";
+  append( aBase, Base, Qt::blue );
+
+  QStringList anExcept;
+  anExcept << "ArithmeticError" << "AssertionError" << "AttributeError"
+          << "EnvironmentError" << "EOFError" << "Exception"
+          << "FloatingPointError" << "ImportError" << "IndentationError"
+          << "IndexError" << "IOError" << "KeyboardInterrupt" << "KeyError"
+          << "LookupError" << "MemoryError" << "NameError" << "OSError"
+          << "NotImplementedError" << "OverflowError" << "ReferenceError"
+          << "RuntimeError" << "StandardError" << "StopIteration"
+          << "SyntaxError" << "SystemError" << "SystemExit" << "TabError"
+          << "TypeError" << "UnboundLocalError" << "UnicodeDecodeError"
+          << "UnicodeEncodeError" << "UnicodeError" << "UnicodeTranslateError"
+          << "ValueError" << "WindowsError" << "ZeroDivisionError"
+          << "Warning" << "UserWarning" << "DeprecationWarning"
+          << "PendingDeprecationWarning" << "SyntaxWarning"
+          << "OverflowWarning" << "RuntimeWarning" << "FutureWarning";
+  append( anExcept, Exceptions, Qt::magenta );
+}
+
+PyEditor_StandardKeywords::~PyEditor_StandardKeywords()
+{
+}
diff --git a/tools/PyEditor/src/PyEditor_Keywords.h b/tools/PyEditor/src/PyEditor_Keywords.h
new file mode 100644 (file)
index 0000000..03f5506
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Keywords.h
+// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com)
+//
+
+#ifndef PYEDITOR_KEYWORDS_H
+#define PYEDITOR_KEYWORDS_H
+
+#include <QObject>
+#include <QColor>
+#include <QList>
+#include <QMap>
+
+class PyEditor_Keywords : public QObject
+{
+  Q_OBJECT
+
+public:
+  PyEditor_Keywords( QObject* = 0 );
+  virtual ~PyEditor_Keywords();
+
+  QList<int>       types() const;
+  QList<QColor>    colors() const;
+
+  int              type( const QString& ) const;
+  QColor           color( const QString& ) const;
+
+  QStringList      keywords() const;
+  QStringList      keywords( int ) const;
+  QStringList      keywords( const QColor& ) const;
+
+  void             append( const QString&, int, const QColor& = QColor() );
+  void             append( const QStringList&, int, const QColor& = QColor() );
+
+  void             remove( int );
+  void             remove( const QString& );
+  void             remove( const QStringList& );
+
+  void             clear();
+
+Q_SIGNALS:
+  void             keywordsChanged();
+
+private:
+  typedef struct { int type; QColor color; } KeywordInfo;
+  typedef QMap<QString, KeywordInfo>         KeywordMap;
+
+private:
+  KeywordMap       myKeywords;
+};
+
+class PyEditor_StandardKeywords : public PyEditor_Keywords
+{
+  Q_OBJECT
+
+public:
+  typedef enum { Base, Exceptions } KeywordType;
+
+public:
+  PyEditor_StandardKeywords( QObject* = 0 );
+  virtual ~PyEditor_StandardKeywords();
+};
+
+#endif
index 70ff0186a03e50ad8e03ccbdb0e112be9602c8c5..70a92748b072c7aa8b4fc1ecfccd4e1d28be1111 100644 (file)
 
 #include "PyEditor_PyHighlighter.h"
 
+#include "PyEditor_Keywords.h"
+
+#include <QSet>
+
 #define NORMAL 0
 #define TRIPLESINGLE 1
 #define TRIPLEDOUBLE 2
@@ -53,192 +57,20 @@ void PyEditor_PyHighlighter::TextBlockData::insert( PyEditor_PyHighlighter::Pare
   \brief Constructor.
   \param theDocument container for structured rich text documents.
 */
-PyEditor_PyHighlighter::PyEditor_PyHighlighter( QTextDocument* theDocument )
-  : QSyntaxHighlighter( theDocument )
-{
-  initialize();
-}
-
-/*!
-  \brief Initialization rules.
-*/
-void PyEditor_PyHighlighter::initialize()
+PyEditor_PyHighlighter::PyEditor_PyHighlighter( QTextDocument* theDocument,
+                                               PyEditor_Keywords* std,
+                                               PyEditor_Keywords* user )
+  : QSyntaxHighlighter( theDocument ),
+    myStdKeywords( std ),
+    myUserKeywords( user )
 {
-  HighlightingRule aRule;
-
-  // Keywords
-  keywordFormat.setForeground( Qt::blue );
-  QStringList aKeywords = keywords();
-  foreach ( const QString& keyword, aKeywords )
-  {
-    aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) );
-    aRule.format = keywordFormat;
-    aRule.capture = 0;
-    highlightingRules.append( aRule );
-  }
-
-  // Special keywords
-  specialFromat.setForeground( Qt::magenta );
-  QStringList aSpecialKeywords = specialKeywords();
-  foreach ( const QString& keyword, aSpecialKeywords )
-  {
-    aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) );
-    aRule.format = specialFromat;
-    aRule.capture = 0;
-    highlightingRules.append( aRule );
-  }
-
-  // Reference to the current instance of the class
-  referenceClassFormat.setForeground( QColor( 179, 143, 0 ) );
-  referenceClassFormat.setFontItalic( true );
-  aRule.pattern = QRegExp( "\\bself\\b" );
-  aRule.format = referenceClassFormat;
-  aRule.capture = 0;
-  highlightingRules.append( aRule );
-
-  // Numbers
-  numberFormat.setForeground( Qt::darkMagenta );
-  aRule.pattern = QRegExp( "\\b([-+])?(\\d+(\\.)?\\d*|\\d*(\\.)?\\d+)(([eE]([-+])?)?\\d+)?\\b" );
-  aRule.format = numberFormat;
-  aRule.capture = 0;
-  highlightingRules.append( aRule );
-
-  // String qoutation
-  quotationFormat.setForeground( Qt::darkGreen );
-  aRule.pattern = QRegExp( "(?:'[^']*'|\"[^\"]*\")" );
-  aRule.pattern.setMinimal( true );
-  aRule.format = quotationFormat;
-  aRule.capture = 0;
-  highlightingRules.append( aRule );
 
-  // Function names
-  functionFormat.setFontWeight( QFont::Bold );
-  aRule.pattern = QRegExp( "(?:def\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" );
-  aRule.capture = 1;
-  aRule.format = functionFormat;
-  highlightingRules.append( aRule );
-
-  // Class names
-  classFormat.setForeground( Qt::darkBlue );
-  classFormat.setFontWeight( QFont::Bold );
-  aRule.pattern = QRegExp( "(?:class\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" );
-  aRule.capture = 1;
-  aRule.format = classFormat;
-  highlightingRules.append( aRule );
-
-  // Multi line comments
-  multiLineCommentFormat.setForeground( Qt::darkRed );
-  tripleQuotesExpression = QRegExp( "(:?\"[\"]\".*\"[\"]\"|'''.*''')" );
-  aRule.pattern = tripleQuotesExpression;
-  aRule.pattern.setMinimal( true );
-  aRule.format = multiLineCommentFormat;
-  aRule.capture = 0;
-  highlightingRules.append( aRule );
-
-  tripleSingleExpression = QRegExp( "'''(?!\")" );
-  tripleDoubleExpression = QRegExp( "\"\"\"(?!')" );
-
-  // Single comments
-  singleLineCommentFormat.setForeground( Qt::darkGray );
-  aRule.pattern = QRegExp( "#[^\n]*" );
-  aRule.format = singleLineCommentFormat;
-  aRule.capture = 0;
-  highlightingRules.append( aRule );
-}
-
-/*!
-  \return string list of Python keywords.
- */
-QStringList PyEditor_PyHighlighter::keywords()
-{
-  QStringList aKeywords;
-  aKeywords << "and"
-            << "as"
-            << "assert"
-            << "break"
-            << "class"
-            << "continue"
-            << "def"
-            << "elif"
-            << "else"
-            << "except"
-            << "exec"
-            << "finally"
-            << "False"
-            << "for"
-            << "from"
-            << "global"
-            << "if"
-            << "import"
-            << "in"
-            << "is"
-            << "lambda"
-            << "None"
-            << "not"
-            << "or"
-            << "pass"
-            << "print"
-            << "raise"
-            << "return"
-            << "True"
-            << "try"
-            << "while"
-            << "with"
-            << "yield";
-  return aKeywords;
-}
+  connect(myStdKeywords, SIGNAL( keywordsChanged() ),
+         this, SLOT( onKeywordsChanged() ) );
+  connect(myUserKeywords, SIGNAL( keywordsChanged() ),
+         this, SLOT( onKeywordsChanged() ) );
 
-/*!
-  \return string list of special Python keywords.
-*/
-QStringList PyEditor_PyHighlighter::specialKeywords()
-{
-  QStringList aSpecialKeywords;
-  aSpecialKeywords << "ArithmeticError"
-                   << "AssertionError"
-                   << "AttributeError"
-                   << "EnvironmentError"
-                   << "EOFError"
-                   << "Exception"
-                   << "FloatingPointError"
-                   << "ImportError"
-                   << "IndentationError"
-                   << "IndexError"
-                   << "IOError"
-                   << "KeyboardInterrupt"
-                   << "KeyError"
-                   << "LookupError"
-                   << "MemoryError"
-                   << "NameError"
-                   << "NotImplementedError"
-                   << "OSError"
-                   << "OverflowError"
-                   << "ReferenceError"
-                   << "RuntimeError"
-                   << "StandardError"
-                   << "StopIteration"
-                   << "SyntaxError"
-                   << "SystemError"
-                   << "SystemExit"
-                   << "TabError"
-                   << "TypeError"
-                   << "UnboundLocalError"
-                   << "UnicodeDecodeError"
-                   << "UnicodeEncodeError"
-                   << "UnicodeError"
-                   << "UnicodeTranslateError"
-                   << "ValueError"
-                   << "WindowsError"
-                   << "ZeroDivisionError"
-                   << "Warning"
-                   << "UserWarning"
-                   << "DeprecationWarning"
-                   << "PendingDeprecationWarning"
-                   << "SyntaxWarning"
-                   << "OverflowWarning"
-                   << "RuntimeWarning"
-                   << "FutureWarning";
-  return aSpecialKeywords;
+  updateHighlight();
 }
 
 void PyEditor_PyHighlighter::highlightBlock( const QString& theText )
@@ -353,3 +185,100 @@ void PyEditor_PyHighlighter::insertBracketsData( Brackets theBrackets,
 
   insertBracketsData( leftChar, rightChar, theData, theText );
 }
+
+void PyEditor_PyHighlighter::onKeywordsChanged()
+{
+  updateHighlight();
+  rehighlight();
+}
+
+void PyEditor_PyHighlighter::updateHighlight()
+{
+  highlightingRules.clear();
+
+  HighlightingRule aRule;
+
+  QList<PyEditor_Keywords*> dictList;
+  dictList << myStdKeywords << myUserKeywords;
+
+  // Keywords
+  QSet<QString> existing;
+  for ( QList<PyEditor_Keywords*>::const_iterator it = dictList.begin();
+       it != dictList.end(); ++it ) {
+    PyEditor_Keywords* kwDict = *it;
+    QList<QColor> colors = kwDict->colors();
+    for ( QList<QColor>::const_iterator itr = colors.begin(); itr != colors.end(); ++itr ) {
+      QColor color = *itr;
+      QTextCharFormat format;
+      format.setForeground( color );
+      QStringList keywords = kwDict->keywords( color );
+      foreach ( const QString& keyword, keywords ) {
+       if ( existing.contains( keyword ) )
+         continue;
+
+       aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) );
+       aRule.format = format;
+       aRule.capture = 0;
+       highlightingRules.append( aRule );
+       existing.insert( keyword );
+      }
+    }
+  }
+
+  // Reference to the current instance of the class
+  referenceClassFormat.setForeground( QColor( 179, 143, 0 ) );
+  referenceClassFormat.setFontItalic( true );
+  aRule.pattern = QRegExp( "\\bself\\b" );
+  aRule.format = referenceClassFormat;
+  aRule.capture = 0;
+  highlightingRules.append( aRule );
+
+  // Numbers
+  numberFormat.setForeground( Qt::darkMagenta );
+  aRule.pattern = QRegExp( "\\b([-+])?(\\d+(\\.)?\\d*|\\d*(\\.)?\\d+)(([eE]([-+])?)?\\d+)?\\b" );
+  aRule.format = numberFormat;
+  aRule.capture = 0;
+  highlightingRules.append( aRule );
+
+  // String qoutation
+  quotationFormat.setForeground( Qt::darkGreen );
+  aRule.pattern = QRegExp( "(?:'[^']*'|\"[^\"]*\")" );
+  aRule.pattern.setMinimal( true );
+  aRule.format = quotationFormat;
+  aRule.capture = 0;
+  highlightingRules.append( aRule );
+
+  // Function names
+  functionFormat.setFontWeight( QFont::Bold );
+  aRule.pattern = QRegExp( "(?:def\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" );
+  aRule.capture = 1;
+  aRule.format = functionFormat;
+  highlightingRules.append( aRule );
+
+  // Class names
+  classFormat.setForeground( Qt::darkBlue );
+  classFormat.setFontWeight( QFont::Bold );
+  aRule.pattern = QRegExp( "(?:class\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" );
+  aRule.capture = 1;
+  aRule.format = classFormat;
+  highlightingRules.append( aRule );
+
+  // Multi line comments
+  multiLineCommentFormat.setForeground( Qt::darkRed );
+  tripleQuotesExpression = QRegExp( "(:?\"[\"]\".*\"[\"]\"|'''.*''')" );
+  aRule.pattern = tripleQuotesExpression;
+  aRule.pattern.setMinimal( true );
+  aRule.format = multiLineCommentFormat;
+  aRule.capture = 0;
+  highlightingRules.append( aRule );
+
+  tripleSingleExpression = QRegExp( "'''(?!\")" );
+  tripleDoubleExpression = QRegExp( "\"\"\"(?!')" );
+
+  // Single comments
+  singleLineCommentFormat.setForeground( Qt::darkGray );
+  aRule.pattern = QRegExp( "#[^\n]*" );
+  aRule.format = singleLineCommentFormat;
+  aRule.capture = 0;
+  highlightingRules.append( aRule );
+}
index 961616fa28993a371ea395e80f37f323efddb1e3..07ac00611f750db94539ff4deffba30d199c85e0 100644 (file)
@@ -26,6 +26,7 @@
 #include <QSyntaxHighlighter>
 
 class QTextDocument;
+class PyEditor_Keywords;
 
 class PyEditor_PyHighlighter : public QSyntaxHighlighter
 {
@@ -52,11 +53,14 @@ public:
   };
 
 public:
-  PyEditor_PyHighlighter( QTextDocument* = 0 );
+  PyEditor_PyHighlighter( QTextDocument*,
+                         PyEditor_Keywords*, PyEditor_Keywords* );
 
-  void initialize();
-  QStringList keywords();
-  QStringList specialKeywords();
+private Q_SLOTS:
+  void        onKeywordsChanged();
+
+protected:
+  void        updateHighlight();
 
 protected:
   struct HighlightingRule
@@ -76,8 +80,6 @@ protected:
   QTextCharFormat classFormat;
   QTextCharFormat referenceClassFormat;
   QTextCharFormat functionFormat;
-  QTextCharFormat keywordFormat;
-  QTextCharFormat specialFromat;
   QTextCharFormat numberFormat;
   QTextCharFormat singleLineCommentFormat;
   QTextCharFormat multiLineCommentFormat;
@@ -86,6 +88,10 @@ protected:
   void highlightBlock( const QString& );
   void insertBracketsData( char, char, TextBlockData*, const QString& );
   void insertBracketsData( Brackets, TextBlockData*, const QString& );
+
+private:
+  PyEditor_Keywords* myStdKeywords;
+  PyEditor_Keywords* myUserKeywords;
 };
 
 #endif // PYEDITOR_PYHIGHLIGHTER_H
index d9fd52fd173343a696322e831a8448ae0b4d9c09..64a43d700e8d4237db26bb62f7d5cd08012cf413 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "PyEditor_Settings.h"
 
+#include "PyEditor_Editor.h"
+
 /*!
   \class PyEditor_Settings
   \brief Manager of setting values.
@@ -61,7 +63,8 @@ PyEditor_Settings::PyEditor_Settings()
     myNumberColumns( 80 ),
     myTabSpaceVisible( true ),
     myTabSize( 4 ),
-    myFont( "Courier", 10 )
+    myFont( "Courier", 10 ),
+    myCompletionPolicy( PyEditor_Editor::Always )
 {
 }
 
@@ -227,6 +230,24 @@ QFont PyEditor_Settings::font() const
   return myFont;
 }
 
+/*!
+  \brief Set "completionPolicy" option.
+  \param completion policy option value
+*/
+void PyEditor_Settings::setCompletionPolicy( int value )
+{
+  myCompletionPolicy = value;
+}
+
+/*!
+  \brief Get "completionPolicy" option.
+  \return option value
+*/
+int PyEditor_Settings::completionPolicy() const
+{
+  return myCompletionPolicy;
+}
+
 /*!
   \brief Read settings from the persistence storage.
   Base implementation does nothing; it should be reimplemented in successors.
@@ -258,6 +279,8 @@ void PyEditor_Settings::copyFrom( const PyEditor_Settings& other )
   setVerticalEdge( other.verticalEdge() );
   setNumberColumns( other.numberColumns() );
   setFont( other.font() );
+  setCompletionPolicy( other.completionPolicy() );
+
   save();
 }
 
@@ -278,6 +301,7 @@ QString PyEditor_Settings::option( Option option )
     "TabSpaceVisible",
     "TabSize",
     "Font",
+    "CompletionPolicy"
   };
-  return option >= 0 && option <= snFont ? options[option] : "Unknown";
+  return option >= 0 && option <= snCompletionPolicy ? options[option] : "Unknown";
 }
index aa6de041985d28231a8c35dc462622eb299de966..7b7e4b7c2e38f441145e786c7c9c6cb8368c0770 100644 (file)
@@ -39,7 +39,8 @@ protected:
                 snNumberColumns,
                 snTabSpaceVisible,
                 snTabSize,
-                snFont };
+                snFont,
+                snCompletionPolicy };
 
 public:
   static PyEditor_Settings* settings();
@@ -75,6 +76,9 @@ public:
   void setFont( const QFont& );
   QFont font() const;
 
+  void setCompletionPolicy( int );
+  int completionPolicy() const;
+
   virtual void load();
   virtual void save();
 
@@ -101,6 +105,9 @@ private:
   // Font settings
   QFont myFont;
 
+  // Completion settings
+  int myCompletionPolicy;
+
   static PyEditor_Settings* myGlobalSettings;
 };
 
index fc2c94b6495a7cbf954a71b5140183af7a4b75e0..4b021a070b58e9455e943636787a14ed5b81b4cd 100644 (file)
@@ -85,6 +85,16 @@ PyEditor_SettingsDlg::PyEditor_SettingsDlg( PyEditor_Editor* theEditor,
   aMainLayout->addWidget( aDisplaySetBox );
   // . Display settings <end>
 
+  // . Editor settings <start>
+  QGroupBox* aEditorSetBox = new QGroupBox( tr( "GR_EDIT_SET" ), this );
+  QGridLayout* aEditorSetLayout = new QGridLayout( aEditorSetBox );
+  aEditorSetLayout->addWidget( new QLabel( tr( "LBL_COMPLETION_MODE" ), aEditorSetBox ), 0, 0 );
+  aEditorSetLayout->addWidget( myCompletionPolicy = new QComboBox( aEditorSetBox ), 0, 1 );
+  myCompletionPolicy->addItems( QStringList() << tr( "LBL_NONE" ) << tr( "LBL_AUTO" )
+                               << tr( "LBL_MANUAL" ) << tr( "LBL_ALWAYS" ) );
+  aMainLayout->addWidget( aEditorSetBox );
+  // . Editor settings <end>
+
   // . Tab settings <start>
   QGroupBox* aTabSetBox = new QGroupBox( tr( "GR_TAB_SET" ), this );
   QVBoxLayout* aTabSetLayout = new QVBoxLayout( aTabSetBox );
@@ -237,6 +247,7 @@ void PyEditor_SettingsDlg::settingsFromGui()
   settings.setVerticalEdge( myVerticalEdge->isChecked() );
   settings.setNumberColumns( myNumberColumns->value() );
   settings.setFont( font );
+  settings.setCompletionPolicy( myCompletionPolicy->currentIndex() );
   myEditor->setSettings(settings); // updateContent()
 
   PyEditor_Settings* globals = PyEditor_Settings::settings();
@@ -261,6 +272,7 @@ void PyEditor_SettingsDlg::settingsToGui()
   myNumberColumns->setValue( settings.numberColumns() );
   myFontFamily->setCurrentFont( settings.font() );
   setFontSize( QString::number( settings.font().pointSize() ) );
+  myCompletionPolicy->setCurrentIndex( settings.completionPolicy() );
 
   onVerticalEdgeChecked();
   onFontChanged();
index 9f3dfa98695a1a2c29f4e5db6d73f408e97b6cac..24e4c6768ba2acc59ef7c7ca8412117dd4186679 100644 (file)
@@ -39,7 +39,7 @@ class PYEDITOR_EXPORT PyEditor_SettingsDlg : public QDialog
 
 public:
   PyEditor_SettingsDlg( PyEditor_Editor*, bool = false, QWidget* = 0 );
-  ~PyEditor_SettingsDlg();
+  virtual ~PyEditor_SettingsDlg();
 
 private Q_SLOTS:
   void onVerticalEdgeChecked();
@@ -71,6 +71,8 @@ private:
   QFontComboBox*    myFontFamily;
   QComboBox*        myFontSize;
 
+  QComboBox*        myCompletionPolicy;
+
   QCheckBox*        myDefaultCheck;
 
   PyEditor_Editor*  myEditor;
index 816db36535ca1c827ae6959a789fa826c5a9cb71..06a2b68eb185c5ea7e37556a9a3bc6edb34c055f 100644 (file)
@@ -59,15 +59,24 @@ void PyEditor_StdSettings::load()
 {
   mySettings.beginGroup( myGroup.isEmpty() ? option( snEditor ) : myGroup );
 
-  setHighlightCurrentLine( mySettings.value( option( snHighlightCurrentLine ), highlightCurrentLine() ).toBool() );
-  setTextWrapping( mySettings.value( option( snTextWrapping ), textWrapping() ).toBool() );
-  setCenterCursorOnScroll( mySettings.value( option( snCenterCursorOnScroll ), centerCursorOnScroll() ).toBool() );
-  setLineNumberArea( mySettings.value( option( snLineNumberArea ), lineNumberArea() ).toBool() );
-  setVerticalEdge( mySettings.value( option( snVerticalEdge  ), verticalEdge() ).toBool() );
-  setNumberColumns( mySettings.value( option( snNumberColumns ), numberColumns() ).toInt() );
-  setTabSpaceVisible( mySettings.value( option( snTabSpaceVisible ), tabSpaceVisible() ).toBool() );
+  setHighlightCurrentLine( mySettings.value( option( snHighlightCurrentLine ),
+                                            highlightCurrentLine() ).toBool() );
+  setTextWrapping( mySettings.value( option( snTextWrapping ),
+                                    textWrapping() ).toBool() );
+  setCenterCursorOnScroll( mySettings.value( option( snCenterCursorOnScroll ),
+                                            centerCursorOnScroll() ).toBool() );
+  setLineNumberArea( mySettings.value( option( snLineNumberArea ),
+                                      lineNumberArea() ).toBool() );
+  setVerticalEdge( mySettings.value( option( snVerticalEdge  ),
+                                    verticalEdge() ).toBool() );
+  setNumberColumns( mySettings.value( option( snNumberColumns ),
+                                     numberColumns() ).toInt() );
+  setTabSpaceVisible( mySettings.value( option( snTabSpaceVisible ),
+                                       tabSpaceVisible() ).toBool() );
   setTabSize( mySettings.value( option( snTabSize ), tabSize() ).toInt() );
   setFont( mySettings.value( option( snFont ), font() ).value<QFont>() );
+  setCompletionPolicy( mySettings.value( option( snCompletionPolicy ),
+                                        completionPolicy() ).toInt() );
   setLanguage( mySettings.value( "language", language() ).toString() );
 
   mySettings.endGroup();
@@ -86,6 +95,7 @@ void PyEditor_StdSettings::save()
   mySettings.setValue( option( snTabSpaceVisible ), tabSpaceVisible() );
   mySettings.setValue( option( snTabSize ), tabSize() );
   mySettings.setValue( option( snFont ), font() );
+  mySettings.setValue( option( snCompletionPolicy ), completionPolicy() );
   mySettings.setValue( "language", language() );
 
   mySettings.endGroup();
diff --git a/tools/PyEditor/src/PyEditor_Widget.cxx b/tools/PyEditor/src/PyEditor_Widget.cxx
new file mode 100644 (file)
index 0000000..badf973
--- /dev/null
@@ -0,0 +1,251 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Widget.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#include "PyEditor_Editor.h"
+#include "PyEditor_FindTool.h"
+#include "PyEditor_Widget.h"
+
+#include <QVBoxLayout>
+
+/*!
+  \class PyEditor_Widget
+  \brief Wraps Python editor with the find/replace functionality to a single widget.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent Parent widget.
+*/
+PyEditor_Widget::PyEditor_Widget( QWidget* parent )
+{
+  // Create editor.
+  myEditor = new PyEditor_Editor( this );
+
+  // Create find tool.
+  myFindTool = new PyEditor_FindTool( myEditor, this );
+
+  // Set-up layout
+  QVBoxLayout* layout = new QVBoxLayout( this );
+  layout->setContentsMargins( 0, 0, 0, 0 );
+  layout->setSpacing( 3 );
+  layout->addWidget( myEditor );
+  layout->addWidget( myFindTool );
+
+  connect( myEditor, SIGNAL( modificationChanged( bool ) ),
+           this, SIGNAL( modificationChanged( bool ) ) );
+  connect( myEditor, SIGNAL( undoAvailable( bool ) ),
+           this, SIGNAL( undoAvailable( bool ) ) );
+  connect( myEditor, SIGNAL( redoAvailable( bool ) ),
+           this, SIGNAL( redoAvailable( bool ) ) );
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
+           this, SIGNAL( copyAvailable( bool ) ) );
+
+  connect( myEditor, SIGNAL( selectionChanged() ),
+           this, SIGNAL( selectionChanged() ) );
+  connect( myEditor, SIGNAL( textChanged() ),
+           this, SIGNAL( textChanged() ) );
+  connect( myEditor, SIGNAL( cursorPositionChanged() ),
+           this, SIGNAL( cursorPositionChanged() ) );
+
+  setFocusProxy( myEditor );
+}
+
+/*!
+  \brief Get editor.
+  \return Pointer to editor.
+*/
+PyEditor_Editor* PyEditor_Widget::editor()
+{
+  return myEditor;
+}
+
+/*!
+  \brief Get find tool.
+  \return Pointer to find tool.
+*/
+PyEditor_FindTool* PyEditor_Widget::findTool()
+{
+  return myFindTool;
+}
+
+/*!
+  \brief Get all custom keywords from editor.
+  \return List of keywords.
+*/
+QStringList PyEditor_Widget::keywords() const
+{
+  return myEditor->keywords();
+}
+
+/*!
+  \brief Set custom keywords to editor.
+  \param keywords List of keywords.
+  \param type Type of keywords (group id).
+  \param color Color of keywords.
+*/
+void PyEditor_Widget::appendKeywords( const QStringList& keywords, int type, const QColor& color )
+{
+  myEditor->appendKeywords( keywords, type, color );
+}
+
+/*!
+  \brief Remove given custom keywords from editor.
+  \param keywords List of keywords to remove.
+*/
+void PyEditor_Widget::removeKeywords( const QStringList& keywords )
+{
+  myEditor->removeKeywords( keywords );
+}
+
+/*!
+  \brief Get current editor's completion policy.
+  \return Completion policy (see PyEditor_Editor::CompletionPolicy).
+*/
+int PyEditor_Widget::completionPolicy() const
+{
+  return (int) myEditor->completionPolicy();
+}
+
+/*!
+  \brief Set editor's completion policy.
+  \param policy Completion policy (see PyEditor_Editor::CompletionPolicy).
+*/
+void PyEditor_Widget::setCompletionPolicy( int policy )
+{
+  myEditor->setCompletionPolicy( (PyEditor_Editor::CompletionPolicy) policy );
+}
+
+/*!
+  \brief Activate Find dialog.
+*/
+void PyEditor_Widget::find()
+{
+  myFindTool->activateFind();
+}
+
+/*!
+  \brief Activate Replace dialog.
+*/
+void PyEditor_Widget::replace()
+{
+  myFindTool->activateReplace();
+}
+
+/*!
+  \brief Undo last editor's operation.
+*/
+void PyEditor_Widget::undo()
+{
+  myEditor->undo();
+}
+
+/*!
+  \brief Redo last undone editor's operation.
+*/
+void PyEditor_Widget::redo()
+{
+  myEditor->redo();
+}
+
+/*!
+  \brief Cut text selected in editor and put it into clipboard.
+*/
+void PyEditor_Widget::cut()
+{
+  myEditor->cut();
+}
+
+/*!
+  \brief Copy text selected in editor into clipboard.
+*/
+void PyEditor_Widget::copy()
+{
+  myEditor->copy();
+}
+
+/*!
+  \brief Paste text from clipboard into editor.
+*/
+void PyEditor_Widget::paste()
+{
+  myEditor->paste();
+}
+
+/*!
+  \brief Delete text selected in editor.
+*/
+void PyEditor_Widget::deleteSelected()
+{
+  myEditor->deleteSelected();
+}
+
+/*!
+  \brief Select all text in editor.
+*/
+void PyEditor_Widget::selectAll()
+{
+  myEditor->selectAll();
+}
+
+/*!
+  \brief Clear content of editor.
+*/
+void PyEditor_Widget::clear()
+{
+  myEditor->clear();
+}
+
+/*!
+  \brief Set/clear modified flag of editor.
+  \param on 'Modified' flag's value.
+*/
+void PyEditor_Widget::setModified( bool on )
+{
+  myEditor->document()->setModified( on );
+}
+
+/*!
+  \brief Get modified flag of editor.
+  \return 'Modified' flag's value.
+*/
+bool PyEditor_Widget::isModified()
+{
+  return myEditor->document()->isModified();
+}
+
+/*!
+  \brief Set text to editor.
+  \param text Text to be put into editor.
+*/
+void PyEditor_Widget::setText( const QString& text )
+{
+  myEditor->setPlainText( text );
+}
+
+/*!
+  \brief Get text from editor.
+  \return Current editor contents.
+*/
+QString PyEditor_Widget::text() const
+{
+  return myEditor->toPlainText();
+}
diff --git a/tools/PyEditor/src/PyEditor_Widget.h b/tools/PyEditor/src/PyEditor_Widget.h
new file mode 100644 (file)
index 0000000..0927a9f
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (C) 2015-2016  OPEN CASCADE
+//
+// 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   : PyEditor_Widget.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#ifndef PYEDITOR_WIDGET_H
+#define PYEDITOR_WIDGET_H
+
+#include "PyEditor.h"
+
+#include <QWidget>
+
+class PyEditor_Editor;
+class PyEditor_FindTool;
+
+class PYEDITOR_EXPORT PyEditor_Widget : public QWidget
+{
+  Q_OBJECT
+
+public:
+  PyEditor_Widget( QWidget* = 0 );
+
+  PyEditor_Editor* editor();
+  PyEditor_FindTool* findTool();
+
+  bool isModified();
+
+  QString text() const;
+
+  QStringList keywords() const;
+  void appendKeywords( const QStringList&, int, const QColor& = QColor() );
+  void removeKeywords( const QStringList& );
+
+  int completionPolicy() const;
+  void setCompletionPolicy( int );
+
+public slots:
+  void find();
+  void replace();
+
+  void undo();
+  void redo();
+  void cut();
+  void copy();
+  void paste();
+  void deleteSelected();
+  void selectAll();
+  void clear();
+
+  void setModified( bool );
+
+  void setText( const QString& );
+
+signals:
+  void modificationChanged( bool );
+  void undoAvailable( bool );
+  void redoAvailable( bool );
+  void copyAvailable( bool );
+  void selectionChanged();
+  void textChanged();
+  void cursorPositionChanged();
+
+private:
+  PyEditor_Editor* myEditor;
+  PyEditor_FindTool* myFindTool;
+};
+
+#endif // PYEDITOR_WIDGET_H
index 74c0be04202c9940d92dad7785d6e873891ce5d8..125a27b818a4e8f119166ea39adeabdc8fe4bde6 100644 (file)
 //
 
 #include "PyEditor_Window.h"
-#include "PyEditor_Editor.h"
+#include "PyEditor_Widget.h"
 #include "PyEditor_Settings.h"
 #include "PyEditor_SettingsDlg.h"
 
 #include <QAction>
 #include <QApplication>
+#include <QCloseEvent>
 #include <QFileDialog>
 #include <QMenuBar>
 #include <QMessageBox>
@@ -48,9 +49,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
 {
   Q_INIT_RESOURCE( PyEditor );
 
-  // Create editor and set it as a central widget.
-  myTextEditor = new PyEditor_Editor( this );
-  setCentralWidget( myTextEditor );
+  // Create central widget.
+  myEditor = new PyEditor_Widget( this );
+  setCentralWidget( myEditor );
 
   // Create actions.
   QAction* action;
@@ -81,7 +82,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setShortcut( QKeySequence::Save );
   connect( action, SIGNAL( triggered( bool ) ), this, SLOT( onSave() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ),
+  connect( myEditor, SIGNAL( modificationChanged( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ SaveId ] = action;
 
@@ -109,9 +110,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_UNDO" ) );
   action->setStatusTip( tr( "DSC_UNDO" ) );
   action->setShortcut( QKeySequence::Undo );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( undo() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( undo() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( undoAvailable( bool ) ),
+  connect( myEditor, SIGNAL( undoAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ UndoId ] = action;
 
@@ -121,9 +122,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_REDO" ) );
   action->setStatusTip( tr( "DSC_REDO" ) );
   action->setShortcut( QKeySequence::Redo );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( redo() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( redo() ) );
   action->setEnabled( false );
-  connect( myTextEditor->document(), SIGNAL( redoAvailable( bool ) ),
+  connect( myEditor, SIGNAL( redoAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ RedoId ] = action;
 
@@ -133,9 +134,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_CUT" ) );
   action->setStatusTip( tr( "DSC_CUT" ) );
   action->setShortcut( QKeySequence::Cut );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( cut() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( cut() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ CutId ] = action;
 
@@ -145,9 +146,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_COPY" ) );
   action->setStatusTip( tr( "DSC_COPY" ) );
   action->setShortcut( QKeySequence::Copy );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( copy() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ CopyId ] = action;
 
@@ -157,7 +158,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_PASTE" ) );
   action->setStatusTip( tr( "DSC_PASTE" ) );
   action->setShortcut( QKeySequence::Paste );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( paste() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
   myActions[ PasteId ] = action;
 
   // . Delete
@@ -166,9 +167,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_DELETE" ) );
   action->setStatusTip( tr( "DSC_DELETE" ) );
   action->setShortcut( QKeySequence::Delete );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( deleteSelected() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( deleteSelected() ) );
   action->setEnabled( false );
-  connect( myTextEditor, SIGNAL( copyAvailable( bool ) ),
+  connect( myEditor, SIGNAL( copyAvailable( bool ) ),
            action, SLOT( setEnabled( bool ) ) );
   myActions[ DeleteId ] = action;
 
@@ -178,9 +179,29 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   action->setToolTip( tr( "TTP_SELECT_ALL" ) );
   action->setStatusTip( tr( "DSC_SELECT_ALL" ) );
   action->setShortcut( QKeySequence::SelectAll );
-  connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( selectAll() ) );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
   myActions[ SelectAllId ] = action;
 
+  // . Find
+  action = new QAction( QIcon( ":/images/py_find.png" ),
+                        tr( "ACT_FIND" ), this );
+  action->setToolTip( tr( "TTP_FIND" ) );
+  action->setStatusTip( tr( "DSC_FIND" ) );
+  action->setShortcut( QKeySequence::Find );
+  action->setShortcutContext( Qt::WidgetShortcut );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( find() ) );
+  myActions[ FindId ] = action;
+
+  // . Replace
+  action = new QAction( QIcon( ":/images/py_replace.png" ),
+                        tr( "ACT_REPLACE" ), this );
+  action->setToolTip( tr( "TTP_REPLACE" ) );
+  action->setStatusTip( tr( "DSC_REPLACE" ) );
+  action->setShortcut( QKeySequence::Replace );
+  action->setShortcutContext( Qt::WidgetShortcut );
+  connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) );
+  myActions[ ReplaceId ] = action;
+
   // . Preferences
   action = new QAction( QIcon( ":/images/py_preferences.png" ),
                         tr( "ACT_PREFERENCES" ), this );
@@ -218,6 +239,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   menu->addSeparator();
   menu->addAction( myActions[ SelectAllId ] );
   menu->addSeparator();
+  menu->addAction( myActions[ FindId ] );
+  menu->addAction( myActions[ ReplaceId ] );
+  menu->addSeparator();
   menu->addAction( myActions[ PreferencesId ] );
 
   menu = menuBar()->addMenu( tr( "MNU_HELP" ) );
@@ -242,6 +266,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   toolbar->addAction( myActions[ DeleteId ] );
   toolbar->addAction( myActions[ SelectAllId ] );
   toolbar->addSeparator();
+  toolbar->addAction( myActions[ FindId ] );
+  toolbar->addAction( myActions[ ReplaceId ] );
+  toolbar->addSeparator();
   toolbar->addAction( myActions[ PreferencesId ] );
   toolbar->addSeparator();
   toolbar->addAction( myActions[ HelpId ] );
@@ -250,7 +277,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) :
   setCurrentFile( QString() );
 
   // Additional set-up for main window.
-  connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ),
+  connect( myEditor, SIGNAL( modificationChanged( bool ) ),
            this, SLOT( setWindowModified( bool ) ) );
 
   // Initialize status bar.
@@ -283,7 +310,7 @@ void PyEditor_Window::onNew()
 {
   if ( whetherSave() )
   {
-    myTextEditor->clear();
+    myEditor->clear();
     setCurrentFile( QString() );
   }
 }
@@ -343,7 +370,7 @@ bool PyEditor_Window::onSaveAs()
 */
 void PyEditor_Window::onPreferences()
 {
-  PyEditor_SettingsDlg dlg( myTextEditor, true, this );
+  PyEditor_SettingsDlg dlg( myEditor->editor(), true, this );
   connect( &dlg, SIGNAL( help() ), this, SLOT( onHelp() ) );
   dlg.exec();
 }
@@ -355,7 +382,7 @@ void PyEditor_Window::onPreferences()
 void PyEditor_Window::setCurrentFile( const QString& filePath )
 {
   myURL = filePath;
-  myTextEditor->document()->setModified( false );
+  myEditor->setModified( false );
 
   setWindowModified( false );
 
@@ -369,7 +396,7 @@ void PyEditor_Window::setCurrentFile( const QString& filePath )
 */
 bool PyEditor_Window::whetherSave()
 {
-  if ( myTextEditor->document()->isModified() )
+  if ( myEditor->isModified() )
   {
     QMessageBox::StandardButton answer =  QMessageBox::warning( this,
                                                                 tr( "NAME_PYEDITOR" ),
@@ -394,19 +421,20 @@ bool PyEditor_Window::whetherSave()
   \brief Open file.
   \param filePath file path
 */
-void PyEditor_Window::loadFile( const QString& filePath )
+void PyEditor_Window::loadFile( const QString& filePath, bool verbose )
 {
   QFile aFile( filePath );
   if ( !aFile.open(QFile::ReadOnly | QFile::Text) )
   {
-    QMessageBox::warning( this, tr( "NAME_PYEDITOR" ),
-                          tr( "WRN_READ_FILE" ).arg( filePath ).arg( aFile.errorString() ) );
+    if ( verbose )
+      QMessageBox::warning( this, tr( "NAME_PYEDITOR" ),
+                            tr( "WRN_READ_FILE" ).arg( filePath ).arg( aFile.errorString() ) );
     return;
   }
 
   QTextStream anInput( &aFile );
   QApplication::setOverrideCursor( Qt::WaitCursor );
-  myTextEditor->setPlainText( anInput.readAll() );
+  myEditor->setText( anInput.readAll() );
   QApplication::restoreOverrideCursor();
 
   setCurrentFile( filePath );
@@ -419,19 +447,20 @@ void PyEditor_Window::loadFile( const QString& filePath )
   \brief Save file.
   \param filePath file path
 */
-bool PyEditor_Window::saveFile( const QString& filePath )
+bool PyEditor_Window::saveFile( const QString& filePath, bool verbose )
 {
   QFile aFile( filePath );
   if ( !aFile.open( QFile::WriteOnly | QFile::Text ) )
   {
-    QMessageBox::warning( this, tr( "NAME_PYEDITOR" ),
-                          tr( "WRN_WRITE_FILE" ).arg( filePath ).arg( aFile.errorString() ) );
+    if ( verbose )
+      QMessageBox::warning( this, tr( "NAME_PYEDITOR" ),
+                            tr( "WRN_WRITE_FILE" ).arg( filePath ).arg( aFile.errorString() ) );
     return false;
   }
 
   QTextStream anOutput( &aFile );
   QApplication::setOverrideCursor( Qt::WaitCursor );
-  anOutput << myTextEditor->toPlainText();
+  anOutput << myEditor->text();
   QApplication::restoreOverrideCursor();
 
   setCurrentFile( filePath );
index 209739e7718139d203342524f1600e44bdff0d86..1369db1cdaee63dc81e8523c734b679be8f5d066 100644 (file)
@@ -29,7 +29,7 @@
 #include <QMap>
 
 class QAction;
-class PyEditor_Editor;
+class PyEditor_Widget;
 
 class PYEDITOR_EXPORT PyEditor_Window : public QMainWindow
 {
@@ -38,11 +38,15 @@ class PYEDITOR_EXPORT PyEditor_Window : public QMainWindow
 public:
   enum { NewId, OpenId, SaveId, SaveAsId, ExitId,
          UndoId, RedoId, CutId, CopyId, PasteId, DeleteId, SelectAllId,
+         FindId, ReplaceId,
          PreferencesId, HelpId };
 
   PyEditor_Window( QWidget* = 0 );
   ~PyEditor_Window();
 
+  void        loadFile( const QString&, bool = true );
+  bool        saveFile( const QString&, bool = true );
+  
 protected:
   virtual void closeEvent( QCloseEvent* );
 
@@ -54,16 +58,12 @@ private Q_SLOTS:
   void        onPreferences();
   void        onHelp();
 
-private:
-  void        loadFile( const QString& );
-  bool        saveFile( const QString& );
-  
   void        setCurrentFile( const QString& );
   bool        whetherSave();
   QString     defaultName() const;
 
 private:
-  PyEditor_Editor*    myTextEditor;
+  PyEditor_Widget*    myEditor;
   QString             myURL;
   QMap<int, QAction*> myActions;
 };
index 372cc2898b7fc123bc3b38bbf4594d7e0b10265e..d6b530be9ca28e79e624d1f9f9d843a0b467021b 100644 (file)
@@ -66,6 +66,9 @@ public:
 
   void setFont( const QFont& );
   QFont font() const;
+
+  void setCompletionPolicy( int );
+  int completionPolicy() const;
 };
 
 class PyEditor_Editor : QPlainTextEdit
@@ -82,6 +85,10 @@ public:
   const PyEditor_Settings& settings() const;
   QString text() const;
 
+  QStringList keywords() const;
+  void        appendKeywords( const QStringList&, int, const QColor& = QColor() );
+  void        removeKeywords( const QStringList& );
+
 public slots:
   void deleteSelected();
   void append( const QString& );  
@@ -96,3 +103,75 @@ private:
   PyEditor_Editor( const PyEditor_Editor& );
   PyEditor_Editor& operator=( const PyEditor_Editor& );
 };
+
+class PyEditor_FindTool : public QWidget
+{ 
+%TypeHeaderCode
+#include <PyEditor_FindTool.h>
+%End
+
+public:
+  explicit PyEditor_FindTool( PyEditor_Editor* /TransferThis/, QWidget* /TransferThis/ = 0 );
+
+public slots:
+  void activateFind();
+  void activateReplace();
+
+private:
+  PyEditor_FindTool( const PyEditor_FindTool& );
+  PyEditor_FindTool& operator=( const PyEditor_FindTool& );
+};
+
+class PyEditor_Widget : public QWidget
+{ 
+%TypeHeaderCode
+#include <PyEditor_Widget.h>
+%End
+
+public:
+  explicit PyEditor_Widget( QWidget* /TransferThis/ = 0 );
+
+  PyEditor_Editor* editor();
+  PyEditor_FindTool* findTool();
+
+  bool isModified();
+
+  QString text() const;
+
+  QStringList keywords() const;
+  void appendKeywords( const QStringList&, int, const QColor& = QColor() );
+  void removeKeywords( const QStringList& );
+
+  int completionPolicy() const;
+  void setCompletionPolicy( int );
+
+public slots:
+  void find();
+  void replace();
+
+  void undo();
+  void redo();
+  void cut();
+  void copy();
+  void paste();
+  void deleteSelected();
+  void selectAll();
+  void clear();
+
+  void setModified( bool );
+
+  void setText( const QString& );
+
+signals:
+  void modificationChanged( bool );
+  void undoAvailable( bool );
+  void redoAvailable( bool );
+  void copyAvailable( bool );
+  void selectionChanged();
+  void textChanged();
+  void cursorPositionChanged();
+
+private:
+  PyEditor_Widget( const PyEditor_Widget& );
+  PyEditor_Widget& operator=( const PyEditor_Widget& );
+};
index 7df3d3208c23e5e9dabf2771cdcf11bbbfe14179..d2ab431f78e8594188b28abff7e085fb810469f5 100644 (file)
@@ -5,14 +5,19 @@
     <file>images/py_delete.png</file>
     <file>images/py_editor.png</file>
     <file>images/py_exit.png</file>
+    <file>images/py_find.png</file>
+    <file>images/py_find_next.png</file>
+    <file>images/py_find_previous.png</file>
     <file>images/py_help.png</file>
     <file>images/py_new.png</file>
     <file>images/py_open.png</file>
     <file>images/py_paste.png</file>
     <file>images/py_preferences.png</file>
     <file>images/py_redo.png</file>
+    <file>images/py_replace.png</file>
     <file>images/py_save.png</file>
     <file>images/py_save_as.png</file>
+    <file>images/py_search.png</file>
     <file>images/py_select_all.png</file>
     <file>images/py_undo.png</file>
     <file>about.txt</file>
index aeb24ff7c043e5e9c656b32096f18463cbd7b30f..9f914c70c6ca26569af45d21c81f1f2d0d05a96d 100644 (file)
@@ -1,10 +1,16 @@
 <b>Python Editor</b>
 <hr>
 
+<p>
 Python Editor is a simple program for writing Python scripts.
+</p>
+
+<p>
 Program provides standard editing operations like copy/cut/paste, undo/redo, select all, delete, etc.
-Also it supports syntax highlighting and auto-indentation of Python code.
+It supports syntax highlighting and auto-indentation of Python code.
+</p>
 
+<p>
 Most often used editing operations are available via the toolbar:
 <ul>
 <li><b>New</b>: creates new document.</li>
@@ -22,7 +28,13 @@ Most often used editing operations are available via the toolbar:
 <li><b>Preferences</b>: opens Preferences dialog that allows specifying advanced parameters for the program.</li>
 <li><b>Help</b>: shows this help information.</li>
 </ul>
+</p>
+
+<p>
+Also, editor supports standard <b>Find</b> and <b>Replace</b> operations.
+</p>
 
+<p>
 The behavior of the editor can be customized via the <b>Preferences</b> dialog. The following options can be customized:
 <ul>
 <li><b>Font settings</b>: choose the font.</li>
@@ -30,7 +42,9 @@ The behavior of the editor can be customized via the <b>Preferences</b> dialog.
 <li><b>Enable text wrapping</b>: allows wrapping text at the border of the editor's window.</li>
 <li><b>Center cursor on scroll</b>: allows scrolling the script vertically to make the cursor visible at the center of the viewer.</li>
 <li><b>Display line numbers area</b>: shows line numbers at the left border of the editor.</li>
+<li><b>Completion mode</b>: select the completion mode for inputted keywords.</li>
 <li><b>Vertical edge settings</b>: draws vertical line at the specified column of the viewer.</li>
 <li><b>Display tab delimiters</b>: displays tab marks at a given number of white spaces.</li>
 <li><b>Save settings as default</b>: saves chosen options as a default ones. These settings will be restored after application restart.</li>
 </ul>
+</p>
diff --git a/tools/PyEditor/src/resources/images/py_find.png b/tools/PyEditor/src/resources/images/py_find.png
new file mode 100644 (file)
index 0000000..be705fd
Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find.png differ
diff --git a/tools/PyEditor/src/resources/images/py_find_next.png b/tools/PyEditor/src/resources/images/py_find_next.png
new file mode 100644 (file)
index 0000000..66a1cfe
Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find_next.png differ
diff --git a/tools/PyEditor/src/resources/images/py_find_previous.png b/tools/PyEditor/src/resources/images/py_find_previous.png
new file mode 100644 (file)
index 0000000..d236de9
Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find_previous.png differ
diff --git a/tools/PyEditor/src/resources/images/py_replace.png b/tools/PyEditor/src/resources/images/py_replace.png
new file mode 100644 (file)
index 0000000..2e0c0ec
Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_replace.png differ
diff --git a/tools/PyEditor/src/resources/images/py_search.png b/tools/PyEditor/src/resources/images/py_search.png
new file mode 100644 (file)
index 0000000..989d1af
Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_search.png differ
index c32adddb261c6814a968533d7f3529f080d98b86..b692da78dc3f529a931752e63a8b4eddb388c16b 100644 (file)
       <source>LBL_LINE_NUMBS_AREA</source>
       <translation>Display line numbers area</translation>
     </message>
+    <message>
+      <source>GR_EDIT_SET</source>
+      <translation>Editor settings</translation>
+    </message>
+    <message>
+      <source>LBL_COMPLETION_MODE</source>
+      <translation>Completion mode</translation>
+    </message>
+    <message>
+      <source>LBL_NONE</source>
+      <translation>None</translation>
+    </message>
+    <message>
+      <source>LBL_AUTO</source>
+      <translation>Auto</translation>
+    </message>
+    <message>
+      <source>LBL_MANUAL</source>
+      <translation>Manual</translation>
+    </message>
+    <message>
+      <source>LBL_ALWAYS</source>
+      <translation>Always</translation>
+    </message>
     <message>
       <source>GR_TAB_SET</source>
       <translation>Tab settings</translation>
       <source>DSC_SELECT_ALL</source>
       <translation>Select all the contents</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation>Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation>Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation>Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation>Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation>Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation>Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>Pre&amp;ferences</translation>
     </message>
     <message>
       <source>WRN_READ_FILE</source>
-      <translation>Cannot read file %1:\n%2.</translation>
+      <translation>Cannot read file %1:
+%2.</translation>
     </message>
     <message>
       <source>WRN_WRITE_FILE</source>
-      <translation>Cannot write file %1:\n%2.</translation>
+      <translation>Cannot write file %1:
+%2.</translation>
     </message>
     <message>
       <source>STS_READY</source>
       <translation>Noname.py</translation>
     </message>
   </context>
+  <context>
+    <name>PyEditor</name>
+    <message>
+      <source>PROGRAM_DESCRIPTION</source>
+      <translation>Simple Python editor</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_NAME</source>
+      <translation>file</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_DESCRIPTION</source>
+      <translation>File to edit.</translation>
+    </message>
+  </context>
+  <context>
+    <name>PyEditor_FindTool</name>
+    <message>
+      <source>FIND_LABEL</source>
+      <translation>Find:</translation>
+    </message>
+    <message>
+      <source>REPLACE_LABEL</source>
+      <translation>Replace with:</translation>
+    </message>
+    <message>
+      <source>REPLACE_BTN</source>
+      <translation>Replace</translation>
+    </message>
+    <message>
+      <source>REPLACE_ALL_BTN</source>
+      <translation>Replace All</translation>
+    </message>
+    <message>
+      <source>CASE_SENSITIVE_CHECK</source>
+      <translation>Case Sensitive</translation>
+    </message>
+    <message>
+      <source>WHOLE_WORDS_CHECK</source>
+      <translation>Whole Words Only</translation>
+    </message>
+    <message>
+      <source>REGEX_CHECK</source>
+      <translation>Use Regular Expressions</translation>
+    </message>
+    <message>
+      <source>NB_MATCHED_LABEL</source>
+      <translation>%1 of %2 matches</translation>
+    </message>
+  </context>
 </TS>
index 96cd1e001aab4bad2843ec1fd6f846cde28490a7..fc2decc6a8d4c59f50c3e1a10bc0f8ee174326a5 100644 (file)
       <source>LBL_LINE_NUMBS_AREA</source>
       <translation>Affiche les numéros de ligne</translation>
     </message>
+    <message>
+      <source>GR_EDIT_SET</source>
+      <translation type="unfinished">Editor settings</translation>
+    </message>
+    <message>
+      <source>LBL_COMPLETION_MODE</source>
+      <translation type="unfinished">Completion mode</translation>
+    </message>
+    <message>
+      <source>LBL_NONE</source>
+      <translation type="unfinished">None</translation>
+    </message>
+    <message>
+      <source>LBL_AUTO</source>
+      <translation type="unfinished">Auto</translation>
+    </message>
+    <message>
+      <source>LBL_MANUAL</source>
+      <translation type="unfinished">Manual</translation>
+    </message>
+    <message>
+      <source>LBL_ALWAYS</source>
+      <translation type="unfinished">Always</translation>
+    </message>
     <message>
       <source>GR_TAB_SET</source>
       <translation>Indentation</translation>
       <source>DSC_SELECT_ALL</source>
       <translation>Sélectionne tout le contenu</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation type="unfinished">Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation type="unfinished">Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation type="unfinished">Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>Préférences</translation>
     </message>
     <message>
       <source>WRN_READ_FILE</source>
-      <translation>Impossible de lire le fichier %1:\n%2.</translation>
+      <translation>Impossible de lire le fichier %1:
+%2.</translation>
     </message>
     <message>
       <source>WRN_WRITE_FILE</source>
-      <translation>Impossible d'écrire le fichier %1:\n%2.</translation>
+      <translation>Impossible d'écrire le fichier %1:
+%2.</translation>
     </message>
     <message>
       <source>STS_READY</source>
       <translation>Noname.py</translation>
     </message>
   </context>
+  <context>
+    <name>PyEditor</name>
+    <message>
+      <source>PROGRAM_DESCRIPTION</source>
+      <translation>Editeur python</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_NAME</source>
+      <translation type="unfinished">file</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_DESCRIPTION</source>
+      <translation type="unfinished">File to edit.</translation>
+    </message>
+  </context>
+  <context>
+    <name>PyEditor_FindTool</name>
+    <message>
+      <source>FIND_LABEL</source>
+      <translation type="unfinished">Find:</translation>
+    </message>
+    <message>
+      <source>REPLACE_LABEL</source>
+      <translation type="unfinished">Replace with:</translation>
+    </message>
+    <message>
+      <source>REPLACE_BTN</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>REPLACE_ALL_BTN</source>
+      <translation type="unfinished">Replace All</translation>
+    </message>
+    <message>
+      <source>CASE_SENSITIVE_CHECK</source>
+      <translation type="unfinished">Case Sensitive</translation>
+    </message>
+    <message>
+      <source>WHOLE_WORDS_CHECK</source>
+      <translation type="unfinished">Whole Words Only</translation>
+    </message>
+    <message>
+      <source>REGEX_CHECK</source>
+      <translation type="unfinished">Use Regular Expressions</translation>
+    </message>
+    <message>
+      <source>NB_MATCHED_LABEL</source>
+      <translation type="unfinished">%1 of %2 matches</translation>
+    </message>
+  </context>
 </TS>
index e77eaa1343fc7b295791d89e61eee78ef2dc33d2..ec1846668f2baa5ef8b9455102c5570f567b199a 100644 (file)
       <source>LBL_LINE_NUMBS_AREA</source>
       <translation>ライン番号エリアの表示</translation>
     </message>
+    <message>
+      <source>GR_EDIT_SET</source>
+      <translation type="unfinished">Editor settings</translation>
+    </message>
+    <message>
+      <source>LBL_COMPLETION_MODE</source>
+      <translation type="unfinished">Completion mode</translation>
+    </message>
+    <message>
+      <source>LBL_NONE</source>
+      <translation type="unfinished">None</translation>
+    </message>
+    <message>
+      <source>LBL_AUTO</source>
+      <translation type="unfinished">Auto</translation>
+    </message>
+    <message>
+      <source>LBL_MANUAL</source>
+      <translation type="unfinished">Manual</translation>
+    </message>
+    <message>
+      <source>LBL_ALWAYS</source>
+      <translation type="unfinished">Always</translation>
+    </message>
     <message>
       <source>GR_TAB_SET</source>
       <translation>タブ設定</translation>
       <source>DSC_SELECT_ALL</source>
       <translation>全選択</translation>
     </message>
+    <message>
+      <source>ACT_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>TTP_FIND</source>
+      <translation type="unfinished">Find</translation>
+    </message>
+    <message>
+      <source>DSC_FIND</source>
+      <translation type="unfinished">Find text</translation>
+    </message>
+    <message>
+      <source>ACT_REPLACE</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>TTP_REPLACE</source>
+      <translation type="unfinished">Find &amp; Replace</translation>
+    </message>
+    <message>
+      <source>DSC_REPLACE</source>
+      <translation type="unfinished">Find and replace text</translation>
+    </message>
     <message>
       <source>ACT_PREFERENCES</source>
       <translation>環境設定 (&amp;f)</translation>
     </message>
     <message>
       <source>WRN_READ_FILE</source>
-      <translation>ファイルが読めません %1:\n%2.</translation>
+      <translation>ファイルが読めません %1:
+%2.</translation>
     </message>
     <message>
       <source>WRN_WRITE_FILE</source>
-      <translation>ファイルが書き込めません %1:\n%2.</translation>
+      <translation>ファイルが書き込めません %1:
+%2.</translation>
     </message>
     <message>
       <source>STS_READY</source>
       <translation>Noname. py</translation>
     </message>
   </context>
+  <context>
+    <name>PyEditor</name>
+    <message>
+      <source>PROGRAM_DESCRIPTION</source>
+      <translation>Pythonのエディタ</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_NAME</source>
+      <translation type="unfinished">file</translation>
+    </message>
+    <message>
+      <source>FILE_PARAM_DESCRIPTION</source>
+      <translation type="unfinished">File to edit.</translation>
+    </message>
+  </context>
+  <context>
+    <name>PyEditor_FindTool</name>
+    <message>
+      <source>FIND_LABEL</source>
+      <translation type="unfinished">Find:</translation>
+    </message>
+    <message>
+      <source>REPLACE_LABEL</source>
+      <translation type="unfinished">Replace with:</translation>
+    </message>
+    <message>
+      <source>REPLACE_BTN</source>
+      <translation type="unfinished">Replace</translation>
+    </message>
+    <message>
+      <source>REPLACE_ALL_BTN</source>
+      <translation type="unfinished">Replace All</translation>
+    </message>
+    <message>
+      <source>CASE_SENSITIVE_CHECK</source>
+      <translation type="unfinished">Case Sensitive</translation>
+    </message>
+    <message>
+      <source>WHOLE_WORDS_CHECK</source>
+      <translation type="unfinished">Whole Words Only</translation>
+    </message>
+    <message>
+      <source>REGEX_CHECK</source>
+      <translation type="unfinished">Use Regular Expressions</translation>
+    </message>
+    <message>
+      <source>NB_MATCHED_LABEL</source>
+      <translation type="unfinished">%1 of %2 matches</translation>
+    </message>
+  </context>
 </TS>