Resolved issue #862. Force Valentina to immediately terminate if a pattern

contains a parsing warning.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2018-07-13 16:18:04 +03:00
parent 6c19748802
commit fd85efacd9
27 changed files with 139 additions and 32 deletions

View File

@ -50,6 +50,7 @@
- [#819] Use OpenGL as render for view.
- [#826] New Feature. Add and remove items to groups from the context menu.
- Mouse double click zoom fit best current pattern piece.
- [#862] Force Valentina to immediately terminate if a pattern contains a parsing warning.
# Version 0.5.1 (unreleased)
- [#683] Tool Seam allowance's dialog is off screen on small resolutions.

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "10 December, 2017" "valentina man page"
.TH valentina 1 "13 July, 2018" "valentina man page"
.SH NAME
Valentina \- Pattern making program.
.SH SYNOPSIS
@ -201,7 +201,9 @@ The path to output destination folder. By default the directory at which the app
.BR "*" " Descending area = 2."
.RE
.IP "-t, --test"
Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq.
.RB "Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq."
.IP "--pedantic"
.RB "Make all parsing warnings into errors. Have effect only in console mode. Use to force Valentina to immediately terminate if a pattern contains a parsing warning."
.IP "--no-scaling"
.RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable."
.IP "--csvWithHeader"

View File

@ -1,6 +1,6 @@
.\" Manpage for valentina.
.\" Contact dismine@gmail.com to correct errors.
.TH valentina 1 "10 December, 2017" "valentina man page"
.TH valentina 1 "13 July, 2018" "valentina man page"
.SH NAME
Valentina \- Pattern making program.
.SH SYNOPSIS
@ -201,7 +201,9 @@ The path to output destination folder. By default the directory at which the app
.BR "*" " Descending area = 2."
.RE
.IP "-t, --test"
Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq.
.RB "Run the program in a test mode. The program in this mode loads a single pattern file and silently quit without showing the main window. The key have priority before key \*(lqbasename\*(rq."
.IP "--pedantic"
.RB "Make all parsing warnings into errors. Have effect only in console mode. Use to force Valentina to immediately terminate if a pattern contains a parsing warning."
.IP "--no-scaling"
.RB "Disable high dpi scaling. Call this option if has problem with scaling (by default scaling enabled). Alternatively you can use the QT_AUTO_SCREEN_SCALE_FACTOR=0 environment variable."
.IP "--csvWithHeader"

View File

@ -696,6 +696,12 @@ bool VApplication::IsAppInGUIMode() const
return IsGUIMode();
}
//---------------------------------------------------------------------------------------------------------------------
bool VApplication::IsPedantic() const
{
return (VCommandLine::instance != nullptr) && VCommandLine::instance->IsPedantic();
}
//---------------------------------------------------------------------------------------------------------------------
const VCommandLinePtr VApplication::CommandLine() const
{

View File

@ -72,6 +72,7 @@ public:
bool static IsGUIMode();
virtual bool IsAppInGUIMode() const override;
virtual bool IsPedantic() const override;
virtual void OpenSettings() override;
VSettings *ValentinaSettings();

View File

@ -268,6 +268,13 @@ void VCommandLine::InitOptions(VCommandLineOptions &options, QMap<QString, int>
"showing the main window. The key have priority before key '%1'.")
.arg(LONG_OPTION_BASENAME)));
optionsIndex.insert(LONG_OPTION_PENDANTIC, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_PENDANTIC,
translate("VCommandLine",
"Make all parsing warnings into errors. Have effect only in "
"console mode. Use to force Valentina to immediately terminate if "
"a pattern contains a parsing warning.")));
optionsIndex.insert(LONG_OPTION_NO_HDPI_SCALING, index++);
options.append(new QCommandLineOption(QStringList() << LONG_OPTION_NO_HDPI_SCALING,
translate("VCommandLine", "Disable high dpi scaling. Call this option if has "
@ -599,6 +606,19 @@ bool VCommandLine::IsTestModeEnabled() const
return r;
}
//---------------------------------------------------------------------------------------------------------------------
bool VCommandLine::IsPedantic() const
{
if (IsGuiEnabled())
{
return false; // Doesn't work in GUI mode
}
else
{
return parser.isSet(*optionsUsed.value(optionsIndex.value(LONG_OPTION_PENDANTIC)));
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VCommandLine::IsNoScalingEnabled() const
{

View File

@ -56,6 +56,10 @@ public:
//case test mode enabled
bool IsTestModeEnabled() const;
//@brief Make all parsing warnings into errors. Have effect only in console mode. Use to force Valentina to
//immediately terminate if a pattern contains a parsing warning.
bool IsPedantic() const;
bool IsNoScalingEnabled() const;
//@brief tests if user enabled export from cmd, throws exception if not exactly 1 input VAL file supplied in case

View File

@ -3093,7 +3093,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}
@ -3104,7 +3104,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}
@ -3115,7 +3115,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}
@ -3126,7 +3126,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}
@ -3137,7 +3137,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}
@ -3147,7 +3147,7 @@ void MainWindow::FullParseFile()
SetEnabledGUI(false);
if (not VApplication::IsGUIMode())
{
qApp->exit(V_EX_NOINPUT);
qApp->exit(V_EX_DATAERR);
}
return;
}

View File

@ -49,6 +49,11 @@ VExceptionObjectError::VExceptionObjectError(const QString &what, const QDomElem
lineNumber = domElement.lineNumber();
}
//---------------------------------------------------------------------------------------------------------------------
VExceptionObjectError::VExceptionObjectError(const QString &what)
:VException(what), tagText(QString()), tagName(QString()), lineNumber(-1)
{}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief VExceptionObjectError copy constructor

View File

@ -45,6 +45,7 @@ class VExceptionObjectError : public VException
{
public:
VExceptionObjectError(const QString &what, const QDomElement &domElement);
VExceptionObjectError(const QString &what);
VExceptionObjectError(const VExceptionObjectError &e);
VExceptionObjectError &operator=(const VExceptionObjectError &e);
virtual ~VExceptionObjectError() V_NOEXCEPT_EXPR (true) Q_DECL_EQ_DEFAULT;

View File

@ -90,6 +90,8 @@ const QString SINGLE_OPTION_GROUPPING = QStringLiteral("g");
const QString LONG_OPTION_TEST = QStringLiteral("test");
const QString SINGLE_OPTION_TEST = QStringLiteral("t");
const QString LONG_OPTION_PENDANTIC = QStringLiteral("pedantic");
const QString LONG_OPTION_GRADATIONSIZE = QStringLiteral("gsize");
const QString SINGLE_OPTION_GRADATIONSIZE = QStringLiteral("x");

View File

@ -87,6 +87,8 @@ extern const QString SINGLE_OPTION_GROUPPING;
extern const QString LONG_OPTION_TEST;
extern const QString SINGLE_OPTION_TEST;
extern const QString LONG_OPTION_PENDANTIC;
extern const QString LONG_OPTION_GRADATIONSIZE;
extern const QString SINGLE_OPTION_GRADATIONSIZE;

View File

@ -235,6 +235,12 @@ QUndoStack *VAbstractApplication::getUndoStack() const
return undoStack;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractApplication::IsPedantic() const
{
return false;
}
//---------------------------------------------------------------------------------------------------------------------
/**
* @brief ClearMessage helps to clear a message string from standard Qt function.

View File

@ -107,6 +107,7 @@ public:
QUndoStack *getUndoStack() const;
virtual bool IsAppInGUIMode()const =0;
virtual bool IsPedantic() const;
QString GetPatternPath() const;
void SetPatternPath(const QString &value);

View File

@ -140,7 +140,8 @@ int AbstractTest::Run(int exit, const QString &program, const QStringList &argum
if (process->exitCode() != exit)
{
error = QStringLiteral("Unexpected finish.\n%1").arg(QString(process->readAllStandardError()));
error = QStringLiteral("Unexpected finish. Exit code: %1\n%2").arg(process->exitCode())
.arg(QString(process->readAllStandardError()));
return process->exitCode();
}

View File

@ -43,6 +43,7 @@
#include "../../../../../dialogs/tools/dialogcurveintersectaxis.h"
#include "../ifc/ifcdef.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../qmuparser/qmudef.h"
#include "../toolcut/vtoolcutsplinepath.h"
#include "../vgeometry/vabstractcubicbezier.h"
@ -138,9 +139,10 @@ VToolCurveIntersectAxis *VToolCurveIntersectAxis::Create(VToolCurveIntersectAxis
if (not success)
{
qWarning() << tr("Error calculating point '%1'. There is no intersection with curve '%2' and axis through "
"point '%3' with angle %4°")
const QString errorMsg = tr("Error calculating point '%1'. There is no intersection with curve '%2' and axis"
" through point '%3' with angle %4°")
.arg(initData.name, curve->name(), basePoint->name()).arg(angle);
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
const qreal segLength = curve->GetLengthByPoint(fPoint);

View File

@ -40,6 +40,7 @@
#include "../../../../../visualization/visualization.h"
#include "../../../../../visualization/line/vistoollineintersectaxis.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vpointf.h"
#include "../vmisc/vabstractapplication.h"
@ -129,9 +130,10 @@ VToolLineIntersectAxis *VToolLineIntersectAxis::Create(VToolLineIntersectAxisIni
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Line (%2;%3) doesn't have intersection with axis through "
"point '%4' and angle %5°")
const QString errorMsg = tr("Error calculating point '%1'. Line (%2;%3) doesn't have intersection with axis "
"through point '%4' and angle %5°")
.arg(initData.name, firstPoint->name(), secondPoint->name(), basePoint->name()).arg(axis.angle());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my);

View File

@ -40,6 +40,7 @@
#include "../../../../visualization/visualization.h"
#include "../../../../visualization/line/vistoolpointfromarcandtangent.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/varc.h"
#include "../vgeometry/vgobject.h"
@ -118,8 +119,9 @@ VToolPointFromArcAndTangent *VToolPointFromArcAndTangent::Create(VToolPointFromA
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Tangent to arc '%2' from point '%3' cannot be found")
const QString errorMsg = tr("Error calculating point '%1'. Tangent to arc '%2' from point '%3' cannot be found")
.arg(initData.name, arc.name(), tPoint.name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -39,6 +39,7 @@
#include "../../../../visualization/visualization.h"
#include "../../../../visualization/line/vistoolpointfromcircleandtangent.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/xml/vdomdocument.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vgobject.h"
@ -123,9 +124,11 @@ VToolPointFromCircleAndTangent *VToolPointFromCircleAndTangent::Create(VToolPoin
initData.crossPoint, &point);
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Tangent to circle with center '%2' and radius '%3' from "
"point '%4' cannot be found")
const QString errorMsg = tr("Error calculating point '%1'. Tangent to circle with center '%2' and radius '%3' "
"from point '%4' cannot be found")
.arg(initData.name, cPoint.name()).arg(radius).arg(tPoint.name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -42,6 +42,7 @@
#include "../../../../visualization/visualization.h"
#include "../../../../visualization/line/vistoolpointofcontact.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/xml/vdomdocument.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vgobject.h"
@ -212,9 +213,10 @@ VToolPointOfContact* VToolPointOfContact::Create(VToolPointOfContactInitData &in
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Circle with center '%2' and radius '%3' doesn't have "
const QString errorMsg = tr("Error calculating point '%1'. Circle with center '%2' and radius '%3' doesn't have "
"intersection with line (%4;%5)")
.arg(initData.name, centerP->name()).arg(result).arg(firstP->name(), secondP->name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(fPoint, initData.name, initData.mx, initData.my);

View File

@ -38,6 +38,7 @@
#include "../../../../dialogs/tools/dialogpointofintersectionarcs.h"
#include "../../../../visualization/line/vistoolpointofintersectionarcs.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/varc.h"
#include "../vgeometry/vgobject.h"
@ -117,8 +118,9 @@ VToolPointOfIntersectionArcs *VToolPointOfIntersectionArcs::Create(VToolPointOfI
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Arcs '%2' and '%3' have no point of intersection")
const QString errorMsg = tr("Error calculating point '%1'. Arcs '%2' and '%3' have no point of intersection")
.arg(initData.name, firstArc->name(), secondArc->name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -39,6 +39,7 @@
#include "../../../../visualization/visualization.h"
#include "../../../../visualization/line/vistoolpointofintersectioncircles.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/xml/vdomdocument.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vgobject.h"
@ -130,8 +131,9 @@ VToolPointOfIntersectionCircles::Create(VToolPointOfIntersectionCirclesInitData
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Circles with centers in points '%2' and '%3' have no point "
"of intersection").arg(initData.name, c1Point.name(), c2Point.name());
const QString errorMsg = tr("Error calculating point '%1'. Circles with centers in points '%2' and '%3' have "
"no point of intersection").arg(initData.name, c1Point.name(), c2Point.name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -40,6 +40,7 @@
#include "../../../../visualization/path/../visualization.h"
#include "../../../../visualization/path/vistoolpointofintersectioncurves.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vabstractcurve.h"
#include "../vgeometry/vgobject.h"
@ -121,8 +122,9 @@ VToolPointOfIntersectionCurves *VToolPointOfIntersectionCurves::Create(VToolPoin
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Curves '%2' and '%3' have no point of intersection")
const QString errorMsg = tr("Error calculating point '%1'. Curves '%2' and '%3' have no point of intersection")
.arg(initData.name, curve1->name(), curve2->name());
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -41,6 +41,7 @@
#include "../../../../visualization/visualization.h"
#include "../../../../visualization/line/vistooltriangle.h"
#include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionobjecterror.h"
#include "../ifc/ifcdef.h"
#include "../vgeometry/vgobject.h"
#include "../vgeometry/vpointf.h"
@ -143,8 +144,9 @@ VToolTriangle* VToolTriangle::Create(VToolTriangleInitData initData)
if (not success)
{
qWarning() << tr("Error calculating point '%1'. Point of intersection cannot be finded")
const QString errorMsg = tr("Error calculating point '%1'. Point of intersection cannot be finded")
.arg(initData.name);
qApp->IsPedantic() ? throw VExceptionObjectError(errorMsg) : qWarning() << errorMsg;
}
VPointF *p = new VPointF(point, initData.name, initData.mx, initData.my);

View File

@ -221,7 +221,8 @@ VALENTINA_TEST_FILES += \
tst_valentina/issue_256_wrong.vit \
tst_valentina/issue_256_correct.vst \
tst_valentina/issue_256_wrong.vit \
tst_valentina/wrong_formula.val
tst_valentina/wrong_formula.val \
tst_valentina/test_pedantic.val
COLLECTION_FILES += \
$${PWD}/../../app/share/tables/multisize/GOST_man_ru.vst \

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<pattern>
<!--Pattern created with Valentina v0.6.0.0a (https://valentinaproject.bitbucket.io/).-->
<version>0.7.8</version>
<unit>cm</unit>
<description/>
<notes/>
<measurements/>
<increments/>
<previewCalculations/>
<draw name="Выкройка 1">
<calculation>
<point id="1" mx="0.132292" my="0.264583" name="А" showLabel="true" type="single" x="0.79375" y="1.05833"/>
<point angle="0.0634838" basePoint="1" id="2" length="7.97917" lineColor="black" mx="0.132292" my="0.264583" name="А1" showLabel="true" type="endLine" typeLine="hair"/>
<arc aScale="0" angle1="270" angle2="90" center="1" color="black" id="3" penStyle="hair" radius="3" type="simple"/>
<arc aScale="0" angle1="0" angle2="250" center="2" color="black" id="4" penStyle="hair" radius="3" type="simple"/>
<point crossPoint="1" firstArc="3" id="5" mx="-3.69639" my="-1.1581" name="А2" secondArc="4" showLabel="true" type="pointOfIntersectionArcs"/>
</calculation>
<modeling/>
<details/>
<groups/>
</draw>
</pattern>

View File

@ -84,20 +84,29 @@ void TST_ValentinaCommandLine::initTestCase()
void TST_ValentinaCommandLine::OpenPatterns_data() const
{
QTest::addColumn<QString>("file");
QTest::addColumn<QString>("arguments");
QTest::addColumn<int>("exitCode");
// The file doesn't exist!
QTest::newRow("Send wrong path to a file") << "wrongPath.val"
<< "--test"
<< V_EX_NOINPUT;
QTest::newRow("Measurement independent empty file") << "empty.val"
<< "--test"
<< V_EX_OK;
QTest::newRow("File with invalid object type") << "wrong_obj_type.val"
<< "--test"
<< V_EX_NOINPUT;
QTest::newRow("Empty text VAL file") << "txt.val"
<< "--test"
<< V_EX_NOINPUT;
QTest::newRow("Pattern with a warning") << "test_pedantic.val"
<< "--test;;--pedantic"
<< V_EX_DATAERR;
}
//---------------------------------------------------------------------------------------------------------------------
@ -105,11 +114,12 @@ void TST_ValentinaCommandLine::OpenPatterns_data() const
void TST_ValentinaCommandLine::OpenPatterns()
{
QFETCH(QString, file);
QFETCH(QString, arguments);
QFETCH(int, exitCode);
QString error;
const QString tmp = QCoreApplication::applicationDirPath() + QDir::separator() + *tmpTestFolder;
const int exit = Run(exitCode, ValentinaPath(), QStringList() << "--test"
const int exit = Run(exitCode, ValentinaPath(), QStringList() << arguments.split(";;")
<< tmp + QDir::separator() + file, error);
QVERIFY2(exit == exitCode, qUtf8Printable(error));