Redesign command-line interface to support client server architecture.

This commit is contained in:
Roman Telezhynskyi 2020-04-14 11:36:21 +03:00
parent a258d5c7ed
commit cc3d3e8021
6 changed files with 77 additions and 45 deletions

View File

@ -198,7 +198,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg) if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
{ {
if (not qApp->IsTestMode()) if (qApp->IsAppInGUIMode())
{ {
if (topWinAllowsPop) if (topWinAllowsPop)
{ {
@ -235,8 +235,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con
PuzzleApplication::PuzzleApplication(int &argc, char **argv) PuzzleApplication::PuzzleApplication(int &argc, char **argv)
:VAbstractApplication(argc, argv), :VAbstractApplication(argc, argv),
mainWindows(), mainWindows(),
localServer(nullptr), localServer(nullptr)
testMode(false)
{ {
setApplicationDisplayName(VER_PRODUCTNAME_STR); setApplicationDisplayName(VER_PRODUCTNAME_STR);
setApplicationName(VER_INTERNALNAME_STR); setApplicationName(VER_INTERNALNAME_STR);
@ -321,19 +320,13 @@ bool PuzzleApplication::notify(QObject *receiver, QEvent *event)
return false; return false;
} }
//---------------------------------------------------------------------------------------------------------------------
bool PuzzleApplication::IsTestMode() const
{
return testMode;
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
/** /**
* @brief IsAppInGUIMode little hack that allow to have access to application state from VAbstractApplication class. * @brief IsAppInGUIMode little hack that allow to have access to application state from VAbstractApplication class.
*/ */
bool PuzzleApplication::IsAppInGUIMode() const bool PuzzleApplication::IsAppInGUIMode() const
{ {
return IsTestMode(); return CommandLine()->IsGuiEnabled();
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -342,7 +335,9 @@ PuzzleMainWindow *PuzzleApplication::MainWindow()
Clean(); Clean();
if (mainWindows.isEmpty()) if (mainWindows.isEmpty())
{ {
NewMainWindow(); VPuzzleCommandLinePtr cmd;
VPuzzleCommandLine::ProcessInstance(cmd, QStringList());
NewMainWindow(true);
} }
return mainWindows[0]; return mainWindows[0];
} }
@ -360,11 +355,11 @@ QList<PuzzleMainWindow *> PuzzleApplication::MainWindows()
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
PuzzleMainWindow *PuzzleApplication::NewMainWindow() PuzzleMainWindow *PuzzleApplication::NewMainWindow(bool guiMode)
{ {
PuzzleMainWindow *puzzle = new PuzzleMainWindow(); PuzzleMainWindow *puzzle = new PuzzleMainWindow();
mainWindows.prepend(puzzle); mainWindows.prepend(puzzle);
if (not qApp->IsTestMode()) if (guiMode)
{ {
puzzle->show(); puzzle->show();
} }
@ -444,10 +439,10 @@ void PuzzleApplication::ActivateDarkMode()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, const QStringList &arguments) void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, const QStringList &arguments)
{ {
VPuzzleCommandLinePtr cmd = CommandLine(); VPuzzleCommandLinePtr cmd;
testMode = cmd->IsTestModeEnabled(); VPuzzleCommandLine::ProcessInstance(cmd, arguments);
if (not testMode && connection == SocketConnection::Client) if (cmd->IsGuiEnabled() && connection == SocketConnection::Client)
{ {
const QString serverName = QCoreApplication::applicationName(); const QString serverName = QCoreApplication::applicationName();
QLocalSocket socket; QLocalSocket socket;
@ -456,7 +451,7 @@ void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, con
{ {
qCDebug(mApp, "Connected to the server '%s'", qUtf8Printable(serverName)); qCDebug(mApp, "Connected to the server '%s'", qUtf8Printable(serverName));
QTextStream stream(&socket); QTextStream stream(&socket);
stream << QCoreApplication::arguments().join(";;"); stream << arguments.join(";;");
stream.flush(); stream.flush();
socket.waitForBytesWritten(); socket.waitForBytesWritten();
qApp->exit(V_EX_OK); qApp->exit(V_EX_OK);
@ -485,43 +480,65 @@ void PuzzleApplication::ParseCommandLine(const SocketConnection &connection, con
LoadTranslation(PuzzleSettings()->GetLocale()); LoadTranslation(PuzzleSettings()->GetLocale());
} }
ProcessArguments(cmd);
}
//---------------------------------------------------------------------------------------------------------------------
void PuzzleApplication::ProcessArguments(const VPuzzleCommandLinePtr &cmd)
{
const QStringList rawLayouts = cmd->OptionRawLayouts();
const QStringList args = cmd->OptionFileNames(); const QStringList args = cmd->OptionFileNames();
if (args.count() > 0) if (args.count() > 0)
{ {
if (testMode && args.count() > 1) if (not cmd->IsGuiEnabled() && args.count() > 1)
{ {
qCCritical(mApp, "%s\n", qPrintable(tr("Test mode doesn't support openning several files."))); qCCritical(mApp, "%s\n", qPrintable(tr("Export mode doesn't support openning several files.")));
cmd.get()->parser.showHelp(V_EX_USAGE);
}
if (args.count() > 1 && rawLayouts.size() > 0)
{
qCCritical(mApp, "%s\n",
qPrintable(tr("Import raw layout data does not support penning several layout files.")));
cmd.get()->parser.showHelp(V_EX_USAGE); cmd.get()->parser.showHelp(V_EX_USAGE);
} }
for (auto &arg : args) for (auto &arg : args)
{ {
NewMainWindow(); NewMainWindow(cmd->IsGuiEnabled());
if (not MainWindow()->LoadFile(arg)) if (not MainWindow()->LoadFile(arg))
{ {
if (testMode) if (not cmd->IsGuiEnabled())
{ {
return; // process only one input file return; // process only one input file
} }
delete MainWindow(); delete MainWindow();
continue; continue;
} }
// if (rawLayouts.size() > 0)
// {
// MainWindow()->ImportRawLayouts(rawLayouts);
// }
} }
} }
else else
{ {
if (not testMode) if (cmd->IsTestModeEnabled())
{
NewMainWindow();
}
else
{ {
qCCritical(mApp, "%s\n", qPrintable(tr("Please, provide one input file."))); qCCritical(mApp, "%s\n", qPrintable(tr("Please, provide one input file.")));
cmd.get()->parser.showHelp(V_EX_USAGE); cmd.get()->parser.showHelp(V_EX_USAGE);
} }
NewMainWindow(cmd->IsGuiEnabled());
// if (rawLayouts.size() > 0)
// {
// MainWindow()->New(); // prepare layout settings
// MainWindow()->ImportRawLayouts(rawLayouts);
// }
} }
if (testMode) if (cmd->IsGuiEnabled())
{ {
qApp->exit(V_EX_OK); // close program after processing in console mode qApp->exit(V_EX_OK); // close program after processing in console mode
} }
@ -591,19 +608,18 @@ void PuzzleApplication::AboutToQuit()
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleApplication::NewLocalSocketConnection() void PuzzleApplication::NewLocalSocketConnection()
{ {
QLocalSocket *socket = localServer->nextPendingConnection(); QScopedPointer<QLocalSocket>socket(localServer->nextPendingConnection());
if (not socket) if (socket.isNull())
{ {
return; return;
} }
socket->waitForReadyRead(1000); socket->waitForReadyRead(1000);
QTextStream stream(socket); QTextStream stream(socket.data());
const QString arg = stream.readAll(); const QString arg = stream.readAll();
if (not arg.isEmpty()) if (not arg.isEmpty())
{ {
ParseCommandLine(SocketConnection::Server, arg.split(";;")); ParseCommandLine(SocketConnection::Server, arg.split(";;"));
} }
delete socket;
MainWindow()->raise(); MainWindow()->raise();
MainWindow()->activateWindow(); MainWindow()->activateWindow();
} }
@ -622,7 +638,7 @@ void PuzzleApplication::Clean()
} }
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
const VPuzzleCommandLinePtr PuzzleApplication::CommandLine() VPuzzleCommandLinePtr PuzzleApplication::CommandLine() const
{ {
return VPuzzleCommandLine::instance; return VPuzzleCommandLine::instance;
} }

View File

@ -55,15 +55,13 @@ public:
virtual bool notify(QObject * receiver, QEvent * event) override; virtual bool notify(QObject * receiver, QEvent * event) override;
bool IsTestMode() const;
virtual bool IsAppInGUIMode() const override; virtual bool IsAppInGUIMode() const override;
PuzzleMainWindow *MainWindow(); PuzzleMainWindow *MainWindow();
QList<PuzzleMainWindow*> MainWindows(); QList<PuzzleMainWindow*> MainWindows();
PuzzleMainWindow *NewMainWindow(); PuzzleMainWindow *NewMainWindow(bool guiMode);
void InitOptions(); void InitOptions();
virtual const VTranslateVars *TrVars() override; virtual const VTranslateVars *TrVars() override;
virtual void OpenSettings() override; virtual void OpenSettings() override;
@ -71,7 +69,8 @@ public:
void ActivateDarkMode(); void ActivateDarkMode();
void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments); void ParseCommandLine(const SocketConnection &connection, const QStringList &arguments);
const VPuzzleCommandLinePtr CommandLine(); void ProcessArguments(const VPuzzleCommandLinePtr &cmd);
VPuzzleCommandLinePtr CommandLine() const;
public slots: public slots:
void ProcessCMD(); void ProcessCMD();
@ -89,7 +88,6 @@ private:
Q_DISABLE_COPY(PuzzleApplication) Q_DISABLE_COPY(PuzzleApplication)
QList<QPointer<PuzzleMainWindow> > mainWindows; QList<QPointer<PuzzleMainWindow> > mainWindows;
QLocalServer *localServer; QLocalServer *localServer;
bool testMode;
void Clean(); void Clean();
}; };

View File

@ -56,6 +56,12 @@ bool PuzzleMainWindow::LoadFile(const QString &path)
return true; return true;
} }
//---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::ImportRawLayouts(const QStringList &layouts)
{
Q_UNUSED(layouts)
}
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
void PuzzleMainWindow::InitMenuBar() void PuzzleMainWindow::InitMenuBar()
{ {

View File

@ -28,14 +28,15 @@
#ifndef PUZZLEMAINWINDOW_H #ifndef PUZZLEMAINWINDOW_H
#define PUZZLEMAINWINDOW_H #define PUZZLEMAINWINDOW_H
#include "../vmisc/def.h"
#include <QMainWindow> #include <QMainWindow>
#include <QMessageBox> #include <QMessageBox>
#include "../vmisc/def.h"
#include "vpiececarrousel.h" #include "vpiececarrousel.h"
namespace Ui { namespace Ui
class PuzzleMainWindow; {
class PuzzleMainWindow;
} }
class PuzzleMainWindow : public QMainWindow class PuzzleMainWindow : public QMainWindow
@ -48,6 +49,11 @@ public:
bool LoadFile(const QString &path); bool LoadFile(const QString &path);
void ImportRawLayouts(const QStringList &layouts);
public slots:
void New();
private: private:
Q_DISABLE_COPY(PuzzleMainWindow) Q_DISABLE_COPY(PuzzleMainWindow)
Ui::PuzzleMainWindow *ui; Ui::PuzzleMainWindow *ui;
@ -62,7 +68,6 @@ private:
void InitPieceCarrousel(); void InitPieceCarrousel();
private slots: private slots:
void New();
void Open(); void Open();
void Save(); void Save();
void SaveAs(); void SaveAs();

View File

@ -84,15 +84,21 @@ VPuzzleCommandLine::VPuzzleCommandLine():
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------
VPuzzleCommandLinePtr VPuzzleCommandLine::Instance(const QCoreApplication &app) VPuzzleCommandLinePtr VPuzzleCommandLine::Instance(const QCoreApplication &app)
{
VPuzzleCommandLine::ProcessInstance(instance, app.arguments());
return instance;
}
//---------------------------------------------------------------------------------------------------------------------
void VPuzzleCommandLine::ProcessInstance(VPuzzleCommandLinePtr &instance, const QStringList &arguments)
{ {
if (instance == nullptr) if (instance == nullptr)
{ {
instance.reset(new VPuzzleCommandLine); instance.reset(new VPuzzleCommandLine);
} }
instance->parser.process(app); instance->parser.process(arguments);
instance->isGuiEnabled = not (instance->IsGuiEnabled() || instance->IsExportEnabled()); instance->isGuiEnabled = not (instance->IsGuiEnabled() || instance->IsExportEnabled());
return instance;
} }
//------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------

View File

@ -38,7 +38,8 @@ protected:
VPuzzleCommandLine(); VPuzzleCommandLine();
/** @brief create the single instance of the class inside puzzleapplication */ /** @brief create the single instance of the class inside puzzleapplication */
static VPuzzleCommandLinePtr Instance(const QCoreApplication &app); static VPuzzleCommandLinePtr Instance(const QCoreApplication &app);
static void ProcessInstance(VPuzzleCommandLinePtr &instance, const QStringList &arguments);
private: private:
Q_DISABLE_COPY(VPuzzleCommandLine) Q_DISABLE_COPY(VPuzzleCommandLine)
static VPuzzleCommandLinePtr instance; static VPuzzleCommandLinePtr instance;