Resolved issue #619. Non writable directory prevents opening.

--HG--
branch : develop
This commit is contained in:
Roman Telezhynskyi 2017-02-04 13:28:47 +02:00
parent 4831d263b9
commit 7d78a0f63f
20 changed files with 545 additions and 596 deletions

View File

@ -54,6 +54,7 @@
- [#88] New feature: Variable width seam allowances.
- [#280] New tool: 'Hem' in Detail mode.
- [#509] Improve feature: Support internal Paths in Detail tool.
- [#619] Non writable directory prevents opening.
# Version 0.4.6
- [#594] Broken export on Mac.

View File

@ -95,6 +95,7 @@ TMainWindow::TMainWindow(QWidget *parent)
actionDockDiagram(nullptr),
dockDiagramVisible(true),
isInitialized(false),
mIsReadOnly(false),
recentFileActs(),
separatorAct(nullptr),
hackedWidgets()
@ -128,9 +129,7 @@ TMainWindow::TMainWindow(QWidget *parent)
}
SetupMenu();
setWindowTitle(tr("untitled %1").arg(qApp->MainWindows().size()+1));
UpdateWindowTitle();
ReadSettings();
#if defined(Q_OS_MAC)
@ -269,20 +268,14 @@ bool TMainWindow::LoadFile(const QString &path)
if (mType == MeasurementsType::Standard)
{
VVSTConverter converter(path);
converter.Convert();
VDomDocument::ValidateXML(VVSTConverter::CurrentSchema, path);
m->setXMLContent(converter.Convert());// Read again after conversion
}
else
{
VVITConverter converter(path);
converter.Convert();
VDomDocument::ValidateXML(VVITConverter::CurrentSchema, path);
m->setXMLContent(converter.Convert());// Read again after conversion
}
m->setXMLContent(path);// Read again after conversion
if (not m->IsDefinedKnownNamesValid())
{
VException e(tr("File contains invalid known measurement(s)."));
@ -298,6 +291,9 @@ bool TMainWindow::LoadFile(const QString &path)
ui->labelToolTip->setVisible(false);
ui->tabWidget->setVisible(true);
mIsReadOnly = m->IsReadOnly();
UpdatePadlock(mIsReadOnly);
SetCurrentFile(path);
InitWindow();
@ -309,7 +305,7 @@ bool TMainWindow::LoadFile(const QString &path)
ui->tableWidget->selectRow(0);
}
GUIReadOnly(m->ReadOnly()); // Keep last
MeasurementGUI();
}
catch (VException &e)
{
@ -367,12 +363,15 @@ void TMainWindow::FileNew()
m = new VMeasurements(mUnit, data);
}
mIsReadOnly = m->IsReadOnly();
UpdatePadlock(mIsReadOnly);
SetCurrentFile("");
MeasurementsWasSaved(false);
InitWindow();
GUIReadOnly(m->ReadOnly()); // Keep last
MeasurementGUI();
}
else
{
@ -608,45 +607,93 @@ bool TMainWindow::eventFilter(QObject *object, QEvent *event)
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::FileSave()
bool TMainWindow::FileSave()
{
if (curFile.isEmpty())
if (curFile.isEmpty() || mIsReadOnly)
{
return FileSaveAs();
}
else
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The measurements document has no write permissions."));
messageBox.setInformativeText("Do you want to change the premissions?");
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::Yes)
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
bool changed = QFile::setPermissions(curFile,
QFileInfo(curFile).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.").arg(curFile));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
}
QString error;
if (not SaveMeasurements(curFile, error))
{
QMessageBox messageBox;
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(tr("Could not save file"));
messageBox.setText(tr("Could not save the file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::FileSaveAs()
bool TMainWindow::FileSaveAs()
{
QString filters;
QString fName = tr("measurements");
QString suffix;
if (mType == MeasurementsType::Individual)
{
filters = tr("Individual measurements (*.vit)");
suffix = "vit";
fName += "." + suffix;
filters = tr("Individual measurements") + QLatin1String(" (*.vit)");
suffix = QLatin1String("vit");
fName += QLatin1String(".") + suffix;
}
else
{
filters = tr("Standard measurements (*.vst)");
suffix = "vst";
fName += "." + suffix;
filters = tr("Standard measurements") + QLatin1String(" (*.vst)");
suffix = QLatin1String("vst");
fName += QLatin1String(".") + suffix;
}
QString dir;
@ -654,30 +701,30 @@ void TMainWindow::FileSaveAs()
{
if (mType == MeasurementsType::Individual)
{
dir = qApp->TapeSettings()->GetPathIndividualMeasurements() + "/" + fName;
dir = qApp->TapeSettings()->GetPathIndividualMeasurements() + QLatin1String("/") + fName;
}
else
{
dir = qApp->TapeSettings()->GetPathStandardMeasurements() + "/" + fName;
dir = qApp->TapeSettings()->GetPathStandardMeasurements() + QLatin1String("/") + fName;
}
}
else
{
dir = QFileInfo(curFile).absolutePath() + "/" + fName;
dir = QFileInfo(curFile).absolutePath() + QLatin1String("/") + fName;
}
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), dir, filters);
if (fileName.isEmpty())
{
return;
return false;
}
QFileInfo f( fileName );
if (f.suffix().isEmpty() && f.suffix() != suffix)
{
fileName += "." + suffix;
fileName += QLatin1String(".") + suffix;
}
if (QFileInfo(fileName).exists())
@ -688,11 +735,16 @@ void TMainWindow::FileSaveAs()
{
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("Failed to lock. This file already opened in another window.")));
return;
return false;
}
}
ReadOnly(false);
// Need for restoring previous state in case of failure
const bool readOnly = m->IsReadOnly();
m->SetReadOnly(false);
mIsReadOnly = false;
QString error;
bool result = SaveMeasurements(fileName, error);
if (result == false)
@ -705,16 +757,23 @@ void TMainWindow::FileSaveAs()
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return;
// Restore previous state
m->SetReadOnly(readOnly);
mIsReadOnly = readOnly;
return false;
}
UpdatePadlock(false);
UpdateWindowTitle();
VlpCreateLock(lock, fileName);
if (not lock->IsLocked())
{
qCCritical(tMainWindow, "%s", qUtf8Printable(tr("Failed to lock. This file already opened in another window. "
"Expect collissions when run 2 copies of the program.")));
return;
return false;
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
@ -925,15 +984,6 @@ void TMainWindow::SavePMSystem(int index)
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::ReadOnly(bool ro)
{
m->SetReadOnly(ro);
MeasurementsWasSaved(false);
GUIReadOnly(ro);
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::Remove()
{
@ -1247,19 +1297,12 @@ void TMainWindow::ImportFromPattern()
return;
}
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
QStringList measurements;
try
{
VPatternConverter converter(mPath);
converter.Convert();
VDomDocument::ValidateXML(VPatternConverter::CurrentSchema, mPath);
QScopedPointer<VLitePattern> doc(new VLitePattern());
doc->setXMLContent(mPath);
doc->setXMLContent(converter.Convert());
measurements = doc->ListMeasurements();
}
catch (VException &e)
@ -1269,10 +1312,6 @@ void TMainWindow::ImportFromPattern()
return;
}
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
measurements = FilterMeasurements(measurements, m->ListAll());
qint32 currentRow;
@ -1410,7 +1449,7 @@ void TMainWindow::ShowMData()
ui->plainTextEditFormula->blockSignals(false);
}
MeasurementReadOnly(m->ReadOnly());
MeasurementGUI();
}
else
{
@ -1779,7 +1818,23 @@ void TMainWindow::SetupMenu()
ui->actionSaveAs->setShortcuts(QKeySequence::SaveAs);
connect(ui->actionExportToCSV, &QAction::triggered, this, &TMainWindow::ExportToCSV);
connect(ui->actionReadOnly, &QAction::triggered, this, &TMainWindow::ReadOnly);
connect(ui->actionReadOnly, &QAction::triggered, RECEIVER(this)[this](bool ro)
{
if (not mIsReadOnly)
{
m->SetReadOnly(ro);
MeasurementsWasSaved(false);
UpdatePadlock(ro);
UpdateWindowTitle();
}
else
{
if (QAction *action = qobject_cast< QAction * >(this->sender()))
{
action->setChecked(true);
}
}
});
connect(ui->actionPreferences, &QAction::triggered, this, &TMainWindow::Preferences);
for (int i = 0; i < MaxRecentFiles; ++i)
@ -1975,11 +2030,11 @@ void TMainWindow::InitWindow()
connect(ui->toolButtonFindPrevious, &QToolButton::clicked, [this] (){search->FindPrevious();});
connect(ui->toolButtonFindNext, &QToolButton::clicked, [this] (){search->FindNext();});
connect(search.data(), &VTableSearch::HasResult, [this] (bool state)
connect(search.data(), &VTableSearch::HasResult, RECEIVER(this)[this] (bool state)
{
ui->toolButtonFindPrevious->setEnabled(state);
});
connect(search.data(), &VTableSearch::HasResult, [this] (bool state)
connect(search.data(), &VTableSearch::HasResult, RECEIVER(this)[this] (bool state)
{
ui->toolButtonFindNext->setEnabled(state);
});
@ -1990,7 +2045,6 @@ void TMainWindow::InitWindow()
ui->actionAddCustom->setEnabled(true);
ui->actionAddKnown->setEnabled(true);
ui->actionImportFromPattern->setEnabled(true);
ui->actionReadOnly->setEnabled(true);
ui->actionSaveAs->setEnabled(true);
#if QT_VERSION > QT_VERSION_CHECK(5, 1, 0)
@ -2073,18 +2127,15 @@ void TMainWindow::ShowHeaderUnits(QTableWidget *table, int column, const QString
void TMainWindow::MeasurementsWasSaved(bool saved)
{
setWindowModified(!saved);
ui->actionSave->setEnabled(!saved);
not mIsReadOnly ? ui->actionSave->setEnabled(!saved): ui->actionSave->setEnabled(false);
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::SetCurrentFile(const QString &fileName)
{
curFile = fileName;
QString shownName = QFileInfo(curFile).fileName();
if (curFile.isEmpty())
{
shownName = tr("untitled");
mType == MeasurementsType::Standard ? shownName += QLatin1String(".vst") : shownName += QLatin1String(".vit");
ui->lineEditPathToFile->setText(tr("<Empty>"));
ui->lineEditPathToFile->setToolTip(tr("File was not saved yet."));
ui->lineEditPathToFile->setCursorPosition(0);
@ -2107,33 +2158,8 @@ void TMainWindow::SetCurrentFile(const QString &fileName)
settings->SetRecentFileList(files);
UpdateRecentFileActions();
}
shownName += "[*]";
setWindowTitle(shownName);
setWindowFilePath(curFile);
#if defined(Q_OS_MAC)
static QIcon fileIcon = QIcon(QApplication::applicationDirPath() +
QLatin1String("/../Resources/measurements.icns"));
QIcon icon;
if (not curFile.isEmpty())
{
if (not isWindowModified())
{
icon = fileIcon;
}
else
{
static QIcon darkIcon;
if (darkIcon.isNull())
{
darkIcon = QIcon(darkenPixmap(fileIcon.pixmap(16, 16)));
}
icon = darkIcon;
}
}
setWindowIcon(icon);
#endif //defined(Q_OS_MAC)
UpdateWindowTitle();
}
//---------------------------------------------------------------------------------------------------------------------
@ -2167,7 +2193,7 @@ bool TMainWindow::MaybeSave()
messageBox->setDefaultButton(QMessageBox::Yes);
messageBox->setEscapeButton(QMessageBox::Cancel);
messageBox->setButtonText(QMessageBox::Yes, curFile.isEmpty() ? tr("Save...") : tr("Save"));
messageBox->setButtonText(QMessageBox::Yes, curFile.isEmpty() || mIsReadOnly ? tr("Save...") : tr("Save"));
messageBox->setButtonText(QMessageBox::No, tr("Don't Save"));
messageBox->setWindowModality(Qt::ApplicationModal);
@ -2176,8 +2202,14 @@ bool TMainWindow::MaybeSave()
switch (ret)
{
case QMessageBox::Yes:
FileSave();
return true;
if (mIsReadOnly)
{
return FileSaveAs();
}
else
{
return FileSave();
}
case QMessageBox::No:
return true;
case QMessageBox::Cancel:
@ -2364,16 +2396,6 @@ void TMainWindow::RefreshTable()
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::Controls()
{
if (m->ReadOnly())
{
ui->toolButtonRemove->setEnabled(false);
ui->toolButtonTop->setEnabled(false);
ui->toolButtonUp->setEnabled(false);
ui->toolButtonDown->setEnabled(false);
ui->toolButtonBottom->setEnabled(false);
return;
}
if (ui->tableWidget->rowCount() > 0)
{
ui->toolButtonRemove->setEnabled(true);
@ -2449,6 +2471,63 @@ void TMainWindow::MFields(bool enabled)
}
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::UpdateWindowTitle()
{
QString showName;
bool isFileWritable = true;
if (not curFile.isEmpty())
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
showName = StrippedName(curFile);
}
else
{
showName = tr("untitled %1").arg(qApp->MainWindows().size()+1);
mType == MeasurementsType::Standard ? showName += QLatin1String(".vst") : showName += QLatin1String(".vit");
}
showName += QLatin1String("[*]");
if (mIsReadOnly || not isFileWritable)
{
showName += QLatin1String(" (") + tr("read only") + QLatin1String(")");
}
setWindowTitle(showName);
setWindowFilePath(curFile);
#if defined(Q_OS_MAC)
static QIcon fileIcon = QIcon(QApplication::applicationDirPath() +
QLatin1String("/../Resources/measurements.icns"));
QIcon icon;
if (not curFile.isEmpty())
{
if (not isWindowModified())
{
icon = fileIcon;
}
else
{
static QIcon darkIcon;
if (darkIcon.isNull())
{
darkIcon = QIcon(darkenPixmap(fileIcon.pixmap(16, 16)));
}
icon = darkIcon;
}
}
setWindowIcon(icon);
#endif //defined(Q_OS_MAC)
}
//---------------------------------------------------------------------------------------------------------------------
QString TMainWindow::ClearCustomName(const QString &name) const
{
@ -2530,7 +2609,7 @@ void TMainWindow::Open(const QString &pathTo, const QString &filter)
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::GUIReadOnly(bool ro)
void TMainWindow::UpdatePadlock(bool ro)
{
ui->actionReadOnly->setChecked(ro);
if (ro)
@ -2542,90 +2621,26 @@ void TMainWindow::GUIReadOnly(bool ro)
ui->actionReadOnly->setIcon(QIcon("://tapeicon/24x24/padlock_opened.png"));
}
ui->actionAddCustom->setDisabled(ro);
ui->actionAddKnown->setDisabled(ro);
ui->plainTextEditNotes->setReadOnly(ro);
if (mType == MeasurementsType::Individual)
{
ui->lineEditGivenName->setReadOnly(ro);
ui->lineEditFamilyName->setReadOnly(ro);
ui->dateEditBirthDate->setReadOnly(ro);
ui->comboBoxGender->setDisabled(ro);
ui->lineEditEmail->setReadOnly(ro);
}
ui->comboBoxPMSystem->setDisabled(ro);
MeasurementReadOnly(ro);
ui->actionReadOnly->setDisabled(mIsReadOnly);
}
//---------------------------------------------------------------------------------------------------------------------
void TMainWindow::MeasurementReadOnly(bool ro)
void TMainWindow::MeasurementGUI()
{
if (ro == false)
{
if (const QTableWidgetItem *nameField = ui->tableWidget->item(ui->tableWidget->currentRow(), ColumnName))
{
if (nameField->text().indexOf(CustomMSign) == 0) // Check if custom
{
ui->lineEditName->setReadOnly(ro);
ui->plainTextEditDescription->setReadOnly(ro);
ui->lineEditFullName->setReadOnly(ro);
const bool isCustom = not (nameField->text().indexOf(CustomMSign) == 0);
ui->lineEditName->setReadOnly(isCustom);
ui->plainTextEditDescription->setReadOnly(isCustom);
ui->lineEditFullName->setReadOnly(isCustom);
// Need to block signals for QLineEdit in readonly mode because it still emits
// QLineEdit::editingFinished signal.
ui->lineEditName->blockSignals(ro);
ui->lineEditFullName->blockSignals(ro);
}
else
{ // known measurement
ui->lineEditName->setReadOnly(not ro);
ui->plainTextEditDescription->setReadOnly(not ro);
ui->lineEditFullName->setReadOnly(not ro);
// Need to block signals for QLineEdit in readonly mode because it still emits
// QLineEdit::editingFinished signal.
ui->lineEditName->blockSignals(not ro);
ui->lineEditFullName->blockSignals(not ro);
}
}
else
{
return;
}
}
else
{
ui->lineEditName->setReadOnly(ro);
ui->plainTextEditDescription->setReadOnly(ro);
ui->lineEditFullName->setReadOnly(ro);
// Need to block signals for QLineEdit in readonly mode because it still emits
// QLineEdit::editingFinished signal.
ui->lineEditName->blockSignals(ro);
ui->lineEditFullName->blockSignals(ro);
}
if (mType == MeasurementsType::Individual)
{
ui->plainTextEditFormula->setReadOnly(ro);
// Need to block signals for QLineEdit in readonly mode because it still emits QLineEdit::editingFinished
// signal.
ui->lineEditGivenName->blockSignals(ro);
ui->lineEditFamilyName->blockSignals(ro);
ui->lineEditEmail->blockSignals(ro);
}
else
{
ui->doubleSpinBoxBaseValue->setReadOnly(ro);
ui->doubleSpinBoxInSizes->setReadOnly(ro);
ui->doubleSpinBoxInHeights->setReadOnly(ro);
}
ui->lineEditName->blockSignals(isCustom);
ui->lineEditFullName->blockSignals(isCustom);
Controls(); // Buttons remove, up, down
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -2733,13 +2748,9 @@ bool TMainWindow::LoadFromExistingFile(const QString &path)
else
{
VVITConverter converter(path);
converter.Convert();
VDomDocument::ValidateXML(VVITConverter::CurrentSchema, path);
m->setXMLContent(converter.Convert());// Read again after conversion
}
m->setXMLContent(path);// Read again after conversion
if (not m->IsDefinedKnownNamesValid())
{
VException e(tr("File contains invalid known measurement(s)."));
@ -2767,7 +2778,9 @@ bool TMainWindow::LoadFromExistingFile(const QString &path)
lock.reset();// Now we can unlock the file
GUIReadOnly(m->ReadOnly()); // Keep last
mIsReadOnly = m->IsReadOnly();
UpdatePadlock(mIsReadOnly);
MeasurementGUI();
}
catch (VException &e)
{

View File

@ -78,8 +78,8 @@ private slots:
void CreateFromExisting();
void Preferences();
void FileSave();
void FileSaveAs();
bool FileSave();
bool FileSaveAs();
void ExportToCSV();
void AboutToShowWindowMenu();
void ShowWindow() const;
@ -96,7 +96,6 @@ private slots:
void SaveBirthDate(const QDate & date);
void SaveNotes();
void SavePMSystem(int index);
void ReadOnly(bool ro);
void Remove();
void MoveTop();
@ -147,6 +146,7 @@ private:
QAction *actionDockDiagram;
bool dockDiagramVisible;
bool isInitialized;
bool mIsReadOnly;
enum { MaxRecentFiles = 5 };
QAction *recentFileActs[MaxRecentFiles];
QAction *separatorAct;
@ -185,10 +185,11 @@ private:
void ShowMDiagram(const QString &name);
void Open(const QString &pathTo, const QString &filter);
void GUIReadOnly(bool ro);
void MeasurementReadOnly(bool ro);
void UpdatePadlock(bool ro);
void MeasurementGUI();
void Controls();
void MFields(bool enabled);
void UpdateWindowTitle();
void ReadSettings();
void WriteSettings();

View File

@ -924,7 +924,6 @@
<addaction name="actionSave"/>
<addaction name="actionAddKnown"/>
<addaction name="actionAddCustom"/>
<addaction name="actionReadOnly"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QToolBar" name="toolBarGradation">

View File

@ -380,20 +380,14 @@ QSharedPointer<VMeasurements> MainWindow::OpenMeasurementFile(const QString &pat
if (m->Type() == MeasurementsType::Standard)
{
VVSTConverter converter(path);
converter.Convert();
VDomDocument::ValidateXML(VVSTConverter::CurrentSchema, path);
m->setXMLContent(converter.Convert());// Read again after conversion
}
else
{
VVITConverter converter(path);
converter.Convert();
VDomDocument::ValidateXML(VVITConverter::CurrentSchema, path);
m->setXMLContent(converter.Convert());// Read again after conversion
}
m->setXMLContent(path);// Read again after conversion
if (not m->IsDefinedKnownNamesValid())
{
VException e(tr("Measurement file contains invalid known measurement(s)."));
@ -2406,7 +2400,7 @@ bool MainWindow::SaveAs()
const bool result = SavePattern(fileName, error);
if (result == false)
{
QMessageBox messageBox;
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(tr("Could not save file"));
messageBox.setDefaultButton(QMessageBox::Ok);
@ -2449,25 +2443,69 @@ bool MainWindow::SaveAs()
*/
bool MainWindow::Save()
{
if (curFile.isEmpty())
if (curFile.isEmpty() || patternReadOnly)
{
return SaveAs();
}
else
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The document has no write permissions."));
messageBox.setInformativeText("Do you want to change the premissions?");
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
messageBox.setDefaultButton(QMessageBox::Yes);
if (messageBox.exec() == QMessageBox::Yes)
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
bool changed = QFile::setPermissions(curFile,
QFileInfo(curFile).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.").arg(curFile));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
}
QString error;
bool result = SavePattern(curFile, error);
if (result)
{
QString autofile = curFile + autosavePrefix;
QFile file(autofile);
file.remove();
QFile::remove(curFile + autosavePrefix);
}
else
{
QMessageBox messageBox;
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(tr("Could not save file"));
messageBox.setText(tr("Could not save the file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
@ -2559,10 +2597,6 @@ void MainWindow::Clear()
#endif
CleanLayout();
listDetails.clear(); // don't move to CleanLayout()
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
qApp->getUndoStack()->clear();
toolOptions->ClearPropertyBrowser();
toolOptions->itemClicked(nullptr);
@ -2698,8 +2732,6 @@ void MainWindow::FullParseFile()
GlobalChangePP(patternPiece);
SetEnableTool(comboBoxDraws->count() > 0);
patternReadOnly = doc->IsReadOnly();
SetEnableWidgets(true);
detailsWidget->UpdateList();
VMainGraphicsView::NewSceneRect(sceneDraw, qApp->getSceneView());
@ -3272,7 +3304,7 @@ bool MainWindow::MaybeSave()
messageBox->setEscapeButton(QMessageBox::Cancel);
messageBox->setButtonText(QMessageBox::Yes,
curFile.isEmpty() || doc->IsReadOnly() ? tr("Save...") : tr("Save"));
curFile.isEmpty() || patternReadOnly ? tr("Save...") : tr("Save"));
messageBox->setButtonText(QMessageBox::No, tr("Don't Save"));
messageBox->setWindowModality(Qt::ApplicationModal);
@ -3281,7 +3313,7 @@ bool MainWindow::MaybeSave()
switch (ret)
{
case QMessageBox::Yes:
if (doc->IsReadOnly())
if (patternReadOnly)
{
return SaveAs();
}
@ -3910,18 +3942,11 @@ bool MainWindow::LoadPattern(const QString &fileName, const QString& customMeasu
VMainGraphicsView::NewSceneRect(sceneDraw, ui->view);
VMainGraphicsView::NewSceneRect(sceneDetails, ui->view);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
qApp->setOpeningPattern();//Begin opening file
try
{
VPatternConverter converter(fileName);
converter.Convert();
VDomDocument::ValidateXML(VPatternConverter::CurrentSchema, fileName);
doc->setXMLContent(fileName);
doc->setXMLContent(converter.Convert());
if (!customMeasureFile.isEmpty())
{
doc->SetPath(RelativeMPath(fileName, customMeasureFile));
@ -3984,14 +4009,12 @@ bool MainWindow::LoadPattern(const QString &fileName, const QString& customMeasu
return false;
}
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
FullParseFile();
if (guiEnabled)
{ // No errors occurred
patternReadOnly = doc->IsReadOnly();
SetEnableWidgets(true);
setCurrentFile(fileName);
helpLabel->setText(tr("File loaded"));
qCDebug(vMainWindow, "File loaded.");
@ -4297,20 +4320,14 @@ QString MainWindow::CheckPathToMeasurements(const QString &patternPath, const QS
if (patternType == MeasurementsType::Standard)
{
VVSTConverter converter(mPath);
converter.Convert();
VDomDocument::ValidateXML(VVSTConverter::CurrentSchema, mPath);
m->setXMLContent(converter.Convert());// Read again after conversion
}
else
{
VVITConverter converter(mPath);
converter.Convert();
VDomDocument::ValidateXML(VVITConverter::CurrentSchema, mPath);
m->setXMLContent(converter.Convert());// Read again after conversion
}
m->setXMLContent(mPath);// Read again after conversion
if (not m->IsDefinedKnownNamesValid())
{
VException e(tr("Measurement file contains invalid known measurement(s)."));
@ -4630,13 +4647,26 @@ QString MainWindow::GetMeasurementFileName()
//---------------------------------------------------------------------------------------------------------------------
void MainWindow::UpdateWindowTitle()
{
if (not patternReadOnly)
bool isFileWritable = true;
if (not curFile.isEmpty())
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
isFileWritable = QFileInfo(curFile).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
}
if (not patternReadOnly && isFileWritable)
{
setWindowTitle(GetPatternFileName()+GetMeasurementFileName());
}
else
{
setWindowTitle(GetPatternFileName()+GetMeasurementFileName() + " " + tr("(read only)"));
setWindowTitle(GetPatternFileName()+GetMeasurementFileName() + QLatin1String(" (") + tr("read only") +
QLatin1String(")"));
}
setWindowFilePath(curFile);

View File

@ -49,17 +49,13 @@
//---------------------------------------------------------------------------------------------------------------------
VAbstractConverter::VAbstractConverter(const QString &fileName)
:VDomDocument(), ver(0x0), fileName(fileName)
: VDomDocument(),
m_ver(0x0),
m_convertedFileName(fileName),
m_tmpFile()
{
QFileInfo info(fileName);
if (info.isSymLink() && not info.isWritable())
{
ReplaceSymLink();
}
this->setXMLContent(fileName);
const QString version = GetVersionStr();
ver = GetVersion(version);
setXMLContent(m_convertedFileName);// Throw an exception on error
m_ver = GetVersion(GetVersionStr());
}
//---------------------------------------------------------------------------------------------------------------------
@ -67,34 +63,29 @@ VAbstractConverter::~VAbstractConverter()
{}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::Convert()
QString VAbstractConverter::Convert()
{
if (ver == MaxVer())
if (m_ver == MaxVer())
{
return;
}
QString error;
const QString backupFileName = fileName + QLatin1String(".backup");
if (SafeCopy(fileName, backupFileName, error) == false)
{
const QString errorMsg(tr("Error creating a backup file: %1.").arg(error));
throw VException(errorMsg);
return m_convertedFileName;
}
ReserveFile();
if (ver <= MaxVer())
if (m_tmpFile.open())
{
ApplyPatches();
m_convertedFileName = m_tmpFile.fileName();
}
else
{
DowngradeToCurrentMaxVersion();
const QString errorMsg(tr("Error openning a temp file file: %1.").arg(m_tmpFile.errorString()));
throw VException(errorMsg);
}
m_tmpFile.close();
QFile file(backupFileName);
file.remove();
m_ver < MaxVer() ? ApplyPatches() : DowngradeToCurrentMaxVersion();
return m_convertedFileName;
}
//---------------------------------------------------------------------------------------------------------------------
@ -180,33 +171,27 @@ void VAbstractConverter::ReserveFile() const
//It's not possible in all cases make conversion without lose data.
//For such cases we will store old version in a reserve file.
QString error;
QFileInfo info(fileName);
const QString reserveFileName = QString("%1/%2(v%3).%4")
QFileInfo info(m_convertedFileName);
const QString reserveFileName = QString("%1/%2(v%3).%4.bak")
.arg(info.absoluteDir().absolutePath())
.arg(info.baseName())
.arg(GetVersionStr())
.arg(info.completeSuffix());
if (not SafeCopy(fileName, reserveFileName, error))
if (not SafeCopy(m_convertedFileName, reserveFileName, error))
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = info.isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not IsReadOnly() && isFileWritable)
{
const QString errorMsg(tr("Error creating a reserv copy: %1.").arg(error));
throw VException(errorMsg);
}
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::ReplaceSymLink() const
{
// See issue #582. Issue with standard path to shared data on Linux
// https://bitbucket.org/dismine/valentina/issues/582/issue-with-standard-path-to-shared-data-on
QFileInfo info(fileName);
if (info.isSymLink() && not info.isWritable())
{
QString error;
if (not SafeCopy(info.symLinkTarget(), fileName, error))
{
const QString errorMsg(tr("Error replacing a symlink by real file: %1.").arg(error));
throw VException(errorMsg);
}
}
}
@ -291,19 +276,19 @@ void VAbstractConverter::ValidateInputFile(const QString &currentSchema) const
QString schema;
try
{
schema = XSDSchema(ver);
schema = XSDSchema(m_ver);
}
catch(const VException &e)
{
if (ver < MinVer())
if (m_ver < MinVer())
{ // Version less than minimally supported version. Can't do anything.
throw;
}
else if (ver > MaxVer())
else if (m_ver > MaxVer())
{ // Version bigger than maximum supported version. We still have a chance to open the file.
try
{ // Try to open like the current version.
ValidateXML(currentSchema, fileName);
ValidateXML(currentSchema, m_convertedFileName);
}
catch(const VException &exp)
{ // Nope, we can't.
@ -319,14 +304,14 @@ void VAbstractConverter::ValidateInputFile(const QString &currentSchema) const
return; // All is fine and we can try to convert to current max version.
}
ValidateXML(schema, fileName);
ValidateXML(schema, m_convertedFileName);
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractConverter::Save() const
{
QString error;
if (SaveDocument(fileName, error) == false)
if (SaveDocument(m_convertedFileName, error) == false)
{
VException e(error);
throw e;

View File

@ -37,6 +37,7 @@
#include <QCoreApplication>
#include <QString>
#include <QTemporaryFile>
#include <QtGlobal>
#include "vdomdocument.h"
@ -52,14 +53,15 @@ public:
explicit VAbstractConverter(const QString &fileName);
virtual ~VAbstractConverter() Q_DECL_OVERRIDE;
void Convert();
QString Convert();
virtual bool SaveDocument(const QString &fileName, QString &error) const Q_DECL_OVERRIDE;
static int GetVersion(const QString &version);
protected:
int ver;
QString fileName;
int m_ver;
QString m_convertedFileName;
void ValidateInputFile(const QString &currentSchema) const;
Q_NORETURN void InvalidVersion(int ver) const;
@ -76,6 +78,8 @@ protected:
virtual void ApplyPatches() =0;
virtual void DowngradeToCurrentMaxVersion() =0;
virtual bool IsReadOnly() const =0;
void Replace(QString &formula, const QString &newName, int position, const QString &token, int &bias) const;
void CorrectionsPositions(int position, int bias, QMap<int, QString> &tokens) const;
static void BiasTokens(int position, int bias, QMap<int, QString> &tokens);
@ -83,12 +87,13 @@ protected:
private:
Q_DISABLE_COPY(VAbstractConverter)
QTemporaryFile m_tmpFile;
QString GetVersionStr() const;
static void ValidateVersion(const QString &version);
void ReserveFile() const;
void ReplaceSymLink() const;
};
#endif // VABSTRACTCONVERTER_H

View File

@ -124,7 +124,8 @@ const QString VDomDocument::TagVersion = QStringLiteral("version");
//---------------------------------------------------------------------------------------------------------------------
VDomDocument::VDomDocument()
: QDomDocument(), map(QHash<QString, QDomElement>())
: QDomDocument(),
map()
{}
//---------------------------------------------------------------------------------------------------------------------
@ -804,12 +805,11 @@ bool VDomDocument::SafeCopy(const QString &source, const QString &destination, Q
#endif /*Q_OS_WIN32*/
QTemporaryFile destFile(destination + QLatin1String(".XXXXXX"));
destFile.setAutoRemove(false);
destFile.setAutoRemove(false);// Will be renamed to be destination file
// cppcheck-suppress ConfigurationNotChecked
if (not destFile.open())
{
error = destFile.errorString();
result = false;
}
else
{
@ -850,6 +850,10 @@ bool VDomDocument::SafeCopy(const QString &source, const QString &destination, Q
}
}
}
else
{
error = sourceFile.errorString();
}
}
#ifdef Q_OS_WIN32

View File

@ -133,10 +133,11 @@ static const QString strSeamAllowance = QStringLiteral("seamAllowanc
static const QString strNodeType = QStringLiteral("nodeType");
static const QString strDet = QStringLiteral("det");
static const QString strTypeObject = QStringLiteral("typeObject");
static const QString strReadOnly = QStringLiteral("readOnly");
//---------------------------------------------------------------------------------------------------------------------
VPatternConverter::VPatternConverter(const QString &fileName)
:VAbstractConverter(fileName)
: VAbstractConverter(fileName)
{
ValidateInputFile(CurrentSchema);
}
@ -207,125 +208,106 @@ QString VPatternConverter::XSDSchema(int ver) const
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ApplyPatches()
{
try
{
switch (ver)
switch (m_ver)
{
case (0x000100):
ToV0_1_1();
ValidateXML(XSDSchema(0x000101), fileName);
ValidateXML(XSDSchema(0x000101), m_convertedFileName);
V_FALLTHROUGH
case (0x000101):
ToV0_1_2();
ValidateXML(XSDSchema(0x000102), fileName);
ValidateXML(XSDSchema(0x000102), m_convertedFileName);
V_FALLTHROUGH
case (0x000102):
ToV0_1_3();
ValidateXML(XSDSchema(0x000103), fileName);
ValidateXML(XSDSchema(0x000103), m_convertedFileName);
V_FALLTHROUGH
case (0x000103):
ToV0_1_4();
ValidateXML(XSDSchema(0x000104), fileName);
ValidateXML(XSDSchema(0x000104), m_convertedFileName);
V_FALLTHROUGH
case (0x000104):
ToV0_2_0();
ValidateXML(XSDSchema(0x000200), fileName);
ValidateXML(XSDSchema(0x000200), m_convertedFileName);
V_FALLTHROUGH
case (0x000200):
ToV0_2_1();
ValidateXML(XSDSchema(0x000201), fileName);
ValidateXML(XSDSchema(0x000201), m_convertedFileName);
V_FALLTHROUGH
case (0x000201):
ToV0_2_2();
ValidateXML(XSDSchema(0x000202), fileName);
ValidateXML(XSDSchema(0x000202), m_convertedFileName);
V_FALLTHROUGH
case (0x000202):
ToV0_2_3();
ValidateXML(XSDSchema(0x000203), fileName);
ValidateXML(XSDSchema(0x000203), m_convertedFileName);
V_FALLTHROUGH
case (0x000203):
ToV0_2_4();
ValidateXML(XSDSchema(0x000204), fileName);
ValidateXML(XSDSchema(0x000204), m_convertedFileName);
V_FALLTHROUGH
case (0x000204):
ToV0_2_5();
ValidateXML(XSDSchema(0x000205), fileName);
ValidateXML(XSDSchema(0x000205), m_convertedFileName);
V_FALLTHROUGH
case (0x000205):
ToV0_2_6();
ValidateXML(XSDSchema(0x000206), fileName);
ValidateXML(XSDSchema(0x000206), m_convertedFileName);
V_FALLTHROUGH
case (0x000206):
ToV0_2_7();
ValidateXML(XSDSchema(0x000207), fileName);
ValidateXML(XSDSchema(0x000207), m_convertedFileName);
V_FALLTHROUGH
case (0x000207):
ToV0_3_0();
ValidateXML(XSDSchema(0x000300), fileName);
ValidateXML(XSDSchema(0x000300), m_convertedFileName);
V_FALLTHROUGH
case (0x000300):
ToV0_3_1();
ValidateXML(XSDSchema(0x000301), fileName);
ValidateXML(XSDSchema(0x000301), m_convertedFileName);
V_FALLTHROUGH
case (0x000301):
ToV0_3_2();
ValidateXML(XSDSchema(0x000302), fileName);
ValidateXML(XSDSchema(0x000302), m_convertedFileName);
V_FALLTHROUGH
case (0x000302):
ToV0_3_3();
ValidateXML(XSDSchema(0x000303), fileName);
ValidateXML(XSDSchema(0x000303), m_convertedFileName);
V_FALLTHROUGH
case (0x000303):
ToV0_3_4();
ValidateXML(XSDSchema(0x000304), fileName);
ValidateXML(XSDSchema(0x000304), m_convertedFileName);
V_FALLTHROUGH
case (0x000304):
ToV0_3_5();
ValidateXML(XSDSchema(0x000305), fileName);
ValidateXML(XSDSchema(0x000305), m_convertedFileName);
V_FALLTHROUGH
case (0x000305):
ToV0_3_6();
ValidateXML(XSDSchema(0x000306), fileName);
ValidateXML(XSDSchema(0x000306), m_convertedFileName);
V_FALLTHROUGH
case (0x000306):
ToV0_3_7();
ValidateXML(XSDSchema(0x000307), fileName);
ValidateXML(XSDSchema(0x000307), m_convertedFileName);
V_FALLTHROUGH
case (0x000307):
ToV0_3_8();
ValidateXML(XSDSchema(0x000308), fileName);
ValidateXML(XSDSchema(0x000308), m_convertedFileName);
V_FALLTHROUGH
case (0x000308):
ToV0_3_9();
ValidateXML(XSDSchema(0x000309), fileName);
ValidateXML(XSDSchema(0x000309), m_convertedFileName);
V_FALLTHROUGH
case (0x000309):
ToV0_4_0();
ValidateXML(XSDSchema(0x000400), fileName);
ValidateXML(XSDSchema(0x000400), m_convertedFileName);
V_FALLTHROUGH
case (0x000400):
break;
default:
InvalidVersion(m_ver);
break;
}
}
catch (VException &e)
{
QString error;
const QString backupFileName = fileName + QLatin1String(".backup");
if (SafeCopy(backupFileName, fileName, error) == false)
{
const QString errorMsg(tr("Error restoring backup file: %1.").arg(error));
VException excep(errorMsg);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
QFile file(backupFileName);
file.remove();
throw;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -335,6 +317,27 @@ void VPatternConverter::DowngradeToCurrentMaxVersion()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
bool VPatternConverter::IsReadOnly() const
{
// Check if attribute readOnly was not changed in file format
Q_STATIC_ASSERT_X(VPatternConverter::PatternMaxVer == CONVERTER_VERSION_CHECK(0, 4, 0),
"Check attribute readOnly.");
// Possibly in future attribute readOnly will change position etc.
// For now position is the same for all supported format versions.
// But don't forget to keep all versions of attribute until we support that format versions
const QDomElement pattern = documentElement();
if (pattern.isNull())
{
return false;
}
return GetParametrBool(pattern, strReadOnly, falseStr);
}
//---------------------------------------------------------------------------------------------------------------------
void VPatternConverter::ToV0_1_1()
{
@ -1095,7 +1098,7 @@ void VPatternConverter::TagMeasurementsToV0_2_0()
ms.removeAttribute(strType);
ms.removeAttribute(strPath);
QDomText newNodeText = createTextNode(QFileInfo(fileName).absoluteDir().relativeFilePath(path));
QDomText newNodeText = createTextNode(QFileInfo(m_convertedFileName).absoluteDir().relativeFilePath(path));
ms.appendChild(newNodeText);
}

View File

@ -72,6 +72,8 @@ protected:
virtual void ApplyPatches() Q_DECL_OVERRIDE;
virtual void DowngradeToCurrentMaxVersion() Q_DECL_OVERRIDE;
virtual bool IsReadOnly() const Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(VPatternConverter)
static const QString PatternMinVerStr;

View File

@ -60,6 +60,8 @@ const QString VVITConverter::CurrentSchema = QStringLiteral("://schema/in
//VVITConverter::MeasurementMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
//VVITConverter::MeasurementMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
static const QString strTagRead_Only = QStringLiteral("read-only");
//---------------------------------------------------------------------------------------------------------------------
VVITConverter::VVITConverter(const QString &fileName)
:VAbstractMConverter(fileName)
@ -95,49 +97,30 @@ QString VVITConverter::XSDSchema(int ver) const
//---------------------------------------------------------------------------------------------------------------------
void VVITConverter::ApplyPatches()
{
try
{
switch (ver)
switch (m_ver)
{
case (0x000200):
ToV0_3_0();
ValidateXML(XSDSchema(0x000300), fileName);
ValidateXML(XSDSchema(0x000300), m_convertedFileName);
V_FALLTHROUGH
case (0x000300):
ToV0_3_1();
ValidateXML(XSDSchema(0x000301), fileName);
ValidateXML(XSDSchema(0x000301), m_convertedFileName);
V_FALLTHROUGH
case (0x000301):
ToV0_3_2();
ValidateXML(XSDSchema(0x000302), fileName);
ValidateXML(XSDSchema(0x000302), m_convertedFileName);
V_FALLTHROUGH
case (0x000302):
ToV0_3_3();
ValidateXML(XSDSchema(0x000303), fileName);
ValidateXML(XSDSchema(0x000303), m_convertedFileName);
V_FALLTHROUGH
case (0x000303):
break;
default:
InvalidVersion(m_ver);
break;
}
}
catch (VException &e)
{
QString error;
const QString backupFileName = fileName + QLatin1String(".backup");
if (SafeCopy(backupFileName, fileName, error) == false)
{
const QString errorMsg(tr("Error restoring backup file: %1.").arg(error));
VException excep(errorMsg);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
QFile file(backupFileName);
file.remove();
throw;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -147,6 +130,20 @@ void VVITConverter::DowngradeToCurrentMaxVersion()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
bool VVITConverter::IsReadOnly() const
{
// Check if attribute read-only was not changed in file format
Q_STATIC_ASSERT_X(VVITConverter::MeasurementMaxVer == CONVERTER_VERSION_CHECK(0, 3, 3),
"Check attribute read-only.");
// Possibly in future attribute read-only will change position etc.
// For now position is the same for all supported format versions.
// But don't forget to keep all versions of attribute until we support that format versions
return UniqueTagText(strTagRead_Only, falseStr) == trueStr;
}
//---------------------------------------------------------------------------------------------------------------------
void VVITConverter::AddNewTagsForV0_3_0()
{

View File

@ -67,6 +67,7 @@ protected:
virtual QString XSDSchema(int ver) const Q_DECL_OVERRIDE;
virtual void ApplyPatches() Q_DECL_OVERRIDE;
virtual void DowngradeToCurrentMaxVersion() Q_DECL_OVERRIDE;
virtual bool IsReadOnly() const Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(VVITConverter)

View File

@ -60,6 +60,8 @@ const QString VVSTConverter::CurrentSchema = QStringLiteral("://schema/st
//VVSTConverter::MeasurementMinVer; // <== DON'T FORGET TO UPDATE TOO!!!!
//VVSTConverter::MeasurementMaxVer; // <== DON'T FORGET TO UPDATE TOO!!!!
static const QString strTagRead_Only = QStringLiteral("read-only");
//---------------------------------------------------------------------------------------------------------------------
VVSTConverter::VVSTConverter(const QString &fileName)
:VAbstractMConverter(fileName)
@ -95,49 +97,30 @@ QString VVSTConverter::XSDSchema(int ver) const
//---------------------------------------------------------------------------------------------------------------------
void VVSTConverter::ApplyPatches()
{
try
{
switch (ver)
switch (m_ver)
{
case (0x000300):
ToV0_4_0();
ValidateXML(XSDSchema(0x000400), fileName);
ValidateXML(XSDSchema(0x000400), m_convertedFileName);
V_FALLTHROUGH
case (0x000400):
ToV0_4_1();
ValidateXML(XSDSchema(0x000401), fileName);
ValidateXML(XSDSchema(0x000401), m_convertedFileName);
V_FALLTHROUGH
case (0x000401):
ToV0_4_2();
ValidateXML(XSDSchema(0x000402), fileName);
ValidateXML(XSDSchema(0x000402), m_convertedFileName);
V_FALLTHROUGH
case (0x000402):
ToV0_4_3();
ValidateXML(XSDSchema(0x000403), fileName);
ValidateXML(XSDSchema(0x000403), m_convertedFileName);
V_FALLTHROUGH
case (0x000403):
break;
default:
InvalidVersion(m_ver);
break;
}
}
catch (VException &e)
{
QString error;
const QString backupFileName = fileName + QLatin1String(".backup");
if (SafeCopy(backupFileName, fileName, error) == false)
{
const QString errorMsg(tr("Error restoring backup file: %1.").arg(error));
VException excep(errorMsg);
excep.AddMoreInformation(e.ErrorMessage());
throw excep;
}
QFile file(backupFileName);
file.remove();
throw;
}
}
//---------------------------------------------------------------------------------------------------------------------
@ -147,6 +130,20 @@ void VVSTConverter::DowngradeToCurrentMaxVersion()
Save();
}
//---------------------------------------------------------------------------------------------------------------------
bool VVSTConverter::IsReadOnly() const
{
// Check if attribute read-only was not changed in file format
Q_STATIC_ASSERT_X(VVSTConverter::MeasurementMaxVer == CONVERTER_VERSION_CHECK(0, 4, 3),
"Check attribute read-only.");
// Possibly in future attribute read-only will change position etc.
// For now position is the same for all supported format versions.
// But don't forget to keep all versions of attribute until we support that format versions
return UniqueTagText(strTagRead_Only, falseStr) == trueStr;
}
//---------------------------------------------------------------------------------------------------------------------
void VVSTConverter::AddNewTagsForV0_4_0()
{

View File

@ -67,6 +67,7 @@ protected:
virtual QString XSDSchema(int ver) const Q_DECL_OVERRIDE;
virtual void ApplyPatches() Q_DECL_OVERRIDE;
virtual void DowngradeToCurrentMaxVersion() Q_DECL_OVERRIDE;
virtual bool IsReadOnly() const Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(VVSTConverter)

View File

@ -373,7 +373,7 @@ QString VMeasurements::Notes() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetNotes(const QString &text)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagNotes, text);
}
@ -388,7 +388,7 @@ QString VMeasurements::FamilyName() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetFamilyName(const QString &text)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagFamilyName, text);
}
@ -403,7 +403,7 @@ QString VMeasurements::GivenName() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetGivenName(const QString &text)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagGivenName, text);
}
@ -418,7 +418,7 @@ QDate VMeasurements::BirthDate() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetBirthDate(const QDate &date)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagBirthDate, date.toString("yyyy-MM-dd"));
}
@ -433,7 +433,7 @@ GenderType VMeasurements::Gender() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetGender(const GenderType &gender)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagGender, GenderToStr(gender));
}
@ -448,7 +448,7 @@ QString VMeasurements::PMSystem() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetPMSystem(const QString &system)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagPMSystem, ClearPMCode(system));
}
@ -463,23 +463,16 @@ QString VMeasurements::Email() const
//---------------------------------------------------------------------------------------------------------------------
void VMeasurements::SetEmail(const QString &text)
{
if (not ReadOnly())
if (not IsReadOnly())
{
setTagText(TagEmail, text);
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VMeasurements::ReadOnly() const
bool VMeasurements::IsReadOnly() const
{
if (UniqueTagText(TagReadOnly, "false") == "true")
{
return true;
}
else
{
return false;
}
return UniqueTagText(TagReadOnly, falseStr) == trueStr;
}
//---------------------------------------------------------------------------------------------------------------------
@ -487,11 +480,11 @@ void VMeasurements::SetReadOnly(bool ro)
{
if (ro)
{
setTagText(TagReadOnly, "true");
setTagText(TagReadOnly, trueStr);
}
else
{
setTagText(TagReadOnly, "false");
setTagText(TagReadOnly, falseStr);
}
}

View File

@ -94,7 +94,7 @@ public:
QString Email() const;
void SetEmail(const QString &text);
bool ReadOnly() const;
bool IsReadOnly() const;
void SetReadOnly(bool ro);
void SetMName(const QString &name, const QString &text);

View File

@ -125,18 +125,6 @@ VAbstractApplication::VAbstractApplication(int &argc, char **argv)
// Connect this slot with VApplication::aboutToQuit.
Settings()->sync();
});
#if !defined(Q_OS_WIN)
QDir standardPath(VCommonSettings::unixStandardSharePath);
const QDir localdata (QDir::homePath() + QDir::separator() + VCommonSettings::valentinaUnixHomeFolder);
if (standardPath.exists() && not localdata.exists())
{
if (localdata.mkdir(localdata.absolutePath()))
{
SymlinkCopyDirRecursive(standardPath.absolutePath(), localdata.absolutePath(), true);
}
}
#endif // !defined(Q_OS_WIN)
}
//---------------------------------------------------------------------------------------------------------------------
@ -406,54 +394,3 @@ void VAbstractApplication::ClearTranslation()
delete pmsTranslator;
}
}
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractApplication::SymlinkCopyDirRecursive(const QString &fromDir, const QString &toDir, bool replaceOnConflit)
{
QDir dir;
dir.setPath(fromDir);
foreach (QString copyFile, dir.entryList(QDir::Files))
{
const QString from = fromDir + QDir::separator() + copyFile;
const QString to = toDir + QDir::separator() + copyFile;
if (QFile::exists(to))
{
if (replaceOnConflit)
{
if (QFile::remove(to) == false)
{
return false;
}
}
else
{
continue;
}
}
if (QFile::link(from, to) == false)
{
return false;
}
}
foreach (QString copyDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
{
const QString from = fromDir + QDir::separator() + copyDir;
const QString to = toDir + QDir::separator() + copyDir;
if (dir.mkpath(to) == false)
{
return false;
}
if (SymlinkCopyDirRecursive(from, to, replaceOnConflit) == false)
{
return false;
}
}
return true;
}

View File

@ -149,8 +149,6 @@ private:
bool openingPattern;
void ClearTranslation();
static bool SymlinkCopyDirRecursive(const QString &fromDir, const QString &toDir, bool replaceOnConflit);
};

View File

@ -77,7 +77,6 @@ static const QString commonIniFilename = QStringLiteral("common");
#if !defined(Q_OS_WIN)
const QString VCommonSettings::unixStandardSharePath = QStringLiteral("/usr/share/valentina");
const QString VCommonSettings::valentinaUnixHomeFolder = QStringLiteral(".valentina");
#endif
//---------------------------------------------------------------------------------------------------------------------
@ -109,18 +108,10 @@ QString VCommonSettings::SharePath(const QString &shareItem)
return dir.absolutePath();
}
else
{
QDir dir(QDir::homePath() + QDir::separator() + VCommonSettings::valentinaUnixHomeFolder + shareItem);
if (dir.exists())
{
return dir.absolutePath();
}
else
{
return VCommonSettings::unixStandardSharePath + shareItem;
}
}
}
#else // Unix
#ifdef QT_DEBUG
return QApplication::applicationDirPath() + shareItem;
@ -131,17 +122,9 @@ QString VCommonSettings::SharePath(const QString &shareItem)
return dir.absolutePath();
}
else
{
QDir dir(QDir::homePath() + QDir::separator() + VCommonSettings::valentinaUnixHomeFolder + shareItem);
if (dir.exists())
{
return dir.absolutePath();
}
else
{
return VCommonSettings::unixStandardSharePath + shareItem;
}
}
#endif
#endif
}

View File

@ -128,7 +128,6 @@ public:
#if !defined(Q_OS_WIN)
static const QString unixStandardSharePath;
static const QString valentinaUnixHomeFolder;
#endif
private: