Merge
--HG-- branch : develop
This commit is contained in:
commit
2bfd22c02c
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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">
|
||||
|
|
208
src/app/tape/vtablesearch.cpp
Normal file
208
src/app/tape/vtablesearch.cpp
Normal 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);
|
||||
}
|
||||
}
|
58
src/app/tape/vtablesearch.h
Normal file
58
src/app/tape/vtablesearch.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
128
src/libs/vmisc/debugbreak.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
200
src/libs/vmisc/vlockguard.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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, "");
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ private:
|
|||
Q_DISABLE_COPY(DeletePatternPiece)
|
||||
QString namePP;
|
||||
QDomElement patternPiece;
|
||||
QString mPath;
|
||||
QString previousPPName;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
234
src/test/ValentinaTest/tst_measurementregexp.cpp
Normal file
234
src/test/ValentinaTest/tst_measurementregexp.cpp
Normal 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;
|
||||
}
|
61
src/test/ValentinaTest/tst_measurementregexp.h
Normal file
61
src/test/ValentinaTest/tst_measurementregexp.h
Normal 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
|
Loading…
Reference in New Issue
Block a user