From 83243e5af366a9f516c24e2b0b2a7e69cc077a3e Mon Sep 17 00:00:00 2001
From: Roman Telezhynskyi <kroluku@gmail.com>
Date: Tue, 24 May 2016 15:06:35 +0300
Subject: [PATCH] Handle case when NaN and Inf value treats like valid.

--HG--
branch : develop
---
 src/app/tape/tmainwindow.cpp                  |  12 +-
 .../valentina/dialogs/dialogincrements.cpp    |   8 ++
 src/app/valentina/xml/vpattern.cpp            |   3 +-
 src/libs/vformat/vmeasurements.cpp            |   3 +-
 src/libs/vpatterndb/vformula.cpp              |  23 +++-
 .../vtools/dialogs/tools/dialogrotation.ui    | 126 +++++++++---------
 src/libs/vtools/dialogs/tools/dialogtool.cpp  |  27 ++--
 src/libs/vtools/tools/drawTools/vdrawtool.cpp |  18 ++-
 .../vtools/visualization/visualization.cpp    |   6 +
 9 files changed, 144 insertions(+), 82 deletions(-)

diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp
index 91def815e..7e86fa957 100644
--- a/src/app/tape/tmainwindow.cpp
+++ b/src/app/tape/tmainwindow.cpp
@@ -50,6 +50,7 @@
 #include <QMessageBox>
 #include <QComboBox>
 #include <QProcess>
+#include <QtNumeric>
 
 #if defined(Q_OS_MAC)
 #include <QMimeData>
@@ -2421,9 +2422,18 @@ bool TMainWindow::EvalFormula(const QString &formula, bool fromUser, VContainer
             }
             f.replace("\n", " ");
             Calculator *cal = new Calculator();
-            const qreal result = UnitConvertor(cal->EvalFormula(data->PlainVariables(), f), mUnit, pUnit);
+            qreal result = cal->EvalFormula(data->PlainVariables(), f);
             delete cal;
 
+            if (qIsInf(result) || qIsNaN(result))
+            {
+                label->setText(tr("Error") + " (" + postfix + ").");
+                label->setToolTip(tr("Invalid value"));
+                return false;
+            }
+
+            result = UnitConvertor(result, mUnit, pUnit);
+
             label->setText(qApp->LocaleToString(result) + " " +postfix);
             label->setToolTip(tr("Value"));
             return true;
diff --git a/src/app/valentina/dialogs/dialogincrements.cpp b/src/app/valentina/dialogs/dialogincrements.cpp
index 12adb9656..9c936f882 100644
--- a/src/app/valentina/dialogs/dialogincrements.cpp
+++ b/src/app/valentina/dialogs/dialogincrements.cpp
@@ -42,6 +42,7 @@
 #include <QTableWidget>
 #include <QSettings>
 #include <QTableWidgetItem>
+#include <QtNumeric>
 
 #define DIALOG_MAX_FORMULA_HEIGHT 64
 
@@ -313,6 +314,13 @@ bool DialogIncrements::EvalIncrementFormula(const QString &formula, bool fromUse
             const qreal result = cal->EvalFormula(data->PlainVariables(), f);
             delete cal;
 
+            if (qIsInf(result) || qIsNaN(result))
+            {
+                label->setText(tr("Error") + " (" + postfix + ").");
+                label->setToolTip(tr("Invalid value"));
+                return false;
+            }
+
             label->setText(qApp->LocaleToString(result) + " " + postfix);
             label->setToolTip(tr("Value"));
             return true;
diff --git a/src/app/valentina/xml/vpattern.cpp b/src/app/valentina/xml/vpattern.cpp
index 6f19e9272..3aed8a375 100644
--- a/src/app/valentina/xml/vpattern.cpp
+++ b/src/app/valentina/xml/vpattern.cpp
@@ -51,6 +51,7 @@
 #include <QMessageBox>
 #include <QUndoStack>
 #include <QtCore/qmath.h>
+#include <QtNumeric>
 
 const QString VPattern::AttrReadOnly = QStringLiteral("readOnly");
 
@@ -2458,7 +2459,7 @@ qreal VPattern::EvalFormula(VContainer *data, const QString &formula, bool *ok)
             const qreal result = cal->EvalFormula(data->PlainVariables(), f);
             delete cal;
 
-            *ok = true;
+            (qIsInf(result) || qIsNaN(result)) ? *ok = false : *ok = true;
             return result;
         }
         catch (qmu::QmuParserError &e)
diff --git a/src/libs/vformat/vmeasurements.cpp b/src/libs/vformat/vmeasurements.cpp
index bf77ec920..de4e0402a 100644
--- a/src/libs/vformat/vmeasurements.cpp
+++ b/src/libs/vformat/vmeasurements.cpp
@@ -34,6 +34,7 @@
 #include "../qmuparser/qmutokenparser.h"
 
 #include <QDate>
+#include <QtNumeric>
 
 const QString VMeasurements::TagVST              = QStringLiteral("vst");
 const QString VMeasurements::TagVIT              = QStringLiteral("vit");
@@ -882,7 +883,7 @@ qreal VMeasurements::EvalFormula(VContainer *data, const QString &formula, bool
             const qreal result = cal->EvalFormula(data->PlainVariables(), f);
             delete cal;
 
-            *ok = true;
+            (qIsInf(result) || qIsNaN(result)) ? *ok = false : *ok = true;
             return result;
         }
         catch (qmu::QmuParserError &e)
diff --git a/src/libs/vpatterndb/vformula.cpp b/src/libs/vpatterndb/vformula.cpp
index 5e06af6c1..811b2a4b8 100644
--- a/src/libs/vpatterndb/vformula.cpp
+++ b/src/libs/vpatterndb/vformula.cpp
@@ -32,7 +32,9 @@
 #include "../vmisc/vabstractapplication.h"
 #include "../vmisc/vsettings.h"
 #include "vtranslatevars.h"
+
 #include <QDebug>
+#include <QtNumeric>
 
 //VFormula
 //---------------------------------------------------------------------------------------------------------------------
@@ -237,18 +239,27 @@ void VFormula::Eval()
             const qreal result = cal->EvalFormula(data->PlainVariables(), expression);
             delete cal;
 
-            //if result equal 0
-            if (checkZero && qFuzzyIsNull(result))
+            if (qIsInf(result) || qIsNaN(result))
             {
-                value = QString("0");
+                value = QString(tr("Error"));
                 _error = true;
                 dValue = 0;
             }
             else
             {
-                dValue = result;
-                value = QString(qApp->LocaleToString(result) + " " + postfix);
-                _error = false;
+                //if result equal 0
+                if (checkZero && qFuzzyIsNull(result))
+                {
+                    value = QString("0");
+                    _error = true;
+                    dValue = 0;
+                }
+                else
+                {
+                    dValue = result;
+                    value = QString(qApp->LocaleToString(result) + " " + postfix);
+                    _error = false;
+                }
             }
         }
         catch (qmu::QmuParserError &e)
diff --git a/src/libs/vtools/dialogs/tools/dialogrotation.ui b/src/libs/vtools/dialogs/tools/dialogrotation.ui
index 0dba13478..95a089b7d 100644
--- a/src/libs/vtools/dialogs/tools/dialogrotation.ui
+++ b/src/libs/vtools/dialogs/tools/dialogrotation.ui
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>309</width>
+    <width>285</width>
     <height>189</height>
    </rect>
   </property>
@@ -18,68 +18,6 @@
     <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout_6">
-     <item>
-      <widget class="QPlainTextEdit" name="plainTextEditFormula">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="maximumSize">
-        <size>
-         <width>16777215</width>
-         <height>28</height>
-        </size>
-       </property>
-       <property name="toolTip">
-        <string>Calulation</string>
-       </property>
-       <property name="tabChangesFocus">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="pushButtonGrowLength">
-       <property name="maximumSize">
-        <size>
-         <width>18</width>
-         <height>18</height>
-        </size>
-       </property>
-       <property name="sizeIncrement">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-       <property name="toolTip">
-        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-       </property>
-       <property name="text">
-        <string notr="true"/>
-       </property>
-       <property name="icon">
-        <iconset theme="go-down">
-         <normaloff/>
-        </iconset>
-       </property>
-       <property name="iconSize">
-        <size>
-         <width>16</width>
-         <height>16</height>
-        </size>
-       </property>
-       <property name="flat">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item alignment="Qt::AlignLeft">
@@ -199,6 +137,68 @@
      </item>
     </layout>
    </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <item>
+      <widget class="QPlainTextEdit" name="plainTextEditFormula">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>28</height>
+        </size>
+       </property>
+       <property name="toolTip">
+        <string>Calulation</string>
+       </property>
+       <property name="tabChangesFocus">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="pushButtonGrowLength">
+       <property name="maximumSize">
+        <size>
+         <width>18</width>
+         <height>18</height>
+        </size>
+       </property>
+       <property name="sizeIncrement">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="toolTip">
+        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show full calculation in message box&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+       </property>
+       <property name="text">
+        <string notr="true"/>
+       </property>
+       <property name="icon">
+        <iconset theme="go-down">
+         <normaloff/>
+        </iconset>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>16</width>
+         <height>16</height>
+        </size>
+       </property>
+       <property name="flat">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
    <item>
     <layout class="QFormLayout" name="formLayout">
      <item row="0" column="0">
diff --git a/src/libs/vtools/dialogs/tools/dialogtool.cpp b/src/libs/vtools/dialogs/tools/dialogtool.cpp
index c288f9fb8..9b0c1f080 100644
--- a/src/libs/vtools/dialogs/tools/dialogtool.cpp
+++ b/src/libs/vtools/dialogs/tools/dialogtool.cpp
@@ -49,6 +49,7 @@
 #include <QSettings>
 #include <QPushButton>
 #include <QDoubleSpinBox>
+#include <QtNumeric>
 
 Q_LOGGING_CATEGORY(vDialog, "v.dialog")
 
@@ -452,21 +453,31 @@ qreal DialogTool::Eval(const QString &text, bool &flag, QLabel *label, const QSt
             result = cal->EvalFormula(data->PlainVariables(), formula);
             delete cal;
 
-            //if result equal 0
-            if (checkZero && qFuzzyIsNull(result))
+            if (qIsInf(result) || qIsNaN(result))
             {
                 flag = false;
                 ChangeColor(labelEditFormula, Qt::red);
                 label->setText(tr("Error") + " (" + postfix + ")");
-                label->setToolTip(tr("Value can't be 0"));
+                label->setToolTip(tr("Invalid value"));
             }
             else
             {
-                label->setText(qApp->LocaleToString(result) + " " +postfix);
-                flag = true;
-                ChangeColor(labelEditFormula, okColor);
-                label->setToolTip(tr("Value"));
-                emit ToolTip("");
+                //if result equal 0
+                if (checkZero && qFuzzyIsNull(result))
+                {
+                    flag = false;
+                    ChangeColor(labelEditFormula, Qt::red);
+                    label->setText(tr("Error") + " (" + postfix + ")");
+                    label->setToolTip(tr("Value can't be 0"));
+                }
+                else
+                {
+                    label->setText(qApp->LocaleToString(result) + " " +postfix);
+                    flag = true;
+                    ChangeColor(labelEditFormula, okColor);
+                    label->setToolTip(tr("Value"));
+                    emit ToolTip("");
+                }
             }
         }
         catch (qmu::QmuParserError &e)
diff --git a/src/libs/vtools/tools/drawTools/vdrawtool.cpp b/src/libs/vtools/tools/drawTools/vdrawtool.cpp
index bd4596537..29ac0a7c3 100644
--- a/src/libs/vtools/tools/drawTools/vdrawtool.cpp
+++ b/src/libs/vtools/tools/drawTools/vdrawtool.cpp
@@ -36,6 +36,8 @@
 #include "../../undocommands/savetooloptions.h"
 #include "../../../ifc/exception/vexceptionundo.h"
 
+#include <QtNumeric>
+
 qreal VDrawTool::factor = 1;
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -295,10 +297,15 @@ qreal VDrawTool::CheckFormula(const quint32 &toolId, QString &formula, VContaine
         cal = new Calculator();
         result = cal->EvalFormula(data->PlainVariables(), formula);
         delete cal;
+
+        if (qIsInf(result) || qIsNaN(result))
+        {
+            qDebug() << "Invalid the formula value";
+            return 0;
+        }
     }
     catch (qmu::QmuParserError &e)
     {
-        //Q_UNUSED(e)
         qDebug() << "\nMath parser error:\n"
                  << "--------------------------------------\n"
                  << "Message:     " << e.GetMsg()  << "\n"
@@ -328,8 +335,15 @@ qreal VDrawTool::CheckFormula(const quint32 &toolId, QString &formula, VContaine
                             delete dialog;
                             Calculator *cal1 = new Calculator();
                             result = cal1->EvalFormula(data->PlainVariables(), formula);
-                            delete cal1; /* Here can be memory leak, but dialog already check this formula and
+                            delete cal1; /* Here can be memory leak, but dialog already checked this formula and
                                             probability very low. */
+
+                            if (qIsInf(result) || qIsNaN(result))
+                            {
+                                qDebug() << "Invalid the formula value";
+                                return 0;
+                            }
+
                             break;
                         }
                         else
diff --git a/src/libs/vtools/visualization/visualization.cpp b/src/libs/vtools/visualization/visualization.cpp
index cc7c7c3aa..04292b85f 100644
--- a/src/libs/vtools/visualization/visualization.cpp
+++ b/src/libs/vtools/visualization/visualization.cpp
@@ -32,6 +32,7 @@
 #include "../../vpatterndb/vtranslatevars.h"
 
 #include <QGraphicsEllipseItem>
+#include <QtNumeric>
 
 Q_LOGGING_CATEGORY(vVis, "v.visualization")
 
@@ -160,6 +161,11 @@ qreal Visualization::FindVal(const QString &expression, const QHash<QString, qre
             Calculator *cal = new Calculator();
             val = cal->EvalFormula(vars, formula);
             delete cal;
+
+            if (qIsInf(val) || qIsNaN(val))
+            {
+                val = 0;
+            }
         }
         catch (qmu::QmuParserError &e)
         {