]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Enter processing from object browser.
authornds <nds@opencascade.com>
Mon, 19 Oct 2015 15:40:27 +0000 (18:40 +0300)
committernds <nds@opencascade.com>
Mon, 2 Nov 2015 09:48:34 +0000 (12:48 +0300)
15 files changed:
src/ModuleBase/ModuleBase_DoubleSpinBox.cpp
src/ModuleBase/ModuleBase_DoubleSpinBox.h
src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp
src/ModuleBase/ModuleBase_WidgetDoubleValue.h
src/ModuleBase/ModuleBase_WidgetExprEditor.cpp
src/ModuleBase/ModuleBase_WidgetExprEditor.h
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSet/PartSet_WidgetPoint2d.h
src/PartSet/PartSet_WidgetPoint2dDistance.cpp
src/PartSet/PartSet_WidgetPoint2dDistance.h
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_PropertyPanel.cpp [changed mode: 0644->0755]
src/XGUI/XGUI_PropertyPanel.h

index e436875bf5da34f40345db76ed51fc80857548c2..46f208ee281ea5cb0c45fdeaafc95ab7585bf807 100644 (file)
@@ -8,6 +8,7 @@
 #include <QLineEdit>
 #include <QDoubleValidator>
 #include <QVariant>
+#include <QKeyEvent>
 
 #include <limits>
 
@@ -78,7 +79,7 @@ ModuleBase_DoubleSpinBox::ModuleBase_DoubleSpinBox(QWidget* theParent, int thePr
           SLOT(onTextChanged( const QString& )));
 
   connect(this, SIGNAL(valueChanged(const QString&)), this, SLOT(onValueChanged(const QString&)));
-  connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
+  //connect(this, SIGNAL(editingFinished()), this, SLOT(onEditingFinished()));
 }
 
 /*!
@@ -200,29 +201,28 @@ QString ModuleBase_DoubleSpinBox::removeTrailingZeroes(const QString& src) const
   return res;
 }
 
-#include <QKeyEvent>
 void ModuleBase_DoubleSpinBox::keyPressEvent(QKeyEvent *theEvent)
 {
-  myProcessedEvent = 0;
-
-  bool anIsModified = myIsModified;
-  QDoubleSpinBox::keyPressEvent(theEvent);
-
   switch (theEvent->key()) {
     case Qt::Key_Enter:
     case Qt::Key_Return: {
-      if (anIsModified)
-        myProcessedEvent = theEvent;
-      /*qDebug("ModuleBase_DoubleSpinBox::keyPressEvent");
-      if (anIsModified) // we should not perform this event outside
-        theEvent->setAccepted(true);
-      else
-        theEvent->setAccepted(false);*/
+      // do not react to the Enter key, the property panel processes it
+      return;
     }
     break;
     default:
       break;
   }
+  QDoubleSpinBox::keyPressEvent(theEvent);
+}
+
+bool ModuleBase_DoubleSpinBox::focusNextPrevChild(bool theIsNext)
+{
+  myIsModified = false;
+
+  emit valueStored();
+  emit focusNextPrev();
+  return QDoubleSpinBox::focusNextPrevChild(theIsNext);
 }
 
 /*!
@@ -345,10 +345,15 @@ void ModuleBase_DoubleSpinBox::onValueChanged(const QString& theValue)
 
 void ModuleBase_DoubleSpinBox::onEditingFinished()
 {
-  myIsModified = false;
+  //myIsModified = false;
 }
 
-bool ModuleBase_DoubleSpinBox::isEventProcessed(QKeyEvent* theEvent)
+bool ModuleBase_DoubleSpinBox::isModified() const
 {
-  return myProcessedEvent && myProcessedEvent == theEvent;
+  return myIsModified;
+}
+
+void ModuleBase_DoubleSpinBox::clearModified()
+{
+  myIsModified = false;
 }
index 52eb6e3f9c7077a630a25aeb23f37871d0b2b9e9..f725c59bc698b26c59883bb5b6fc5eb8479923ae 100644 (file)
@@ -49,7 +49,16 @@ Q_OBJECT
   /// Validate current value
   virtual QValidator::State validate(QString&, int&) const;
 
-  virtual bool isEventProcessed(QKeyEvent* theEvent);
+  // Returns true if the current value is modified by has not been applyed yet
+  virtual bool isModified() const;
+
+  // Clears modified state
+  void clearModified();
+
+signals:
+  /// A signal that is emitted by the "Tab" key event. It is emitted before the key is processed.
+  void focusNextPrev();
+  void valueStored();
 
  protected slots:
    /// Called on text changed
@@ -62,6 +71,11 @@ Q_OBJECT
   QString removeTrailingZeroes(const QString&) const;
   virtual void keyPressEvent(QKeyEvent* theEvent);
 
+  /// The parent method that processes the "Tab"/"SHIF + Tab" keyboard events
+  /// Emits a signal about focus change
+  /// If theIsNext is true, this function searches forward, if next is false, it searches backward.
+  virtual bool focusNextPrevChild(bool theIsNext);
+
  private:
    /// Is clear flag
   bool myCleared;
@@ -70,8 +84,6 @@ Q_OBJECT
   int myPrecision;
   /// Boolean value whether the spin box content is modified
   bool myIsModified;
-
-  QKeyEvent* myProcessedEvent;
 };
 
 #endif
index 66fe88f12b0f98a2d7a40a75c6c6907c8f3f0c23..721c6c7b0470afd3ce84db7a0ee2517d58a6f7d2 100644 (file)
@@ -136,6 +136,28 @@ void ModuleBase_ModelWidget::activate()
   activateCustom();
 }
 
+QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)
+{
+  QWidget* aControl = 0;
+
+  QList<QWidget*> aControls = getControls();
+  int aSize = aControls.size();
+
+  if (isFirst) {
+    for (int i = 0; i < aSize && !aControl; i++)  {
+      if (aControls[i]->focusPolicy() != Qt::NoFocus)
+        aControl = aControls[i];
+    }
+  }
+  else {
+    for (int i = aSize - 1; i >= 0 && !aControl; i--)  {
+      if (aControls[i]->focusPolicy() != Qt::NoFocus)
+        aControl = aControls[i];
+    }
+  }
+  return aControl;
+}
+
 void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
 {
   myDefaultValue = theValue;
@@ -198,7 +220,7 @@ void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
   //blockUpdateViewer(false);
 }
 
-bool ModuleBase_ModelWidget::isEventProcessed(QKeyEvent* theEvent)
+bool ModuleBase_ModelWidget::processEnter()
 {
   return false;
 }
index 8804fdbeb0a95038d1713a3eb02eb3fde6f145da..c805502d1b9a4aabcf9325a6aecb1eacacfe03d4 100644 (file)
@@ -120,6 +120,11 @@ Q_OBJECT
   /// \return a control list
   virtual QList<QWidget*> getControls() const = 0;
 
+  /// Returns the first or the last control that can accept the focus
+  /// \param isFirst if true, the first controls is returned or the last one
+  /// \return a control from a list of controls
+  QWidget* getControlAcceptingFocus(const bool isFirst);
+
   /// FocusIn events processing
   virtual bool eventFilter(QObject* theObject, QEvent *theEvent);
 
@@ -162,7 +167,7 @@ Q_OBJECT
   bool isEditingMode() const { return myIsEditing; }
 
   /// Returns true if the event is processed.
-  virtual bool isEventProcessed(QKeyEvent* theEvent);
+  virtual bool processEnter();
 
   /// Sends Update and Redisplay for the given object
   /// \param theObj is updating object
@@ -202,6 +207,9 @@ signals:
   /// The signal about value state modification
   void valueStateChanged();
 
+  void focusNextPrev();
+  void valueStored();
+
 protected:
   /// Sets default value of widget. Normally, widget should fetch this value
   /// from the xml. However, some widgets derived widgets could define it
index 997554cc12fc2194bf80b171d6abfd5f5d072cc6..9cd6797fc09bc2049ba89beaa6d0e50e6fc7b34b 100644 (file)
@@ -90,8 +90,10 @@ ModuleBase_WidgetDoubleValue::ModuleBase_WidgetDoubleValue(QWidget* theParent,
   aControlLay->addRow(myLabel, mySpinBox);
 #ifdef APPLY_BY_ENTER_OR_TAB
   // Apply widget value change by enter/tab event.
-  connect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+  //connect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+  connect(mySpinBox, SIGNAL(valueStored()), this, SIGNAL(valuesChanged()));
   connect(mySpinBox, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
+  connect(mySpinBox, SIGNAL(focusNextPrev()), this, SIGNAL(focusNextPrev()));
 
 #else
   connect(mySpinBox, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesChanged()));
@@ -160,7 +162,13 @@ QList<QWidget*> ModuleBase_WidgetDoubleValue::getControls() const
   return aList;
 }
 
-bool ModuleBase_WidgetDoubleValue::isEventProcessed(QKeyEvent* theEvent)
+bool ModuleBase_WidgetDoubleValue::processEnter()
 {
-  return mySpinBox->isEventProcessed(theEvent);
+  bool isModified = mySpinBox->isModified();
+  if (isModified) {
+    emit valuesChanged();
+    mySpinBox->clearModified();
+    mySpinBox->selectAll();
+  }
+  return isModified;
 }
index ec3daae2c4e625fc8d878a2a318d41d2ed0ab4e7..8c1e0a1d8d955f0488b389ca23201d36caf0c836 100644 (file)
@@ -42,7 +42,7 @@ Q_OBJECT
   virtual QList<QWidget*> getControls() const;
 
   /// Returns true if the event is processed.
-  virtual bool isEventProcessed(QKeyEvent* theEvent);
+  virtual bool processEnter();
 
  public slots:
  // Delayed value chnged: when user starts typing something,
index 3b3d25c0815a8b9c8c2fdf2086de0da80dcd6a34..2d0e841a4a3de3273b35f17512a77e490e618d32 100644 (file)
@@ -36,7 +36,7 @@
 #include <string>
 
 ExpressionEditor::ExpressionEditor(QWidget* theParent)
-: QPlainTextEdit(theParent), myCompletedAndSelected(false)
+: QPlainTextEdit(theParent), myCompletedAndSelected(false), myIsModified(false)
 {
   myCompleter = new QCompleter(this);
   myCompleter->setWidget(this);
@@ -52,6 +52,10 @@ ExpressionEditor::ExpressionEditor(QWidget* theParent)
           this,        SLOT(insertCompletion(const QString&)));
   (void) new QShortcut(QKeySequence(tr("Ctrl+Space", "Complete")),
                        this, SLOT(performCompletion()));
+
+  connect(this, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
+
+  setTabChangesFocus(true);
 }
 
 ExpressionEditor::~ExpressionEditor()
@@ -110,6 +114,8 @@ void ExpressionEditor::performCompletion(const QString& theCompletionPrefix)
 
 void ExpressionEditor::keyPressEvent(QKeyEvent* theEvent)
 {
+  bool anIsModified = myIsModified;
+
   if (myCompletedAndSelected && handledCompletedAndSelected(theEvent))
     return;
   myCompletedAndSelected = false;
@@ -117,16 +123,27 @@ void ExpressionEditor::keyPressEvent(QKeyEvent* theEvent)
     switch (theEvent->key()) {
       case Qt::Key_Up:
       case Qt::Key_Down:
+      case Qt::Key_Escape:
       case Qt::Key_Enter:
       case Qt::Key_Return:
-      case Qt::Key_Escape:
         theEvent->ignore();
-        return;
+      return;
       default:
         myCompleter->popup()->hide();
         break;
     }
   }
+  else {
+    switch (theEvent->key()) {
+      case Qt::Key_Enter:
+      case Qt::Key_Return:
+        // do not react to the Enter key, the property panel processes it
+        return;
+      break;
+      default:
+        break;
+    }
+  }
   QPlainTextEdit::keyPressEvent(theEvent);
 }
 
@@ -155,6 +172,16 @@ QString ExpressionEditor::placeHolderText() const
   return myPlaceHolderText;
 }
 
+bool ExpressionEditor::isModified() const
+{
+  return myIsModified;
+}
+
+void ExpressionEditor::clearModified()
+{
+  myIsModified = false;
+}
+
 void ExpressionEditor::paintEvent( QPaintEvent* theEvent )
 {
   QPlainTextEdit::paintEvent( theEvent );
@@ -184,6 +211,20 @@ void ExpressionEditor::paintEvent( QPaintEvent* theEvent )
   }
 }
 
+bool ExpressionEditor::focusNextPrevChild(bool theIsNext)
+{
+  if (myIsModified)
+    emit editingFinished();
+  emit valueStored();
+  emit focusNextPrev();
+  return QPlainTextEdit::focusNextPrevChild(theIsNext);
+}
+
+void ExpressionEditor::onTextChanged()
+{
+  myIsModified = true;
+  emit valueModified();
+}
 
 
 ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor( QWidget* theParent,
@@ -207,7 +248,10 @@ ModuleBase_WidgetExprEditor::ModuleBase_WidgetExprEditor( QWidget* theParent,
   aMainLay->addWidget(myEditor);
   this->setLayout(aMainLay);
 
-  connect(myEditor, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
+  connect(myEditor, SIGNAL(valueModified()), this, SIGNAL(valuesModified()));
+  //connect(myEditor, SIGNAL(editingFinished()), this, SLOT(onTextChanged()));
+  connect(myEditor, SIGNAL(valueStored()), this, SLOT(onTextChanged()));
+  connect(myEditor, SIGNAL(focusNextPrev()), this, SIGNAL(focusNextPrev()));
 }
 
 ModuleBase_WidgetExprEditor::~ModuleBase_WidgetExprEditor()
@@ -273,7 +317,18 @@ QList<QWidget*> ModuleBase_WidgetExprEditor::getControls() const
   return result;
 }
 
+bool ModuleBase_WidgetExprEditor::processEnter()
+{
+  bool isModified = myEditor->isModified();
+  if (isModified) {
+    emit valuesChanged();
+    myEditor->clearModified();
+    myEditor->selectAll();
+  }
+  return isModified;
+}
+
 void ModuleBase_WidgetExprEditor::onTextChanged()
 {
-  storeValue();
+  emit valuesChanged();
 }
index 39ae9823546f07afd09c1960fe7ba6dd70f21c37..56d91029fdbd234fd962e4d109ef4c762be06266 100644 (file)
@@ -45,6 +45,12 @@ class ExpressionEditor: public QPlainTextEdit
   /// Returns placeholder list
   QString placeHolderText() const;
 
+  // Returns true if the current value is modified by has not been applyed yet
+  bool isModified() const;
+
+  // Clears modified state
+  void clearModified();
+
  public slots:
   /// Insert additional string for completion
   /// \param theCompletion a string to insert
@@ -54,6 +60,16 @@ class ExpressionEditor: public QPlainTextEdit
   /// Perform completion
   void performCompletion();
 
+  /// A slot for processing text changed event
+  void onTextChanged();
+
+signals:
+  void editingFinished();
+  void valueModified();
+  /// A signal that is emitted by the "Tab" key event. It is emitted before the key is processed.
+  void valueStored();
+  void focusNextPrev();
+
  protected:
   /// Perform completion by prefix
   /// \param theCompletionPrefix a prefix for looking for completion
@@ -70,11 +86,19 @@ class ExpressionEditor: public QPlainTextEdit
   /// Redefinition of virtual method
   virtual void paintEvent( QPaintEvent* );
 
+  /// The parent method that processes the "Tab"/"SHIF + Tab" keyboard events
+  /// Emits a signal about focus change
+  /// If theIsNext is true, this function searches forward, if next is false, it searches backward.
+  virtual bool focusNextPrevChild(bool theIsNext);
+
  private:
   QStringListModel* myCompleterModel;
   QCompleter* myCompleter;
   bool myCompletedAndSelected;
   QString myPlaceHolderText;
+
+  /// Boolean value whether the spin box content is modified
+  bool myIsModified;
 };
 
 /**
@@ -99,8 +123,11 @@ class MODULEBASE_EXPORT ModuleBase_WidgetExprEditor : public ModuleBase_ModelWid
   /// Redefinition of virtual method
   virtual QList<QWidget*> getControls() const;
 
- public slots:
-   /// A slot for processing text changed event
+  /// Returns true if the event is processed.
+  virtual bool processEnter();
+
+protected slots:
+  /// A slot for processing text changed event
   void onTextChanged();
 
 protected:
index e69c62cc3aef5444b30f9f04090a3c9d5624f28c..7cdf8cc92e1f3e67ab554d816cbeb3c9e157ffdd 100644 (file)
@@ -92,8 +92,11 @@ PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent,
 
 #ifdef APPLY_BY_ENTER_OR_TAB
     // Apply widget value change by enter/tab event.
-    connect(myXSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+    //connect(myXSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+    //connect(myXSpin, SIGNAL(focusNextPrev()), this, SLOT(onValuesChanged()));
+    connect(myXSpin, SIGNAL(valueStored()), this, SLOT(onValuesChanged()));
     connect(myXSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
+    connect(myXSpin, SIGNAL(focusNextPrev()), this, SIGNAL(focusNextPrev()));
 #else
     connect(myXSpin, SIGNAL(valueChanged(const QString&)), this, SLOT(onValuesChanged()));
 #endif
@@ -111,8 +114,10 @@ PartSet_WidgetPoint2D::PartSet_WidgetPoint2D(QWidget* theParent,
 
 #ifdef APPLY_BY_ENTER_OR_TAB
     // Apply widget value change by enter/tab event.
-    connect(myYSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+    //connect(myYSpin, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
+    connect(myYSpin, SIGNAL(valueStored()), this, SLOT(onValuesChanged()));
     connect(myYSpin, SIGNAL(valueChanged(const QString&)), this, SIGNAL(valuesModified()));
+    connect(myYSpin, SIGNAL(focusNextPrev()), this, SIGNAL(focusNextPrev()));
 #else
     connect(myYSpin, SIGNAL(valueChanged(const QString&)), this, SLOT(onValuesChanged()));
 #endif
@@ -476,7 +481,18 @@ void PartSet_WidgetPoint2D::onValuesChanged()
   emit valuesChanged();
 }
 
-bool PartSet_WidgetPoint2D::isEventProcessed(QKeyEvent* theEvent)
+bool PartSet_WidgetPoint2D::processEnter()
 {
-  return myXSpin->isEventProcessed(theEvent) || myXSpin->isEventProcessed(theEvent);
+  bool isModified = myXSpin->isModified() || myYSpin->isModified();
+  if (isModified) {
+    bool isXModified = myXSpin->isModified();
+    emit valuesChanged();
+    myXSpin->clearModified();
+    myYSpin->clearModified();
+    if (isXModified)
+      myXSpin->selectAll();
+    else
+      myYSpin->selectAll();
+  }
+  return isModified;
 }
index ae3ca08b2556c472a49c0a57e95f7f0601624353..e56da6badd91962c4a29a36e6467da44a2d6888f 100644 (file)
@@ -85,7 +85,7 @@ Q_OBJECT
   double y() const;
 
   /// Returns true if the event is processed.
-  virtual bool isEventProcessed(QKeyEvent* theEvent);
+  virtual bool processEnter();
 
 signals:
   /// Signal about selection of an existing vertex from an object
index 15061b90c586312eb48fc13b238b55e0312d2eff..2e665cf97fb2a86eb8df0fa55e0aa560e93dc965 100644 (file)
@@ -38,7 +38,8 @@ PartSet_WidgetPoint2dDistance::PartSet_WidgetPoint2dDistance(QWidget* theParent,
   // Reconnect to local slot
 #ifdef APPLY_BY_ENTER_OR_TAB
   // Apply widget value change by enter/tab event.
-  disconnect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+  //disconnect(mySpinBox, SIGNAL(editingFinished()), this, SIGNAL(valuesChanged()));
+  disconnect(mySpinBox, SIGNAL(valueStored()), this, SIGNAL(valuesChanged()));
   connect(mySpinBox, SIGNAL(editingFinished()), this, SLOT(onValuesChanged()));
   connect(mySpinBox, SIGNAL(valueChanged(double)), this, SIGNAL(valuesModified()));
 #else
@@ -140,7 +141,13 @@ void PartSet_WidgetPoint2dDistance::onValuesChanged()
   emit valuesChanged();
 }
 
-bool PartSet_WidgetPoint2dDistance::isEventProcessed(QKeyEvent* theEvent)
+bool PartSet_WidgetPoint2dDistance::processEnter()
 {
-  return mySpinBox->isEventProcessed(theEvent);
+  bool isModified = mySpinBox->isModified();
+  if (isModified) {
+    emit valuesChanged();
+    mySpinBox->clearModified();
+    mySpinBox->selectAll();
+  }
+  return isModified;
 }
index 7dc45bcca26e3dac785bc0d1064af8310fadd9a6..857212aca8288da21fb1a91118b9972402401da7 100644 (file)
@@ -60,7 +60,7 @@ Q_OBJECT
   void setSketch(CompositeFeaturePtr theSketch) { mySketch = theSketch; }
 
   /// Returns true if the event is processed.
-  virtual bool isEventProcessed(QKeyEvent* theEvent);
+  virtual bool processEnter();
 
 public slots:
    /// Process of mouse move
index 0410fce4929933d21c64c8a53aa197802a1f0986..5da8053b03edac501a3ce0e26884df4d0abf9b91 100644 (file)
@@ -9,6 +9,8 @@
 #include "XGUI_Workshop.h"
 #include "XGUI_ErrorMgr.h"
 
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ModelWidget.h>
 #include "ModuleBase_Operation.h"
 #include "ModuleBase_IWorkshop.h"
 #include "ModuleBase_IModule.h"
@@ -494,10 +496,10 @@ void XGUI_OperationMgr::onOperationStopped()
   }
 }
 
-#include <ModuleBase_IPropertyPanel.h>
-#include <ModuleBase_ModelWidget.h>
 bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
 {
+  qDebug("XGUI_OperationMgr::onKeyReleased");
+
   QObject* aSender = sender();
 
   // Let the manager decide what to do with the given key combination.
@@ -506,10 +508,11 @@ bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
   switch (theEvent->key()) {
     case Qt::Key_Return:
     case Qt::Key_Enter: {
+      qDebug("XGUI_OperationMgr::onKeyReleased: Key_Return");
       ModuleBase_Operation* aOperation = currentOperation();
       ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
       ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
-      if (!aActiveWgt || !aActiveWgt->isEventProcessed(theEvent)) {
+      if (!aActiveWgt || !aActiveWgt->processEnter()) {
         ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
         if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {
           emit keyEnterReleased();
old mode 100644 (file)
new mode 100755 (executable)
index 3838f78..994193c
@@ -118,23 +118,8 @@ void XGUI_PropertyPanel::setModelWidgets(const QList<ModuleBase_ModelWidget*>& t
             this,    SLOT(activateNextWidget(ModuleBase_ModelWidget*)));
     connect(aWidget, SIGNAL(keyReleased(QKeyEvent*)),
             this,    SIGNAL(keyReleased(QKeyEvent*)));
-  }
-
-  QWidget* aLastControl = 0;
-  QList<QWidget*> aControls;
-  for (int i = myWidgets.size()-1; i >= 0 && !aLastControl; i--)  {
-    aControls = myWidgets[i]->getControls();
-    for (int j = aControls.size()-1; j >= 0 && !aLastControl; j--)  {
-      if (aControls[j]->focusPolicy() != Qt::NoFocus)
-        aLastControl = aControls[j];
-    }
-  }
-  if (aLastControl) {
-    QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
-    QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
-
-    setTabOrder(aLastControl, anOkBtn);
-    setTabOrder(anOkBtn, aCancelBtn);
+    connect(aWidget, SIGNAL(focusNextPrev()),
+            this, SLOT(onFocusNextPrev()));
   }
 }
 
@@ -145,7 +130,6 @@ const QList<ModuleBase_ModelWidget*>& XGUI_PropertyPanel::modelWidgets() const
 
 ModuleBase_PageBase* XGUI_PropertyPanel::contentWidget()
 {
-
   return static_cast<ModuleBase_PageBase*>(myPanelPage);
 }
 
@@ -186,12 +170,88 @@ void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget)
   activateWidget(NULL);
 }
 
+void XGUI_PropertyPanel::onFocusNextPrev()
+{
+  setActiveWidget(NULL);
+}
+
+bool XGUI_PropertyPanel::focusNextPrevChild(bool theIsNext)
+{
+  // it wraps the Tabs clicking to follow in the chain:
+  // controls, last control, Apply, Cancel, first control, controls
+
+  bool isChangedFocus = false;
+  if (theIsNext) { // forward by Tab
+    QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+    if (aCancelBtn->hasFocus()) {
+      // after cancel, the first control should be focused
+      QWidget* aFirstControl = 0;
+      for (int i = 0, aSize = myWidgets.size(); i < aSize && !aFirstControl; i++)
+        aFirstControl = myWidgets[i]->getControlAcceptingFocus(true);
+      if (aFirstControl)
+        aFirstControl->setFocus();
+        isChangedFocus = true;
+    }
+    else {
+      // after the last control, the Apply button should be focused
+      QWidget* aLastControl = 0;
+      for (int i = myWidgets.size()-1; i >= 0 && !aLastControl; i--)
+        aLastControl = myWidgets[i]->getControlAcceptingFocus(false);
+      if (aLastControl && aLastControl->hasFocus()) {
+        setFocusOnOkButton();
+        isChangedFocus = true;
+      }
+    }
+  }
+  else { // backward by SHIFT + Tab
+    QToolButton* anOkBtn = findChild<QToolButton*>(PROP_PANEL_OK);
+    if (anOkBtn->hasFocus()) {
+      // after Apply, the last control should be focused
+      QWidget* aLastControl = 0;
+      for (int i = myWidgets.size()-1; i >= 0 && !aLastControl; i--)
+        aLastControl = myWidgets[i]->getControlAcceptingFocus(false);
+      if (aLastControl)
+        aLastControl->setFocus();
+        isChangedFocus = true;
+    }
+    else {
+      // after the first control, the Cancel button should be focused
+      QWidget* aFirstControl = 0;
+      for (int i = 0, aSize = myWidgets.size(); i < aSize && !aFirstControl; i++)
+        aFirstControl = myWidgets[i]->getControlAcceptingFocus(true);
+      if (aFirstControl && aFirstControl->hasFocus()) {
+        QToolButton* aCancelBtn = findChild<QToolButton*>(PROP_PANEL_CANCEL);
+        aCancelBtn->setFocus();
+        isChangedFocus = true;
+      }
+    }
+  }
+
+  if (!isChangedFocus)
+    isChangedFocus = ModuleBase_IPropertyPanel::focusNextPrevChild(theIsNext);
+
+  return isChangedFocus;
+}
+
 void XGUI_PropertyPanel::activateNextWidget()
 {
   activateNextWidget(myActiveWidget);
 }
 
 void XGUI_PropertyPanel::activateWidget(ModuleBase_ModelWidget* theWidget)
+{
+  // Avoid activation of already actve widget. It could happen on focusIn event many times
+  setActiveWidget(theWidget);
+
+  if (myActiveWidget) {
+    emit widgetActivated(myActiveWidget);
+  } else if (!isEditingMode()) {
+    emit noMoreWidgets();
+    setFocusOnOkButton();
+  }
+}
+
+void XGUI_PropertyPanel::setActiveWidget(ModuleBase_ModelWidget* theWidget)
 {
   // Avoid activation of already actve widget. It could happen on focusIn event many times
   if (theWidget == myActiveWidget) {
@@ -207,12 +267,7 @@ void XGUI_PropertyPanel::activateWidget(ModuleBase_ModelWidget* theWidget)
     theWidget->activate();
   }
   myActiveWidget = theWidget;
-  if (myActiveWidget) {
-    emit widgetActivated(theWidget);
-  } else if (!isEditingMode()) {
-    emit noMoreWidgets();
     setFocusOnOkButton();
-  }
 }
 
 void XGUI_PropertyPanel::setFocusOnOkButton()
index 0b158921ef92d6a3f1c965a9c00c1e443716d37a..a85af1e09c71783160d69ef76f17475efb6a3469 100644 (file)
@@ -118,6 +118,18 @@ public slots:
   */
   virtual void activateWidget(ModuleBase_ModelWidget* theWidget);
 
+  void onFocusNextPrev();
+
+protected:
+  /// Makes the widget active, deactivate the previous, activate and hightlight the given one
+  /// \param theWidget a widget
+  void setActiveWidget(ModuleBase_ModelWidget* theWidget);
+
+  /// The parent method that processes the "Tab"/"SHIF + Tab" keyboard events
+  /// Emits a signal about focus change
+  /// If theIsNext is true, this function searches forward, if next is false, it searches backward.
+  virtual bool focusNextPrevChild(bool theIsNext);
+
  protected:
    /// A method called on the property panel closed
    /// \param theEvent a close event