2015-06-12 10:55:44 +02:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file def.cpp
|
|
|
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
|
|
|
** @date 11 6, 2015
|
|
|
|
**
|
|
|
|
** @brief
|
|
|
|
** @copyright
|
2017-10-05 11:20:01 +02:00
|
|
|
** This source code is part of the Valentina project, a pattern making
|
2015-06-12 10:55:44 +02:00
|
|
|
** program, whose allow create and modeling patterns of clothing.
|
|
|
|
** Copyright (C) 2015 Valentina project
|
|
|
|
** <https://bitbucket.org/dismine/valentina> All Rights Reserved.
|
|
|
|
**
|
|
|
|
** Valentina is free software: you can redistribute it and/or modify
|
|
|
|
** it under the terms of the GNU General Public License as published by
|
|
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** Valentina 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 General Public License for more details.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
**
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#include "def.h"
|
|
|
|
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QChar>
|
|
|
|
#include <QColor>
|
2015-10-16 19:26:05 +02:00
|
|
|
#include <QComboBox>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QCursor>
|
2015-10-31 13:41:52 +01:00
|
|
|
#include <QDir>
|
2017-04-12 14:50:48 +02:00
|
|
|
#include <QDirIterator>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QGuiApplication>
|
|
|
|
#include <QImage>
|
|
|
|
#include <QLatin1Char>
|
|
|
|
#include <QList>
|
|
|
|
#include <QMap>
|
|
|
|
#include <QMessageLogger>
|
|
|
|
#include <QObject>
|
|
|
|
#include <QPixmap>
|
2015-11-09 12:33:36 +01:00
|
|
|
#include <QPrinterInfo>
|
2016-06-18 15:57:07 +02:00
|
|
|
#include <QProcess>
|
2016-08-08 13:44:49 +02:00
|
|
|
#include <QRgb>
|
|
|
|
#include <QStaticStringData>
|
|
|
|
#include <QStringData>
|
|
|
|
#include <QStringDataPtr>
|
|
|
|
#include <QtDebug>
|
2017-08-01 13:35:48 +02:00
|
|
|
#include <QPixmapCache>
|
|
|
|
#include <QGraphicsItem>
|
2018-03-14 14:39:15 +01:00
|
|
|
#include <QGlobalStatic>
|
2016-08-08 13:44:49 +02:00
|
|
|
|
|
|
|
#include "vabstractapplication.h"
|
2020-01-07 13:21:47 +01:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
2020-01-07 08:45:26 +01:00
|
|
|
# include "vdatastreamenum.h"
|
|
|
|
#endif
|
2019-07-01 12:25:03 +02:00
|
|
|
#include "../ifc/exception/vexception.h"
|
2015-06-15 15:47:44 +02:00
|
|
|
|
2017-10-11 12:51:06 +02:00
|
|
|
const qreal defCurveApproximationScale = 0.5;
|
2019-05-27 17:51:55 +02:00
|
|
|
const qreal minCurveApproximationScale = 0.2;
|
2017-10-11 12:51:06 +02:00
|
|
|
const qreal maxCurveApproximationScale = 10.0;
|
|
|
|
|
2019-05-08 18:22:55 +02:00
|
|
|
const int minLabelFontSize = 5;
|
|
|
|
const int maxLabelFontSize = 100;
|
|
|
|
|
2015-06-12 10:55:44 +02:00
|
|
|
//functions
|
qmuparser: added triangular functions that work with degree
new functions are: degTorad, radTodeg, , sinD, cosD, tanD, asinD, acosD , atanD, sinhD, coshD , tanhD, asinhD, acoshD, atanhD
--HG--
branch : feature
2017-02-27 20:42:35 +01:00
|
|
|
const QString degTorad_F = QStringLiteral("degTorad");
|
|
|
|
const QString radTodeg_F = QStringLiteral("radTodeg");
|
2015-06-12 10:55:44 +02:00
|
|
|
const QString sin_F = QStringLiteral("sin");
|
|
|
|
const QString cos_F = QStringLiteral("cos");
|
|
|
|
const QString tan_F = QStringLiteral("tan");
|
|
|
|
const QString asin_F = QStringLiteral("asin");
|
|
|
|
const QString acos_F = QStringLiteral("acos");
|
|
|
|
const QString atan_F = QStringLiteral("atan");
|
|
|
|
const QString sinh_F = QStringLiteral("sinh");
|
|
|
|
const QString cosh_F = QStringLiteral("cosh");
|
|
|
|
const QString tanh_F = QStringLiteral("tanh");
|
|
|
|
const QString asinh_F = QStringLiteral("asinh");
|
|
|
|
const QString acosh_F = QStringLiteral("acosh");
|
|
|
|
const QString atanh_F = QStringLiteral("atanh");
|
qmuparser: added triangular functions that work with degree
new functions are: degTorad, radTodeg, , sinD, cosD, tanD, asinD, acosD , atanD, sinhD, coshD , tanhD, asinhD, acoshD, atanhD
--HG--
branch : feature
2017-02-27 20:42:35 +01:00
|
|
|
const QString sinD_F = QStringLiteral("sinD");
|
|
|
|
const QString cosD_F = QStringLiteral("cosD");
|
|
|
|
const QString tanD_F = QStringLiteral("tanD");
|
|
|
|
const QString asinD_F = QStringLiteral("asinD");
|
|
|
|
const QString acosD_F = QStringLiteral("acosD");
|
|
|
|
const QString atanD_F = QStringLiteral("atanD");
|
2015-06-12 10:55:44 +02:00
|
|
|
const QString log2_F = QStringLiteral("log2");
|
|
|
|
const QString log10_F = QStringLiteral("log10");
|
|
|
|
const QString log_F = QStringLiteral("log");
|
|
|
|
const QString ln_F = QStringLiteral("ln");
|
|
|
|
const QString exp_F = QStringLiteral("exp");
|
|
|
|
const QString sqrt_F = QStringLiteral("sqrt");
|
|
|
|
const QString sign_F = QStringLiteral("sign");
|
|
|
|
const QString rint_F = QStringLiteral("rint");
|
2017-09-29 16:47:11 +02:00
|
|
|
const QString r2cm_F = QStringLiteral("r2cm");
|
2017-11-13 09:53:27 +01:00
|
|
|
const QString csrCm_F = QStringLiteral("csrCm");
|
|
|
|
const QString csrInch_F = QStringLiteral("csrInch");
|
2015-06-12 10:55:44 +02:00
|
|
|
const QString abs_F = QStringLiteral("abs");
|
|
|
|
const QString min_F = QStringLiteral("min");
|
|
|
|
const QString max_F = QStringLiteral("max");
|
|
|
|
const QString sum_F = QStringLiteral("sum");
|
|
|
|
const QString avg_F = QStringLiteral("avg");
|
|
|
|
const QString fmod_F = QStringLiteral("fmod");
|
|
|
|
|
2017-09-29 16:47:11 +02:00
|
|
|
const QStringList builInFunctions = QStringList() << degTorad_F
|
|
|
|
<< radTodeg_F
|
|
|
|
<< sin_F
|
|
|
|
<< cos_F
|
|
|
|
<< tan_F
|
|
|
|
<< asin_F
|
|
|
|
<< acos_F
|
|
|
|
<< atan_F
|
|
|
|
<< sinh_F
|
|
|
|
<< cosh_F
|
|
|
|
<< tanh_F
|
|
|
|
<< asinh_F
|
|
|
|
<< acosh_F
|
|
|
|
<< atanh_F
|
|
|
|
<< sinD_F
|
|
|
|
<< cosD_F
|
|
|
|
<< tanD_F
|
|
|
|
<< asinD_F
|
|
|
|
<< acosD_F
|
|
|
|
<< atanD_F
|
|
|
|
<< log2_F
|
|
|
|
<< log10_F
|
|
|
|
<< log_F
|
|
|
|
<< ln_F
|
|
|
|
<< exp_F
|
|
|
|
<< sqrt_F
|
|
|
|
<< sign_F
|
|
|
|
<< rint_F
|
|
|
|
<< r2cm_F
|
2017-11-13 09:53:27 +01:00
|
|
|
<< csrCm_F
|
|
|
|
<< csrInch_F
|
2017-09-29 16:47:11 +02:00
|
|
|
<< abs_F
|
|
|
|
<< min_F
|
|
|
|
<< max_F
|
|
|
|
<< sum_F
|
|
|
|
<< avg_F
|
|
|
|
<< fmod_F;
|
2015-06-12 10:55:44 +02:00
|
|
|
|
2017-08-14 14:11:14 +02:00
|
|
|
const QString pl_size = QStringLiteral("size");
|
|
|
|
const QString pl_height = QStringLiteral("height");
|
|
|
|
const QString pl_date = QStringLiteral("date");
|
|
|
|
const QString pl_time = QStringLiteral("time");
|
|
|
|
const QString pl_patternName = QStringLiteral("patternName");
|
|
|
|
const QString pl_patternNumber = QStringLiteral("patternNumber");
|
|
|
|
const QString pl_author = QStringLiteral("author");
|
|
|
|
const QString pl_customer = QStringLiteral("customer");
|
2017-08-30 06:26:18 +02:00
|
|
|
const QString pl_userMaterial = QStringLiteral("userMaterial");
|
2017-08-14 14:11:14 +02:00
|
|
|
const QString pl_pExt = QStringLiteral("pExt");
|
|
|
|
const QString pl_pFileName = QStringLiteral("pFileName");
|
|
|
|
const QString pl_mFileName = QStringLiteral("mFileName");
|
|
|
|
const QString pl_mExt = QStringLiteral("mExt");
|
2017-08-17 18:18:03 +02:00
|
|
|
const QString pl_pLetter = QStringLiteral("pLetter");
|
2017-08-21 12:16:43 +02:00
|
|
|
const QString pl_pAnnotation = QStringLiteral("pAnnotation");
|
|
|
|
const QString pl_pOrientation = QStringLiteral("pOrientation");
|
|
|
|
const QString pl_pRotation = QStringLiteral("pRotation");
|
|
|
|
const QString pl_pTilt = QStringLiteral("pTilt");
|
|
|
|
const QString pl_pFoldPosition = QStringLiteral("pFoldPosition");
|
2017-08-17 18:18:03 +02:00
|
|
|
const QString pl_pName = QStringLiteral("pName");
|
|
|
|
const QString pl_pQuantity = QStringLiteral("pQuantity");
|
|
|
|
const QString pl_mFabric = QStringLiteral("mFabric");
|
|
|
|
const QString pl_mLining = QStringLiteral("mLining");
|
|
|
|
const QString pl_mInterfacing = QStringLiteral("mInterfacing");
|
|
|
|
const QString pl_mInterlining = QStringLiteral("mInterlining");
|
|
|
|
const QString pl_wCut = QStringLiteral("wCut");
|
|
|
|
const QString pl_wOnFold = QStringLiteral("wOnFold");
|
2016-08-23 13:02:09 +02:00
|
|
|
|
2017-08-16 12:09:29 +02:00
|
|
|
const QStringList labelTemplatePlaceholders = QStringList() << pl_size
|
|
|
|
<< pl_height
|
|
|
|
<< pl_date
|
|
|
|
<< pl_time
|
|
|
|
<< pl_patternName
|
|
|
|
<< pl_patternNumber
|
|
|
|
<< pl_author
|
|
|
|
<< pl_customer
|
2017-08-30 06:26:18 +02:00
|
|
|
<< pl_userMaterial
|
2017-08-16 12:09:29 +02:00
|
|
|
<< pl_pExt
|
|
|
|
<< pl_pFileName
|
|
|
|
<< pl_mFileName
|
2017-08-17 18:18:03 +02:00
|
|
|
<< pl_mExt
|
|
|
|
<< pl_pLetter
|
2017-08-21 12:16:43 +02:00
|
|
|
<< pl_pAnnotation
|
|
|
|
<< pl_pOrientation
|
|
|
|
<< pl_pRotation
|
|
|
|
<< pl_pTilt
|
|
|
|
<< pl_pFoldPosition
|
2017-08-17 18:18:03 +02:00
|
|
|
<< pl_pName
|
|
|
|
<< pl_pQuantity
|
|
|
|
<< pl_mFabric
|
|
|
|
<< pl_mLining
|
|
|
|
<< pl_mInterfacing
|
|
|
|
<< pl_mInterlining
|
|
|
|
<< pl_wCut
|
|
|
|
<< pl_wOnFold;
|
2017-08-16 12:09:29 +02:00
|
|
|
|
2015-06-15 15:47:44 +02:00
|
|
|
const QString cursorArrowOpenHand = QStringLiteral("://cursor/cursor-arrow-openhand.png");
|
|
|
|
const QString cursorArrowCloseHand = QStringLiteral("://cursor/cursor-arrow-closehand.png");
|
|
|
|
|
2017-06-16 15:01:09 +02:00
|
|
|
const QString unitMM = QStringLiteral("mm");
|
|
|
|
const QString unitCM = QStringLiteral("cm");
|
|
|
|
const QString unitINCH = QStringLiteral("inch");
|
|
|
|
const QString unitPX = QStringLiteral("px");
|
|
|
|
|
2018-09-18 15:38:16 +02:00
|
|
|
const QString valentinaNamespace = QStringLiteral("valentina");
|
|
|
|
|
2015-06-15 15:47:44 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2018-01-12 13:31:45 +01:00
|
|
|
QPixmap QPixmapFromCache(const QString &pixmapPath)
|
2015-06-15 15:47:44 +02:00
|
|
|
{
|
2017-08-01 13:35:48 +02:00
|
|
|
QPixmap pixmap;
|
2015-06-15 15:47:44 +02:00
|
|
|
|
2019-07-24 14:10:13 +02:00
|
|
|
if (not QPixmapCache::find(pixmapPath, &pixmap))
|
2015-06-15 15:47:44 +02:00
|
|
|
{
|
2017-08-01 13:35:48 +02:00
|
|
|
pixmap = QPixmap(pixmapPath);
|
|
|
|
QPixmapCache::insert(pixmapPath, pixmap);
|
2015-06-15 15:47:44 +02:00
|
|
|
}
|
2018-01-12 13:31:45 +01:00
|
|
|
return pixmap;
|
|
|
|
}
|
2017-08-01 13:35:48 +02:00
|
|
|
|
2018-01-12 13:31:45 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void SetItemOverrideCursor(QGraphicsItem *item, const QString &pixmapPath, int hotX, int hotY)
|
|
|
|
{
|
|
|
|
#ifndef QT_NO_CURSOR
|
|
|
|
SCASSERT(item != nullptr)
|
|
|
|
item->setCursor(QCursor(QPixmapFromCache(pixmapPath), hotX, hotY));
|
2015-10-01 16:59:01 +02:00
|
|
|
#else
|
2017-08-01 13:35:48 +02:00
|
|
|
Q_UNUSED(item)
|
2016-12-20 20:19:21 +01:00
|
|
|
Q_UNUSED(pixmapPath)
|
|
|
|
Q_UNUSED(hotX)
|
|
|
|
Q_UNUSED(hotY)
|
2015-06-15 15:47:44 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-09-19 21:58:32 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QStringList SupportedLocales()
|
|
|
|
{
|
2015-10-23 19:47:33 +02:00
|
|
|
const QStringList locales = QStringList() << QStringLiteral("ru_RU")
|
|
|
|
<< QStringLiteral("uk_UA")
|
|
|
|
<< QStringLiteral("de_DE")
|
|
|
|
<< QStringLiteral("cs_CZ")
|
|
|
|
<< QStringLiteral("he_IL")
|
|
|
|
<< QStringLiteral("fr_FR")
|
|
|
|
<< QStringLiteral("it_IT")
|
|
|
|
<< QStringLiteral("nl_NL")
|
|
|
|
<< QStringLiteral("id_ID")
|
|
|
|
<< QStringLiteral("es_ES")
|
|
|
|
<< QStringLiteral("fi_FI")
|
2015-10-30 11:44:10 +01:00
|
|
|
<< QStringLiteral("en_US")
|
|
|
|
<< QStringLiteral("en_CA")
|
|
|
|
<< QStringLiteral("en_IN")
|
2016-01-21 16:20:47 +01:00
|
|
|
<< QStringLiteral("ro_RO")
|
2016-03-08 19:27:25 +01:00
|
|
|
<< QStringLiteral("zh_CN")
|
2016-10-25 20:29:54 +02:00
|
|
|
<< QStringLiteral("pt_BR")
|
2017-09-11 15:57:49 +02:00
|
|
|
<< QStringLiteral("el_GR")
|
|
|
|
<< QStringLiteral("pl_PL");
|
2015-09-19 21:58:32 +02:00
|
|
|
|
|
|
|
return locales;
|
|
|
|
}
|
2015-09-22 16:41:05 +02:00
|
|
|
|
2015-10-31 09:46:45 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief strippedName the function call around curFile to exclude the path to the file.
|
|
|
|
* @param fullFileName full path to the file.
|
|
|
|
* @return file name.
|
|
|
|
*/
|
|
|
|
QString StrippedName(const QString &fullFileName)
|
|
|
|
{
|
|
|
|
return QFileInfo(fullFileName).fileName();
|
|
|
|
}
|
2015-10-31 13:41:52 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString RelativeMPath(const QString &patternPath, const QString &absoluteMPath)
|
|
|
|
{
|
2016-02-09 16:19:19 +01:00
|
|
|
if (patternPath.isEmpty() || absoluteMPath.isEmpty())
|
2015-10-31 13:41:52 +01:00
|
|
|
{
|
|
|
|
return absoluteMPath;
|
|
|
|
}
|
|
|
|
|
2016-02-09 16:19:19 +01:00
|
|
|
if (QFileInfo(absoluteMPath).isRelative())
|
2015-10-31 13:41:52 +01:00
|
|
|
{
|
|
|
|
return absoluteMPath;
|
|
|
|
}
|
|
|
|
|
2016-02-09 16:19:19 +01:00
|
|
|
return QFileInfo(patternPath).absoluteDir().relativeFilePath(absoluteMPath);
|
2015-10-31 13:41:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString AbsoluteMPath(const QString &patternPath, const QString &relativeMPath)
|
|
|
|
{
|
2016-02-09 16:19:19 +01:00
|
|
|
if (patternPath.isEmpty() || relativeMPath.isEmpty())
|
2015-10-31 13:41:52 +01:00
|
|
|
{
|
|
|
|
return relativeMPath;
|
|
|
|
}
|
|
|
|
|
2016-02-09 16:19:19 +01:00
|
|
|
if (QFileInfo(relativeMPath).isAbsolute())
|
|
|
|
{
|
|
|
|
return relativeMPath;
|
2015-10-31 13:41:52 +01:00
|
|
|
}
|
|
|
|
|
2016-02-09 16:19:19 +01:00
|
|
|
return QFileInfo(QFileInfo(patternPath).absoluteDir(), relativeMPath).absoluteFilePath();
|
2015-10-31 13:41:52 +01:00
|
|
|
}
|
2015-11-09 12:33:36 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
2016-08-22 18:43:22 +02:00
|
|
|
QSharedPointer<QPrinter> PreparePrinter(const QPrinterInfo &info, QPrinter::PrinterMode mode)
|
2015-11-09 12:33:36 +01:00
|
|
|
{
|
2016-08-22 18:43:22 +02:00
|
|
|
QPrinterInfo tmpInfo = info;
|
|
|
|
if(tmpInfo.isNull() || tmpInfo.printerName().isEmpty())
|
2015-11-09 12:33:36 +01:00
|
|
|
{
|
2019-04-05 14:42:22 +02:00
|
|
|
const QStringList list = QPrinterInfo::availablePrinterNames();
|
2016-08-22 18:43:22 +02:00
|
|
|
if(list.isEmpty())
|
2015-11-09 12:33:36 +01:00
|
|
|
{
|
|
|
|
return QSharedPointer<QPrinter>();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-05 14:42:22 +02:00
|
|
|
tmpInfo = QPrinterInfo::printerInfo(list.first());
|
2015-11-09 12:33:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-22 18:43:22 +02:00
|
|
|
auto printer = QSharedPointer<QPrinter>(new QPrinter(tmpInfo, mode));
|
2015-11-09 12:33:36 +01:00
|
|
|
printer->setResolution(static_cast<int>(PrintDPI));
|
|
|
|
return printer;
|
|
|
|
}
|
2015-12-03 13:07:51 +01:00
|
|
|
|
2016-10-06 18:13:06 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QMarginsF GetMinPrinterFields(const QSharedPointer<QPrinter> &printer)
|
|
|
|
{
|
|
|
|
QPageLayout layout = printer->pageLayout();
|
|
|
|
layout.setUnits(QPageLayout::Millimeter);
|
|
|
|
const QMarginsF minMargins = layout.minimumMargins();
|
|
|
|
|
|
|
|
QMarginsF min;
|
|
|
|
min.setLeft(UnitConvertor(minMargins.left(), Unit::Mm, Unit::Px));
|
|
|
|
min.setRight(UnitConvertor(minMargins.right(), Unit::Mm, Unit::Px));
|
|
|
|
min.setTop(UnitConvertor(minMargins.top(), Unit::Mm, Unit::Px));
|
|
|
|
min.setBottom(UnitConvertor(minMargins.bottom(), Unit::Mm, Unit::Px));
|
|
|
|
return min;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QMarginsF GetPrinterFields(const QSharedPointer<QPrinter> &printer)
|
|
|
|
{
|
|
|
|
if (printer.isNull())
|
|
|
|
{
|
|
|
|
return QMarginsF();
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal left = 0;
|
|
|
|
qreal top = 0;
|
|
|
|
qreal right = 0;
|
|
|
|
qreal bottom = 0;
|
|
|
|
printer->getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
|
|
|
|
// We can't use Unit::Px because our dpi in most cases is different
|
|
|
|
QMarginsF def;
|
|
|
|
def.setLeft(UnitConvertor(left, Unit::Mm, Unit::Px));
|
|
|
|
def.setRight(UnitConvertor(right, Unit::Mm, Unit::Px));
|
|
|
|
def.setTop(UnitConvertor(top, Unit::Mm, Unit::Px));
|
|
|
|
def.setBottom(UnitConvertor(bottom, Unit::Mm, Unit::Px));
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
2015-12-03 13:07:51 +01:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QPixmap darkenPixmap(const QPixmap &pixmap)
|
|
|
|
{
|
|
|
|
QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
|
|
|
|
const int imgh = img.height();
|
|
|
|
const int imgw = img.width();
|
|
|
|
for (int y = 0; y < imgh; ++y)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < imgw; ++x)
|
|
|
|
{
|
|
|
|
int h, s, v;
|
|
|
|
QRgb pixel = img.pixel(x, y);
|
|
|
|
const int a = qAlpha(pixel);
|
|
|
|
QColor hsvColor(pixel);
|
|
|
|
hsvColor.getHsv(&h, &s, &v);
|
|
|
|
s = qMin(100, s * 2);
|
|
|
|
v = v / 2;
|
|
|
|
hsvColor.setHsv(h, s, v);
|
|
|
|
pixel = hsvColor.rgb();
|
|
|
|
img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return QPixmap::fromImage(img);
|
|
|
|
}
|
2016-06-18 15:57:07 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void ShowInGraphicalShell(const QString &filePath)
|
|
|
|
{
|
|
|
|
#ifdef Q_OS_MAC
|
|
|
|
QStringList args;
|
|
|
|
args << "-e";
|
|
|
|
args << "tell application \"Finder\"";
|
|
|
|
args << "-e";
|
|
|
|
args << "activate";
|
|
|
|
args << "-e";
|
|
|
|
args << "select POSIX file \""+filePath+"\"";
|
|
|
|
args << "-e";
|
|
|
|
args << "end tell";
|
|
|
|
QProcess::startDetached("osascript", args);
|
|
|
|
#elif defined(Q_OS_WIN)
|
|
|
|
QProcess::startDetached(QString("explorer /select, \"%1\"").arg(QDir::toNativeSeparators(filePath)));
|
|
|
|
#else
|
|
|
|
const QString app = "xdg-open %d";
|
|
|
|
QString cmd;
|
|
|
|
for (int i = 0; i < app.size(); ++i)
|
|
|
|
{
|
|
|
|
QChar c = app.at(i);
|
|
|
|
if (c == QLatin1Char('%') && i < app.size()-1)
|
|
|
|
{
|
|
|
|
c = app.at(++i);
|
|
|
|
QString s;
|
|
|
|
if (c == QLatin1Char('d'))
|
|
|
|
{
|
|
|
|
s = QLatin1Char('"') + QFileInfo(filePath).path() + QLatin1Char('"');
|
|
|
|
}
|
|
|
|
else if (c == QLatin1Char('%'))
|
|
|
|
{
|
|
|
|
s = c;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s = QLatin1Char('%');
|
|
|
|
s += c;
|
|
|
|
}
|
|
|
|
cmd += s;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
cmd += c;
|
|
|
|
}
|
|
|
|
QProcess::startDetached(cmd);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
2017-02-09 14:43:17 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
bool IsOptionSet(int argc, char *argv[], const char *option)
|
|
|
|
{
|
|
|
|
for (int i = 1; i < argc; ++i)
|
|
|
|
{
|
|
|
|
if (!qstrcmp(argv[i], option))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// See issue #624. https://bitbucket.org/dismine/valentina/issues/624
|
|
|
|
void InitHighDpiScaling(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
/* For more info see: http://doc.qt.io/qt-5/highdpi.html */
|
|
|
|
if (IsOptionSet(argc, argv, qPrintable(QLatin1String("--") + LONG_OPTION_NO_HDPI_SCALING)))
|
|
|
|
{
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
|
|
|
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
|
|
|
|
#else
|
|
|
|
qputenv("QT_DEVICE_PIXEL_RATIO", QByteArray("1"));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
|
|
|
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support
|
|
|
|
#else
|
|
|
|
qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", QByteArray("1"));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2017-03-24 13:48:07 +01:00
|
|
|
|
|
|
|
const QString strOne = QStringLiteral("one");
|
|
|
|
const QString strTwo = QStringLiteral("two");
|
|
|
|
const QString strThree = QStringLiteral("three");
|
2018-03-14 14:39:15 +01:00
|
|
|
|
|
|
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strTMark, (QLatin1String("tMark")))
|
|
|
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strVMark, (QLatin1String("vMark")))
|
2019-01-24 08:26:57 +01:00
|
|
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strVMark2, (QLatin1String("vMark2")))
|
2019-04-23 19:56:11 +02:00
|
|
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strUMark, (QLatin1String("uMark")))
|
|
|
|
Q_GLOBAL_STATIC_WITH_ARGS(const QString, strBoxMark, (QLatin1String("boxMark")))
|
2017-03-24 13:48:07 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString PassmarkLineTypeToString(PassmarkLineType type)
|
|
|
|
{
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case PassmarkLineType::OneLine:
|
|
|
|
return strOne;
|
|
|
|
case PassmarkLineType::TwoLines:
|
|
|
|
return strTwo;
|
|
|
|
case PassmarkLineType::ThreeLines:
|
|
|
|
return strThree;
|
2017-04-05 12:22:33 +02:00
|
|
|
case PassmarkLineType::TMark:
|
2018-03-14 14:39:15 +01:00
|
|
|
return *strTMark;
|
2017-04-05 12:22:33 +02:00
|
|
|
case PassmarkLineType::VMark:
|
2018-03-14 14:39:15 +01:00
|
|
|
return *strVMark;
|
2019-01-24 08:26:57 +01:00
|
|
|
case PassmarkLineType::VMark2:
|
|
|
|
return *strVMark2;
|
2019-04-23 19:56:11 +02:00
|
|
|
case PassmarkLineType::UMark:
|
|
|
|
return *strUMark;
|
|
|
|
case PassmarkLineType::BoxMark:
|
|
|
|
return *strBoxMark;
|
2017-03-24 13:48:07 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strOne;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
PassmarkLineType StringToPassmarkLineType(const QString &value)
|
|
|
|
{
|
2019-04-23 19:56:11 +02:00
|
|
|
const QStringList values{strOne, strTwo, strThree, *strTMark, *strVMark, *strVMark2, *strUMark, *strBoxMark};
|
2017-03-24 13:48:07 +01:00
|
|
|
|
|
|
|
switch(values.indexOf(value))
|
|
|
|
{
|
2017-04-05 12:22:33 +02:00
|
|
|
case 0: // strOne
|
2017-03-24 13:48:07 +01:00
|
|
|
return PassmarkLineType::OneLine;
|
2017-04-05 12:22:33 +02:00
|
|
|
case 1: // strTwo
|
2017-03-24 13:48:07 +01:00
|
|
|
return PassmarkLineType::TwoLines;
|
2017-04-05 12:22:33 +02:00
|
|
|
case 2: // strThree
|
2017-03-24 13:48:07 +01:00
|
|
|
return PassmarkLineType::ThreeLines;
|
2017-04-05 12:22:33 +02:00
|
|
|
case 3: // strTMark
|
|
|
|
return PassmarkLineType::TMark;
|
|
|
|
case 4: // strVMark
|
|
|
|
return PassmarkLineType::VMark;
|
2019-01-24 08:26:57 +01:00
|
|
|
case 5: // strVMark2
|
|
|
|
return PassmarkLineType::VMark2;
|
2019-04-23 19:56:11 +02:00
|
|
|
case 6: // strUMark
|
|
|
|
return PassmarkLineType::UMark;
|
|
|
|
case 7: // strBoxMark
|
|
|
|
return PassmarkLineType::BoxMark;
|
2017-03-24 13:48:07 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return PassmarkLineType::OneLine;
|
|
|
|
}
|
|
|
|
|
2019-01-16 15:24:41 +01:00
|
|
|
const QString strStraightforward = QStringLiteral("straightforward");
|
|
|
|
const QString strBisector = QStringLiteral("bisector");
|
|
|
|
const QString strIntersection = QStringLiteral("intersection");
|
|
|
|
const QString strIntersectionOnlyLeft = QStringLiteral("intersectionLeft");
|
|
|
|
const QString strIntersectionOnlyRight = QStringLiteral("intersectionRight");
|
2018-02-04 11:35:27 +01:00
|
|
|
const QString strIntersection2 = QStringLiteral("intersection2");
|
|
|
|
const QString strIntersection2OnlyLeft = QStringLiteral("intersection2Left");
|
|
|
|
const QString strIntersection2OnlyRight = QStringLiteral("intersection2Right");
|
2019-01-16 15:24:41 +01:00
|
|
|
const QString strTypeIncrement = QStringLiteral("increment");
|
|
|
|
const QString strTypeSeparator = QStringLiteral("separator");
|
2017-03-24 13:48:07 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString PassmarkAngleTypeToString(PassmarkAngleType type)
|
|
|
|
{
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case PassmarkAngleType::Straightforward:
|
|
|
|
return strStraightforward;
|
|
|
|
case PassmarkAngleType::Bisector:
|
|
|
|
return strBisector;
|
2017-04-25 10:42:08 +02:00
|
|
|
case PassmarkAngleType::Intersection:
|
|
|
|
return strIntersection;
|
2017-09-28 20:18:13 +02:00
|
|
|
case PassmarkAngleType::IntersectionOnlyLeft:
|
|
|
|
return strIntersectionOnlyLeft;
|
|
|
|
case PassmarkAngleType::IntersectionOnlyRight:
|
|
|
|
return strIntersectionOnlyRight;
|
2018-02-04 11:35:27 +01:00
|
|
|
case PassmarkAngleType::Intersection2:
|
|
|
|
return strIntersection2;
|
|
|
|
case PassmarkAngleType::Intersection2OnlyLeft:
|
|
|
|
return strIntersection2OnlyLeft;
|
|
|
|
case PassmarkAngleType::Intersection2OnlyRight:
|
|
|
|
return strIntersection2OnlyRight;
|
2017-03-24 13:48:07 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strStraightforward;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
PassmarkAngleType StringToPassmarkAngleType(const QString &value)
|
|
|
|
{
|
2017-09-28 20:18:13 +02:00
|
|
|
const QStringList values = QStringList() << strStraightforward
|
|
|
|
<< strBisector
|
|
|
|
<< strIntersection
|
|
|
|
<< strIntersectionOnlyLeft
|
2018-02-04 11:35:27 +01:00
|
|
|
<< strIntersectionOnlyRight
|
|
|
|
<< strIntersection2
|
|
|
|
<< strIntersection2OnlyLeft
|
|
|
|
<< strIntersection2OnlyRight;
|
2017-03-24 13:48:07 +01:00
|
|
|
|
|
|
|
switch(values.indexOf(value))
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return PassmarkAngleType::Straightforward;
|
|
|
|
case 1:
|
|
|
|
return PassmarkAngleType::Bisector;
|
2017-04-25 10:42:08 +02:00
|
|
|
case 2:
|
|
|
|
return PassmarkAngleType::Intersection;
|
2017-09-28 20:18:13 +02:00
|
|
|
case 3:
|
|
|
|
return PassmarkAngleType::IntersectionOnlyLeft;
|
|
|
|
case 4:
|
|
|
|
return PassmarkAngleType::IntersectionOnlyRight;
|
2018-02-04 11:35:27 +01:00
|
|
|
case 5:
|
|
|
|
return PassmarkAngleType::Intersection2;
|
|
|
|
case 6:
|
|
|
|
return PassmarkAngleType::Intersection2OnlyLeft;
|
|
|
|
case 7:
|
|
|
|
return PassmarkAngleType::Intersection2OnlyRight;
|
2017-03-24 13:48:07 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return PassmarkAngleType::Straightforward;
|
|
|
|
}
|
2017-04-12 14:50:48 +02:00
|
|
|
|
2017-07-02 13:34:36 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
Unit StrToUnits(const QString &unit)
|
|
|
|
{
|
|
|
|
const QStringList units = QStringList() << unitMM << unitCM << unitINCH << unitPX;
|
|
|
|
Unit result = Unit::Cm;
|
|
|
|
switch (units.indexOf(unit))
|
|
|
|
{
|
|
|
|
case 0:// mm
|
|
|
|
result = Unit::Mm;
|
|
|
|
break;
|
|
|
|
case 2:// inch
|
|
|
|
result = Unit::Inch;
|
|
|
|
break;
|
|
|
|
case 3:// px
|
|
|
|
result = Unit::Px;
|
|
|
|
break;
|
|
|
|
case 1:// cm
|
|
|
|
default:
|
|
|
|
result = Unit::Cm;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
/**
|
|
|
|
* @brief UnitsToStr translate unit to string.
|
|
|
|
*
|
|
|
|
* This method used when need write unit in xml file and for showing unit in dialogs.
|
|
|
|
* @param unit curent unit
|
|
|
|
* @param translate true if need show translated name. Default value false.
|
|
|
|
* @return string reprezantation for unit.
|
|
|
|
*/
|
|
|
|
QString UnitsToStr(const Unit &unit, const bool translate)
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
switch (unit)
|
|
|
|
{
|
|
|
|
case Unit::Mm:
|
|
|
|
translate ? result = QObject::tr("mm") : result = unitMM;
|
|
|
|
break;
|
|
|
|
case Unit::Inch:
|
|
|
|
translate ? result = QObject::tr("inch") : result = unitINCH;
|
|
|
|
break;
|
|
|
|
case Unit::Px:
|
|
|
|
translate ? result = QObject::tr("px") : result = unitPX;
|
|
|
|
break;
|
|
|
|
case Unit::Cm:
|
|
|
|
default:
|
|
|
|
translate ? result = QObject::tr("cm") : result = unitCM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-04-12 14:50:48 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void InitLanguages(QComboBox *combobox)
|
|
|
|
{
|
|
|
|
SCASSERT(combobox != nullptr)
|
|
|
|
combobox->clear();
|
|
|
|
|
|
|
|
QStringList fileNames;
|
|
|
|
QDirIterator it(qApp->translationsPath(), QStringList("valentina_*.qm"), QDir::Files, QDirIterator::Subdirectories);
|
|
|
|
while (it.hasNext())
|
|
|
|
{
|
|
|
|
it.next();
|
|
|
|
fileNames.append(it.fileName());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool englishUS = false;
|
|
|
|
const QString en_US = QStringLiteral("en_US");
|
|
|
|
|
2018-04-03 13:36:38 +02:00
|
|
|
for (auto locale : fileNames)
|
2017-04-12 14:50:48 +02:00
|
|
|
{
|
2018-04-03 13:36:38 +02:00
|
|
|
// get locale extracted by filename "valentina_de_De.qm"
|
2017-04-12 14:50:48 +02:00
|
|
|
locale.truncate(locale.lastIndexOf('.')); // "valentina_de_De"
|
|
|
|
locale.remove(0, locale.indexOf('_') + 1); // "de_De"
|
|
|
|
|
|
|
|
if (not englishUS)
|
|
|
|
{
|
|
|
|
englishUS = (en_US == locale);
|
|
|
|
}
|
|
|
|
|
|
|
|
QLocale loc = QLocale(locale);
|
|
|
|
QString lang = loc.nativeLanguageName();
|
2018-03-14 14:39:15 +01:00
|
|
|
QIcon ico(QString("%1/%2.png").arg("://flags", QLocale::countryToString(loc.country())));
|
2017-04-12 14:50:48 +02:00
|
|
|
|
|
|
|
combobox->addItem(ico, lang, locale);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (combobox->count() == 0 || not englishUS)
|
|
|
|
{
|
|
|
|
// English language is internal and doens't have own *.qm file.
|
2018-03-14 14:39:15 +01:00
|
|
|
QIcon ico(QString("%1/%2.png").arg("://flags", QLocale::countryToString(QLocale::UnitedStates)));
|
2017-04-12 14:50:48 +02:00
|
|
|
QString lang = QLocale(en_US).nativeLanguageName();
|
|
|
|
combobox->addItem(ico, lang, en_US);
|
|
|
|
}
|
|
|
|
|
|
|
|
// set default translators and language checked
|
|
|
|
qint32 index = combobox->findData(qApp->Settings()->GetLocale());
|
|
|
|
if (index != -1)
|
|
|
|
{
|
|
|
|
combobox->setCurrentIndex(index);
|
|
|
|
}
|
|
|
|
}
|
2018-12-21 12:01:32 +01:00
|
|
|
|
2019-07-01 12:25:03 +02:00
|
|
|
const quint32 CustomSARecord::streamHeader = 0xEBFF7586; // CRC-32Q string "CustomSARecord"
|
|
|
|
const quint16 CustomSARecord::classVersion = 1;
|
|
|
|
|
2018-12-21 12:01:32 +01:00
|
|
|
// Friend functions
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QDataStream &operator<<(QDataStream &out, const CustomSARecord &record)
|
|
|
|
{
|
2019-07-01 12:25:03 +02:00
|
|
|
out << CustomSARecord::streamHeader << CustomSARecord::classVersion;
|
|
|
|
|
|
|
|
// Added in classVersion = 1
|
2018-12-21 12:01:32 +01:00
|
|
|
out << record.startPoint;
|
|
|
|
out << record.path;
|
|
|
|
out << record.endPoint;
|
|
|
|
out << record.reverse;
|
|
|
|
out << record.includeType;
|
2019-07-01 12:25:03 +02:00
|
|
|
|
|
|
|
// Added in classVersion = 2
|
|
|
|
|
2018-12-21 12:01:32 +01:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QDataStream &operator>>(QDataStream &in, CustomSARecord &record)
|
|
|
|
{
|
2019-07-01 12:25:03 +02:00
|
|
|
quint32 actualStreamHeader = 0;
|
|
|
|
in >> actualStreamHeader;
|
|
|
|
|
|
|
|
if (actualStreamHeader != CustomSARecord::streamHeader)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("CustomSARecord prefix mismatch error: actualStreamHeader = 0x%1 "
|
|
|
|
"and streamHeader = 0x%2")
|
|
|
|
.arg(actualStreamHeader, 8, 0x10, QChar('0'))
|
|
|
|
.arg(CustomSARecord::streamHeader, 8, 0x10, QChar('0'));
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
quint16 actualClassVersion = 0;
|
|
|
|
in >> actualClassVersion;
|
|
|
|
|
|
|
|
if (actualClassVersion > CustomSARecord::classVersion)
|
|
|
|
{
|
|
|
|
QString message = QCoreApplication::tr("CustomSARecord compatibility error: actualClassVersion = %1 and "
|
|
|
|
"classVersion = %2")
|
|
|
|
.arg(actualClassVersion).arg(CustomSARecord::classVersion);
|
|
|
|
throw VException(message);
|
|
|
|
}
|
|
|
|
|
2018-12-21 12:01:32 +01:00
|
|
|
in >> record.startPoint;
|
|
|
|
in >> record.path;
|
|
|
|
in >> record.endPoint;
|
|
|
|
in >> record.reverse;
|
|
|
|
in >> record.includeType;
|
2019-07-01 12:25:03 +02:00
|
|
|
|
|
|
|
// if (actualClassVersion >= 2)
|
|
|
|
// {
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
2018-12-21 12:01:32 +01:00
|
|
|
return in;
|
|
|
|
}
|
2019-01-16 15:24:41 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString IncrementTypeToString(IncrementType type)
|
|
|
|
{
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case IncrementType::Increment:
|
|
|
|
return strTypeIncrement;
|
|
|
|
case IncrementType::Separator:
|
|
|
|
return strTypeSeparator;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strTypeIncrement;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
IncrementType StringToIncrementType(const QString &value)
|
|
|
|
{
|
|
|
|
const QStringList values { strTypeIncrement, strTypeSeparator };
|
|
|
|
|
|
|
|
switch(values.indexOf(value))
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return IncrementType::Increment;
|
|
|
|
case 1:
|
|
|
|
return IncrementType::Separator;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return IncrementType::Increment;
|
|
|
|
}
|