Salome HOME
Merge branch 'Dev_GroupsRevision'
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetEditor.cpp
index aa4cd79b70bdaa0d9af645402e6779dd43788e61..be60db9d3b503a620ba69118b8e50af10ef2be79 100644 (file)
@@ -1,8 +1,22 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        ModuleBase_WidgetEditor.cpp
-// Created:     25 Apr 2014
-// Author:      Natalia ERMOLAEVA
+// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+//
+// 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<mailto:webmaster.salome@opencascade.com>
+//
 
 #include <ModuleBase_WidgetEditor.h>
 #include <ModuleBase_ParamSpinBox.h>
@@ -22,6 +36,7 @@
 #include <GeomDataAPI_Point2D.h>
 
 #include <QApplication>
+#include <QKeyEvent>
 #include <QLineEdit>
 #include <QMenu>
 #include <QWidget>
 #include <QDialog>
 #include <QLayout>
 
+// Dialog is redefined to avoid Escape key processing
+class ModuleBase_EditorDialog : public QDialog
+{
+public:
+  ModuleBase_EditorDialog(QWidget* theParent, Qt::WindowFlags theFlags)
+    : QDialog(theParent, theFlags) {}
+  ~ModuleBase_EditorDialog() {}
+
+protected:
+  // Do nothing if key pressed because it is processing on operation manager level
+  virtual void keyPressEvent(QKeyEvent* theEvent) {
+    if (theEvent->key() == Qt::Key_Escape)
+        return;
+    QDialog::keyPressEvent(theEvent);
+  }
+};
+
 ModuleBase_WidgetEditor::ModuleBase_WidgetEditor(QWidget* theParent,
-                                                 const Config_WidgetAPI* theData,
-                                                 const std::string& theParentId)
-: ModuleBase_WidgetDoubleValue(theParent, theData, theParentId),
-  //myIsEnterPressedEmitted(false),
-  myXPosition(-1), myYPosition(-1)
+                                                 const Config_WidgetAPI* theData)
+: ModuleBase_WidgetDoubleValue(theParent, theData),
+  myXPosition(-1), myYPosition(-1), myEditorDialog(0)
 {
 }
 
@@ -45,20 +75,19 @@ ModuleBase_WidgetEditor::~ModuleBase_WidgetEditor()
 {
 }
 
-void ModuleBase_WidgetEditor::editedValue(double& outValue, QString& outText)
+bool ModuleBase_WidgetEditor::editedValue(double theSpinMinValue, double theSpinMaxValue,
+                                          double& outValue, QString& outText)
 {
-  QDialog aDlg(QApplication::desktop(), Qt::FramelessWindowHint);
-  QHBoxLayout* aLay = new QHBoxLayout(&aDlg);
-  aLay->setContentsMargins(2, 2, 2, 2);
+  bool isValueAccepted = false;
+
+  myEditorDialog = new ModuleBase_EditorDialog(QApplication::desktop(), Qt::FramelessWindowHint);
 
-  ModuleBase_ParamSpinBox* anEditor = new ModuleBase_ParamSpinBox(&aDlg);
-  anEditor->enableKeyPressEvent(true);
-  //if (!myIsEditing) {
-  //  connect(anEditor, SIGNAL(enterPressed()), this, SLOT(onEnterPressed()));
-  //}
+  QHBoxLayout* aLay = new QHBoxLayout(myEditorDialog);
+  aLay->setContentsMargins(2, 2, 2, 2);
 
-  anEditor->setMinimum(0);
-  anEditor->setMaximum(DBL_MAX);
+  ModuleBase_ParamSpinBox* anEditor = new ModuleBase_ParamSpinBox(myEditorDialog);
+  anEditor->setMinimum(theSpinMinValue);
+  anEditor->setMaximum(theSpinMaxValue);
   if (outText.isEmpty())
     anEditor->setValue(outValue);
   else
@@ -68,43 +97,42 @@ void ModuleBase_WidgetEditor::editedValue(double& outValue, QString& outText)
 
   ModuleBase_Tools::setFocus(anEditor, "ModuleBase_WidgetEditor::editedValue");
   anEditor->selectAll();
-  QObject::connect(anEditor, SIGNAL(enterReleased()), &aDlg, SLOT(accept()));
 
   QPoint aPoint = QCursor::pos();
   if (myXPosition >= 0 && myYPosition >= 0)
     aPoint = QPoint(myXPosition, myYPosition);
 
-  aDlg.move(aPoint);
-  aDlg.exec();
-
-  //if (!myIsEditing) {
-  //  disconnect(anEditor, SIGNAL(keyReleased(QKeyEvent*)), this, SLOT(onEnterPressed()));
-  //}
-
-  outText = anEditor->text();
-  bool isDouble;
-  double aValue = outText.toDouble(&isDouble);
-  if (isDouble) {
-    outValue = aValue;
-    outText = ""; // return empty string, if it's can be converted to a double
+  myEditorDialog->move(aPoint);
+  isValueAccepted = myEditorDialog->exec() == QDialog::Accepted;
+  if (isValueAccepted) {
+    outText = anEditor->text();
+    bool isDouble;
+    double aValue = outText.toDouble(&isDouble);
+    if (isDouble) {
+      outValue = aValue;
+      outText = ""; // return empty string, if it's can be converted to a double
+    }
   }
+  delete myEditorDialog;
+  myEditorDialog = 0;
+  return isValueAccepted;
 }
 
 bool ModuleBase_WidgetEditor::focusTo()
 {
   showPopupEditor();
-  return true;
+  return false;
 }
 
-void ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
+bool ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
 {
-  //myIsEnterPressedEmitted = false;
-
+  bool isValueAccepted = false;
   // we need to emit the focus in event manually in order to save the widget as an active
   // in the property panel before the mouse leave event happens in the viewer. The module
-  // ask an active widget and change the feature visualization if the widget is not the current one.
-  if (theSendSignals)
-    emit focusInWidget(this);
+  // ask an active widget and change the feature visualization if the widget is not the current
+  // one.  Also we need this widget as active to provide call of processEnter() applyed
+  // by operation manager to the current widget. If not, the myEditorDialog will stay opened
+  emitFocusInWidget();
 
   // nds: it seems, that the envents processing is not necessary anymore
   // White while all events will be processed
@@ -114,33 +142,58 @@ void ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
   if (mySpinBox->hasVariable())
     aText = mySpinBox->text();
 
-  editedValue(aValue, aText);
-  if (aText.isEmpty()) {
-    ModuleBase_Tools::setSpinValue(mySpinBox, aValue);
-  } else {
-    ModuleBase_Tools::setSpinText(mySpinBox, aText);
+  isValueAccepted = editedValue(mySpinBox->minimum(), mySpinBox->maximum(), aValue, aText);
+  if (isValueAccepted) {
+    if (aText.isEmpty()) {
+      if (mySpinBox->hasVariable()) {
+        // variable text should be cleared before setting value as the value
+        // will not be set if there is a varable in control
+        ModuleBase_Tools::setSpinText(mySpinBox, "");
+      }
+      ModuleBase_Tools::setSpinValue(mySpinBox, aValue);
+    } else {
+      ModuleBase_Tools::setSpinText(mySpinBox, aText);
+    }
+    if (theSendSignals) {
+      emit valuesChanged();
+      // the focus leaves the control automatically by the Enter/Esc event
+      // it is processed in operation manager
+      //emit focusOutWidget(this);
+    }
+    else
+      storeValue();
   }
-  if (theSendSignals) {
-    emit valuesChanged();
-    // the focus leaves the control automatically by the Enter/Esc event
-    // it is processed in operation manager
-    //emit focusOutWidget(this);
-
-    //if (myIsEnterPressedEmitted)
-    if (!myIsEditing)
-      emit enterClicked();
-  }
-  else
-    storeValue();
-}
+  ModuleBase_Tools::setFocus(mySpinBox, "ModuleBase_WidgetEditor::editedValue");
+  mySpinBox->selectAll();
+  // enter is processed, so we need not anymore emit clicked signal
+  //if (theSendSignals && !myIsEditing && isValueAccepted)
+  //  emit enterClicked(this);
 
-/*void ModuleBase_WidgetEditor::onEnterPressed()
-{
-  myIsEnterPressedEmitted = true;
-}*/
+  return isValueAccepted;
+}
 
 void ModuleBase_WidgetEditor::setCursorPosition(const int theX, const int theY)
 {
   myXPosition = theX;
   myYPosition = theY;
 }
+
+bool ModuleBase_WidgetEditor::processEnter()
+{
+  if (myEditorDialog) {
+    myEditorDialog->accept();
+    return true;
+  }
+
+  return ModuleBase_WidgetDoubleValue::processEnter();
+}
+
+bool ModuleBase_WidgetEditor::processEscape()
+{
+  if (myEditorDialog) {
+    myEditorDialog->reject();
+    return true;
+  }
+
+  return ModuleBase_WidgetDoubleValue::processEscape();
+}