Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetEditor.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <ModuleBase_WidgetEditor.h>
22 #include <ModuleBase_ParamSpinBox.h>
23 #include <ModuleBase_Tools.h>
24
25 #include <Config_Keywords.h>
26 #include <Config_WidgetAPI.h>
27
28 #include <Events_Loop.h>
29 #include <ModelAPI_Events.h>
30
31 #include <ModelAPI_Feature.h>
32 #include <ModelAPI_Data.h>
33 #include <ModelAPI_Object.h>
34 #include <ModelAPI_AttributeDouble.h>
35
36 #include <GeomDataAPI_Point2D.h>
37
38 #include <QApplication>
39 #include <QLineEdit>
40 #include <QMenu>
41 #include <QWidget>
42 #include <QWidgetAction>
43 #include <QRegExp>
44 #include <QRegExpValidator>
45 #include <QDesktopWidget>
46 #include <QDialog>
47 #include <QLayout>
48
49 ModuleBase_WidgetEditor::ModuleBase_WidgetEditor(QWidget* theParent,
50                                                  const Config_WidgetAPI* theData)
51 : ModuleBase_WidgetDoubleValue(theParent, theData),
52   myXPosition(-1), myYPosition(-1), myEditorDialog(0)
53 {
54 }
55
56 ModuleBase_WidgetEditor::~ModuleBase_WidgetEditor()
57 {
58 }
59
60 bool ModuleBase_WidgetEditor::editedValue(double& outValue, QString& outText)
61 {
62   bool isValueAccepted = false;
63
64   myEditorDialog = new QDialog(QApplication::desktop(), Qt::FramelessWindowHint);
65
66   QHBoxLayout* aLay = new QHBoxLayout(myEditorDialog);
67   aLay->setContentsMargins(2, 2, 2, 2);
68
69   ModuleBase_ParamSpinBox* anEditor = new ModuleBase_ParamSpinBox(myEditorDialog);
70   anEditor->setMinimum(0);
71   anEditor->setMaximum(DBL_MAX);
72   if (outText.isEmpty())
73     anEditor->setValue(outValue);
74   else
75     anEditor->setText(outText);
76
77   aLay->addWidget(anEditor);
78
79   ModuleBase_Tools::setFocus(anEditor, "ModuleBase_WidgetEditor::editedValue");
80   anEditor->selectAll();
81
82   QPoint aPoint = QCursor::pos();
83   if (myXPosition >= 0 && myYPosition >= 0)
84     aPoint = QPoint(myXPosition, myYPosition);
85
86   myEditorDialog->move(aPoint);
87   isValueAccepted = myEditorDialog->exec() == QDialog::Accepted;
88   if (isValueAccepted) {
89     outText = anEditor->text();
90     bool isDouble;
91     double aValue = outText.toDouble(&isDouble);
92     if (isDouble) {
93       outValue = aValue;
94       outText = ""; // return empty string, if it's can be converted to a double
95     }
96   }
97   delete myEditorDialog;
98   myEditorDialog = 0;
99   return isValueAccepted;
100 }
101
102 bool ModuleBase_WidgetEditor::focusTo()
103 {
104   showPopupEditor();
105   return false;
106 }
107
108 bool ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
109 {
110   bool isValueAccepted = false;
111   // we need to emit the focus in event manually in order to save the widget as an active
112   // in the property panel before the mouse leave event happens in the viewer. The module
113   // ask an active widget and change the feature visualization if the widget is not the current
114   // one.  Also we need this widget as active to provide call of processEnter() applyed
115   // by operation manager to the current widget. If not, the myEditorDialog will stay opened
116   emitFocusInWidget();
117
118   // nds: it seems, that the envents processing is not necessary anymore
119   // White while all events will be processed
120   //QApplication::processEvents();
121   double aValue = mySpinBox->value();
122   QString aText;
123   if (mySpinBox->hasVariable())
124     aText = mySpinBox->text();
125
126   isValueAccepted = editedValue(aValue, aText);
127   if (isValueAccepted) {
128     if (aText.isEmpty()) {
129       if (mySpinBox->hasVariable()) {
130         // variable text should be cleared before setting value as the value
131         // will not be set if there is a varable in control
132         ModuleBase_Tools::setSpinText(mySpinBox, "");
133       }
134       ModuleBase_Tools::setSpinValue(mySpinBox, aValue);
135     } else {
136       ModuleBase_Tools::setSpinText(mySpinBox, aText);
137     }
138     if (theSendSignals) {
139       emit valuesChanged();
140       // the focus leaves the control automatically by the Enter/Esc event
141       // it is processed in operation manager
142       //emit focusOutWidget(this);
143     }
144     else
145       storeValue();
146   }
147   ModuleBase_Tools::setFocus(mySpinBox, "ModuleBase_WidgetEditor::editedValue");
148   mySpinBox->selectAll();
149
150   if (theSendSignals && !myIsEditing)
151     emit enterClicked(this);
152
153   return isValueAccepted;
154 }
155
156 void ModuleBase_WidgetEditor::setCursorPosition(const int theX, const int theY)
157 {
158   myXPosition = theX;
159   myYPosition = theY;
160 }
161
162 bool ModuleBase_WidgetEditor::processEnter()
163 {
164   if (myEditorDialog) {
165     myEditorDialog->accept();
166     return true;
167   }
168
169   return ModuleBase_WidgetDoubleValue::processEnter();
170 }