--HG--
branch : develop
This commit is contained in:
Valentina Zhuravska 2015-09-18 16:41:09 +03:00
commit 2bfd22c02c
34 changed files with 1387 additions and 264 deletions

View File

@ -26,4 +26,9 @@ Patch contributors:
* Mac OS package.
Peter Gsellmann
* Testing
Alex Zaharov <alexzkhr@gmail.com>
* Developing.
Valentina Zhuravska <zhuravska19@gmail.com>
* Developing.
* Testing.
* Translation.

View File

@ -38,6 +38,8 @@
#include <QTranslator>
#include <QPointer>
#include <QLocalServer>
#include <QMessageBox>
#include <iostream>
#if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
# include "../../libs/vmisc/backport/qcommandlineparser.h"
@ -45,6 +47,91 @@
# include <QCommandLineParser>
#endif
//---------------------------------------------------------------------------------------------------------------------
inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
Q_UNUSED(context)
// Why on earth didn't Qt want to make failed signal/slot connections qWarning?
if ((type == QtDebugMsg) && msg.contains("::connect"))
{
type = QtWarningMsg;
}
// this is another one that doesn't make sense as just a debug message. pretty serious
// sign of a problem
// http://www.developer.nokia.com/Community/Wiki/QPainter::begin:Paint_device_returned_engine_%3D%3D_0_(Known_Issue)
if ((type == QtDebugMsg) && msg.contains("QPainter::begin") && msg.contains("Paint device returned engine"))
{
type = QtWarningMsg;
}
// This qWarning about "Cowardly refusing to send clipboard message to hung application..."
// is something that can easily happen if you are debugging and the application is paused.
// As it is so common, not worth popping up a dialog.
if ((type == QtWarningMsg) && QString(msg).contains("QClipboard::event")
&& QString(msg).contains("Cowardly refusing"))
{
type = QtDebugMsg;
}
// only the GUI thread should display message boxes. If you are
// writing a multithreaded application and the error happens on
// a non-GUI thread, you'll have to queue the message to the GUI
QCoreApplication *instance = QCoreApplication::instance();
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
if (isGuiThread)
{
//fixme: trying to make sure there are no save/load dialogs are opened, because error message during them will
//lead to crash
const bool topWinAllowsPop = (qApp->activeModalWidget() == nullptr) ||
!qApp->activeModalWidget()->inherits("QFileDialog");
QMessageBox messageBox;
switch (type)
{
case QtDebugMsg:
std::cerr << msg.toUtf8().constData() << std::endl;
return;
case QtWarningMsg:
messageBox.setIcon(QMessageBox::Warning);
break;
case QtCriticalMsg:
messageBox.setIcon(QMessageBox::Critical);
break;
case QtFatalMsg:
messageBox.setIcon(QMessageBox::Critical);
break;
default:
break;
}
if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
{
if (topWinAllowsPop)
{
messageBox.setInformativeText(msg);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setWindowModality(Qt::ApplicationModal);
messageBox.setModal(true);
messageBox.exec();
}
}
if (QtFatalMsg == type)
{
abort();
}
}
else
{
if (type != QtDebugMsg)
{
abort(); // be NOISY unless overridden!
}
}
}
//---------------------------------------------------------------------------------------------------------------------
MApplication::MApplication(int &argc, char **argv)
:VAbstractApplication(argc, argv),
@ -138,6 +225,8 @@ QList<TMainWindow *> MApplication::MainWindows()
//---------------------------------------------------------------------------------------------------------------------
void MApplication::InitOptions()
{
qInstallMessageHandler(noisyFailureMsgHandler);
OpenSettings();
qDebug()<<"Version:"<<APP_VERSION_STR;

View File

@ -12,7 +12,8 @@ SOURCES += \
$$PWD/dialogs/tapeconfigdialog.cpp \
$$PWD/dialogs/configpages/tapeconfigurationpage.cpp \
$$PWD/dialogs/configpages/tapepathpage.cpp \
$$PWD/vlitepattern.cpp
$$PWD/vlitepattern.cpp \
$$PWD/vtablesearch.cpp
HEADERS += \
$$PWD/tmainwindow.h \
@ -25,7 +26,8 @@ HEADERS += \
$$PWD/dialogs/tapeconfigdialog.h \
$$PWD/dialogs/configpages/tapeconfigurationpage.h \
$$PWD/dialogs/configpages/tapepathpage.h \
$$PWD/vlitepattern.h
$$PWD/vlitepattern.h \
$$PWD/vtablesearch.h
FORMS += \
$$PWD/tmainwindow.ui \

View File

@ -37,6 +37,7 @@
#include "../ifc/xml/vvitconverter.h"
#include "../ifc/xml/vvstconverter.h"
#include "../ifc/xml/vpatternconverter.h"
#include "../vmisc/vlockguard.h"
#include "vlitepattern.h"
#include "../qmuparser/qmudef.h"
#include "../vtools/dialogs/support/dialogeditwrongformula.h"
@ -48,9 +49,6 @@
#include <QMessageBox>
#include <QComboBox>
#include <QProcess>
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
# include <QLockFile>
#endif
#define DIALOG_MAX_FORMULA_HEIGHT 64
@ -70,9 +68,11 @@ TMainWindow::TMainWindow(QWidget *parent)
gradationSizes(nullptr),
comboBoxUnits(nullptr),
formulaBaseHeight(0),
lock(nullptr)
lock(nullptr),
search()
{
ui->setupUi(this);
search = QSharedPointer<VTableSearch>(new VTableSearch(ui->tableWidget));
ui->tabWidget->setVisible(false);
ui->mainToolBar->setContextMenuPolicy(Qt::PreventContextMenu);
@ -98,10 +98,6 @@ TMainWindow::~TMainWindow()
delete m;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
delete lock; // Unlock pattern file
#endif
delete ui;
}
@ -182,18 +178,14 @@ void TMainWindow::LoadFile(const QString &path)
}
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
lock = new QLockFile(QFileInfo(path).fileName()+".lock");
lock->setStaleLockTime(0);
if (not MApplication::TryLock(lock))
VlpCreateLock(lock, QFileInfo(path).fileName()+".lock");
if (lock->GetLockError() == QLockFile::LockFailedError)
{
if (lock->error() == QLockFile::LockFailedError)
{
qCCritical(tMainWindow, "%s", tr("This file already opened in another window.").toUtf8().constData());
return;
}
qCCritical(tMainWindow, "%s", tr("This file already opened in another window.").toUtf8().constData());
lock.reset();
return;
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
try
{
@ -257,6 +249,7 @@ void TMainWindow::LoadFile(const QString &path)
m = nullptr;
delete data;
data = nullptr;
lock.reset();
return;
}
}
@ -361,6 +354,24 @@ void TMainWindow::OpenTemplate()
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::Find(const QString &term)
{
search->Find(term);
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::FindPrevious()
{
search->FindPrevious();
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::FindNext()
{
search->FindNext();
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::closeEvent(QCloseEvent *event)
{
@ -462,6 +473,22 @@ void TMainWindow::FileSaveAs()
{
fileName += "." + suffix;
}
if (QFileInfo(fileName).exists())
{
VLockGuard<char> tmp(fileName + ".lock");
if (not tmp.IsLocked())
{
if (lock->GetLockError() == QLockFile::LockFailedError)
{
qCCritical(tMainWindow, "%s", tr("Failed to lock. This file already opened in another window.")
.toUtf8().constData());
return;
}
}
}
QString error;
bool result = SaveMeasurements(fileName, error);
if (result == false)
@ -473,6 +500,20 @@ void TMainWindow::FileSaveAs()
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return;
}
lock.reset();
VlpCreateLock(lock, fileName + ".lock");
if (lock->GetLockError() == QLockFile::LockFailedError)
{
qCCritical(tMainWindow, "%s", tr("Failed to lock. This file already opened in another window. "
"Expect collissions when run 2 copies of the program.").toUtf8().constData());
lock.reset();
return;
}
}
@ -613,7 +654,9 @@ void TMainWindow::Remove()
MeasurementsWasSaved(false);
search->RemoveRow(row);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
if (ui->tableWidget->rowCount() > 0)
{
@ -679,6 +722,7 @@ void TMainWindow::MoveUp()
m->MoveUp(nameField->text());
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row-1);
}
@ -696,6 +740,7 @@ void TMainWindow::MoveDown()
m->MoveDown(nameField->text());
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row+1);
}
@ -730,6 +775,8 @@ void TMainWindow::Fx()
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row);
}
delete dialog;
@ -760,7 +807,9 @@ void TMainWindow::AddCustom()
m->AddEmptyAfter(nameField->text(), name);
}
search->AddRow(currentRow);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(currentRow);
@ -789,6 +838,8 @@ void TMainWindow::AddKnown()
{
m->AddEmpty(list.at(i));
}
search->AddRow(currentRow);
}
}
else
@ -806,11 +857,13 @@ void TMainWindow::AddKnown()
{
m->AddEmptyAfter(after, list.at(i));
}
search->AddRow(currentRow);
after = list.at(i);
}
}
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(currentRow);
@ -839,18 +892,13 @@ void TMainWindow::ImportFromPattern()
return;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
QLockFile *lock = new QLockFile(QFileInfo(mPath).fileName()+".lock");
lock->setStaleLockTime(0);
if (not MApplication::TryLock(lock))
VLockGuard<char> tmp(QFileInfo(mPath).fileName()+".lock");
if (tmp.GetLockError() == QLockFile::LockFailedError)
{
if (lock->error() == QLockFile::LockFailedError)
{
qCCritical(tMainWindow, "%s", tr("This file already opened in another window.").toUtf8().constData());
return;
}
qCCritical(tMainWindow, "%s", tr("This file already opened in another window.").toUtf8().constData());
return;
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
@ -878,8 +926,6 @@ void TMainWindow::ImportFromPattern()
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
delete lock; // release a pattern file
measurements = FilterMeasurements(measurements, m->ListAll());
qint32 currentRow;
@ -906,6 +952,8 @@ void TMainWindow::ImportFromPattern()
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(currentRow);
MeasurementsWasSaved(false);
@ -917,6 +965,7 @@ void TMainWindow::ChangedSize(const QString &text)
const int row = ui->tableWidget->currentRow();
data->SetSize(text.toInt());
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row);
}
@ -926,6 +975,7 @@ void TMainWindow::ChangedHeight(const QString &text)
const int row = ui->tableWidget->currentRow();
data->SetHeight(text.toInt());
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row);
}
@ -1070,6 +1120,7 @@ void TMainWindow::SaveMName()
m->SetMName(nameField->text(), newName);
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
@ -1139,6 +1190,7 @@ void TMainWindow::SaveMValue()
const QTextCursor cursor = ui->plainTextEditFormula->textCursor();
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
@ -1163,6 +1215,7 @@ void TMainWindow::SaveMBaseValue(double value)
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
@ -1185,6 +1238,7 @@ void TMainWindow::SaveMSizeIncrease(double value)
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->blockSignals(true);
ui->tableWidget->selectRow(row);
@ -1207,6 +1261,7 @@ void TMainWindow::SaveMHeightIncrease(double value)
MeasurementsWasSaved(false);
RefreshData();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row);
}
@ -1464,6 +1519,10 @@ void TMainWindow::InitWindow()
connect(ui->toolButtonExpr, &QToolButton::clicked, this, &TMainWindow::Fx);
}
connect(ui->lineEditFind, &QLineEdit::textEdited, this, &TMainWindow::Find);
connect(ui->toolButtonFindPrevious, &QToolButton::clicked, this, &TMainWindow::FindPrevious);
connect(ui->toolButtonFindNext, &QToolButton::clicked, this, &TMainWindow::FindNext);
ui->plainTextEditNotes->setPlainText(m->Notes());
connect(ui->plainTextEditNotes, &QPlainTextEdit::textChanged, this, &TMainWindow::SaveNotes);
@ -1678,6 +1737,7 @@ void TMainWindow::SetDefaultSize(int value)
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::RefreshData()
{
data->ClearUniqueNames();
data->ClearVariables(VarType::Measurement);
m->ReadMeasurements();
@ -1817,6 +1877,10 @@ void TMainWindow::MFields(bool enabled)
ui->pushButtonGrow->setEnabled(enabled);
ui->toolButtonExpr->setEnabled(enabled);
}
ui->lineEditFind->setEnabled(enabled);
ui->toolButtonFindPrevious->setEnabled(enabled);
ui->toolButtonFindNext->setEnabled(enabled);
}
//---------------------------------------------------------------------------------------------------------------------
@ -2003,6 +2067,8 @@ void TMainWindow::UpdatePatternUnit()
ShowUnits();
RefreshTable();
search->RefreshList(ui->lineEditFind->text());
ui->tableWidget->selectRow(row);
}

View File

@ -33,7 +33,9 @@
#include <QTableWidget>
#include "../vmisc/def.h"
#include "../vmisc/vlockguard.h"
#include "../vformat/vmeasurements.h"
#include "vtablesearch.h"
namespace Ui
{
@ -43,9 +45,6 @@ namespace Ui
class QComboBox;
class QTableWidgetItem;
class QLabel;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
class QLockFile;
#endif
class TMainWindow : public QMainWindow
{
@ -115,10 +114,11 @@ private slots:
void SaveMFullName();
void NewWindow();
void Preferences();
void PatternUnitChanged(int index);
void Find(const QString &term);
void FindPrevious();
void FindNext();
private:
Q_DISABLE_COPY(TMainWindow)
@ -133,10 +133,8 @@ private:
QComboBox *gradationSizes;
QComboBox *comboBoxUnits;
int formulaBaseHeight;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
QLockFile *lock;
#endif
VLockGuardPtr<char> lock;
QSharedPointer<VTableSearch> search;
void SetupMenu();
void InitWindow();

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>536</width>
<height>694</height>
<height>726</height>
</rect>
</property>
<property name="windowTitle">
@ -43,6 +43,69 @@
<string>Measurements</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelFind">
<property name="text">
<string>Find:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditFind">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonFindPrevious">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Find Previous</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-previous">
<normaloff/>
</iconset>
</property>
<property name="shortcut">
<string>Ctrl+Shift+G</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonFindNext">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Find Next</string>
</property>
<property name="text">
<string notr="true">...</string>
</property>
<property name="icon">
<iconset theme="go-next">
<normaloff/>
</iconset>
</property>
<property name="shortcut">
<string>Ctrl+G</string>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="sizePolicy">

View File

@ -0,0 +1,208 @@
/************************************************************************
**
** @file vtablesearch.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 15 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** 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 "vtablesearch.h"
#include "../vmisc/def.h"
//---------------------------------------------------------------------------------------------------------------------
VTableSearch::VTableSearch(QTableWidget *table)
:table(table),
searchIndex(-1),
searchList()
{
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::Clear()
{
SCASSERT(table != nullptr);
foreach(QTableWidgetItem *item, searchList)
{
if (item->row() % 2 != 0 && table->alternatingRowColors())
{
item->setBackground(QPalette().alternateBase());
}
else
{
item->setBackground(QPalette().base());
}
}
searchIndex = -1;
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::ShowNext(int newIndex)
{
if (not searchList.isEmpty())
{
QTableWidgetItem *item = searchList.at(searchIndex);
item->setBackground(Qt::yellow);
item = searchList.at(newIndex);
item->setBackground(Qt::red);
table->scrollToItem(item);
searchIndex = newIndex;
}
else
{
Clear();
}
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::Find(const QString &term)
{
SCASSERT(table != nullptr);
const QList<QTableWidgetItem *> list = table->findItems(term, Qt::MatchContains);
if (list.isEmpty() || term.isEmpty())
{
Clear();
}
else
{
Clear();
searchList = list;
foreach(QTableWidgetItem *item, searchList)
{
item->setBackground(Qt::yellow);
}
searchIndex = 0;
QTableWidgetItem *item = searchList.at(searchIndex);
item->setBackground(Qt::red);
table->scrollToItem(item);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::FindPrevious()
{
int newIndex = searchIndex - 1;
if (newIndex < 0)
{
newIndex = searchList.size() - 1;
}
ShowNext(newIndex);
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::FindNext()
{
int newIndex = searchIndex + 1;
if (newIndex >= searchList.size())
{
newIndex = 0;
}
ShowNext(newIndex);
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::RemoveRow(int row)
{
if (searchIndex < 0 || searchIndex >= searchList.size())
{
return;
}
const int indexRow = searchList.at(searchIndex)->row();
if (row <= indexRow)
{
foreach(QTableWidgetItem *item, searchList)
{
if (item->row() == row)
{
--searchIndex;
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::AddRow(int row)
{
if (searchIndex < 0 || searchIndex >= searchList.size())
{
return;
}
const int indexRow = searchList.at(searchIndex)->row();
if (row <= indexRow)
{
foreach(QTableWidgetItem *item, searchList)
{
if (item->row() == row)
{
++searchIndex;
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
void VTableSearch::RefreshList(const QString &term)
{
SCASSERT(table != nullptr);
if (term.isEmpty())
{
return;
}
searchList = table->findItems(term, Qt::MatchContains);
foreach(QTableWidgetItem *item, searchList)
{
item->setBackground(Qt::yellow);
}
if (not searchList.isEmpty())
{
if (searchIndex < 0)
{
searchIndex = searchList.size() - 1;
}
else if (searchIndex >= searchList.size())
{
searchIndex = 0;
}
QTableWidgetItem *item = searchList.at(searchIndex);
item->setBackground(Qt::red);
table->scrollToItem(item);
}
}

View File

@ -0,0 +1,58 @@
/************************************************************************
**
** @file vtablesearch.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 15 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** 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/>.
**
*************************************************************************/
#ifndef VTABLESEARCH_H
#define VTABLESEARCH_H
#include <QList>
#include <QTableWidget>
class VTableSearch
{
public:
VTableSearch(QTableWidget *table);
void Find(const QString &term);
void FindPrevious();
void FindNext();
void RemoveRow(int row);
void AddRow(int row);
void RefreshList(const QString &term);
private:
Q_DISABLE_COPY(VTableSearch)
QTableWidget *table;
int searchIndex;
QList<QTableWidgetItem *> searchList;
void Clear();
void ShowNext(int newIndex);
};
#endif // VTABLESEARCH_H

View File

@ -53,6 +53,8 @@
Q_LOGGING_CATEGORY(vApp, "v.application")
constexpr auto DAYS_TO_KEEP_LOGS = 3;
//---------------------------------------------------------------------------------------------------------------------
inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
@ -170,12 +172,8 @@ const QString VApplication::GistFileName = QStringLiteral("gist.json");
VApplication::VApplication(int &argc, char **argv)
: VAbstractApplication(argc, argv),
trVars(nullptr), autoSaveTimer(nullptr),
log(nullptr),
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
out(nullptr), logLock(nullptr)
#else
lockLog(),
out(nullptr)
#endif
{
VCommandLine::Reset(); // making sure will create new instance...just in case we will ever do 2 objects of VApplication
VCommandLine::Get(*this);
@ -187,16 +185,6 @@ VApplication::~VApplication()
{
qCDebug(vApp, "Application closing.");
qInstallMessageHandler(0); // Resore the message handler
delete out;
if (log != nullptr)
{
log->close();
delete log;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
delete logLock;
#endif
}
delete trVars;
VCommandLine::Reset();
}
@ -418,32 +406,25 @@ void VApplication::CreateLogDir() const
//---------------------------------------------------------------------------------------------------------------------
void VApplication::BeginLogging()
{
log = new QFile(LogPath());
if (log->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
{
out = new QTextStream(log);
qInstallMessageHandler(noisyFailureMsgHandler);
VlpCreateLock(lockLog, LogPath()+".lock", [this](){return new QFile(LogPath());});
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
logLock = new QLockFile(LogPath()+".lock");
logLock->setStaleLockTime(0);
if (TryLock(logLock))
if (lockLog->IsLocked())
{
if (lockLog->GetProtected()->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
{
out.reset(new QTextStream(lockLog->GetProtected().get()));
qInstallMessageHandler(noisyFailureMsgHandler);
qCDebug(vApp, "Log file %s was locked.", LogPath().toUtf8().constData());
}
else
{
qCDebug(vApp, "Failed to lock %s", LogPath().toUtf8().constData());
qCDebug(vApp, "Error type: %d", logLock->error());
qCDebug(vApp, "Error opening log file \'%s\'. All debug output redirected to console.",
LogPath().toUtf8().constData());
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
}
else
{
delete log;
log = nullptr;
qCDebug(vApp, "Error opening log file \'%s\'. All debug output redirected to console.",
LogPath().toUtf8().constData());
qCDebug(vApp, "Failed to lock %s", LogPath().toUtf8().constData());
}
}
@ -459,45 +440,29 @@ void VApplication::ClearOldLogs() const
if (allFiles.isEmpty() == false)
{
qCDebug(vApp, "Clearing old logs");
for (int i = 0; i < allFiles.size(); ++i)
for (int i = 0, sz = allFiles.size(); i < sz; ++i)
{
QFileInfo info(allFiles.at(i));
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
QLockFile *lock = new QLockFile(info.absoluteFilePath() + ".lock");
if (TryLock(lock))
auto fn = allFiles.at(i);
QFileInfo info(fn);
if (info.created().daysTo(QDateTime::currentDateTime()) >= DAYS_TO_KEEP_LOGS)
{
qCDebug(vApp, "Locked file %s", info.absoluteFilePath().toUtf8().constData());
QFile oldLog(allFiles.at(i));
if (oldLog.remove())
VLockGuard<QFile> tmp(info.absoluteFilePath() + ".lock", [&fn](){return new QFile(fn);});
if (tmp.GetProtected() != nullptr)
{
qCDebug(vApp, "Deleted %s", info.absoluteFilePath().toUtf8().constData());
if (tmp.GetProtected()->remove())
{
qCDebug(vApp, "Deleted %s", info.absoluteFilePath().toUtf8().constData());
}
else
{
qCDebug(vApp, "Could not delete %s", info.absoluteFilePath().toUtf8().constData());
}
}
else
{
qCDebug(vApp, "Could not delete %s", info.absoluteFilePath().toUtf8().constData());
qCDebug(vApp, "Failed to lock %s", info.absoluteFilePath().toUtf8().constData());
}
}
else
{
qCDebug(vApp, "Failed to lock %s", info.absoluteFilePath().toUtf8().constData());
}
delete lock;
lock = nullptr;
#else
if (info.created().daysTo(QDateTime::currentDateTime()) >= 3)
{
QFile oldLog(allFiles.at(i));
if (oldLog.remove())
{
qCDebug(vApp, "Deleted %s", info.absoluteFilePath().toUtf8().constData());
}
else
{
qCDebug(vApp, "Could not delete %s", info.absoluteFilePath().toUtf8().constData());
}
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
}
}
else
@ -614,7 +579,7 @@ void VApplication::StartLogging()
//---------------------------------------------------------------------------------------------------------------------
QTextStream *VApplication::LogFile()
{
return out;
return out.get();
}
//---------------------------------------------------------------------------------------------------------------------
@ -707,27 +672,28 @@ void VApplication::GatherLogs() const
const QStringList allFiles = logsDir.entryList(QDir::NoDotAndDotDot | QDir::Files);
if (allFiles.isEmpty() == false)
{
for (int i = 0; i < allFiles.size(); ++i)
for (int i = 0, sz = allFiles.size(); i < sz; ++i)
{
QFileInfo info(allFiles.at(i));
auto fn = allFiles.at(i);
QFileInfo info(fn);
if (info.fileName() == "valentina.log")
{
continue;
}
QLockFile *logLock = new QLockFile(info.absoluteFilePath()+".lock");
logLock->setStaleLockTime(0);
if (TryLock(logLock))
VLockGuard<QFile> tmp(info.absoluteFilePath() + ".lock", [&fn](){return new QFile(fn);});
if (tmp.IsLocked())
{
*out <<"--------------------------" << endl;
QFile logFile(info.absoluteFilePath());
if (logFile.open(QIODevice::ReadOnly | QIODevice::Text))
if (tmp.GetProtected()->open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&logFile);
QTextStream in(&tmp.GetProtected());
while (!in.atEnd())
{
*out << in.readLine() << endl;
}
logFile.close();
tmp.GetProtected()->close();
}
else
{
@ -736,9 +702,8 @@ void VApplication::GatherLogs() const
}
else
{
*out << "Could not lock" << info.absoluteFilePath() << ".";
qCDebug(vApp, "Failed to lock %s", info.absoluteFilePath().toUtf8().constData());
}
delete logLock;
}
}
else
@ -924,7 +889,9 @@ void VApplication::SendReport(const QString &reportName) const
const QString arg = QString("curl.exe -k -H \"Authorization: bearer ")+token.join("")+
QString("\" -H \"Accept: application/json\" -H \"Content-type: application/json\" -X POST "
"--data @gist.json https://api.github.com/gists");
QProcess::startDetached(arg);
QProcess proc;
proc.start(arg);
proc.waitForFinished(10000); // 10 sec
reportFile.remove();// Clear after yourself
}
else

View File

@ -36,7 +36,6 @@
#include "vsettings.h"
#include "vcmdexport.h"
class VApplication;// use in define
class VMainGraphicsView;
class VPattern;
@ -95,11 +94,9 @@ private:
VTranslateVars *trVars;
QTimer *autoSaveTimer;
QFile *log;
QTextStream *out;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
QLockFile *logLock;
#endif
VLockGuardPtr<QFile> lockLog;
std::shared_ptr<QTextStream> out;
void InitLineWidth();
#if defined(Q_OS_WIN) && defined(Q_CC_GNU)

View File

@ -214,7 +214,9 @@ Robert Martin
Michaela Orth
Rina Rivera
Fritz Rometsch
Felix Ulber </string>
Felix Ulber
Alex Zaharov
Valentina Zhuravska </string>
</property>
</widget>
</item>

View File

@ -46,6 +46,7 @@
#include "../vformat/vmeasurements.h"
#include "../ifc/xml/vvstconverter.h"
#include "../ifc/xml/vvitconverter.h"
#include "../vwidgets/vwidgetpopup.h"
#include <QInputDialog>
#include <QDebug>
@ -62,9 +63,6 @@
#include <QtGlobal>
#include <QDesktopWidget>
#include <QDesktopServices>
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
# include <QLockFile>
#endif
#include <chrono>
#include <thread>
@ -1162,13 +1160,16 @@ void MainWindow::SyncMeasurements()
{
if (mChanges)
{
if(LoadMeasurements(doc->MPath()))
const QString path = AbsoluteMPath(curFile, doc->MPath());
if(LoadMeasurements(path))
{
if (not watcher->files().contains(doc->MPath()))
if (not watcher->files().contains(path))
{
watcher->addPath(doc->MPath());
watcher->addPath(path);
}
helpLabel->setText(tr("Measurements updated"));
const QString msg = tr("Measurements was updated");
helpLabel->setText(msg);
VWidgetPopup::PopupMessage(this, msg);
doc->LiteParseTree(Document::LiteParse);
mChanges = false;
}
@ -1395,9 +1396,10 @@ void MainWindow::currentPPChanged(int index)
*/
void MainWindow::mouseMove(const QPointF &scenePos)
{
QString string = QString("%1, %2 (%3)").arg(static_cast<qint32>(qApp->fromPixel(scenePos.x())))
//: Coords in status line: "X, Y (units)"
QString string = QString(tr("%1, %2 (%3)")).arg(static_cast<qint32>(qApp->fromPixel(scenePos.x())))
.arg(static_cast<qint32>(qApp->fromPixel(scenePos.y())))
.arg(doc->UnitsToStr(qApp->patternUnit()));
.arg(doc->UnitsToStr(qApp->patternUnit(), true));
if (mouseCoordinate != nullptr)
{
mouseCoordinate->setText(string);
@ -1859,9 +1861,24 @@ bool MainWindow::SaveAs()
{
fileName += ".val";
}
const QString oldFileName = curFile;
if (QFileInfo(fileName).exists())
{
VLockGuard<char> tmp(fileName + ".lock");
if (not tmp.IsLocked())
{
if (lock->GetLockError() == QLockFile::LockFailedError)
{
qCCritical(vMainWindow, "%s", tr("Failed to lock. This file already opened in another window.")
.toUtf8().constData());
return false;
}
}
}
QString error;
bool result = SavePattern(fileName, error);
const bool result = SavePattern(fileName, error);
if (result == false)
{
QMessageBox messageBox;
@ -1871,14 +1888,33 @@ bool MainWindow::SaveAs()
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return result;
}
if (oldFileName != curFile)
{// Now we have new file name after save as.
// But still have previous name in restore list. We should delete them.
QStringList restoreFiles = qApp->ValentinaSettings()->GetRestoreFileList();
restoreFiles.removeAll(oldFileName);
qApp->ValentinaSettings()->SetRestoreFileList(restoreFiles);
qCDebug(vMainWindow, "Unlock old file");
lock.reset();
qCDebug(vMainWindow, "Locking file");
VlpCreateLock(lock, fileName+".lock");
if (lock->IsLocked())
{
qCDebug(vMainWindow, "Pattern file %s was locked.", fileName.toUtf8().constData());
}
else
{
qCDebug(vMainWindow, "Failed to lock %s", fileName.toUtf8().constData());
qCDebug(vMainWindow, "Error type: %d", lock->GetLockError());
if (lock->GetLockError() == QLockFile::LockFailedError)
{
qCCritical(vMainWindow, "%s", tr("Failed to lock. This file already opened in another window. "
"Expect collissions when run 2 copies of the program.")
.toUtf8().constData());
lock.reset();
}
}
return result;
}
@ -1983,13 +2019,8 @@ void MainWindow::OnlineHelp()
void MainWindow::Clear()
{
qCDebug(vMainWindow, "Reseting main window.");
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
delete lock; // Unlock pattern file
lock = nullptr;
lock.reset();
qCDebug(vMainWindow, "Unlocked pattern file.");
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
ui->actionDetails->setChecked(true);
ui->actionDraw->setChecked(true);
ui->actionLayout->setEnabled(true);
@ -3060,9 +3091,6 @@ MainWindow::~MainWindow()
CancelTool();
CleanLayout();
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
delete lock; // Unlock pattern file
#endif
delete doc;
delete sceneDetails;
delete sceneDraw;
@ -3091,26 +3119,24 @@ bool MainWindow::LoadPattern(const QString &fileName, const QString& customMeasu
return false;
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
qCDebug(vMainWindow, "Loking file");
lock = new QLockFile(fileName+".lock");
lock->setStaleLockTime(0);
if (VApplication::TryLock(lock))
VlpCreateLock(lock, fileName+".lock");
if (lock->IsLocked())
{
qCDebug(vMainWindow, "Pattern file %s was locked.", fileName.toUtf8().constData());
}
else
{
qCDebug(vMainWindow, "Failed to lock %s", fileName.toUtf8().constData());
qCDebug(vMainWindow, "Error type: %d", lock->error());
if (lock->error() == QLockFile::LockFailedError)
qCDebug(vMainWindow, "Error type: %d", lock->GetLockError());
if (lock->GetLockError() == QLockFile::LockFailedError)
{
qCCritical(vMainWindow, "%s", tr("This file already opened in another window.").toUtf8().constData());
Clear();
return false;
}
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
// On this stage scene empty. Fit scene size to view size
VMainGraphicsView::NewSceneRect(sceneDraw, ui->view);
@ -3213,14 +3239,11 @@ QStringList MainWindow::GetUnlokedRestoreFileList() const
for (int i = 0; i < files.size(); ++i)
{
// Seeking file that realy need reopen
QLockFile *lock = new QLockFile(files.at(i)+".lock");
lock->setStaleLockTime(0);
if (VApplication::TryLock(lock))
VLockGuard<char> tmp(files.at(i)+".lock");
if (tmp.IsLocked())
{
restoreFiles.append(files.at(i));
}
delete lock;
lock = nullptr;
}
// Clearing list after filtering
@ -3230,7 +3253,6 @@ QStringList MainWindow::GetUnlokedRestoreFileList() const
}
qApp->ValentinaSettings()->SetRestoreFileList(files);
}
return restoreFiles;
#else

View File

@ -37,7 +37,7 @@
#include "tools/vtooluniondetails.h"
#include "tools/drawTools/drawtools.h"
#include "core/vcmdexport.h"
#include <QLockFile>
#include "../vmisc/vlockguard.h"
#include <QPointer>
#include <QFileSystemWatcher>
@ -48,9 +48,6 @@ namespace Ui
}
class VToolOptionsPropertyBrowser;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
class QLockFile;
#endif
/**
* @brief The MainWindow class main windows.
@ -233,9 +230,7 @@ private:
QPointer<QLabel> gradationHeightsLabel;
QPointer<QLabel> gradationSizesLabel;
VToolOptionsPropertyBrowser *toolOptions;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
QLockFile *lock;
#endif
VLockGuardPtr<char> lock;
void ToolBarOption();
void ToolBarStages();

View File

@ -344,7 +344,7 @@ INSTALL_TRANSLATIONS += \
$${TRANSLATIONS_PATH}/measurements_p9_fi_FI.qm \
$${TRANSLATIONS_PATH}/measurements_p9_en_US.qm
TRANSLATIONS += \
INSTALL_TRANSLATIONS += \
$${TRANSLATIONS_PATH}/measurements_p10_ru_RU.qm \
$${TRANSLATIONS_PATH}/measurements_p10_uk_UA.qm \
$${TRANSLATIONS_PATH}/measurements_p10_de_DE.qm \

View File

@ -34,6 +34,10 @@
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="measurementName">
<xs:selector xpath="body-measurements/m"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">

View File

@ -74,6 +74,10 @@
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="incrementName">
<xs:selector xpath="increment"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:element name="draw" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>

View File

@ -35,6 +35,10 @@
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="measurementName">
<xs:selector xpath="body-measurements/m"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:simpleType name="shortName">
<xs:restriction base="xs:string">

View File

@ -1018,6 +1018,7 @@ QStringList VAbstractPattern::ListExpressions() const
list << ListPointExpressions();
list << ListArcExpressions();
list << ListSplineExpressions();
list << ListIncrementExpressions();
return list;
}
@ -1176,6 +1177,28 @@ QStringList VAbstractPattern::ListPathPointExpressions() const
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
QStringList VAbstractPattern::ListIncrementExpressions() const
{
QStringList expressions;
const QDomNodeList list = elementsByTagName(TagIncrement);
for (int i=0; i < list.size(); ++i)
{
const QDomElement dom = list.at(i).toElement();
try
{
expressions.append(GetParametrString(dom, IncrementFormula));
}
catch (VExceptionEmptyParameter &e)
{
Q_UNUSED(e)
}
}
return expressions;
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractPattern::IsVariable(const QString &token) const
{

View File

@ -248,6 +248,7 @@ private:
QStringList ListArcExpressions() const;
QStringList ListSplineExpressions() const;
QStringList ListPathPointExpressions() const;
QStringList ListIncrementExpressions() const;
bool IsVariable(const QString& token) const;
bool IsPostfixOperator(const QString& token) const;

128
src/libs/vmisc/debugbreak.h Normal file
View File

@ -0,0 +1,128 @@
/* Copyright (c) 2011-2015, Scott Tsai
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEBUG_BREAK_H
#define DEBUG_BREAK_H
#ifdef _MSC_VER
#define debug_break __debugbreak
#else
#include <signal.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
/* gcc optimizers consider code after __builtin_trap() dead.
* Making __builtin_trap() unsuitable for breaking into the debugger */
DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0,
};
#if defined(__i386__) || defined(__x86_64__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
__asm__ volatile("int $0x03");
}
#elif defined(__thumb__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
/* FIXME: handle __THUMB_INTERWORK__ */
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
/* See 'arm-linux-tdep.c' in GDB source.
* Both instruction sequences below work. */
#if 1
/* 'eabi_linux_thumb_le_breakpoint' */
__asm__ volatile(".inst 0xde01");
#else
/* 'eabi_linux_thumb2_le_breakpoint' */
__asm__ volatile(".inst.w 0xf7f0a000");
#endif
/* Known problem:
* After a breakpoint hit, can't stepi, step, or continue in GDB.
* 'step' stuck on the same instruction.
*
* Workaround: a new GDB command,
* 'debugbreak-step' is defined in debugbreak-gdb.py
* that does:
* (gdb) set $instruction_len = 2
* (gdb) tbreak *($pc + $instruction_len)
* (gdb) jump *($pc + $instruction_len)
*/
}
#elif defined(__arm__) && !defined(__thumb__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
/* See 'arm-linux-tdep.c' in GDB source,
* 'eabi_linux_arm_le_breakpoint' */
__asm__ volatile(".inst 0xe7f001f0");
/* Has same known problem and workaround
* as Thumb mode */
}
#elif defined(__aarch64__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
/* See 'aarch64-tdep.c' in GDB source,
* 'aarch64_default_breakpoint' */
__asm__ volatile(".inst 0xd4200000");
}
#else
enum { HAVE_TRAP_INSTRUCTION = 0, };
#endif
__attribute__((gnu_inline, always_inline))
static void __inline__ debug_break(void)
{
if (HAVE_TRAP_INSTRUCTION) {
trap_instruction();
} else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) {
/* raises SIGILL on Linux x86{,-64}, to continue in gdb:
* (gdb) handle SIGILL stop nopass
* */
__builtin_trap();
} else {
raise(SIGTRAP);
}
}
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -193,7 +193,7 @@ const QString neckSideToBustSideB_M = QStringLiteral("neck_side_to_bus
const QString shoulderTipToWaistB_1inOffset_M = QStringLiteral("shoulder_tip_to_waist_b_1in_offset"); // H13
// I
const QString armShoulderTipToWristBent_M = QStringLiteral("arm_shoulder_tip_to_wrist_bent"); // I01
const QString armShoulderTipToElbowBent_M = QStringLiteral(" arm_shoulder_tip_to_elbow_bent"); // I02
const QString armShoulderTipToElbowBent_M = QStringLiteral("arm_shoulder_tip_to_elbow_bent"); // I02
const QString armElbowToWristBent_M = QStringLiteral("arm_elbow_to_wrist_bent"); // I03
const QString armElbowCircBent_M = QStringLiteral("arm_elbow_circ_bent"); // I04
const QString armShoulderTipToWrist_M = QStringLiteral("arm_shoulder_tip_to_wrist"); // I05

View File

@ -36,6 +36,8 @@
#include <windows.h>
#endif /* Q_OS_WIN */
#include "debugbreak.h"
#define SceneSize 50000
#define DefPointRadius 1.5//mm
@ -160,43 +162,23 @@ enum class GSizes : unsigned char { ALL,
* https://stackoverflow.com/questions/1721543/continue-to-debug-after-failed-assertion-on-linux-c-c
*/
#ifndef V_NO_ASSERT
#ifdef Q_OS_WIN32
#ifdef Q_CC_MSVC
#define SCASSERT(cond) \
{ \
if (!(cond)) \
{ \
qDebug("ASSERT: %s in %s (%s:%u)", \
#cond, __FUNCSIG__, __FILE__, __LINE__); \
DebugBreak(); \
} \
} \
#else // GCC (Windows)
#define SCASSERT(cond) \
{ \
if (!(cond)) \
{ \
qDebug("ASSERT: %s in %s (%s:%u)", \
#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\
DebugBreak(); \
} \
} \
#define V_PRETTY_FUNCTION __FUNCSIG__
#else // GCC/Clang
#define V_PRETTY_FUNCTION __PRETTY_FUNCTION__
#endif /*Q_CC_MSVC*/
#else // UNIX
#define SCASSERT(cond) \
{ \
if (!(cond)) \
{ \
qDebug("ASSERT: %s in %s (%s:%u)", \
#cond, __PRETTY_FUNCTION__, __FILE__, __LINE__);\
std::raise(SIGTRAP); \
#cond, V_PRETTY_FUNCTION, __FILE__, __LINE__); \
debug_break(); \
} \
} \
#endif /* Q_OS_WIN32 */
#else // define but disable this function if debugging is not set
#define SCASSERT(cond) qt_noop();
#endif /* V_NO_ASSERT */

View File

@ -29,10 +29,6 @@
#include "vabstractapplication.h"
#include "../vmisc/def.h"
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
# include <QLockFile>
#endif
//---------------------------------------------------------------------------------------------------------------------
VAbstractApplication::VAbstractApplication(int &argc, char **argv)
:QApplication(argc, argv),
@ -116,43 +112,3 @@ double VAbstractApplication::fromPixel(double pix) const
{
return FromPixel(pix, _patternUnit);
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractApplication::TryLock(QLockFile *lock)
{
if (lock == nullptr)
{
return false;
}
if (lock->tryLock())
{
return true;
}
else
{
if (lock->error() == QLockFile::LockFailedError)
{
// This happens if a stale lock file exists and another process uses that PID.
// Try removing the stale file, which will fail if a real process is holding a
// file-level lock. A false error is more problematic than not locking properly
// on corner-case systems.
if (lock->removeStaleLockFile() == false || lock->tryLock() == false)
{
return false;
}
else
{
return true;
}
}
else
{
return false;
}
return false;
}
}
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)

View File

@ -33,15 +33,13 @@
#include <QGraphicsScene>
#include "def.h"
#include "vsettings.h"
#include "vlockguard.h"
class VAbstractApplication;// use in define
class VTranslateVars;
class VAbstractPattern;
class VMainGraphicsView;
class QUndoStack;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
class QLockFile;
#endif
#if defined(qApp)
#undef qApp
@ -89,10 +87,6 @@ public:
QUndoStack *getUndoStack() const;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
static bool TryLock(QLockFile *lock);
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
protected:
QUndoStack *undoStack;

200
src/libs/vmisc/vlockguard.h Normal file
View File

@ -0,0 +1,200 @@
/************************************************************************
**
** @file VLockGuard.h
** @author Alex Zaharov <alexzkhr@gmail.com>
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 14 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** 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/>.
**
*************************************************************************/
#ifndef VLOCKGUARD_H
#define VLOCKGUARD_H
#include <QString>
#include <stdint.h>
#include <memory>
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
#include <QLockFile>
#define PEDANT_COMPILER ,lock(nullptr)
#else
#define PEDANT_COMPILER
#warning To have lock-file support you must use Qt 5.1+. Expect collissions when run 2 copies of the program.
#endif
/*@brief
* This class creates Guarded object if and only if lock file taken. It keeps shared_ptr to object and lock-file.
* Can use optional object allocator and deleter.
*
* On older Qt lock assumed always taken and compile-time warning is shown.
*
*/
template <typename Guarded>
class VLockGuard
{
public:
VLockGuard(const QString& lockName, int stale = 0, int timeout = 0);
template <typename Alloc>
VLockGuard(const QString& lockName, Alloc a, int stale = 0, int timeout=0);
template <typename Alloc, typename Delete>
VLockGuard(const QString& lockName, Alloc a, Delete d, int stale = 0, int timeout=0);
const std::shared_ptr<Guarded> &GetProtected() const;
int GetLockError() const;
bool IsLocked() const;
private:
Q_DISABLE_COPY(VLockGuard<Guarded>)
std::shared_ptr<Guarded> holder;
int lockError;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
std::shared_ptr<QLockFile> lock;
#endif
bool TryLock(const QString &lockName, int stale, int timeout);
};
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded>
VLockGuard<Guarded>::VLockGuard(const QString &lockName, int stale, int timeout)
: holder(nullptr), lockError(0) PEDANT_COMPILER
{
if (TryLock(lockName, stale, timeout))
{
holder.reset(new Guarded());
}
}
//---------------------------------------------------------------------------------------------------------------------
//using allocator lambdas seems logically better than supplying pointer, because we will take ownership of allocated
//object
template <typename Guarded> template <typename Alloc>
VLockGuard<Guarded>::VLockGuard(const QString& lockName, Alloc a, int stale, int timeout)
: holder(nullptr), lockError(0) PEDANT_COMPILER
{
if (TryLock(lockName, stale, timeout))
{
holder.reset(a());
}
}
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded> template <typename Alloc, typename Delete>
VLockGuard<Guarded>::VLockGuard(const QString& lockName, Alloc a, Delete d, int stale, int timeout)
: holder(nullptr), lockError(0) PEDANT_COMPILER
{
if (TryLock(lockName, stale, timeout))
{
holder.reset(a(), d);
}
}
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded>
const std::shared_ptr<Guarded> &VLockGuard<Guarded>::GetProtected() const
{
return holder;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded>
int VLockGuard<Guarded>::GetLockError() const
{
return lockError;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded>
bool VLockGuard<Guarded>::IsLocked() const
{
return holder != nullptr;
}
//---------------------------------------------------------------------------------------------------------------------
template <typename Guarded>
bool VLockGuard<Guarded>::TryLock(const QString &lockName, int stale, int timeout)
{
bool res = true;
#if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
lock.reset(new QLockFile(lockName));
lock->setStaleLockTime(stale);
for (int i = 0; i < 2 && !lock->tryLock(timeout); i++)
{
if (QLockFile::LockFailedError != lock->error())
{
break;
}
else
{
// This happens if a stale lock file exists and another process uses that PID.
// Try removing the stale file, which will fail if a real process is holding a
// file-level lock. A false error is more problematic than not locking properly
// on corner-case systems.
lock->removeStaleLockFile();
lock->tryLock(timeout);
}
}
res = QLockFile::NoError == (lockError = lock->error());
if (!res)
{
lock.reset();
}
#endif
return res;
}
#undef PEDANT_COMPILER
//use pointer and function below to persistent things like class-member, because lock is taken by constructor
//helper functions allow to write shorter creating and setting new lock-pointer
//new C++11 - "template typedef" http://stackoverflow.com/questions/2795023/c-template-typedef
template <typename Guarded>
using VLockGuardPtr = std::shared_ptr<VLockGuard<Guarded>>;
template <typename Guarded>
void VlpCreateLock(VLockGuardPtr<Guarded>& r, const QString& lockName, int stale = 0, int timeout = 0)
{
r.reset(new VLockGuard<Guarded>(lockName, stale, timeout));
}
template <typename Guarded, typename Alloc>
void VlpCreateLock(VLockGuardPtr<Guarded>& r, const QString& lockName, Alloc a, int stale = 0, int timeout = 0)
{
r.reset(new VLockGuard<Guarded>(lockName, a, stale, timeout));
}
template <typename Guarded, typename Alloc, typename Del>
void VlpCreateLock(VLockGuardPtr<Guarded>& r, const QString& lockName, Alloc a, Del d, int stale = 0, int timeout = 0)
{
r.reset(new VLockGuard<Guarded>(lockName, a, d, stale, timeout));
}
#endif // VLOCKGUARD_H

View File

@ -25,4 +25,6 @@ HEADERS += \
$$PWD/vabstractapplication.h \
$$PWD/projectversion.h \
$$PWD/vcommonsettings.h \
$$PWD/vtapesettings.h
$$PWD/vtapesettings.h \
$$PWD/debugbreak.h \
$$PWD/vlockguard.h

View File

@ -31,14 +31,13 @@
//---------------------------------------------------------------------------------------------------------------------
DeletePatternPiece::DeletePatternPiece(VAbstractPattern *doc, const QString &namePP, QUndoCommand *parent)
: VUndoCommand(QDomElement(), doc, parent), namePP(namePP), patternPiece(QDomElement()), mPath(QString()),
: VUndoCommand(QDomElement(), doc, parent), namePP(namePP), patternPiece(QDomElement()),
previousPPName(QString())
{
setText(tr("delete pattern piece %1").arg(namePP));
QDomElement patternP = doc->GetPPElement(namePP);
patternPiece = patternP.cloneNode().toElement();
mPath = doc->MPath();
QDomNode previousPP = patternP.previousSibling();//find previous pattern piece
previousPPName = doc->GetParametrString(previousPP.toElement(), VAbstractPattern::AttrName, "");
}

View File

@ -43,7 +43,6 @@ private:
Q_DISABLE_COPY(DeletePatternPiece)
QString namePP;
QDomElement patternPiece;
QString mPath;
QString previousPPName;
};

View File

@ -31,6 +31,9 @@
#include <QVBoxLayout>
#include <QDesktopWidget>
#include <QTimer>
#include <QLabel>
#include "../vmisc/def.h"
//---------------------------------------------------------------------------------------------------------------------
VWidgetPopup::VWidgetPopup(QWidget *parent)
@ -77,6 +80,22 @@ void VWidgetPopup::SetWidget(QWidget *widget, bool own)
}
}
//---------------------------------------------------------------------------------------------------------------------
void VWidgetPopup::PopupMessage(QWidget *w, const QString &msg)
{
SCASSERT(w != nullptr);
VWidgetPopup *popup = new VWidgetPopup();
QLabel *label = new QLabel(msg);
QFont f = label->font();
f.setBold(true);
f.setPixelSize(16);
label->setFont(f);
popup->SetWidget(label);
popup->SetLifeTime(2000);
popup->Show(w->frameGeometry().center());
}
//---------------------------------------------------------------------------------------------------------------------
void VWidgetPopup::Show(QPoint coord)
{

View File

@ -67,6 +67,8 @@ public:
int GetLifeTime() const;
void SetLifeTime(int value);
static void PopupMessage(QWidget *w, const QString &msg);
public slots:
/** Pops up the widget at global coordinates \a coord. */
void Show(QPoint coord);

View File

@ -42,7 +42,8 @@ SOURCES += \
tst_nameregexp.cpp \
tst_vlayoutdetail.cpp \
tst_varc.cpp \
stable.cpp
stable.cpp \
tst_measurementregexp.cpp
HEADERS += \
tst_vposter.h \
@ -52,7 +53,8 @@ HEADERS += \
tst_nameregexp.h \
tst_vlayoutdetail.h \
tst_varc.h \
stable.h
stable.h \
tst_measurementregexp.h
# Set using ccache. Function enable_ccache() defined in common.pri.
$$enable_ccache()
@ -115,6 +117,42 @@ CONFIG(debug, debug|release){
}
}
#VPatternDB static library (depend on vgeometry, vmisc, VLayout)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vpatterndb/$${DESTDIR} -lvpatterndb
INCLUDEPATH += $$PWD/../../libs/vpatterndb
DEPENDPATH += $$PWD/../../libs/vpatterndb
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/vpatterndb.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vpatterndb/$${DESTDIR}/libvpatterndb.a
#VMisc static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vmisc/$${DESTDIR}/ -lvmisc
INCLUDEPATH += $$PWD/../../libs/vmisc
DEPENDPATH += $$PWD/../../libs/vmisc
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/vmisc.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vmisc/$${DESTDIR}/libvmisc.a
# VGeometry static library (depend on ifc)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vgeometry/$${DESTDIR} -lvgeometry
INCLUDEPATH += $$PWD/../../libs/vgeometry
DEPENDPATH += $$PWD/../../libs/vgeometry
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/vgeometry.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/libvgeometry.a
# IFC static library (depend on QMuParser)
unix|win32: LIBS += -L$$OUT_PWD/../../libs/ifc/$${DESTDIR}/ -lifc
INCLUDEPATH += $$PWD/../../libs/ifc
DEPENDPATH += $$PWD/../../libs/ifc
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/ifc/$${DESTDIR}/ifc.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/ifc/$${DESTDIR}/libifc.a
# VLayout static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vlayout/$${DESTDIR} -lvlayout
@ -124,11 +162,10 @@ DEPENDPATH += $$PWD/../../libs/vlayout
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vlayout/$${DESTDIR}/vlayout.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vlayout/$${DESTDIR}/libvlayout.a
# VGeometry static library
unix|win32: LIBS += -L$$OUT_PWD/../../libs/vgeometry/$${DESTDIR} -lvgeometry
# QMuParser library
win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser2
else:unix: LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser
INCLUDEPATH += $$PWD/../../libs/vgeometry
DEPENDPATH += $$PWD/../../libs/vgeometry
win32:!win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/vgeometry.lib
else:unix|win32-g++: PRE_TARGETDEPS += $$OUT_PWD/../../libs/vgeometry/$${DESTDIR}/libvgeometry.a
INCLUDEPATH += $${PWD}/../../libs/qmuparser
DEPENDPATH += $${PWD}/../../libs/qmuparser

View File

@ -34,6 +34,7 @@
#include "tst_nameregexp.h"
#include "tst_vlayoutdetail.h"
#include "tst_varc.h"
#include "tst_measurementregexp.h"
int main(int argc, char** argv)
{
@ -52,6 +53,7 @@ int main(int argc, char** argv)
ASSERT_TEST(new TST_NameRegExp());
ASSERT_TEST(new TST_VLayoutDetail());
ASSERT_TEST(new TST_VArc());
ASSERT_TEST(new TST_MeasurementRegExp());
return status;
}

View File

@ -0,0 +1,234 @@
/************************************************************************
**
** @file tst_measurementregexp.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** 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 "tst_measurementregexp.h"
#include "../qmuparser/qmudef.h"
#include "../vmisc/def.h"
#include "../vpatterndb/vtranslatemeasurements.h"
#include <QtTest>
#include <QTranslator>
enum ErrorState {ErrorLoad = 0, ErrorInstall, ErrorSize, NoError};
//---------------------------------------------------------------------------------------------------------------------
TST_MeasurementRegExp::TST_MeasurementRegExp(QObject *parent)
:QObject(parent),
pmsTranslator(nullptr),
trMs(nullptr)
{
}
//---------------------------------------------------------------------------------------------------------------------
TST_MeasurementRegExp::~TST_MeasurementRegExp()
{
delete pmsTranslator;
delete trMs;
}
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
void TST_MeasurementRegExp::TestOriginalMeasurementNamesRegExp()
{
const QStringList originalNames = OriginalNames();
const QRegularExpression re(NameRegExp());
foreach(const QString &str, originalNames)
{
QCOMPARE(re.match(str).hasMatch(), true);
}
}
//---------------------------------------------------------------------------------------------------------------------
// cppcheck-suppress unusedFunction
void TST_MeasurementRegExp::TestMeasurementRegExp()
{
const int systemCounts = 55;
const QStringList locales {"ru_RU", "uk_UA", "de_DE", "cs_CZ", "he_IL", "fr_FR", "it_IT", "nl_NL", "id_ID",
"es_ES", "fi_FI", "en_US"};
{
const int combinations = systemCounts * locales.size(); // 55*12=660
QDir dir(TranslationsPath());
const QStringList fileNames = dir.entryList(QStringList("measurements_p*_*.qm"));
QVERIFY2(combinations == fileNames.size(), "Unexpected count of files.");
}
for(int s = 0; s < systemCounts; ++s)
{
for(int l = 0, sz = locales.size(); l < sz; ++l)
{
const int res = LoadTranslation(QString("p%1").arg(s), locales.at(l));
switch(res)
{
case ErrorInstall:
case ErrorSize:
case ErrorLoad:
{
const QString message = QString("Failed to check translation for system = p%1 and locale = %2")
.arg(s)
.arg(locales.at(l));
QFAIL(message.toUtf8().constData());
break;
}
case NoError:
{
CheckNames();
if (not pmsTranslator.isNull())
{
const bool result = QCoreApplication::removeTranslator(pmsTranslator);
if (result == false)
{
const QString message = QString("Can't remove translation for system = p%1 and locale = %2")
.arg(s)
.arg(locales.at(l));
QWARN(message.toUtf8().constData());
}
delete pmsTranslator;
}
}
default:
QWARN("Unexpected state");
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
QString TST_MeasurementRegExp::TranslationsPath() const
{
return QApplication::applicationDirPath() + QStringLiteral("/../../../app/valentina/bin/translations");
}
//---------------------------------------------------------------------------------------------------------------------
int TST_MeasurementRegExp::LoadTranslation(const QString &checkedSystem, const QString &checkedLocale)
{
const QString path = TranslationsPath();
const QString file = QString("measurements_%1_%2.qm").arg(checkedSystem).arg(checkedLocale);
if (QFileInfo(path+"/"+file).size() <= 34)
{
const QString message = QString("Translation for system = %1 and locale = %2 is empty. \nFull path: %3/%4")
.arg(checkedSystem)
.arg(checkedLocale)
.arg(path)
.arg(file);
QWARN(message.toUtf8().constData());
return ErrorSize;
}
pmsTranslator = new QTranslator(this);
if (not pmsTranslator->load(file, path))
{
const QString message = QString("Can't load translation for system = %1 and locale = %2. \nFull path: %3/%4")
.arg(checkedSystem)
.arg(checkedLocale)
.arg(path)
.arg(file);
QWARN(message.toUtf8().constData());
delete pmsTranslator;
return ErrorLoad;
}
if (not QCoreApplication::installTranslator(pmsTranslator))
{
const QString message = QString("Can't install translation for system = %1 and locale = %2. \nFull path: %3/%4")
.arg(checkedSystem)
.arg(checkedLocale)
.arg(path)
.arg(file);
QWARN(message.toUtf8().constData());
delete pmsTranslator;
return ErrorInstall;
}
InitTrMs();//Very important do it after load QM file.
return NoError;
}
//---------------------------------------------------------------------------------------------------------------------
void TST_MeasurementRegExp::InitTrMs()
{
if (trMs != nullptr)
{
trMs->Retranslate();
}
else
{
trMs = new VTranslateMeasurements();
}
}
//---------------------------------------------------------------------------------------------------------------------
void TST_MeasurementRegExp::CheckNames() const
{
const QStringList originalNames = OriginalNames();
const QRegularExpression re(NameRegExp());
foreach(const QString &str, originalNames)
{
const QString translated = trMs->MToUser(str);
QCOMPARE(re.match(translated).hasMatch(), true);
}
}
//---------------------------------------------------------------------------------------------------------------------
QStringList TST_MeasurementRegExp::OriginalNames() const
{
const QStringList originalNames = QStringList() << ListGroupA()
<< ListGroupB()
<< ListGroupC()
<< ListGroupD()
<< ListGroupE()
<< ListGroupF()
<< ListGroupG()
<< ListGroupH()
<< ListGroupI()
<< ListGroupJ()
<< ListGroupK()
<< ListGroupL()
<< ListGroupM()
<< ListGroupN()
<< ListGroupO()
<< ListGroupP()
<< ListGroupQ();
return originalNames;
}

View File

@ -0,0 +1,61 @@
/************************************************************************
**
** @file tst_measurementregexp.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @date 16 9, 2015
**
** @brief
** @copyright
** This source code is part of the Valentine project, a pattern making
** 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/>.
**
*************************************************************************/
#ifndef TST_MEASUREMENTREGEXP_H
#define TST_MEASUREMENTREGEXP_H
#include <QObject>
class QTranslator;
class VTranslateMeasurements;
class TST_MeasurementRegExp : public QObject
{
Q_OBJECT
public:
explicit TST_MeasurementRegExp(QObject *parent = 0);
virtual ~TST_MeasurementRegExp() Q_DECL_OVERRIDE;
private slots:
void TestOriginalMeasurementNamesRegExp();
void TestMeasurementRegExp();
private:
Q_DISABLE_COPY(TST_MeasurementRegExp)
QPointer<QTranslator> pmsTranslator;
VTranslateMeasurements *trMs;
QString TranslationsPath() const;
int LoadTranslation(const QString &checkedSystem, const QString &checkedLocale);
void InitTrMs();
void CheckNames() const;
QStringList OriginalNames() const;
};
#endif // TST_MEASUREMENTREGEXP_H