Salome HOME
[bos #40650][CEA 33012] Beta Law distribution: added a new type of distribution for...
[modules/smesh.git] / src / SMESHGUI / SMESHGUI_SpinBoxForbiddendRange.cxx
diff --git a/src/SMESHGUI/SMESHGUI_SpinBoxForbiddendRange.cxx b/src/SMESHGUI/SMESHGUI_SpinBoxForbiddendRange.cxx
new file mode 100644 (file)
index 0000000..bc0a54c
--- /dev/null
@@ -0,0 +1,197 @@
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// 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
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_SpinBoxForbiddendRange.cxx
+// Author : Konstantin Leontev, Open CASCADE S.A.S.
+// SMESH includes
+//
+#include "SMESHGUI_SpinBoxForbiddendRange.h"
+
+#include <QToolTip>
+
+#include "utilities.h"
+
+
+//=================================================================================
+// class    : SMESHGUI_SpinBoxForbiddendRange()
+// purpose  : constructor
+//=================================================================================
+SMESHGUI_SpinBoxForbiddendRange::SMESHGUI_SpinBoxForbiddendRange(QWidget* parent)
+  : SMESHGUI_SpinBox(parent), forbiddenMin(0.0), forbiddenMax(1.0)
+{
+  // This property allows to return QValidator::Invalid from QtxDoubleSpinBox::validate()
+  // for any values outside of the min/max range.
+  // Otherwise a user could type any intermediate value.
+  setProperty("strict_validity_check", true);
+}
+
+//=================================================================================
+// function : ~SMESHGUI_SpinBoxForbiddendRange()
+// purpose  : destructor
+//=================================================================================
+SMESHGUI_SpinBoxForbiddendRange::~SMESHGUI_SpinBoxForbiddendRange()
+{
+}
+
+//=================================================================================
+// function : stepBy()
+// purpose  : Validates value in ranges on each step
+//=================================================================================
+void SMESHGUI_SpinBoxForbiddendRange::stepBy(const int steps)
+{
+  double const newValue = value() + (steps * singleStep());
+  double const validatedValue = GetValueInRange(newValue);
+
+  setValue(validatedValue);
+}
+
+//=================================================================================
+// function : valueFromText()
+// purpose  : Validates value entered by user 
+//=================================================================================
+double SMESHGUI_SpinBoxForbiddendRange::valueFromText(QString const& text) const
+{
+  double const newValue = SMESHGUI_SpinBox::valueFromText(text);
+  return GetValueInRange(newValue);
+}
+
+QValidator::State SMESHGUI_SpinBoxForbiddendRange::validate(QString& text, int& pos) const
+{
+  // Do parent's min/max and all other validation first
+  const QValidator::State res = SMESHGUI_SpinBox::validate(text, pos);
+  if (res != QValidator::Acceptable)
+    return res;
+
+  // Now we know that we have a valid numeric value in the text
+  // that we can check against forbidden range.
+  bool ok = false;
+  const double inputValue = text.toDouble(&ok);
+
+  // Return intermediate to allow a user input any value.
+  // If press ok button, it will be checked again with checkRange() call.
+  const QValidator::State state = ok && IsValueInRange(inputValue) ?
+    QValidator::Acceptable : QValidator::Intermediate;
+
+  showValidationToolTip(state);
+
+  return state;
+}
+
+//=================================================================================
+// function : SetForbiddenRange()
+// purpose  : Sets min and max values for forbidden range
+//=================================================================================
+void SMESHGUI_SpinBoxForbiddendRange::SetForbiddenRange(const double min, const double max)
+{
+  forbiddenMin = min;
+  forbiddenMax = max;
+}
+
+//=================================================================================
+// function : checkRange()
+// purpose  : adds checking against forbidden range to the parent's inmplementation
+//=================================================================================
+bool SMESHGUI_SpinBoxForbiddendRange::checkRange(const double value) const
+{
+  return SalomeApp_DoubleSpinBox::checkRange(value) && IsValueInRange(value);
+}
+
+//=================================================================================
+// function : IsValueInRange()
+// purpose  : Validates a given value against forbidden range
+//=================================================================================
+bool SMESHGUI_SpinBoxForbiddendRange::IsValueInRange(const double inputValue) const
+{
+  // A given value must be outside of [forbiddenMin, forbiddenMax] scope
+  return inputValue < forbiddenMin || inputValue > forbiddenMax;
+}
+
+//=================================================================================
+// function : GetValueInRange()
+// purpose  : Validates value considering forbidden range
+//=================================================================================
+double SMESHGUI_SpinBoxForbiddendRange::GetValueInRange(const double inputValue) const
+{
+  // Check if a given value is outside of [forbiddenMin, forbiddenMax] scope
+  if (IsValueInRange(inputValue))
+    return inputValue;
+
+  const double curValue = value();
+  const double step = SMESHGUI_SpinBox::singleStep();
+
+  // Find the nearest value outside of forbidden range
+  if (inputValue > curValue)
+    return forbiddenMax + step;
+  else
+    return forbiddenMin - step;
+}
+
+//=================================================================================
+// function : showValidationToolTip()
+// purpose  : Shows tooltip with a valid range
+//=================================================================================
+void SMESHGUI_SpinBoxForbiddendRange::showValidationToolTip(const QValidator::State state) const
+{
+  if (state == QValidator::Acceptable)
+  {
+    QToolTip::hideText();
+    return;
+  }
+
+  // All the rest is an edited copy from SalomeApp_DoubleSpinBox::validate()
+
+  // Get position and min/max values
+  const QPoint pos(size().width(), 0.);
+  const QPoint globalPos = mapToGlobal(pos);
+  const QString minVal = textFromValue(minimum());
+  const QString maxVal = textFromValue(maximum());
+
+  // Same stuff as in QtxDoubleSpinBox::textFromValue()
+  int digits = getPrecision();
+
+  // For 'g' format, max. number of digits after the decimal point is getPrecision() - 1
+  // See also QtxDoubleSpinBox::validate()
+  if (digits < 0)
+    digits = qAbs(digits) - 1;
+
+  QString msg = QString(tr("VALID_RANGE_NOVAR_MSG")).
+    arg(minVal).
+    arg(forbiddenMin).
+    arg(forbiddenMax).
+    arg(maxVal).
+    arg(digits);
+
+  // It is not possible to hide and shortly afterwards reshow a tooltip
+  // with the same text because of some interference between the internal hideTimer of the tooltip and
+  // the QToolTip::showText(). As a result, the tooltip does not persist - it disappears immediately.
+  // If we are here, then QToolTip::hideText() was just called from the parent.
+  // So, below is a workaround that changes the text and lets the tooltip stay in place.
+  toolTipFlag = !toolTipFlag;
+  if (toolTipFlag)
+  {
+    msg.append(" ");
+  }
+
+  // Show tooltip
+  QToolTip::showText(globalPos, msg, const_cast<SMESHGUI_SpinBoxForbiddendRange*>(this));
+}