Salome HOME
Issue #1303 Re-ordering of Sketcher menus: Delete to be the last
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetEditor.cpp
index 7f77acd5a97ac1064fdfd533699a7e85dd71b4ad..3adc21b0d452e653b5a0c32ed4665bdfb3caca70 100644 (file)
@@ -5,7 +5,7 @@
 // Author:      Natalia ERMOLAEVA
 
 #include <ModuleBase_WidgetEditor.h>
-#include <ModuleBase_DoubleSpinBox.h>
+#include <ModuleBase_ParamSpinBox.h>
 #include <ModuleBase_Tools.h>
 
 #include <Config_Keywords.h>
 
 #include <GeomDataAPI_Point2D.h>
 
-#include <QWidget>
+#include <QApplication>
 #include <QLineEdit>
-#include <QTimer>
+#include <QMenu>
+#include <QWidget>
+#include <QWidgetAction>
+#include <QRegExp>
+#include <QRegExpValidator>
+#include <QDesktopWidget>
 #include <QDialog>
 #include <QLayout>
-#include <QApplication>
 
 ModuleBase_WidgetEditor::ModuleBase_WidgetEditor(QWidget* theParent,
-                                                 const Config_WidgetAPI* theData,
-                                                 const std::string& theParentId)
-    : ModuleBase_WidgetDoubleValue(theParent, theData, theParentId)
+                                                 const Config_WidgetAPI* theData)
+: ModuleBase_WidgetDoubleValue(theParent, theData),
+  myXPosition(-1), myYPosition(-1)
 {
 }
 
@@ -39,62 +43,96 @@ ModuleBase_WidgetEditor::~ModuleBase_WidgetEditor()
 {
 }
 
-double editedValue(double theValue, bool& isDone)
+bool ModuleBase_WidgetEditor::editedValue(double& outValue, QString& outText)
 {
-  QDialog aDlg;
-  aDlg.setWindowFlags(Qt::FramelessWindowHint);
+  bool isValueAccepted = false;
+
+  QDialog aDlg(QApplication::desktop(), Qt::FramelessWindowHint);
   QHBoxLayout* aLay = new QHBoxLayout(&aDlg);
-  ModuleBase_Tools::zeroMargins(aLay);
+  aLay->setContentsMargins(2, 2, 2, 2);
+
+  ModuleBase_ParamSpinBox* anEditor = new ModuleBase_ParamSpinBox(&aDlg);
+  anEditor->enableKeyPressEvent(true);
+
+  anEditor->setMinimum(0);
+  anEditor->setMaximum(DBL_MAX);
+  if (outText.isEmpty())
+    anEditor->setValue(outValue);
+  else
+    anEditor->setText(outText);
 
-  QLineEdit* aEditor = new QLineEdit(QString::number(theValue), &aDlg);
-  aEditor->setValidator(new QDoubleValidator(aEditor));
-  QObject::connect(aEditor, SIGNAL(returnPressed()), &aDlg, SLOT(accept()));
-  aLay->addWidget(aEditor);
+  aLay->addWidget(anEditor);
+
+  ModuleBase_Tools::setFocus(anEditor, "ModuleBase_WidgetEditor::editedValue");
+  anEditor->selectAll();
+  QObject::connect(anEditor, SIGNAL(enterReleased()), &aDlg, SLOT(accept()));
 
   QPoint aPoint = QCursor::pos();
-  aDlg.move(aPoint);
+  if (myXPosition >= 0 && myYPosition >= 0)
+    aPoint = QPoint(myXPosition, myYPosition);
 
-  isDone = aDlg.exec() == QDialog::Accepted;
-  double aValue = theValue;
-  if (isDone)
-    aValue = aEditor->text().toDouble();
-  return aValue;
+  aDlg.move(aPoint);
+  isValueAccepted = aDlg.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
+    }
+  }
+  return isValueAccepted;
 }
 
 bool ModuleBase_WidgetEditor::focusTo()
 {
-  // We can not launch here modal process for value editing because 
-  // it can be called on other focusOutWidget event and will block it
-  QTimer::singleShot(1, this, SLOT(showPopupEditor()));
+  showPopupEditor();
   return true;
 }
 
-void ModuleBase_WidgetEditor::showPopupEditor()
+bool ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
 {
+  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);
+
+  // nds: it seems, that the envents processing is not necessary anymore
   // White while all events will be processed
-  QApplication::processEvents();
+  //QApplication::processEvents();
   double aValue = mySpinBox->value();
-  bool isDone;
-  aValue = editedValue(aValue, isDone);
-
-  if (isDone) {
-    bool isBlocked = mySpinBox->blockSignals(true);
-    mySpinBox->setValue(aValue);
-    mySpinBox->blockSignals(isBlocked);
+  QString aText;
+  if (mySpinBox->hasVariable())
+    aText = mySpinBox->text();
+
+  isValueAccepted = editedValue(aValue, aText);
+  if (isValueAccepted) {
+    if (aText.isEmpty()) {
+      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();
   }
-  emit valuesChanged();
-  emit focusOutWidget(this);
+
+  if (theSendSignals && !myIsEditing)
+    emit enterClicked(this);
+
+  return isValueAccepted;
 }
 
-void ModuleBase_WidgetEditor::editFeatureValue(FeaturePtr theFeature,
-                                               const std::string theAttribute)
+void ModuleBase_WidgetEditor::setCursorPosition(const int theX, const int theY)
 {
-  DataPtr aData = theFeature->data();
-  AttributeDoublePtr aRef = aData->real(theAttribute);
-  double aValue = aRef->value();
-
-  bool isDone;
-  aValue = editedValue(aValue, isDone);
-  if (isDone)
-    aRef->setValue(aValue);
+  myXPosition = theX;
+  myYPosition = theY;
 }