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
# ===================
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
# =============
ADD_DEFINITIONS(-DWITH_SALOMEDS_OBSERVER)
ENDIF()
-# Single-study GUI
-IF(SALOME_USE_SINGLE_DESKTOP)
- ADD_DEFINITIONS(-DSINGLE_DESKTOP)
-ENDIF()
-
# OCCT
FIND_PACKAGE(SalomeCAS REQUIRED)
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()
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
{
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
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()
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)
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)
<ul>
$navpath
<li class="footer">
- Copyright © 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE<br>
+ Copyright © 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE<br>
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS<br>
</li>
</ul>
<ul>
$navpath
<li class="footer">
- Copyright © 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE<br>
+ Copyright © 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE<br>
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS<br>
</li>
</ul>
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;
{
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)
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)
'''
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.
'''
sobj, entry = getSObjectSelected()
if ( sobj ):
- study = getActiveStudy()
+ study = salome.myStudy
builder = study.NewBuilder()
builder.RemoveObject( sobj )
- SalomeGUI.updateObjBrowser(True)
+ SalomeGUI.updateObjBrowser()
pass
#
#
# 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
// Author: Guillaume Boulant (EDF/R&D)
#include "SALOME_AppStudyEditor.hxx"
+#include "SALOME_GuiServices.hxx"
#include <SalomeApp_Study.h>
#include <SALOME_ListIO.hxx>
: 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();
}
}
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;
// 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() {
// 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;
}
}
// 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):
#include "StandardApp_Module.hxx"
+#include "SALOME_GuiServices.hxx"
+
#include <SUIT_Desktop.h>
#include <SUIT_Study.h>
#include <SalomeApp_Application.h>
setToolShown( true );
if ( this->createStudyComponentAtActivation() ) {
- this->createStudyComponent(theStudy);
+ this->createStudyComponent();
}
return bOk;
* 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())
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();
"....................",
"...................."};
-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.
}
}
-/*!
- \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()
{
desktop()->statusBar()->showMessage( "" );
LightApp_EventFilter::Init();
+
+ onNewDoc();
}
/*!Closeapplication.*/
*/
void LightApp_Application::onNewDoc()
{
-#ifdef SINGLE_DESKTOP
if ( !checkExistingDoc() )
return;
-#endif
//asl: fix for 0020515
saveDockWindowsState();
{
SUIT_Study* study = activeStudy();
-#ifdef SINGLE_DESKTOP
if ( !checkExistingDoc() )
return;
-#endif
CAM_Application::onOpenDoc();
*/
bool LightApp_Application::onOpenDoc( const QString& aName )
{
-#ifdef SINGLE_DESKTOP
if ( !checkExistingDoc() )
return false;
-#endif
saveDockWindowsState();
/*!
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 )
*/
SUIT_Study* LightApp_Application::createNewStudy()
{
- LightApp_Application::lastStudyId++;
-
LightApp_Study* aStudy = new LightApp_Study( this );
// Set up processing of major study-related events
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 );
{
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;
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* );
void setDefaultStudyName( const QString& theName );
- static int studyId();
-
virtual bool event( QEvent* );
virtual bool checkDataObject( LightApp_DataObject* theObj );
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* );
static LightApp_Preferences* _prefs_;
- static int lastStudyId;
QStringList myUserWmTypes;
};
*/
bool LightApp_Study::createDocument( const QString& theStr )
{
- setStudyName( QString( "Study%1" ).arg( LightApp_Application::studyId() ) );
-
// create myRoot
setRoot( new LightApp_RootObject( this ) );
<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"/>
</message>
<message>
<source>ABOUT_COPYRIGHT</source>
- <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+ <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS</translation>
</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>&Save && Close</translation>
+ <translation>&Yes</translation>
</message>
<message>
<source>APPCLOSE_CLOSE</source>
- <translation>Close &w/o saving</translation>
+ <translation>&No</translation>
</message>
<message>
<source>APPCLOSE_CANCEL</source>
<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>
</message>
<message>
<source>ABOUT_COPYRIGHT</source>
- <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+ <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS</translation>
</message>
<message>
<source>STUDYCLOSE_DESCRIPTION</source>
- <translation>Une étude est déjà ouverte. Elle doit être fermée avant d'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>&Sauvegarder && Fermer</translation>
+ <translation>&Oui</translation>
</message>
<message>
<source>APPCLOSE_CLOSE</source>
- <translation>&Fermer sans sauvegarder</translation>
+ <translation>&Non</translation>
</message>
<message>
<source>APPCLOSE_CANCEL</source>
<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>
</message>
<message>
<source>ABOUT_COPYRIGHT</source>
- <translation>Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+ <translation>Copyright (C) 2007-2017 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6,
CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS</translation>
</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>保存して閉じる(&S)</translation>
+ <translation>はい(&Y)</translation>
</message>
<message>
<source>APPCLOSE_CLOSE</source>
- <translation>保存せずに閉じる(&C)</translation>
+ <translation>いいえ(&N)</translation>
</message>
<message>
<source>APPCLOSE_CANCEL</source>
<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>
myIsRelative(true),
myTopLayerId( 0 ),
myTrihedronSize(100),
- myClippingDlg (NULL)
+ myClippingDlg (NULL),
+ myIsUseLocalSelection(false)
{
// init CasCade viewers
myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() );
break;
case Qt::Key_N:
if ( isPreselectionEnabled() ) {
- if ( getAISContext()->HasOpenedContext() )
+ if ( useLocalSelection() )
getAISContext()->HilightNextDetected( aView->getViewPort()->getView() );
}
break;
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
{
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; }
QString myClippingTexture;
bool myTextureModulated;
double myClippingTextureScale;
-
+ bool myIsUseLocalSelection;
};
#ifdef WIN32
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 {
${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
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()
myResMgr->setValue( group, option( snTabSpaceVisible ), tabSpaceVisible() );
myResMgr->setValue( group, option( snTabSize ), tabSize() );
myResMgr->setValue( group, option( snFont ), font() );
+ myResMgr->setValue( group, option( snCompletionPolicy ), completionPolicy() );
}
#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
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();
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 );
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 );
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 );
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 );
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 );
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
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 );
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" ) ),
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 );
{
if ( whetherSave() )
{
- myTextEditor->clear();
+ myEditor->clear();
setCurrentFile( QString() );
}
}
*/
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();
}
void PyViewer_ViewWindow::setCurrentFile( const QString& filePath )
{
myURL = filePath;
- myTextEditor->document()->setModified( false );
+ myEditor->setModified( false );
}
/*!
*/
bool PyViewer_ViewWindow::whetherSave()
{
- if ( myTextEditor->document()->isModified() )
+ if ( myEditor->isModified() )
{
QMessageBox::StandardButton answer = QMessageBox::warning( this,
tr( "NAME_PYEDITOR" ),
QTextStream anInput( &aFile );
QApplication::setOverrideCursor( Qt::WaitCursor );
- myTextEditor->setPlainText( anInput.readAll() );
+ myEditor->setText( anInput.readAll() );
QApplication::restoreOverrideCursor();
setCurrentFile( filePath );
QTextStream anOutput( &aFile );
QApplication::setOverrideCursor( Qt::WaitCursor );
- anOutput << myTextEditor->toPlainText();
+ anOutput << myEditor->text();
QApplication::restoreOverrideCursor();
setCurrentFile( filePath );
#include <SUIT_ViewWindow.h>
-class PyEditor_Editor;
+class PyEditor_Widget;
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 );
QString defaultName() const;
private:
- PyEditor_Editor* myTextEditor;
+ PyEditor_Widget* myEditor;
QString myURL;
};
<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>
<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 & Replace</translation>
+ </message>
+ <message>
+ <source>DSC_REPLACE</source>
+ <translation>Find and replace text</translation>
+ </message>
<message>
<source>ACT_PREFERENCES</source>
<translation>Pre&ferences</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 & 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>
<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 & Replace</translation>
+ </message>
+ <message>
+ <source>DSC_REPLACE</source>
+ <translation type="unfinished">Find and replace text</translation>
+ </message>
<message>
<source>ACT_PREFERENCES</source>
<translation>環境設定 (&f)</translation>
SALOME GUI modules.
*/
-PyModuleHelper::InterpMap PyModuleHelper::myInterpMap;
LightApp_Module* PyModuleHelper::myInitModule = 0;
/*!
/*!
\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 ) {
}
// ... 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();
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
// 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
// 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
// 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 ) {
}
// 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();
}
// 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
// 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();
}
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
void onObjectBrowserClicked(SUIT_DataObject*, int);
private:
- void initInterp( int );
+ void initInterp();
void importModule();
void setWorkSpace();
#include <QApplication>
#include <QPaintEvent>
#include <QCoreApplication>
+#include <QVBoxLayout>
#include <utilities.h>
+
namespace
{
/*!
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
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.
}
/*!
- \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;
}
}
}
};
- ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
+ ProcessVoidEvent( new TEvent() );
}
}
}
};
- 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 ) );
}
/*!
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
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 );
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 );
PT_Font,
PT_DirList,
PT_File,
+ PT_Slider,
+ PT_Shortcut,
+ PT_ShortcutTree,
+ PT_BiColor,
+ PT_Background,
+ PT_UserDefined
};
enum Orientation {
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,
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/ ;
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,
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
/*!
\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
{
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
bool hasDesktop();
- void updateObjBrowser( bool );
+ void updateObjBrowser();
- int getActiveStudyId();
const char* getActiveStudyName();
const char* getComponentName( const char* );
bool hasDesktop();
/* update object browser*/
- void updateObjBrowser(bool);
+ void updateObjBrowser();
/* get active study */
- int getActiveStudyId();
const char *getActiveStudyName();
/* get component name/username */
ARealTable.SetTitle("Very useful data")
# >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
# ============================================================================
myBuilder.Addreference(myRefObject,myObject3);
# >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
# ============================================================================
ACmt.SetValue("Just a comment")
# >>> Updating Object Browser ================================================
-salome.sg.updateObjBrowser(True)
+salome.sg.updateObjBrowser()
# ============================================================================
#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
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();
// 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
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();
// 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 );
// }
//}
}
*/
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();
// 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 );
// }
//}
}
#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
*/
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" ) ),
// 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
{
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;
// 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
*/
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)){
// 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();
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)){
// 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();
*/
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)))
// 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);
QString hdffile;
QStringList pyfiles;
- QString loadStudy;
for (int i = 1; i < qApp->arguments().size(); i++) {
QRegExp rxs ("--study-hdf=(.+)");
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
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++ ) {
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 );
{
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"
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
/*!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
/*!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()
{
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 );
{
_PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
try {
- studyMgr()->Copy(so);
+ stdDS->Copy(so);
onSelectionChanged();
}
catch(...) {
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() ) {
{
_PTR(SObject) so = stdDS->FindObjectID(it.Value()->getEntry());
try {
- studyMgr()->Paste(so);
+ stdDS->Paste(so);
updateObjectBrowser( true );
updateActions(); //SRN: BugID IPAL9377, case 3
}
/*! 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.*/
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);
}
}
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;
// Connect study menu
a = action( ConnectId );
if( a )
- a->setEnabled( !activeStudy() && studyMgr()->GetOpenStudies().size() > 0 );
+ a->setEnabled( !activeStudy() );
// Disconnect study menu
a = action( DisconnectId );
{
SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
if ( !appStudy ) return;
- _PTR(Study) aStudy = appStudy->studyDS();
QStringList aFilters;
aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
/*!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;
}
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" );
}
{
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 );
}
}
}
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
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];
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 ),
{
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 );
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.*/
// 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() ) );
}
}
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 );
}
}
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() )
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.
{
bool ok = true;
- // create a new study
- onNewDoc();
-
// get active application
SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
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();
*/
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();
}
virtual bool checkExistingDoc();
static CORBA::ORB_var orb();
- static SALOMEDSClient_StudyManager* studyMgr();
+ static _PTR(Study) getStudy();
static SALOME_NamingService* namingService();
static SALOME_LifeCycleCORBA* lcc();
void onStudyOpened( SUIT_Study* );
void onDesktopMessage( const QString& );
+ virtual void onModuleActivation( const QString& );
+
protected:
virtual void createActions();
virtual SUIT_Study* createNewStudy();
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 );
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() ) );
}
}
}
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() ) );
}
}
}
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();
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 ) {
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" ) )
{
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;
{
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();
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
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);
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();
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() );
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 );
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;}
static PortableServer::POA_var poa();
static SALOME_NamingService* namingService();
private:
- typedef std::map<int, ListOfFiles> MapOfListOfFiles;
- MapOfListOfFiles myMap;
+ ListOfFiles myListOfFiles;
std::string myComponentName;
};
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;
* Purpose : Add variables in the table from theStudy
*/
//============================================================================
-void NoteBook_Table::Init(_PTR(Study) theStudy)
+void NoteBook_Table::Init()
{
isProcessItemChangedSignal = false;
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
isProcessItemChangedSignal = true;
ResetMaps();
-
- myStudy = 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;
}
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 ),
//============================================================================
void NoteBook_Table::RemoveSelected()
{
+ _PTR(Study) aStudy = SalomeApp_Application::getStudy();
isProcessItemChangedSignal = false;
QList<QTableWidgetItem*> aSelectedItems = selectedItems();
if( !(aSelectedItems.size() > 0)) {
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() ),
myVariableMap.remove( index );
removeRow(nRow);
myRows.removeAt(nRow);
- if(myStudy->IsVariable(aVarName.toLatin1().constData()))
+ if(aStudy->IsVariable(aVarName.toLatin1().constData()))
removedFromStudy = true;
}
}
* 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"));
connect( myUpdateStudyBtn, SIGNAL(clicked()), this, SLOT(onUpdateStudy()) );
connect( myRemoveButton, SIGNAL(clicked()), this, SLOT(onRemove()));
- myTable->Init(myStudy);
+ myTable->Init();
myDumpedStudyScript = "";
myIsDumpedStudySaved = false;
* 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();
}
//============================================================================
void SalomeApp_NoteBook::onVarUpdate(QString theVarName)
{
- myTable->Init(myStudy);
+ myTable->Init();
}
//============================================================================
SUIT_MessageBox::warning( this, tr( "WARNING" ), tr( "INCORRECT_DATA" ) );
return;
}
+ _PTR(Study) aStudy = SalomeApp_Application::getStudy();
double aDVal;
int anIVal;
if( aVariableMapRef.contains( anIndex ) )
{
QString aRemovedVariable = aVariableMapRef[ anIndex ].Name;
- myStudy->RemoveVariable( std::string( aRemovedVariable.toLatin1().constData() ) );
+ aStudy->RemoveVariable( std::string( aRemovedVariable.toLatin1().constData() ) );
}
}
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();
if(app)
app->updateActions();
- myStudy->Modified();
+ aStudy->Modified();
}
//============================================================================
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;
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; }
QPushButton* myRemoveButton;
QPushButton* myUpdateStudyBtn;
- _PTR(Study) myStudy;
QString myDumpedStudyScript; // path to script of dumped study
QString myDumpedStudyName;
bool myIsDumpedStudySaved;
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;
}
public:
- Observer_i(_PTR(Study) aStudyDS, SalomeApp_Study* aStudy):QObject(aStudy)
+ Observer_i( SalomeApp_Study* aStudy):QObject(aStudy)
{
- myStudyDS=aStudyDS;
myStudy=aStudy;
fillEntryMap();
}
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()) {
}
// 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
}
private:
- _PTR(Study) myStudyDS;
SalomeApp_Study* myStudy;
EntryMap entry2SuitObject;
};
SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
: LightApp_Study( app ), myObserver( 0 )
{
+ myStudyDS = SalomeApp_Application::getStudy();
}
/*!
}
#endif
-/*!
- Gets study id.
-*/
-int SalomeApp_Study::id() const
-{
- int id = -1;
- if ( studyDS() )
- id = studyDS()->StudyId();
- return id;
-}
-
/*!
Get study name.
*/
// 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 );
{
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 );
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
{
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()));
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 )
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.
#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 ) {
}
/*!
- 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
#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 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);
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 )
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) );
}
}
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();
// 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.
*/
void SalomeApp_Study::Modified()
{
- if(_PTR(Study) aStudy = studyDS())
- aStudy->Modified();
+ myStudyDS->Modified();
LightApp_Study::Modified();
}
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.
}
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;
// 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();
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()) {
// 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)
// 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 );
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() ) );
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
// 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;
// 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);
}
/*!
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);
}
}
void SalomeApp_Study::updateFromNotebook( const QString& theFileName, bool isSaved )
{
setStudyName(theFileName);
- studyDS()->Name(theFileName.toStdString());
+ studyDS()->URL(theFileName.toStdString());
setIsSaved( isSaved );
}
#endif
SalomeApp_Study( SUIT_Application* );
virtual ~SalomeApp_Study();
- virtual int id() const;
virtual QString studyName() const;
virtual bool createDocument( const QString& );
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:
void onNoteBookVarUpdate( QString theVarName );
#endif
-private:
- QString newStudyName() const;
-
private:
_PTR(Study) myStudyDS;
Observer_i* myObserver;
// Author : Roman NIKOLAEV
#include "SalomeApp_StudyPropertiesDlg.h"
+#include "SalomeApp_Application.h"
#include "SalomeApp_Study.h"
#include "SUIT_Session.h"
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);
*/
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) {
*/
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();
void initData();
private:
- _PTR(Study) myStudyDoc;
bool myIsChanged;
QLineEdit* myAuthor;
QLabel* myDate;
#include "LightApp_DataOwner.h"
#include "SalomeApp_Study.h"
+#include "SalomeApp_Application.h"
/*!
Constructor.
{
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;
}
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
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,
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
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)
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)
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
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)
#
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
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',
dialogWithApply.setData(tubebuilder.DEFAULT_RADIUS,
tubebuilder.DEFAULT_LENGTH,
tubebuilder.DEFAULT_WIDTH)
- activeStudy = None
previewShapeEntry = None
DEFAULT_FOLDER_NAME="TubeList"
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
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():
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
# 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
required callback functions to be associated to the button
signals.
"""
- global dialogWithApply, activeStudy
- activeStudy = context.study
+ global dialogWithApply
dialogWithApply.open()
import GEOM
from salome.geom import geomBuilder
-geompy = geomBuilder.New(salome.myStudy)
+geompy = geomBuilder.New()
# Create the objects
Vx = geompy.MakeVectorDXDYDZ(10, 0, 0)
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
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)
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()
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):
'''
#
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__":
# 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
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
# 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)
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
# 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.
3. destroy the underlying geom object
"""
eraseShape(shapeStudyEntry)
- shape = removeFromStudy(study, shapeStudyEntry)
+ shape = removeFromStudy(shapeStudyEntry)
if shape is not None:
shape.Destroy()
"""
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)
# 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)
radius = 10
sphere = geompy.MakeSphereR(radius)
sphereName = "sph.r%s"%radius
- sphereStudyEntry = addToStudy(study, sphere, sphereName)
+ sphereStudyEntry = addToStudy(sphere, sphereName)
displayShape(sphereStudyEntry)
# --------------------------------------------------
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)
# --------------------------------------------------
# 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
<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>
</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>
<source>WRN_FILE_NOT_EXIST</source>
<translation>Le fichier %1 n'existe pas.</translation>
</message>
- <message>
- <source>ERR_ACTIVEDOC_LOAD</source>
- <translation>Une étude est déjà chargée dans votre session mais vous n'y êtes pas connectée. Utilisez le bouton "Connecter" pour charger l'étude dans l'interface.</translation>
- </message>
<message>
<source>WRN_STUDY_LOCKED</source>
<translation>L'étude est verrouillée</translation>
</message>
<message>
<source>QUE_DOC_ALREADYEXIST</source>
- <translation>Le document %1 existe déjà dans le gestionnaire d'études.
+ <translation>Le document %1 existe déjà.
Voulez-vous le recharger ?</translation>
</message>
<message>
<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>
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
"""
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("|")
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
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;
}
}
case 4: // Session
{
- NamingService_WaitForServerReadiness(_NS,"/myStudyManager");
+ NamingService_WaitForServerReadiness(_NS,"/Study");
std::string containerName = "/Containers/";
containerName = containerName + Kernel_Utils::GetHostname();
containerName = containerName + "/FactoryServer";
// 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." );
_argc = argc ;
_argv = argv ;
_isGUI = false ;
- _runningStudies= 0 ;
_orb = CORBA::ORB::_duplicate(orb) ;
_poa = PortableServer::POA::_duplicate(poa) ;
_GUIMutex = GUIMutex;
/*!
Send a SALOME::StatSession structure (see idl) to the client
- (number of running studies and presence of GUI)
+ (presence of GUI)
*/
/*class QtLock
{
{
// 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();
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
//! Unregister the servant from Naming Service
void NSunregister();
- CORBA::Long GetActiveStudyId();
-
void ping(){};
CORBA::Long getPID();
char* getHostname();
CORBA::Boolean _isGUI ;
QMutex* _GUIMutex ;
QWaitCondition* _GUILauncher;
- int _runningStudies ;
CORBA::ORB_var _orb;
PortableServer::POA_var _poa;
bool _isShuttingDown;
${CAS_KERNEL}
${KERNEL_SalomeIDLKernel}
${KERNEL_SALOMELocalTrace}
+ ${KERNEL_SalomeDSClient}
${KERNEL_SalomeNS}
${KERNEL_OpUtil}
+ ${KERNEL_SalomeKernelHelpers}
${OMNIORB_LIBRARIES}
qtx suit
)
// 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;
/*!
\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 )
{
}
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 );
}
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 );
};
# 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
)
# 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
)
#include "PyEditor_StdSettings.h"
#include <QApplication>
+#include <QCommandLineParser>
#include <QDir>
#include <QLibraryInfo>
#include <QLocale>
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();
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;
}
// 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();
}
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
#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 ) ) );
// Set size white spaces
setTabStopWidth( mySettings.tabSize() * 10 );
+ // Set completion policy
+ setCompletionPolicy( (CompletionPolicy)mySettings.completionPolicy() );
+
// Update current line highlight
updateHighlightCurrentLine();
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.
*/
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();
{
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;
+}
#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& );
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();
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;
};
--- /dev/null
+// 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 );
+ }
+}
--- /dev/null
+// 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
--- /dev/null
+// 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()
+{
+}
--- /dev/null
+// 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
#include "PyEditor_PyHighlighter.h"
+#include "PyEditor_Keywords.h"
+
+#include <QSet>
+
#define NORMAL 0
#define TRIPLESINGLE 1
#define TRIPLEDOUBLE 2
\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 )
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 );
+}
#include <QSyntaxHighlighter>
class QTextDocument;
+class PyEditor_Keywords;
class PyEditor_PyHighlighter : public QSyntaxHighlighter
{
};
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
QTextCharFormat classFormat;
QTextCharFormat referenceClassFormat;
QTextCharFormat functionFormat;
- QTextCharFormat keywordFormat;
- QTextCharFormat specialFromat;
QTextCharFormat numberFormat;
QTextCharFormat singleLineCommentFormat;
QTextCharFormat multiLineCommentFormat;
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
#include "PyEditor_Settings.h"
+#include "PyEditor_Editor.h"
+
/*!
\class PyEditor_Settings
\brief Manager of setting values.
myNumberColumns( 80 ),
myTabSpaceVisible( true ),
myTabSize( 4 ),
- myFont( "Courier", 10 )
+ myFont( "Courier", 10 ),
+ myCompletionPolicy( PyEditor_Editor::Always )
{
}
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.
setVerticalEdge( other.verticalEdge() );
setNumberColumns( other.numberColumns() );
setFont( other.font() );
+ setCompletionPolicy( other.completionPolicy() );
+
save();
}
"TabSpaceVisible",
"TabSize",
"Font",
+ "CompletionPolicy"
};
- return option >= 0 && option <= snFont ? options[option] : "Unknown";
+ return option >= 0 && option <= snCompletionPolicy ? options[option] : "Unknown";
}
snNumberColumns,
snTabSpaceVisible,
snTabSize,
- snFont };
+ snFont,
+ snCompletionPolicy };
public:
static PyEditor_Settings* settings();
void setFont( const QFont& );
QFont font() const;
+ void setCompletionPolicy( int );
+ int completionPolicy() const;
+
virtual void load();
virtual void save();
// Font settings
QFont myFont;
+ // Completion settings
+ int myCompletionPolicy;
+
static PyEditor_Settings* myGlobalSettings;
};
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 );
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();
myNumberColumns->setValue( settings.numberColumns() );
myFontFamily->setCurrentFont( settings.font() );
setFontSize( QString::number( settings.font().pointSize() ) );
+ myCompletionPolicy->setCurrentIndex( settings.completionPolicy() );
onVerticalEdgeChecked();
onFontChanged();
public:
PyEditor_SettingsDlg( PyEditor_Editor*, bool = false, QWidget* = 0 );
- ~PyEditor_SettingsDlg();
+ virtual ~PyEditor_SettingsDlg();
private Q_SLOTS:
void onVerticalEdgeChecked();
QFontComboBox* myFontFamily;
QComboBox* myFontSize;
+ QComboBox* myCompletionPolicy;
+
QCheckBox* myDefaultCheck;
PyEditor_Editor* myEditor;
{
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();
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();
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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
//
#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>
{
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;
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;
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;
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;
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;
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;
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
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;
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 );
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" ) );
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 ] );
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.
{
if ( whetherSave() )
{
- myTextEditor->clear();
+ myEditor->clear();
setCurrentFile( QString() );
}
}
*/
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();
}
void PyEditor_Window::setCurrentFile( const QString& filePath )
{
myURL = filePath;
- myTextEditor->document()->setModified( false );
+ myEditor->setModified( false );
setWindowModified( false );
*/
bool PyEditor_Window::whetherSave()
{
- if ( myTextEditor->document()->isModified() )
+ if ( myEditor->isModified() )
{
QMessageBox::StandardButton answer = QMessageBox::warning( this,
tr( "NAME_PYEDITOR" ),
\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 );
\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 );
#include <QMap>
class QAction;
-class PyEditor_Editor;
+class PyEditor_Widget;
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* );
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;
};
void setFont( const QFont& );
QFont font() const;
+
+ void setCompletionPolicy( int );
+ int completionPolicy() const;
};
class PyEditor_Editor : QPlainTextEdit
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& );
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& );
+};
<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>
<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>
<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>
<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>
<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 & Replace</translation>
+ </message>
+ <message>
+ <source>DSC_REPLACE</source>
+ <translation>Find and replace text</translation>
+ </message>
<message>
<source>ACT_PREFERENCES</source>
<translation>Pre&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>
<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 & 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>
<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 & Replace</translation>
+ </message>
+ <message>
+ <source>DSC_REPLACE</source>
+ <translation type="unfinished">Find and replace text</translation>
+ </message>
<message>
<source>ACT_PREFERENCES</source>
<translation>環境設定 (&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>