]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Process property panel values change. This modification should be corrected: keyRelea...
authornds <natalia.donis@opencascade.com>
Mon, 26 May 2014 09:04:45 +0000 (13:04 +0400)
committernds <natalia.donis@opencascade.com>
Mon, 26 May 2014 09:04:45 +0000 (13:04 +0400)
17 files changed:
src/ModuleBase/ModuleBase_MetaWidget.cpp
src/ModuleBase/ModuleBase_MetaWidget.h
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_Operation.h
src/ModuleBase/ModuleBase_WidgetPoint2D.cpp
src/ModuleBase/ModuleBase_WidgetPoint2D.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_OperationSketchBase.cpp
src/PartSet/PartSet_OperationSketchBase.h
src/PartSet/PartSet_OperationSketchLine.cpp
src/PartSet/PartSet_OperationSketchLine.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_Workshop.cpp

index 308cc3065fa743b363d6469f3d6821baae8ee150..a8a65232b423e09cff1312ac37c23d400a3a0408 100644 (file)
@@ -38,3 +38,17 @@ bool ModuleBase_MetaWidget::restoreValue(boost::shared_ptr<ModelAPI_Feature> the
   #endif
   return true;
 }
+
+bool ModuleBase_MetaWidget::focusTo(const std::string& theAttributeName)
+{
+  #ifdef _DEBUG
+  std::cout << "ModuleBase_MetaWidget::focusTo"
+            << myWrappedWidget->metaObject()->className() << std::endl;
+  #endif
+  return true;
+}
+
+QList<QWidget*> ModuleBase_MetaWidget::getControls() const
+{
+  return QList<QWidget*>();
+}
index 2899374c5d4fd33cabcd9151315813775ed9ef9f..0bbc6fbcdfdc945964273092697e5acb451eb596 100644 (file)
@@ -27,6 +27,14 @@ public:
   //! Interface for loading widget's data from the data model
   MODULEBASE_EXPORT virtual bool restoreValue(boost::shared_ptr<ModelAPI_Feature> theFeature);
 
+  /// Set focus to the current widget if it corresponds to the given attribute
+  /// \param theAttribute name
+  MODULEBASE_EXPORT virtual bool focusTo(const std::string& theAttributeName);
+
+  /// Returns list of widget controls
+  /// \return a control list
+  virtual QList<QWidget*> getControls() const;
+
 private:
   QWidget* myWrappedWidget;
 };
index a684515a39e8d46b67cb742a520e7e80892cbe71..57b75346aec15b629d8ff5d2401e43652285fdc3 100644 (file)
@@ -12,6 +12,7 @@
 #include <boost/shared_ptr.hpp>
 
 class ModelAPI_Feature;
+class QKeyEvent;
 
 /**\class ModuleBase_ModelWidget
  * \brief An abstract custom widget class. This class realization is assumed to create some controls.
@@ -37,10 +38,21 @@ public:
 
   virtual bool restoreValue(boost::shared_ptr<ModelAPI_Feature> theFeature) = 0;
 
+  /// Set focus to the current widget if it corresponds to the given attribute
+  /// \param theAttribute name
+  virtual bool focusTo(const std::string& theAttributeName) = 0;
+
+  /// Returns list of widget controls
+  /// \return a control list
+  virtual QList<QWidget*> getControls() const = 0;
 
 signals:
   /// The signal about widget values changed
   void valuesChanged();
+  /// The signal about key release on the control, that corresponds to the attribute
+  /// \param theAttributeName a name of the attribute
+  /// \param theEvent key release event
+  void keyReleased(const std::string& theAttributeName, QKeyEvent* theEvent);
 };
 
 #endif
index 89b369995926046420fbd3256b035f732b1623c0..e66d58ab99c56ebfe6b6fe46bafa5c818693c568 100644 (file)
@@ -20,6 +20,8 @@
 class ModelAPI_Feature;
 class ModelAPI_Document;
 
+class QKeyEvent;
+
 /*!
  \class ModuleBase_Operation
  * \brief Base class for all operations
@@ -66,6 +68,8 @@ public:
   /// Stores a custom value in model.
   void storeCustomValue();
 
+  virtual void keyReleased(std::string theName, QKeyEvent* theEvent) {};
+
 protected:
   /// Virtual method called when operation started (see start() method for more description)
   /// Default impl calls corresponding slot and commits immediately.
index 4d99d01be7fccfd41897cc5c04ea5d594e8f1548..01f9902eb5fa4918500cf931b6f3905b44eb8d50 100644 (file)
@@ -17,6 +17,8 @@
 #include <QGridLayout>
 #include <QDoubleSpinBox>
 #include <QLabel>
+#include <QEvent>
+#include <QKeyEvent>
 
 #include <cfloat>
 #include <climits>
@@ -57,6 +59,8 @@ ModuleBase_WidgetPoint2D::ModuleBase_WidgetPoint2D(QWidget* theParent, QString t
 
     connect(myYSpin, SIGNAL(valueChanged(double)), this, SIGNAL(valuesChanged()));
   }
+  myXSpin->installEventFilter(this);
+  myYSpin->installEventFilter(this);
 }
 
 ModuleBase_WidgetPoint2D::~ModuleBase_WidgetPoint2D()
@@ -90,7 +94,39 @@ bool ModuleBase_WidgetPoint2D::restoreValue(boost::shared_ptr<ModelAPI_Feature>
   return true;
 }
 
+bool ModuleBase_WidgetPoint2D::focusTo(const std::string& theAttributeName)
+{
+  if (theAttributeName != myFeatureAttributeID)
+    return false;
+
+  if (!myXSpin->hasFocus() && !myYSpin->hasFocus()) {
+    myXSpin->setFocus();
+  }
+
+  return true;
+}
+
 QWidget* ModuleBase_WidgetPoint2D::getControl() const
 {
   return myGroupBox;
 }
+
+QList<QWidget*> ModuleBase_WidgetPoint2D::getControls() const
+{
+  QList<QWidget*> aControls;
+  aControls.push_back(myXSpin);
+  aControls.push_back(myYSpin);
+
+  return aControls;
+}
+
+bool ModuleBase_WidgetPoint2D::eventFilter(QObject *theObject, QEvent *theEvent)
+{
+  if (theObject == myXSpin || theObject == myYSpin) {
+    if (theEvent->type() == QEvent::KeyRelease) {
+      emit keyReleased(myFeatureAttributeID, (QKeyEvent*) theEvent);
+      return true;
+    }
+  }
+  return ModuleBase_ModelWidget::eventFilter(theObject, theEvent);
+}
index cd52779dc484dcade9ac2454673e436f17c6077c..016b17217c0e0901640cc1293cc6c5c6440858c9 100644 (file)
@@ -38,10 +38,20 @@ public:
 
   virtual bool restoreValue(boost::shared_ptr<ModelAPI_Feature> theFeature);
 
+  /// Set focus to the current widget if it corresponds to the given attribute
+  /// \param theAttribute name
+  virtual bool focusTo(const std::string& theAttributeName);
+
   /// Returns the internal parent wiget control, that can be shown anywhere
   /// \returns the widget
   QWidget* getControl() const;
 
+  /// Returns list of widget controls
+  /// \return a control list
+  virtual QList<QWidget*> getControls() const;
+
+  virtual bool eventFilter(QObject *theObject, QEvent *theEvent);
+
 private:
   std::string myFeatureAttributeID; ///< the identifier of the feature attribute
   QGroupBox* myGroupBox; ///< the parent group box for all intenal widgets
index 57fbe728fbcd98bb670e2d181d28cd22ff4794e1..94ef5f9268a75228a36eef6becd5cfd2295d0e24 100644 (file)
@@ -18,6 +18,7 @@
 #include <XGUI_ActionsMgr.h>
 #include <XGUI_ViewerProxy.h>
 #include <XGUI_ContextMenuMgr.h>
+#include <XGUI_PropertyPanel.h>
 
 #include <Config_PointerMessage.h>
 #include <Config_ModuleReader.h>
@@ -52,6 +53,9 @@ PartSet_Module::PartSet_Module(XGUI_Workshop* theWshop)
 
   XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
 
+  connect(anOperationMgr, SIGNAL(operationStarted()),
+          this, SLOT(onOperationStarted()));
+
   connect(anOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
           this, SLOT(onOperationStopped(ModuleBase_Operation*)));
 
@@ -118,12 +122,26 @@ void PartSet_Module::launchOperation(const QString& theCmdId)
   sendOperation(anOperation);
 }
 
+void PartSet_Module::onOperationStarted()
+{
+  PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
+                                       myWorkshop->operationMgr()->currentOperation());
+  if (aPreviewOp) {
+    XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
+    connect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
+            aPropPanel, SLOT(onFocusActivated(const std::string&)));
+  }
+}
+
 void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation)
 {
   if (!theOperation)
     return;
   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(theOperation);
   if (aPreviewOp) {
+    XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
+    disconnect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
+               aPropPanel, SLOT(onFocusActivated(const std::string&)));
   }
 }
 
index 1766a6e02b8a31c4174001c9da14555f6437bd5f..bf571a32332a294f68bd532a7a6d627bfb16fd7a 100644 (file)
@@ -59,6 +59,8 @@ public:
 
 public slots:
   void onFeatureTriggered();
+  /// SLOT, that is called after the operation is started. Connect on the focus activated signal
+  void onOperationStarted();
   /// SLOT, that is called after the operation is stopped. Switched off the modfications performed
   /// by the operation start
   void onOperationStopped(ModuleBase_Operation* theOperation);
@@ -79,7 +81,7 @@ public slots:
 
   /// SLOT, that is called by the key in the viewer is clicked.
   /// \param theEvent the mouse event
-  void onKeyRelease(QKeyEvent*);
+  void onKeyRelease(QKeyEvent* theEvent);
 
   /// SLOT, to apply to the current viewer the operation
   /// \param theX the X projection value
index acf76c60a094e134b5a9691c7e1be72ad383cbbe..0a581c178674dce6930742965edf7f1e23c712fa 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <V3d_View.hxx>
 
+#include <QKeyEvent>
+
 #ifdef _DEBUG
 #include <QDebug>
 #endif
@@ -88,3 +90,8 @@ void PartSet_OperationSketchBase::keyReleased(const int theKey)
     break;
   }
 }
+
+void PartSet_OperationSketchBase::keyReleased(std::string theName, QKeyEvent* theEvent)
+{
+  keyReleased(theEvent->key());
+}
index 5aa07c3f002c0ab90f8171e5d701c8fe629262ae..f4d01b3a086417f50f4d7802779a9aa61210d8e0 100644 (file)
@@ -92,7 +92,17 @@ public:
   /// \param theKey a key value
   virtual void keyReleased(const int theKey);
 
+  virtual void keyReleased(std::string theName, QKeyEvent* theEvent);
+
 signals:
+  /// signal about the request to launch operation
+  /// theName the operation name
+  /// theFeature the operation argument
+  void launchOperation(std::string theName, boost::shared_ptr<ModelAPI_Feature> theFeature);
+  /// signal about the focus activated
+  /// theName the attribute name
+  void focusActivated(const std::string& theAttibuteName);
+
   /// Signal about the feature construing is finished
   /// \param theFeature the result feature
   /// \param theMode the mode of the feature modification
@@ -101,10 +111,6 @@ signals:
   /// Signal about the features should be selected
   /// \param theSelected the list of selected presentations
   void featureSelected(const std::list<XGUI_ViewerPrs>& theSelected);
-  /// signal about the request to launch operation
-  /// theName the operation name
-  /// theFeature the operation argument
-  void launchOperation(std::string theName, boost::shared_ptr<ModelAPI_Feature> theFeature);
   /// signal to enable/disable multi selection in the viewer
   /// \param theEnabled the boolean state
   void multiSelectionEnabled(bool theEnabled);
index 33e03c5e2c4d4c841b9148252902ee0834c3a0a2..ddd9bd7281857bdf1ab1d34ac2ebc7adb9e60068 100644 (file)
@@ -25,6 +25,7 @@
 #include <gp_Lin.hxx>
 
 #include <XGUI_ViewerPrs.h>
+#include <XGUI_Constants.h>
 
 #include <SketchPlugin_Line.h>
 
@@ -146,15 +147,15 @@ void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3
       setLinePoint(feature(), aX, anY, LINE_ATTR_END);
       flushUpdated();
 
-      myPointSelectionMode = SM_SecondPoint;
+      setPointSelectionMode(SM_SecondPoint);
     }
     break;
     case SM_SecondPoint: {
       setLinePoint(feature(), aX, anY, LINE_ATTR_END);
       flushUpdated();
 
-      myPointSelectionMode = SM_DonePoint;
-    }
+      setPointSelectionMode(SM_DonePoint);
+   }
     break;
     default:
       break;
@@ -172,6 +173,7 @@ void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_V
       setLinePoint(feature(), aX, anY, LINE_ATTR_START);
       setLinePoint(feature(), aX, anY, LINE_ATTR_END);
       flushUpdated();
+      emit focusActivated(LINE_ATTR_START);
     }
     break;
     case SM_SecondPoint:
@@ -179,6 +181,7 @@ void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_V
       gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView);
       setLinePoint(aPoint, theView, LINE_ATTR_END);
       flushUpdated();
+      emit focusActivated(LINE_ATTR_END);
     }
     break;
     case SM_DonePoint:
@@ -192,6 +195,20 @@ void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_V
   }
 }
 
+void PartSet_OperationSketchLine::keyReleased(std::string theName, QKeyEvent* theEvent)
+{
+  int aKeyType = theEvent->key();
+  if (!theName.empty() && aKeyType == Qt::Key_Return) {
+    if (theName == LINE_ATTR_START) {
+      setPointSelectionMode(SM_SecondPoint, false);
+    }
+    else if (theName == LINE_ATTR_END) {
+      setPointSelectionMode(SM_DonePoint, false);
+    }
+  }
+  keyReleased(theEvent->key());
+}
+
 void PartSet_OperationSketchLine::keyReleased(const int theKey)
 {
   switch (theKey) {
@@ -200,10 +217,11 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey)
       {
         commit();
         emit featureConstructed(feature(), FM_Deactivation);
+        emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
       }
-      else
-        abort();
-      emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
+      //else
+      //  abort();
+      //emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
     }
     break;
     case Qt::Key_Escape: {
@@ -223,7 +241,8 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey)
 void PartSet_OperationSketchLine::startOperation()
 {
   PartSet_OperationSketchBase::startOperation();
-  myPointSelectionMode = !myInitPoint ? SM_FirstPoint : SM_SecondPoint;
+  setPointSelectionMode(!myInitPoint ? SM_FirstPoint : SM_SecondPoint);
+
   emit multiSelectionEnabled(false);
 }
 
@@ -378,3 +397,26 @@ void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint,
         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
   aPoint->setValue(aX, anY);
 }
+
+void PartSet_OperationSketchLine::setPointSelectionMode(const PointSelectionMode& theMode,
+                                                        const bool isToEmitSignal)
+{
+  myPointSelectionMode = theMode;
+  if (isToEmitSignal) {
+    std::string aName;
+    switch (theMode) {
+      case SM_FirstPoint:
+        aName = LINE_ATTR_START;
+        break;
+      case SM_SecondPoint:
+        aName = LINE_ATTR_END;
+        break;
+      case SM_DonePoint:
+        aName = XGUI::PROP_PANEL_OK;
+        break;
+      default:
+        break;
+    }
+    emit focusActivated(aName);
+  }
+}
index db20415c74cb86f54548866d6b52f83077734eb7..6b78f03691fb2e8aaaefd3f2ba98ef12510a0b05 100644 (file)
@@ -12,6 +12,7 @@
 
 class GeomDataAPI_Point2D;
 class QMouseEvent;
+class QKeyEvent;
 
 /*!
  \class PartSet_OperationSketchLine
@@ -72,6 +73,8 @@ public:
   /// \param theKey a key value
   virtual void keyReleased(const int theKey);
 
+  virtual void keyReleased(std::string theName, QKeyEvent* theEvent);
+
 protected:
   /// \brief Virtual method called when operation is started
   /// Virtual method called when operation started (see start() method for more description)
@@ -134,6 +137,11 @@ protected:
   ///< Structure to lists the possible types of point selection modes
   enum PointSelectionMode {SM_FirstPoint, SM_SecondPoint, SM_DonePoint};
 
+  ///< Set the point selection mode. Emit signal about focus change if necessary.
+  /// \param theMode a new selection mode
+  /// \param isToEmitSignal the neccessity to emit signal
+  void setPointSelectionMode(const PointSelectionMode& theMode, const bool isToEmitSignal = true);
+
 private:
   boost::shared_ptr<ModelAPI_Feature> mySketch; ///< the sketch feature
   boost::shared_ptr<GeomDataAPI_Point2D> myInitPoint; ///< the first line point
index 2a27188c9e9447073a6147681c192c4fe67bcc04..3fb2cad89dce5d54dc9705829b0555b0fdc9adb3 100644 (file)
@@ -7,10 +7,14 @@
 #include "ModuleBase_Operation.h"
 
 #include <QMessageBox>
+#include <QApplication>
+#include <QKeyEvent>
 
 XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent)
 : QObject(theParent)
 {
+  // listen to Escape signal to stop the current operation
+  qApp->installEventFilter(this);
 }
 
 XGUI_OperationMgr::~XGUI_OperationMgr()
@@ -66,6 +70,20 @@ QStringList XGUI_OperationMgr::operationList()
   return result;
 }
 
+bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
+{
+  if (theEvent->type() == QEvent::KeyRelease) {
+    QKeyEvent* aKeyEvent = (QKeyEvent*)theEvent;
+    if (aKeyEvent && aKeyEvent->key() == Qt::Key_Escape) {
+      // TODO: this is Escape button processing when the property panel has empty content,
+      // but the operation should be stopped by the Enter has been clicked
+      onKeyReleased("", aKeyEvent);
+      return true;
+    }
+  }
+  return QObject::eventFilter(theObject, theEvent);
+}
+
 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
 {
   theOperation->resume();
@@ -135,3 +153,10 @@ void XGUI_OperationMgr::onOperationStopped()
   if (aResultOp)
     resumeOperation(aResultOp);
 }
+
+void XGUI_OperationMgr::onKeyReleased(const std::string& theName, QKeyEvent* theEvent)
+{
+  ModuleBase_Operation* anOperation = currentOperation();
+  if (anOperation)
+    anOperation->keyReleased(theName, theEvent);
+}
index 56db2c4c57710f5219401ff32f655cc9805e2d72..82680fb56035ab4f072be9ef0db42b82c37c15b8 100644 (file)
@@ -13,6 +13,8 @@
 #include <QObject>
 #include <QStringList>
 
+class QKeyEvent;
+
 /**\class XGUI_OperationMgr
  * \ingroup GUI
  * \brief Operation manager. Servers to manupulate to the workshop operations. Contains a stack
@@ -50,6 +52,8 @@ public:
   ///Returns list of all operations IDs
   QStringList operationList();
 
+  virtual bool eventFilter(QObject *theObject, QEvent *theEvent);
+
 signals:
   /// Signal about an operation is started. It is emitted after the start() of operation is done.
   void operationStarted();
@@ -84,6 +88,11 @@ protected slots:
   /// If there is a suspended operation, restart it.
   void onOperationStopped();
 
+  /// SLOT, that is called by the key in the property panel is clicked.
+  /// \param theName the attribute name
+  /// \param theEvent the mouse event
+  void onKeyReleased(const std::string& theName, QKeyEvent* theEvent);
+
 private:
   typedef QList<ModuleBase_Operation*> Operations; ///< definition for a list of operations
   Operations myOperations; ///< a stack of started operations. The active operation is on top,
index ccf0469cfc2944b3d30b38fce8fbc867bbfcca27..f9328b5e16a276f6dadf83b2fb377251d3cc07b2 100644 (file)
@@ -14,6 +14,8 @@
 #include <QPushButton>
 #include <QIcon>
 #include <QVBoxLayout>
+#include <QEvent>
+#include <QKeyEvent>
 
 #ifdef _DEBUG
 #include <iostream>
@@ -44,9 +46,13 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent)
   aBtnLay->addStretch(1);
   aBtn = new QPushButton(QIcon(":pictures/button_ok.png"), "", aFrm);
   aBtn->setObjectName(XGUI::PROP_PANEL_OK);
+  aBtn->setToolTip(tr("Ok"));
   aBtn->setFlat(true);
   aBtnLay->addWidget(aBtn);
+  aBtn->installEventFilter(this);
+
   aBtn = new QPushButton(QIcon(":pictures/button_cancel.png"), "", aFrm);
+  aBtn->setToolTip(tr("Cancel"));
   aBtn->setObjectName(XGUI::PROP_PANEL_CANCEL);
   aBtn->setFlat(true);
   aBtnLay->addWidget(aBtn);
@@ -54,6 +60,8 @@ XGUI_PropertyPanel::XGUI_PropertyPanel(QWidget* theParent)
   myCustomWidget = new QWidget(aContent);
   aMainLay->addWidget(myCustomWidget);
   aMainLay->addStretch(1);
+
+  aBtn->installEventFilter(this);
 }
 
 XGUI_PropertyPanel::~XGUI_PropertyPanel()
@@ -63,6 +71,45 @@ XGUI_PropertyPanel::~XGUI_PropertyPanel()
 void XGUI_PropertyPanel::setModelWidgets(const QList<ModuleBase_ModelWidget*>& theWidgets)
 {
   myWidgets = theWidgets;
+
+  if (!theWidgets.empty()) {
+
+    QList<ModuleBase_ModelWidget*>::const_iterator anIt = theWidgets.begin(), aLast = theWidgets.end();
+    for (; anIt != aLast; anIt++) {
+      connect(*anIt, SIGNAL(keyReleased(const std::string&, QKeyEvent*)),
+              this, SIGNAL(keyReleased(const std::string&, QKeyEvent*)));
+    }
+    ModuleBase_ModelWidget* aLastWidget = theWidgets.last();
+    if (aLastWidget) {
+      QList<QWidget*> aControls = aLastWidget->getControls();
+      if (!aControls.empty()) {
+        QWidget* aLastControl = aControls.last();
+
+        QPushButton* anOkBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_OK);
+        QPushButton* aCancelBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_CANCEL);
+
+        setTabOrder(aLastControl, anOkBtn);
+        setTabOrder(anOkBtn, aCancelBtn);
+      }
+    }
+  }
+}
+
+bool XGUI_PropertyPanel::eventFilter(QObject *theObject, QEvent *theEvent)
+{
+  QPushButton* anOkBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_OK);
+  QPushButton* aCancelBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_CANCEL);
+  if (theObject == anOkBtn || theObject == aCancelBtn) {
+    if (theEvent->type() == QEvent::KeyRelease) {
+      QKeyEvent* aKeyEvent = (QKeyEvent*)theEvent;
+      if (aKeyEvent && aKeyEvent->key() == Qt::Key_Return) {
+        // TODO: this is enter button processing when the focus is on "Apply" or "Cancel" buttons
+        emit keyReleased("", (QKeyEvent*) theEvent);
+        return true;
+      }
+    }
+  }
+  return QDockWidget::eventFilter(theObject, theEvent);
 }
 
 QWidget* XGUI_PropertyPanel::contentWidget()
@@ -78,3 +125,21 @@ void XGUI_PropertyPanel::updateContentWidget(boost::shared_ptr<ModelAPI_Feature>
   // the repaint is used here to immediatelly react in GUI to the values change.
   repaint();
 }
+
+void XGUI_PropertyPanel::onFocusActivated(const std::string& theAttributeName)
+{
+  if (theAttributeName == XGUI::PROP_PANEL_OK) {
+    QPushButton* aBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_OK);
+    aBtn->setFocus();
+  }
+  if (theAttributeName == XGUI::PROP_PANEL_CANCEL) {
+    QPushButton* aBtn = findChild<QPushButton*>(XGUI::PROP_PANEL_CANCEL);
+    aBtn->setFocus();
+  }
+  else {
+    foreach(ModuleBase_ModelWidget* eachWidget, myWidgets) {
+      if (eachWidget->focusTo(theAttributeName))
+        break;
+    }
+  }
+}
index 546ae19b780fe7e2c62d30b3d3f90bc6b5a9a3b0..d034d728903641885564db7737e56e2748e61d74 100644 (file)
@@ -15,6 +15,8 @@
 #include <QDockWidget>
 #include <QList>
 
+class QKeyEvent;
+
 class XGUI_EXPORT XGUI_PropertyPanel: public QDockWidget
 {
   Q_OBJECT
@@ -25,8 +27,19 @@ public:
   QWidget* contentWidget();
   void setModelWidgets(const QList<ModuleBase_ModelWidget*>& theWidgets);
 
+  virtual bool eventFilter(QObject *theObject, QEvent *theEvent);
+
 public slots:
   void updateContentWidget(boost::shared_ptr<ModelAPI_Feature> theFeature);
+  /// slot to set the focus to the widget visualized an attribute with the given name
+  /// \param theAttributteName
+  void onFocusActivated(const std::string& theAttributeName);
+
+signals:
+  /// The signal about key release on the control, that corresponds to the attribute
+  /// \param theAttributeName a name of the attribute
+  /// \param theEvent key release event
+  void keyReleased(const std::string& theAttributeName, QKeyEvent* theEvent);
 
 private:
   QWidget* myCustomWidget;
index 2c9efd2965bc95ca680ad9326aafde225423085c..e075762aebfda8440c83f59f9fa34d092d56c374 100644 (file)
@@ -687,6 +687,9 @@ void XGUI_Workshop::createDockWidgets()
   connect(aOkBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onCommitOperation()));
   QPushButton* aCancelBtn = myPropertyPanel->findChild<QPushButton*>(XGUI::PROP_PANEL_CANCEL);
   connect(aCancelBtn, SIGNAL(clicked()), myOperationMgr, SLOT(onAbortOperation()));
+
+  connect(myPropertyPanel, SIGNAL(keyReleased(const std::string&, QKeyEvent*)),
+          myOperationMgr, SLOT(onKeyReleased(const std::string&, QKeyEvent*)));
 }
 
 //******************************************************