From 567efd9864811a8eb7de02faa4e3f76f29f66d9c Mon Sep 17 00:00:00 2001 From: vsr Date: Tue, 13 Jun 2017 09:37:06 +0300 Subject: [PATCH] PyEditor: implement Find/Replace feature - Show Find and Replace items in popup menu + Export set/get settings in PyEditor_Widget class + Properly handle key press event + Export set / get font preference option into Python API (SalomePyQt) + Change shortcuts for File/Preferences and File/Properties actions --- src/LightApp/LightApp_Application.cxx | 2 +- src/PyViewer/PyViewer_ViewWindow.cxx | 2 +- src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx | 64 ++++++++++++++++++++++- src/SALOME_PYQT/SalomePyQt/SalomePyQt.h | 2 + src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip | 2 + src/SalomeApp/SalomeApp_Application.cxx | 2 +- tools/PyEditor/src/PyEditor_Editor.cxx | 9 ++++ tools/PyEditor/src/PyEditor_Editor.h | 5 ++ tools/PyEditor/src/PyEditor_FindTool.cxx | 20 +++++-- tools/PyEditor/src/PyEditor_FindTool.h | 2 + tools/PyEditor/src/PyEditor_Widget.cxx | 18 +++++++ tools/PyEditor/src/PyEditor_Widget.h | 4 ++ tools/PyEditor/src/PyEditor_Window.cxx | 2 +- tools/PyEditor/src/python/PyEditorPy.sip | 3 ++ 14 files changed, 129 insertions(+), 8 deletions(-) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 1005ae4f4..5f71544ba 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -586,7 +586,7 @@ void LightApp_Application::createActions() // Preferences createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(), tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ), - Qt::CTRL+Qt::Key_R, desk, false, this, SLOT( onPreferences() ) ); + Qt::CTRL+Qt::Key_P, desk, false, this, SLOT( onPreferences() ) ); // Help menu: diff --git a/src/PyViewer/PyViewer_ViewWindow.cxx b/src/PyViewer/PyViewer_ViewWindow.cxx index a9e6c79c2..bb8320a11 100644 --- a/src/PyViewer/PyViewer_ViewWindow.cxx +++ b/src/PyViewer/PyViewer_ViewWindow.cxx @@ -190,7 +190,7 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : resMgr->loadPixmap( "PyViewer", tr( "ICON_REPLACE" ) ), tr( "ACT_REPLACE" ), 0, this ); action->setStatusTip( tr( "DSC_REPLACE" ) ); - action->setShortcut( QKeySequence::Replace ); + action->setShortcuts( QList() << QKeySequence( "Ctrl+H" ) << QKeySequence( QKeySequence::Replace ) ); action->setShortcutContext( Qt::WidgetShortcut ); connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) ); toolMgr()->registerAction( action, ReplaceId ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index 699ce585f..04074001c 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -1398,6 +1398,34 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const ProcessVoidEvent( new TEvent( section, name, value ) ); } +/*! + \brief Add font setting to the application preferences. + \param section resources file section name + \param name setting name + \param value new setting value +*/ +void SalomePyQt::addSetting( const QString& section, const QString& name, const QFont& value ) +{ + class TEvent: public SALOME_Event + { + QString mySection; + QString myName; + QFont myValue; + public: + TEvent( const QString& section, const QString& name, const QFont& value ) + : mySection( section ), myName( name ), myValue( value ) {} + virtual void Execute() + { + if ( SUIT_Session::session() ) { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + if ( !mySection.isEmpty() && !myName.isEmpty() ) + resMgr->setValue( mySection, myName, myValue ); + } + } + }; + ProcessVoidEvent( new TEvent( section, name, value ) ); +} + /*! \fn int SalomePyQt::integerSetting( const QString& section, const QString& name, @@ -1574,7 +1602,7 @@ QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, c /*! \fn QByteArray SalomePyQt::byteArraySetting( const QString& section, const QString& name, - const QByteArray def ); + const QByteArray& def ); \brief Get byte array setting from the application preferences. \param section resources file section name \param name setting name @@ -1605,6 +1633,40 @@ QByteArray SalomePyQt::byteArraySetting ( const QString& section, const QString& return ProcessEvent( new TGetByteArraySettingEvent( section, name, def ) ); } +/*! + \fn QByteArray SalomePyQt::fontSetting( const QString& section, + const QString& name, + const QFont& def ); + \brief Get font setting from the application preferences. + \param section resources file section name + \param name setting name + \param def default value which is returned if the setting is not found + \return setting value +*/ + +class TGetFontSettingEvent: public SALOME_Event +{ +public: + typedef QFont TResult; + TResult myResult; + QString mySection; + QString myName; + TResult myDefault; + TGetFontSettingEvent( const QString& section, const QString& name, const QFont& def ) + : mySection( section ), myName( name ), myDefault( def ) {} + virtual void Execute() + { + if ( SUIT_Session::session() ) { + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->fontValue( mySection, myName, myDefault ) : myDefault; + } + } +}; +QFont SalomePyQt::fontSetting ( const QString& section, const QString& name, const QFont& def ) +{ + return ProcessEvent( new TGetFontSettingEvent( section, name, def ) ); +} + /*! \brief Remove setting from the application preferences. \param section resources file section name diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h index a64b01e89..201e1b315 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -275,12 +275,14 @@ public: static void addSetting ( const QString&, const QString&, const QString& ); static void addSetting ( const QString&, const QString&, const QColor& ); static void addSetting ( const QString&, const QString&, const QByteArray& ); + static void addSetting ( const QString&, const QString&, const QFont& ); static int integerSetting( const QString&, const QString&, const int = 0 ); static double doubleSetting ( const QString&, const QString&, const double = 0 ); static bool boolSetting ( const QString&, const QString&, const bool = 0 ); static QString stringSetting ( const QString&, const QString&, const QString& = QString(""), const bool = true ); static QColor colorSetting ( const QString&, const QString&, const QColor& = QColor() ); static QByteArray byteArraySetting( const QString&, const QString&, const QByteArray& = QByteArray() ); + static QFont fontSetting( const QString&, const QString&, const QFont& = QFont() ); static void removeSetting ( const QString&, const QString& ); static bool hasSetting ( const QString&, const QString& ); static QStringList parameters ( const QString& ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index ca70e94c5..e684602e5 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -388,12 +388,14 @@ public: static void addSetting ( const QString&, const QString&, const QString& ) /ReleaseGIL/ ; static void addSetting ( const QString&, const QString&, const QColor& ) /ReleaseGIL/ ; static void addSetting ( const QString&, const QString&, const QByteArray& ) /ReleaseGIL/ ; + static void addSetting ( const QString&, const QString&, const QFont& ) /ReleaseGIL/ ; static int integerSetting( const QString&, const QString&, const int = 0 ) /ReleaseGIL/ ; static double doubleSetting ( const QString&, const QString&, const double = 0 ) /ReleaseGIL/ ; static bool boolSetting ( const QString&, const QString&, const bool = false ) /ReleaseGIL/ ; static QString stringSetting ( const QString&, const QString&, const QString& = QString(""), const bool = true ) /ReleaseGIL/ ; static QColor colorSetting ( const QString&, const QString&, const QColor& = QColor() ) /ReleaseGIL/ ; static QByteArray byteArraySetting( const QString&, const QString&, const QByteArray& = QByteArray() ) /ReleaseGIL/ ; + static QFont fontSetting( const QString&, const QString&, const QFont& = QFont() ) /ReleaseGIL/ ; static void removeSetting ( const QString&, const QString& ) /ReleaseGIL/ ; static bool hasSetting ( const QString&, const QString& ) /ReleaseGIL/ ; static QStringList parameters ( const QString& ) /ReleaseGIL/ ; diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index 12a733584..95c0e878b 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -320,7 +320,7 @@ void SalomeApp_Application::createActions() //! Properties createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIcon(), tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ), - Qt::CTRL+Qt::Key_P, desk, false, this, SLOT( onProperties() ) ); + 0, desk, false, this, SLOT( onProperties() ) ); //! Catalog Generator createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ), QIcon(), diff --git a/tools/PyEditor/src/PyEditor_Editor.cxx b/tools/PyEditor/src/PyEditor_Editor.cxx index 6fe34f196..7e62c6f7b 100644 --- a/tools/PyEditor/src/PyEditor_Editor.cxx +++ b/tools/PyEditor/src/PyEditor_Editor.cxx @@ -27,6 +27,7 @@ #include "PyEditor_Settings.h" #include "PyEditor_Keywords.h" +#include #include #include @@ -355,6 +356,14 @@ void PyEditor_Editor::paintEvent( QPaintEvent* event ) } } +void PyEditor_Editor::contextMenuEvent( QContextMenuEvent* event ) +{ + QMenu* menu = createStandardContextMenu(); + emit customizeMenu( menu ); + menu->exec( event->globalPos() ); + delete menu; +} + /*! \brief Indent and tab text. \param isShift flag defines reverse tab direction diff --git a/tools/PyEditor/src/PyEditor_Editor.h b/tools/PyEditor/src/PyEditor_Editor.h index d37c1a860..8ec688366 100644 --- a/tools/PyEditor/src/PyEditor_Editor.h +++ b/tools/PyEditor/src/PyEditor_Editor.h @@ -31,6 +31,7 @@ class PyEditor_Keywords; class PyEditor_Completer; class PyEditor_PyHighlighter; +class QMenu; class PYEDITOR_EXPORT PyEditor_Editor : public QPlainTextEdit { @@ -63,6 +64,7 @@ protected: virtual void keyPressEvent( QKeyEvent* ); virtual void resizeEvent( QResizeEvent* ); virtual void paintEvent( QPaintEvent* ); + virtual void contextMenuEvent( QContextMenuEvent* ); PyEditor_Keywords* userKeywords() const; PyEditor_Keywords* standardKeywords() const; @@ -74,6 +76,9 @@ private Q_SLOTS: void updateLineNumberAreaWidth( int ); void updateLineNumberArea( const QRect&, int ); +Q_SIGNALS: + void customizeMenu( QMenu* ); + private: bool matchLeftParenthesis( const QTextBlock&, int, int ); bool matchRightParenthesis( const QTextBlock&, int, int ); diff --git a/tools/PyEditor/src/PyEditor_FindTool.cxx b/tools/PyEditor/src/PyEditor_FindTool.cxx index b91000ab1..0e41bfe65 100644 --- a/tools/PyEditor/src/PyEditor_FindTool.cxx +++ b/tools/PyEditor/src/PyEditor_FindTool.cxx @@ -110,10 +110,10 @@ PyEditor_FindTool::PyEditor_FindTool( PyEditor_Editor* editor, QWidget* parent ) 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( QIcon( ":/images/py_find.png" ), tr( "Find" ), this ) ); addAction( new QAction( tr( "FindPrevious" ), this ) ); addAction( new QAction( tr( "FindNext" ), this ) ); - addAction( new QAction( tr( "Replace" ), this ) ); + addAction( new QAction( QIcon( ":/images/py_replace.png" ), tr( "Replace" ), this ) ); foreach ( QAction* action, actions().mid( CaseSensitive, RegExp+1 ) ) { @@ -135,6 +135,7 @@ PyEditor_FindTool::PyEditor_FindTool( PyEditor_Editor* editor, QWidget* parent ) } myEditor->installEventFilter( this ); + connect( myEditor, SIGNAL( customizeMenu( QMenu* ) ), this, SLOT( customizeMenu( QMenu* ) ) ); hide(); } @@ -221,7 +222,10 @@ bool PyEditor_FindTool::eventFilter( QObject* o, QEvent* e ) { case Qt::Key_Escape: if ( isVisible() ) + { hide(); + return true; + } break; default: break; @@ -239,6 +243,16 @@ void PyEditor_FindTool::activateFind() activate( Find ); } +/*! + \brief Customize menu for editor. +*/ +void PyEditor_FindTool::customizeMenu( QMenu* menu ) +{ + menu->addSeparator(); + menu->addAction( actions()[Find] ); + menu->addAction( actions()[Replace] ); +} + /*! \brief Slot: activate 'Replace' dialog. */ @@ -406,8 +420,8 @@ QList PyEditor_FindTool::shortcuts( int action ) const bindings << QKeySequence( QKeySequence::FindNext ); break; case Replace: - bindings << QKeySequence( QKeySequence::Replace ); bindings << QKeySequence( "Ctrl+H" ); + bindings << QKeySequence( QKeySequence::Replace ); break; default: break; diff --git a/tools/PyEditor/src/PyEditor_FindTool.h b/tools/PyEditor/src/PyEditor_FindTool.h index e6501700e..2eab236ec 100644 --- a/tools/PyEditor/src/PyEditor_FindTool.h +++ b/tools/PyEditor/src/PyEditor_FindTool.h @@ -33,6 +33,7 @@ class PyEditor_Editor; class QAction; class QLabel; class QLineEdit; +class QMenu; class PYEDITOR_EXPORT PyEditor_FindTool : public QWidget { @@ -60,6 +61,7 @@ private slots: void replaceAll(); void update(); void activate( int ); + void customizeMenu( QMenu* ); private: QList shortcuts( int ) const; diff --git a/tools/PyEditor/src/PyEditor_Widget.cxx b/tools/PyEditor/src/PyEditor_Widget.cxx index badf97329..58d4c285c 100644 --- a/tools/PyEditor/src/PyEditor_Widget.cxx +++ b/tools/PyEditor/src/PyEditor_Widget.cxx @@ -249,3 +249,21 @@ QString PyEditor_Widget::text() const { return myEditor->toPlainText(); } + +/*! + \brief Set editor's settings. + \param settings Settings object. +*/ +void PyEditor_Widget::setSettings( const PyEditor_Settings& settings ) +{ + myEditor->setSettings( settings ); +} + +/*! + \brief Get editor's settings. + \return Settings object. +*/ +const PyEditor_Settings& PyEditor_Widget::settings() const +{ + return myEditor->settings(); +} diff --git a/tools/PyEditor/src/PyEditor_Widget.h b/tools/PyEditor/src/PyEditor_Widget.h index 0927a9fe8..f7ba95977 100644 --- a/tools/PyEditor/src/PyEditor_Widget.h +++ b/tools/PyEditor/src/PyEditor_Widget.h @@ -24,6 +24,7 @@ #define PYEDITOR_WIDGET_H #include "PyEditor.h" +#include "PyEditor_Settings.h" #include @@ -40,6 +41,9 @@ public: PyEditor_Editor* editor(); PyEditor_FindTool* findTool(); + void setSettings( const PyEditor_Settings& ); + const PyEditor_Settings& settings() const; + bool isModified(); QString text() const; diff --git a/tools/PyEditor/src/PyEditor_Window.cxx b/tools/PyEditor/src/PyEditor_Window.cxx index 125a27b81..cfeebe2bd 100644 --- a/tools/PyEditor/src/PyEditor_Window.cxx +++ b/tools/PyEditor/src/PyEditor_Window.cxx @@ -197,7 +197,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : tr( "ACT_REPLACE" ), this ); action->setToolTip( tr( "TTP_REPLACE" ) ); action->setStatusTip( tr( "DSC_REPLACE" ) ); - action->setShortcut( QKeySequence::Replace ); + action->setShortcuts( QList() << QKeySequence( "Ctrl+H" ) << QKeySequence( QKeySequence::Replace ) ); action->setShortcutContext( Qt::WidgetShortcut ); connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) ); myActions[ ReplaceId ] = action; diff --git a/tools/PyEditor/src/python/PyEditorPy.sip b/tools/PyEditor/src/python/PyEditorPy.sip index d6b530be9..854e7a86b 100644 --- a/tools/PyEditor/src/python/PyEditorPy.sip +++ b/tools/PyEditor/src/python/PyEditorPy.sip @@ -134,6 +134,9 @@ public: PyEditor_Editor* editor(); PyEditor_FindTool* findTool(); + void setSettings( const PyEditor_Settings& ); + const PyEditor_Settings& settings() const; + bool isModified(); QString text() const; -- 2.39.2