File > Save functions.

This commit is contained in:
Roman Telezhynskyi 2021-05-21 17:17:22 +03:00
parent 67fc4b7539
commit d10355b400
10 changed files with 260 additions and 136 deletions

View File

@ -45,6 +45,12 @@
#include "../vwidgets/vmaingraphicsscene.h"
#include "vpsheet.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
#include "../vmisc/backport/qscopeguard.h"
#else
#include <QScopeGuard>
#endif
#include <QLoggingCategory>
QT_WARNING_PUSH
@ -157,16 +163,50 @@ bool VPMainWindow::LoadFile(QString path)
}
//---------------------------------------------------------------------------------------------------------------------
bool VPMainWindow::SaveFile(const QString &path)
void VPMainWindow::LayoutWasSaved(bool saved)
{
setWindowModified(!saved);
not lIsReadOnly ? ui->actionSave->setEnabled(!saved): ui->actionSave->setEnabled(false);
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::SetCurrentFile(const QString &fileName)
{
curFile = fileName;
if (not curFile.isEmpty())
{
auto settings = VPApplication::VApp()->PuzzleSettings();
QStringList files = settings->GetRecentFileList();
files.removeAll(fileName);
files.prepend(fileName);
while (files.size() > MaxRecentFiles)
{
files.removeLast();
}
settings->SetRecentFileList(files);
UpdateRecentFileActions();
}
UpdateWindowTitle();
}
//---------------------------------------------------------------------------------------------------------------------
auto VPMainWindow::SaveLayout(const QString &path, QString &error) -> bool
{
QFile file(path);
file.open(QIODevice::WriteOnly);
VPLayoutFileWriter *fileWriter = new VPLayoutFileWriter();
fileWriter->WriteFile(m_layout, &file);
VPLayoutFileWriter fileWriter;
fileWriter.WriteFile(m_layout, &file);
// TODO / FIXME : better return value and error handling
if (fileWriter.hasError())
{
error = tr("Fail to create layout.");
return false;
}
SetCurrentFile(path);
LayoutWasSaved(true);
return true;
}
@ -1058,47 +1098,143 @@ void VPMainWindow::on_actionOpen_triggered()
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionSave_triggered()
bool VPMainWindow::on_actionSave_triggered()
{
// just for test purpuses, to be removed:
QMessageBox msgBox;
msgBox.setText("TODO VPMainWindow::Save");
int ret = msgBox.exec();
if (curFile.isEmpty() || lIsReadOnly)
{
return on_actionSaveAs_triggered();
}
Q_UNUSED(ret);
if (m_curFileFormatVersion < VLayoutConverter::LayoutMaxVer
&& not ContinueFormatRewrite(m_curFileFormatVersionStr, VLayoutConverter::LayoutMaxVerStr))
{
return false;
}
// TODO
if (not CheckFilePermissions(curFile, this))
{
return false;
}
QString error;
if (not SaveLayout(curFile, error))
{
QMessageBox messageBox;
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Could not save the file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
m_curFileFormatVersion = VLayoutConverter::LayoutMaxVer;
m_curFileFormatVersionStr = VLayoutConverter::LayoutMaxVerStr;
return true;
}
//---------------------------------------------------------------------------------------------------------------------
void VPMainWindow::on_actionSaveAs_triggered()
bool VPMainWindow::on_actionSaveAs_triggered()
{
// TODO / FIXME : See valentina how the save is done over there. we need to add the
// extension .vlt, check for empty file names etc.
QString filters = tr("Layout files") + QStringLiteral(" (*.vlt)");
QString suffix = QStringLiteral("vlt");
QString fName = tr("layout") + QChar('.') + suffix;
//Get list last open files
QStringList recentFiles = VPApplication::VApp()->PuzzleSettings()->GetRecentFileList();
QString dir;
if (recentFiles.isEmpty())
if (curFile.isEmpty())
{
dir = QDir::homePath();
dir = VPApplication::VApp()->PuzzleSettings()->GetPathLayouts();
}
else
{
//Absolute path to last open file
dir = QFileInfo(recentFiles.first()).absolutePath();
dir = QFileInfo(curFile).absolutePath();
}
QString filters(tr("Layout files") + QLatin1String("(*.vlt)"));
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"),
dir + QLatin1String("/") + tr("Layout") + QLatin1String(".vlt"),
filters, nullptr
#ifdef Q_OS_LINUX
, QFileDialog::DontUseNativeDialog
#endif
);
bool usedNotExistedDir = false;
QDir directory(dir);
if (not directory.exists())
{
usedNotExistedDir = directory.mkpath(QChar('.'));
}
SaveFile(fileName);
QString fileName = QFileDialog::getSaveFileName(this, tr("Save as"), dir + QChar('/') + fName, filters, nullptr,
VAbstractApplication::VApp()->NativeFileDialog());
auto RemoveTempDir = qScopeGuard([usedNotExistedDir, dir]()
{
if (usedNotExistedDir)
{
QDir(dir).rmpath(QChar('.'));
}
});
if (fileName.isEmpty())
{
return false;
}
QFileInfo f( fileName );
if (f.suffix().isEmpty() && f.suffix() != suffix)
{
fileName += QChar('.') + suffix;
}
if (QFileInfo::exists(fileName) && curFile != fileName)
{
// Temporary try to lock the file before saving
VLockGuard<char> tmp(fileName);
if (not tmp.IsLocked())
{
qCCritical(pWindow, "%s",
qUtf8Printable(tr("Failed to lock. This file already opened in another window.")));
return false;
}
}
// Need for restoring previous state in case of failure
// const bool readOnly = m_layout->IsReadOnly();
// m_layout->SetReadOnly(false);
lIsReadOnly = false;
QString error;
bool result = SaveLayout(fileName, error);
if (not result)
{
QMessageBox messageBox;
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(tr("Could not save file"));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setDetailedText(error);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
// Restore previous state
// m_layout->SetReadOnly(readOnly);
// lIsReadOnly = readOnly;
return false;
}
m_curFileFormatVersion = VLayoutConverter::LayoutMaxVer;
m_curFileFormatVersionStr = VLayoutConverter::LayoutMaxVerStr;
// UpdatePadlock(false);
UpdateWindowTitle();
if (curFile == fileName && not lock.isNull())
{
lock->Unlock();
}
VlpCreateLock(lock, fileName);
if (not lock->IsLocked())
{
qCCritical(pWindow, "%s", qUtf8Printable(tr("Failed to lock. This file already opened in another window. "
"Expect collissions when run 2 copies of the program.")));
return false;
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------

View File

@ -43,6 +43,7 @@
#include "vpcommandline.h"
#include "../vlayout/vlayoutdef.h"
#include "../vwidgets/vabstractmainwindow.h"
#include "../vmisc/vlockguard.h"
namespace Ui
{
@ -65,12 +66,15 @@ public:
*/
bool LoadFile(QString path);
void LayoutWasSaved(bool saved);
void SetCurrentFile(const QString &fileName);
/**
* @brief SaveFile Saves the current layout to the layout file of given path
* @brief SaveLayout Saves the current layout to the layout file of given path
* @param path path to layout file
* @return true if success
*/
bool SaveFile(const QString &path);
bool SaveLayout(const QString &path, QString &error);
/**
* @brief ImportRawLayouts The function imports the raw layouts of given paths
@ -110,14 +114,14 @@ private slots:
* triggered.
* The slot is automatically connected through name convention.
*/
void on_actionSave_triggered();
bool on_actionSave_triggered();
/**
* @brief on_actionSaveAs_triggered When the menu action File > Save As
* is triggered.
* The slot is automatically connected through name convention.
*/
void on_actionSaveAs_triggered();
bool on_actionSaveAs_triggered();
/**
* @brief on_actionImportRawLayout_triggered When the menu action
@ -424,6 +428,8 @@ private:
bool isInitialized{false};
bool lIsReadOnly{false};
QSharedPointer<VLockGuard<char>> lock{nullptr};
/**
* @brief CreatePiece creates a piece from the given VLayoutPiece data
* @param rawPiece the raw piece data

View File

@ -34,18 +34,6 @@
#include "vplayoutliterals.h"
#include "../ifc/xml/vlayoutconverter.h"
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileWriter::VPLayoutFileWriter()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileWriter::~VPLayoutFileWriter()
{
}
//---------------------------------------------------------------------------------------------------------------------
void VPLayoutFileWriter::WriteFile(VPLayout *layout, QFile *file)
{

View File

@ -31,6 +31,7 @@
#include <QLocale>
#include <QXmlStreamWriter>
#include <QCoreApplication>
#include "../vmisc/literals.h"
@ -43,14 +44,14 @@ class QMarginsF;
class VPLayoutFileWriter : public QXmlStreamWriter
{
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileWriter)
public:
VPLayoutFileWriter();
~VPLayoutFileWriter();
VPLayoutFileWriter()= default;
~VPLayoutFileWriter()= default;
void WriteFile(VPLayout *layout, QFile *file);
private:
void WriteLayout(VPLayout *layout);
void WriteProperties(VPLayout *layout);
void WriteUnplacePiecesList(VPLayout *layout);
@ -69,7 +70,6 @@ private:
template <size_t N>
void SetAttribute(const QString &name, const char (&value)[N]);
};
//---------------------------------------------------------------------------------------------------------------------

View File

@ -775,48 +775,9 @@ bool TMainWindow::FileSave()
return false;
}
#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)
if (not CheckFilePermissions(curFile, this))
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The measurements document has no write permissions."));
messageBox.setInformativeText(tr("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)
{
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.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
return false;
}
QString error;

View File

@ -3253,52 +3253,9 @@ bool MainWindow::on_actionSave_triggered()
return false;
}
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(VAbstractValApplication::VApp()->GetPatternPath()).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
if (not CheckFilePermissions(VAbstractValApplication::VApp()->GetPatternPath(), this))
{
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The document has no write permissions."));
messageBox.setInformativeText(tr("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(VAbstractValApplication::VApp()->GetPatternPath(),
QFileInfo(VAbstractValApplication::VApp()
->GetPatternPath()).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(VAbstractValApplication::VApp()->GetPatternPath()));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
return false;
}
QString error;

View File

@ -73,6 +73,7 @@ namespace
{
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsIndividualMeasurements, (QLatin1String("paths/individual_measurements")))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsMultisizeMeasurements, (QLatin1String("paths/standard_measurements")))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsLayouts, (QLatin1String("paths/layouts")))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsPattern, (QLatin1String("paths/pattern")))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsTemplates, (QLatin1String("paths/templates")))
Q_GLOBAL_STATIC_WITH_ARGS(const QString, settingPathsLabelTemplate, (QLatin1String("paths/labels")))
@ -406,6 +407,27 @@ void VCommonSettings::SetPathMultisizeMeasurements(const QString &value)
settings.sync();
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommonSettings::GetDefPathLayouts()
{
return QDir::homePath() + QLatin1String("/valentina/") + tr("layouts");
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommonSettings::GetPathLayouts() const
{
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
return settings.value(*settingPathsLayouts, GetDefPathLayouts()).toString();
}
//---------------------------------------------------------------------------------------------------------------------
void VCommonSettings::SetPathLayouts(const QString &value)
{
QSettings settings(this->format(), this->scope(), this->organizationName(), *commonIniFilename);
settings.setValue(*settingPathsLayouts, value);
settings.sync();
}
//---------------------------------------------------------------------------------------------------------------------
QString VCommonSettings::GetDefPathPattern()
{

View File

@ -1,4 +1,4 @@
/************************************************************************
/************************************************************************
**
** @file vcommonsettings.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
@ -68,6 +68,10 @@ public:
QString GetPathMultisizeMeasurements() const;
void SetPathMultisizeMeasurements(const QString &value);
static QString GetDefPathLayouts();
QString GetPathLayouts() const;
void SetPathLayouts(const QString &value);
static QString GetDefPathPattern();
QString GetPathPattern() const;
void SetPathPattern(const QString &value);

View File

@ -236,6 +236,54 @@ void VAbstractMainWindow::UpdateRecentFileActions()
m_separatorAct->setVisible(numRecentFiles>0);
}
//---------------------------------------------------------------------------------------------------------------------
auto VAbstractMainWindow::CheckFilePermissions(const QString &path, QWidget *messageBoxParent) -> bool
{
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup++; // turn checking on
#endif /*Q_OS_WIN32*/
const bool isFileWritable = QFileInfo(path).isWritable();
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not isFileWritable)
{
QMessageBox messageBox(messageBoxParent);
messageBox.setIcon(QMessageBox::Question);
messageBox.setText(tr("The measurements document has no write permissions."));
messageBox.setInformativeText(tr("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(path, QFileInfo(path).permissions() | QFileDevice::WriteUser);
#ifdef Q_OS_WIN32
qt_ntfs_permission_lookup--; // turn it off again
#endif /*Q_OS_WIN32*/
if (not changed)
{
messageBox.setIcon(QMessageBox::Warning);
messageBox.setText(tr("Cannot set permissions for %1 to writable.").arg(path));
messageBox.setInformativeText(tr("Could not save the file."));
messageBox.setStandardButtons(QMessageBox::Ok);
messageBox.setDefaultButton(QMessageBox::Ok);
messageBox.exec();
return false;
}
}
else
{
return false;
}
}
return true;
}
//---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::WindowsLocale()
{

View File

@ -71,6 +71,8 @@ protected:
virtual QStringList RecentFileList() const =0;
void UpdateRecentFileActions();
static bool CheckFilePermissions(const QString &path, QWidget *messageBoxParent=nullptr) ;
private:
Q_DISABLE_COPY(VAbstractMainWindow)
};