1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <ModuleBase_WidgetEditor.h>
22 #include <ModuleBase_ParamSpinBox.h>
23 #include <ModuleBase_Tools.h>
25 #include <Config_Keywords.h>
26 #include <Config_WidgetAPI.h>
28 #include <Events_Loop.h>
29 #include <ModelAPI_Events.h>
31 #include <ModelAPI_Feature.h>
32 #include <ModelAPI_Data.h>
33 #include <ModelAPI_Object.h>
34 #include <ModelAPI_AttributeDouble.h>
36 #include <GeomDataAPI_Point2D.h>
38 #include <QApplication>
43 #include <QWidgetAction>
45 #include <QRegExpValidator>
46 #include <QDesktopWidget>
50 // Dialog is redefined to avoid Escape key processing
51 class ModuleBase_EditorDialog : public QDialog
54 ModuleBase_EditorDialog(QWidget* theParent, Qt::WindowFlags theFlags)
55 : QDialog(theParent, theFlags)
59 ~ModuleBase_EditorDialog() {}
62 // Do nothing if key pressed because it is processing on operation manager level
63 virtual void keyPressEvent(QKeyEvent* theEvent) {
64 if (theEvent->key() == Qt::Key_Escape)
66 QDialog::keyPressEvent(theEvent);
70 ModuleBase_WidgetEditor::ModuleBase_WidgetEditor(QWidget* theParent,
71 const Config_WidgetAPI* theData)
72 : ModuleBase_WidgetDoubleValue(theParent, theData),
73 myXPosition(-1), myYPosition(-1), myEditorDialog(0)
77 ModuleBase_WidgetEditor::~ModuleBase_WidgetEditor()
81 bool ModuleBase_WidgetEditor::editedValue(double theSpinMinValue, double theSpinMaxValue,
82 double& outValue, QString& outText)
84 bool isValueAccepted = false;
86 myEditorDialog = new ModuleBase_EditorDialog(QApplication::desktop(), Qt::FramelessWindowHint);
88 QHBoxLayout* aLay = new QHBoxLayout(myEditorDialog);
89 aLay->setContentsMargins(2, 2, 2, 2);
91 ModuleBase_ParamSpinBox* anEditor = new ModuleBase_ParamSpinBox(myEditorDialog);
92 anEditor->setMinimum(theSpinMinValue);
93 anEditor->setMaximum(theSpinMaxValue);
95 QStringList aParameters;
96 ModuleBase_Tools::getParameters(aParameters);
97 anEditor->setCompletionList(aParameters);
99 if (outText.isEmpty())
100 anEditor->setValue(outValue);
102 anEditor->setText(outText);
104 aLay->addWidget(anEditor);
106 ModuleBase_Tools::setFocus(anEditor, "ModuleBase_WidgetEditor::editedValue");
107 anEditor->selectAll();
109 QPoint aPoint = QCursor::pos();
110 if (myXPosition >= 0 && myYPosition >= 0)
111 aPoint = QPoint(myXPosition, myYPosition);
113 myEditorDialog->move(aPoint);
114 isValueAccepted = myEditorDialog->exec() == QDialog::Accepted;
115 if (isValueAccepted) {
116 outText = anEditor->text();
118 double aValue = outText.toDouble(&isDouble);
121 outText = ""; // return empty string, if it's can be converted to a double
124 delete myEditorDialog;
126 return isValueAccepted;
129 bool ModuleBase_WidgetEditor::focusTo()
135 bool ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
137 bool isValueAccepted = false;
138 // we need to emit the focus in event manually in order to save the widget as an active
139 // in the property panel before the mouse leave event happens in the viewer. The module
140 // ask an active widget and change the feature visualization if the widget is not the current
141 // one. Also we need this widget as active to provide call of processEnter() applyed
142 // by operation manager to the current widget. If not, the myEditorDialog will stay opened
145 // nds: it seems, that the envents processing is not necessary anymore
146 // White while all events will be processed
147 //QApplication::processEvents();
148 double aValue = mySpinBox->value();
150 if (mySpinBox->hasVariable())
151 aText = mySpinBox->text();
153 isValueAccepted = editedValue(mySpinBox->minimum(), mySpinBox->maximum(), aValue, aText);
154 if (isValueAccepted) {
155 if (aText.isEmpty()) {
156 if (mySpinBox->hasVariable()) {
157 // variable text should be cleared before setting value as the value
158 // will not be set if there is a varable in control
159 ModuleBase_Tools::setSpinText(mySpinBox, "");
161 ModuleBase_Tools::setSpinValue(mySpinBox, aValue);
163 ModuleBase_Tools::setSpinText(mySpinBox, aText);
165 if (theSendSignals) {
166 emit valuesChanged();
167 // the focus leaves the control automatically by the Enter/Esc event
168 // it is processed in operation manager
169 //emit focusOutWidget(this);
174 ModuleBase_Tools::setFocus(mySpinBox, "ModuleBase_WidgetEditor::editedValue");
175 mySpinBox->selectAll();
176 // enter is processed, so we need not anymore emit clicked signal
177 //if (theSendSignals && !myIsEditing && isValueAccepted)
178 // emit enterClicked(this);
180 return isValueAccepted;
183 void ModuleBase_WidgetEditor::setCursorPosition(const int theX, const int theY)
189 bool ModuleBase_WidgetEditor::processEnter()
191 if (myEditorDialog) {
192 myEditorDialog->accept();
196 return ModuleBase_WidgetDoubleValue::processEnter();
199 bool ModuleBase_WidgetEditor::processEscape()
201 if (myEditorDialog) {
202 myEditorDialog->reject();
206 return ModuleBase_WidgetDoubleValue::processEscape();