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

View File

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

View File

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

View File

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

View File

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

View File

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