File > Open Layout.

This commit is contained in:
Roman Telezhynskyi 2021-05-21 18:08:37 +03:00
parent d10355b400
commit 6efa26ffe3
11 changed files with 176 additions and 214 deletions

View File

@ -131,11 +131,50 @@ VPMainWindow::~VPMainWindow()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPMainWindow::LoadFile(QString path) auto VPMainWindow::CurrentFile() const -> QString
{ {
return curFile;
}
//---------------------------------------------------------------------------------------------------------------------
auto VPMainWindow::LoadFile(QString path) -> bool
{
if (not QFileInfo::exists(path))
{
qCCritical(pWindow, "%s", qUtf8Printable(tr("File '%1' doesn't exist!").arg(path)));
if (m_cmd->IsTestModeEnabled())
{
qApp->exit(V_EX_NOINPUT);
}
return false;
}
// Check if file already opened
QList<VPMainWindow*> list = VPApplication::VApp()->MainWindows();
auto w = std::find_if(list.begin(), list.end(),
[path](VPMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{
(*w)->activateWindow();
close();
return false;
}
VlpCreateLock(lock, path);
if (not lock->IsLocked())
{
if (not IgnoreLocking(lock->GetLockError(), path, m_cmd->IsGuiEnabled()))
{
return false;
}
}
try try
{ {
VLayoutConverter converter(path); VLayoutConverter converter(path);
m_curFileFormatVersion = converter.GetCurrentFormatVersion();
m_curFileFormatVersionStr = converter.GetFormatVersionStr();
path = converter.Convert(); path = converter.Convert();
} }
catch (VException &e) catch (VException &e)
@ -148,16 +187,32 @@ bool VPMainWindow::LoadFile(QString path)
QFile file(path); QFile file(path);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
QScopedPointer<VPLayoutFileReader> fileReader(new VPLayoutFileReader()); VPLayoutFileReader fileReader;
if(m_layout == nullptr) if(m_layout == nullptr)
{ {
m_layout = new VPLayout(); m_layout = new VPLayout();
} }
fileReader->ReadFile(m_layout, &file); fileReader.ReadFile(m_layout, &file);
// TODO / FIXME : better return value and error handling if (fileReader.hasError())
{
qCCritical(pWindow, "%s\n\n%s", qUtf8Printable(tr("File error.")),
qUtf8Printable(tr("Unable to read a layout file")));
lock.reset();
if (m_cmd->IsTestModeEnabled())
{
qApp->exit(V_EX_NOINPUT);
}
return false;
}
// updates the properties with the loaded data
SetPropertiesData();
// TODO : update the Carrousel and the QGraphicView
return true; return true;
} }
@ -1049,52 +1104,28 @@ void VPMainWindow::on_actionOpen_triggered()
qCDebug(pWindow, "Openning puzzle layout file."); qCDebug(pWindow, "Openning puzzle layout file.");
const QString filter(tr("Layout files") + QLatin1String(" (*.vlt)")); const QString filter(tr("Layout files") + QLatin1String(" (*.vlt)"));
//Use standard path to individual measurements
const QString pathTo = VPApplication::VApp()->PuzzleSettings()->GetPathLayouts();
//Get list last open files bool usedNotExistedDir = false;
QStringList recentFiles = VPApplication::VApp()->PuzzleSettings()->GetRecentFileList(); QDir directory(pathTo);
QString dir; if (not directory.exists())
if (recentFiles.isEmpty())
{ {
dir = QDir::homePath(); usedNotExistedDir = directory.mkpath(QChar('.'));
}
else
{
//Absolute path to last open file
dir = QFileInfo(recentFiles.first()).absolutePath();
}
qCDebug(pWindow, "Run QFileDialog::getOpenFileName: dir = %s.", qUtf8Printable(dir));
const QString filePath = QFileDialog::getOpenFileName(this, tr("Open file"), dir, filter, nullptr);
if (filePath.isEmpty())
{
return;
} }
const QString mPath = QFileDialog::getOpenFileName(this, tr("Open file"), pathTo, filter, nullptr,
VAbstractApplication::VApp()->NativeFileDialog());
// TODO : if m_layout == nullptr, open in current window if (not mPath.isEmpty())
// otherwise open in new window
// TODO : if layout file has a lock, warning message
if(!LoadFile(filePath))
{ {
return; VPApplication::VApp()->NewMainWindow()->LoadFile(mPath);
} }
// Updates the list of recent files if (usedNotExistedDir)
recentFiles.removeAll(filePath);
recentFiles.prepend(filePath);
while (recentFiles.size() > MaxRecentFiles)
{ {
recentFiles.removeLast(); QDir(pathTo).rmpath(QChar('.'));
} }
VPApplication::VApp()->PuzzleSettings()->SetRecentFileList(recentFiles);
// updates the properties with the loaded data
SetPropertiesData();
// TODO : update the Carrousel and the QGraphicView
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -58,6 +58,8 @@ public:
explicit VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent = nullptr); explicit VPMainWindow(const VPCommandLinePtr &cmd, QWidget *parent = nullptr);
virtual ~VPMainWindow(); virtual ~VPMainWindow();
QString CurrentFile() const;
/** /**
* @brief LoadFile Loads the layout file of given path in m_layout. * @brief LoadFile Loads the layout file of given path in m_layout.
* This function doesn't update the gui. * This function doesn't update the gui.

View File

@ -33,19 +33,6 @@
#include "../ifc/exception/vexception.h" #include "../ifc/exception/vexception.h"
#include "../ifc/exception/vexceptionconversionerror.h" #include "../ifc/exception/vexceptionconversionerror.h"
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileReader::VPLayoutFileReader()
{
}
//---------------------------------------------------------------------------------------------------------------------
VPLayoutFileReader::~VPLayoutFileReader()
{
// TODO
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file) bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file)
{ {
@ -56,7 +43,7 @@ bool VPLayoutFileReader::ReadFile(VPLayout *layout, QFile *file)
ReadLayout(layout); ReadLayout(layout);
} }
return !error(); return hasError();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -39,8 +39,8 @@ class VPLayoutFileReader : public QXmlStreamReader
{ {
Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader) Q_DECLARE_TR_FUNCTIONS(VPLayoutFileReader)
public: public:
VPLayoutFileReader(); VPLayoutFileReader()=default;
~VPLayoutFileReader(); ~VPLayoutFileReader()=default;
bool ReadFile(VPLayout *layout, QFile *file); bool ReadFile(VPLayout *layout, QFile *file);
@ -64,7 +64,7 @@ private:
static QString ReadAttributeEmptyString(const QXmlStreamAttributes &attribs, const QString &name); static QString ReadAttributeEmptyString(const QXmlStreamAttributes &attribs, const QString &name);
static bool ReadAttributeBool(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue); static bool ReadAttributeBool(const QXmlStreamAttributes &attribs, const QString &name, const QString &defValue);
static qreal ReadAttributeDouble(const QXmlStreamAttributes &attribs, const QString &name, static qreal ReadAttributeDouble(const QXmlStreamAttributes &attribs, const QString &name,
const QString &defValue); const QString &defValue);
}; };
#endif // VPLAYOUTFILEREADER_H #endif // VPLAYOUTFILEREADER_H

View File

@ -374,7 +374,7 @@ bool MApplication::IsTestMode() const
*/ */
bool MApplication::IsAppInGUIMode() const bool MApplication::IsAppInGUIMode() const
{ {
return IsTestMode(); return not IsTestMode();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------

View File

@ -278,21 +278,20 @@ bool TMainWindow::LoadFile(const QString &path)
// Check if file already opened // Check if file already opened
const QList<TMainWindow*> list = MApplication::VApp()->MainWindows(); const QList<TMainWindow*> list = MApplication::VApp()->MainWindows();
for (auto w : list) auto w = std::find_if(list.begin(), list.end(),
[path](TMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{ {
if (w->CurrentFile() == path) (*w)->activateWindow();
{ close();
w->activateWindow(); return false;
close();
return false;
}
} }
VlpCreateLock(lock, path); VlpCreateLock(lock, path);
if (not lock->IsLocked()) if (not lock->IsLocked())
{ {
if (not IgnoreLocking(lock->GetLockError(), path)) if (not IgnoreLocking(lock->GetLockError(), path, MApplication::VApp()->IsAppInGUIMode()))
{ {
return false; return false;
} }
@ -3478,21 +3477,20 @@ bool TMainWindow::LoadFromExistingFile(const QString &path)
// Check if file already opened // Check if file already opened
const QList<TMainWindow*> list = MApplication::VApp()->MainWindows(); const QList<TMainWindow*> list = MApplication::VApp()->MainWindows();
for (auto w : list) auto w = std::find_if(list.begin(), list.end(),
[path](TMainWindow *window) { return window->CurrentFile() == path; });
if (w != list.end())
{ {
if (w->CurrentFile() == path) (*w)->activateWindow();
{ close();
w->activateWindow(); return false;
close();
return false;
}
} }
VlpCreateLock(lock, path); VlpCreateLock(lock, path);
if (not lock->IsLocked()) if (not lock->IsLocked())
{ {
if (not IgnoreLocking(lock->GetLockError(), path)) if (not IgnoreLocking(lock->GetLockError(), path, MApplication::VApp()->IsAppInGUIMode()))
{ {
return false; return false;
} }
@ -3617,72 +3615,6 @@ void TMainWindow::CreateWindowMenu(QMenu *menu)
} }
} }
//---------------------------------------------------------------------------------------------------------------------
bool TMainWindow::IgnoreLocking(int error, const QString &path)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (not MApplication::VApp()->IsTestMode())
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file. Ignore if you want to "
"continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(tMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(tMainWindow, "Error type: %d", error);
if (MApplication::VApp()->IsTestMode())
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(tMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void TMainWindow::HackDimensionBaseValue() void TMainWindow::HackDimensionBaseValue()
{ {

View File

@ -228,8 +228,6 @@ private:
void CreateWindowMenu(QMenu *menu); void CreateWindowMenu(QMenu *menu);
bool IgnoreLocking(int error, const QString &path);
template <class T> template <class T>
void HackWidget(T **widget); void HackWidget(T **widget);
void HackDimensionBaseValue(); void HackDimensionBaseValue();

View File

@ -5282,7 +5282,7 @@ bool MainWindow::LoadPattern(QString fileName, const QString& customMeasureFile)
} }
else else
{ {
if (not IgnoreLocking(lock->GetLockError(), fileName)) if (not IgnoreLocking(lock->GetLockError(), fileName, VApplication::IsGUIMode()))
{ {
return false; return false;
} }
@ -6390,73 +6390,6 @@ void MainWindow::UpdateWindowTitle()
#endif //defined(Q_OS_MAC) #endif //defined(Q_OS_MAC)
} }
//---------------------------------------------------------------------------------------------------------------------
bool MainWindow::IgnoreLocking(int error, const QString &path)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (VApplication::IsGUIMode())
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition prevented "
"writing out the lock file. Ignore if you want to continue (not "
"recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(vMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(vMainWindow, "Error type: %d", error);
Clear();
if (not VApplication::IsGUIMode())
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(vMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition prevented "
"writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void MainWindow::ToolSelectPoint() void MainWindow::ToolSelectPoint()
{ {

View File

@ -392,8 +392,6 @@ private:
void UpdateWindowTitle(); void UpdateWindowTitle();
bool IgnoreLocking(int error, const QString &path);
void ToolSelectPoint(); void ToolSelectPoint();
void ToolSelectPointByPress(); void ToolSelectPointByPress();
void ToolSelectPointByRelease(); void ToolSelectPointByRelease();

View File

@ -31,18 +31,31 @@
#include "../vmisc/vabstractapplication.h" #include "../vmisc/vabstractapplication.h"
#include "../vmisc/compatibility.h" #include "../vmisc/compatibility.h"
#include "../vmisc/def.h" #include "../vmisc/def.h"
#include "../vmisc/vsysexits.h"
#include "dialogs/dialogexporttocsv.h" #include "dialogs/dialogexporttocsv.h"
#include "../vwidgets/vmaingraphicsview.h"
#include <QStyle> #include <QStyle>
#include <QToolBar> #include <QToolBar>
#include <QFileDialog> #include <QFileDialog>
#include <QAction> #include <QAction>
#include <QLockFile>
#include <QMessageBox>
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
#include "../vwidgets/vmaingraphicsview.h"
#include <QStyleFactory> #include <QStyleFactory>
#endif #endif
#include <QLoggingCategory>
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wmissing-prototypes")
QT_WARNING_DISABLE_INTEL(1418)
Q_LOGGING_CATEGORY(abstactMainWindow, "abs.MainWindow")
QT_WARNING_POP
namespace namespace
{ {
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -284,6 +297,72 @@ auto VAbstractMainWindow::CheckFilePermissions(const QString &path, QWidget *mes
return true; return true;
} }
//---------------------------------------------------------------------------------------------------------------------
bool VAbstractMainWindow::IgnoreLocking(int error, const QString &path, bool guiMode)
{
QMessageBox::StandardButton answer = QMessageBox::Abort;
if (guiMode)
{
switch(error)
{
case QLockFile::LockFailedError:
answer = QMessageBox::warning(this, tr("Locking file"),
tr("This file already opened in another window. Ignore if you want "
"to continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::PermissionError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("The lock file could not be created, for lack of permissions. "
"Ignore if you want to continue (not recommended, can cause "
"a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
case QLockFile::UnknownError:
answer = QMessageBox::question(this, tr("Locking file"),
tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file. Ignore if you want to "
"continue (not recommended, can cause a data corruption)."),
QMessageBox::Abort|QMessageBox::Ignore, QMessageBox::Abort);
break;
default:
answer = QMessageBox::Abort;
break;
}
}
if (answer == QMessageBox::Abort)
{
qCDebug(abstactMainWindow, "Failed to lock %s", qUtf8Printable(path));
qCDebug(abstactMainWindow, "Error type: %d", error);
if (not guiMode)
{
switch(error)
{
case QLockFile::LockFailedError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("This file already opened in another window.")));
break;
case QLockFile::PermissionError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("The lock file could not be created, for lack of permissions.")));
break;
case QLockFile::UnknownError:
qCCritical(abstactMainWindow, "%s",
qUtf8Printable(tr("Unknown error happened, for instance a full partition "
"prevented writing out the lock file.")));
break;
default:
break;
}
qApp->exit(V_EX_NOINPUT);
}
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void VAbstractMainWindow::WindowsLocale() void VAbstractMainWindow::WindowsLocale()
{ {

View File

@ -71,7 +71,9 @@ protected:
virtual QStringList RecentFileList() const =0; virtual QStringList RecentFileList() const =0;
void UpdateRecentFileActions(); void UpdateRecentFileActions();
static bool CheckFilePermissions(const QString &path, QWidget *messageBoxParent=nullptr) ; static bool CheckFilePermissions(const QString &path, QWidget *messageBoxParent=nullptr);
bool IgnoreLocking(int error, const QString &path, bool guiMode);
private: private:
Q_DISABLE_COPY(VAbstractMainWindow) Q_DISABLE_COPY(VAbstractMainWindow)