mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
add command line parser
Support open files via command line.
This commit is contained in:
parent
2bad915583
commit
c506b3e1e7
55
src/commandlineoptions.cpp
Normal file
55
src/commandlineoptions.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include "commandlineoptions.h"
|
||||||
|
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QCommandLineOption>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#define TR(x) QCoreApplication::translate("main", (x))
|
||||||
|
|
||||||
|
CommandLineOptions::ParseResult CommandLineOptions::parse(const QStringList &p_arguments)
|
||||||
|
{
|
||||||
|
QCommandLineParser parser;
|
||||||
|
parser.setApplicationDescription(TR("A pleasant note-taking platform."));
|
||||||
|
const auto helpOpt = parser.addHelpOption();
|
||||||
|
const auto versionOpt = parser.addVersionOption();
|
||||||
|
|
||||||
|
// Positional arguments.
|
||||||
|
parser.addPositionalArgument("paths", TR("Files or folders to open."));
|
||||||
|
|
||||||
|
const QCommandLineOption verboseOpt("verbose", TR("Print more logs."));
|
||||||
|
parser.addOption(verboseOpt);
|
||||||
|
|
||||||
|
// WebEngine options.
|
||||||
|
// No need to handle them. Just add them to the parser to avoid parse error.
|
||||||
|
QCommandLineOption webRemoteDebuggingPortOpt("remote-debugging-port",
|
||||||
|
TR("WebEngine remote debugging port."),
|
||||||
|
"port_number");
|
||||||
|
webRemoteDebuggingPortOpt.setFlags(QCommandLineOption::HiddenFromHelp);
|
||||||
|
parser.addOption(webRemoteDebuggingPortOpt);
|
||||||
|
|
||||||
|
if (!parser.parse(p_arguments)) {
|
||||||
|
m_errorMsg = parser.errorText();
|
||||||
|
return ParseResult::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle results.
|
||||||
|
m_helpText = parser.helpText();
|
||||||
|
if (parser.isSet(helpOpt)) {
|
||||||
|
return ParseResult::HelpRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser.isSet(versionOpt)) {
|
||||||
|
return ParseResult::VersionRequested;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position arguments.
|
||||||
|
const auto args = parser.positionalArguments();
|
||||||
|
m_pathsToOpen = args;
|
||||||
|
|
||||||
|
if (parser.isSet(verboseOpt)) {
|
||||||
|
m_verbose = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseResult::Ok;
|
||||||
|
}
|
30
src/commandlineoptions.h
Normal file
30
src/commandlineoptions.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef COMMANDLINEOPTIONS_H
|
||||||
|
#define COMMANDLINEOPTIONS_H
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class CommandLineOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ParseResult
|
||||||
|
{
|
||||||
|
Ok,
|
||||||
|
Error,
|
||||||
|
VersionRequested,
|
||||||
|
HelpRequested
|
||||||
|
};
|
||||||
|
|
||||||
|
CommandLineOptions() = default;
|
||||||
|
|
||||||
|
ParseResult parse(const QStringList &p_arguments);
|
||||||
|
|
||||||
|
QString m_errorMsg;
|
||||||
|
|
||||||
|
QString m_helpText;
|
||||||
|
|
||||||
|
QStringList m_pathsToOpen;
|
||||||
|
|
||||||
|
bool m_verbose = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMMANDLINEOPTIONS_H
|
@ -229,7 +229,7 @@ QString ConfigMgr::getConfigFilePath(Source p_src) const
|
|||||||
QString configPath;
|
QString configPath;
|
||||||
switch (p_src) {
|
switch (p_src) {
|
||||||
case Source::Default:
|
case Source::Default:
|
||||||
configPath = QStringLiteral(":/vnotex/data/core/") + c_configFileName;
|
configPath = getDefaultConfigFilePath();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Source::App:
|
case Source::App:
|
||||||
@ -255,9 +255,13 @@ QString ConfigMgr::getConfigFilePath(Source p_src) const
|
|||||||
return configPath;
|
return configPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ConfigMgr::getDefaultConfigFilePath()
|
||||||
|
{
|
||||||
|
return QStringLiteral(":/vnotex/data/core/") + c_configFileName;
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<ConfigMgr::Settings> ConfigMgr::getSettings(Source p_src) const
|
QSharedPointer<ConfigMgr::Settings> ConfigMgr::getSettings(Source p_src) const
|
||||||
{
|
{
|
||||||
|
|
||||||
return ConfigMgr::Settings::fromFile(getConfigFilePath(p_src));
|
return ConfigMgr::Settings::fromFile(getConfigFilePath(p_src));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,3 +437,18 @@ QString ConfigMgr::getDocumentOrHomePath()
|
|||||||
|
|
||||||
return docHomePath;
|
return docHomePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ConfigMgr::getApplicationVersion()
|
||||||
|
{
|
||||||
|
static QString appVersion;
|
||||||
|
|
||||||
|
if (appVersion.isEmpty()) {
|
||||||
|
auto defaultSettings = ConfigMgr::Settings::fromFile(getDefaultConfigFilePath());
|
||||||
|
const auto &defaultObj = defaultSettings->getJson();
|
||||||
|
|
||||||
|
auto metaDataObj = defaultObj.value(QStringLiteral("metadata")).toObject();
|
||||||
|
appVersion = metaDataObj.value(QStringLiteral("version")).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return appVersion;
|
||||||
|
}
|
||||||
|
@ -104,6 +104,8 @@ namespace vnotex
|
|||||||
|
|
||||||
static QString getDocumentOrHomePath();
|
static QString getDocumentOrHomePath();
|
||||||
|
|
||||||
|
static QString getApplicationVersion();
|
||||||
|
|
||||||
static const QString c_orgName;
|
static const QString c_orgName;
|
||||||
|
|
||||||
static const QString c_appName;
|
static const QString c_appName;
|
||||||
@ -129,6 +131,8 @@ namespace vnotex
|
|||||||
// Update it if in need.
|
// Update it if in need.
|
||||||
void checkAppConfig();
|
void checkAppConfig();
|
||||||
|
|
||||||
|
static QString getDefaultConfigFilePath();
|
||||||
|
|
||||||
QScopedPointer<MainConfig> m_config;;
|
QScopedPointer<MainConfig> m_config;;
|
||||||
|
|
||||||
// Session config.
|
// Session config.
|
||||||
|
@ -12,6 +12,8 @@ using namespace vnotex;
|
|||||||
|
|
||||||
const QString SingleInstanceGuard::c_serverName = "vnote";
|
const QString SingleInstanceGuard::c_serverName = "vnote";
|
||||||
|
|
||||||
|
const QChar SingleInstanceGuard::c_stringListSeparator = '>';
|
||||||
|
|
||||||
SingleInstanceGuard::SingleInstanceGuard()
|
SingleInstanceGuard::SingleInstanceGuard()
|
||||||
{
|
{
|
||||||
qInfo() << "guarding is on";
|
qInfo() << "guarding is on";
|
||||||
@ -54,6 +56,14 @@ void SingleInstanceGuard::requestOpenFiles(const QStringList &p_files)
|
|||||||
if (p_files.isEmpty()) {
|
if (p_files.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(!m_online);
|
||||||
|
if (!m_client || m_client->state() != QLocalSocket::ConnectedState) {
|
||||||
|
qWarning() << "failed to request open files" << m_client->errorString();
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendRequest(m_client.data(), OpCode::OpenFiles, p_files.join(c_stringListSeparator));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleInstanceGuard::requestShow()
|
void SingleInstanceGuard::requestShow()
|
||||||
@ -157,6 +167,7 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
|||||||
inStream.setDevice(p_socket);
|
inStream.setDevice(p_socket);
|
||||||
inStream.setVersion(QDataStream::Qt_5_12);
|
inStream.setVersion(QDataStream::Qt_5_12);
|
||||||
|
|
||||||
|
while (p_socket->bytesAvailable() > 0) {
|
||||||
if (m_command.m_opCode == OpCode::Null) {
|
if (m_command.m_opCode == OpCode::Null) {
|
||||||
// Relies on the fact that QDataStream serializes a quint32 into
|
// Relies on the fact that QDataStream serializes a quint32 into
|
||||||
// sizeof(quint32) bytes.
|
// sizeof(quint32) bytes.
|
||||||
@ -174,7 +185,7 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "op code" << m_command.m_opCode << m_command.m_size;
|
qDebug() << "op code" << m_command.m_opCode << m_command.m_size << p_socket->bytesAvailable();
|
||||||
|
|
||||||
switch (m_command.m_opCode) {
|
switch (m_command.m_opCode) {
|
||||||
case OpCode::Show:
|
case OpCode::Show:
|
||||||
@ -182,9 +193,23 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
|||||||
emit showRequested();
|
emit showRequested();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpCode::OpenFiles:
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_command.m_size != 0);
|
||||||
|
QString payload;
|
||||||
|
inStream >> payload;
|
||||||
|
const auto files = payload.split(c_stringListSeparator);
|
||||||
|
emit openFilesRequested(files);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qWarning() << "unknown op code" << m_command.m_opCode;
|
qWarning() << "unknown op code" << m_command.m_opCode;
|
||||||
break;
|
m_command.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_command.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ namespace vnotex
|
|||||||
enum OpCode
|
enum OpCode
|
||||||
{
|
{
|
||||||
Null = 0,
|
Null = 0,
|
||||||
Show
|
Show,
|
||||||
|
OpenFiles
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Command
|
struct Command
|
||||||
@ -78,6 +79,8 @@ namespace vnotex
|
|||||||
Command m_command;
|
Command m_command;
|
||||||
|
|
||||||
static const QString c_serverName;
|
static const QString c_serverName;
|
||||||
|
|
||||||
|
static const QChar c_stringListSeparator;
|
||||||
};
|
};
|
||||||
} // ns vnotex
|
} // ns vnotex
|
||||||
|
|
||||||
|
49
src/main.cpp
49
src/main.cpp
@ -21,6 +21,7 @@
|
|||||||
#include <QWebEngineSettings>
|
#include <QWebEngineSettings>
|
||||||
#include <core/exception.h>
|
#include <core/exception.h>
|
||||||
#include <widgets/messageboxhelper.h>
|
#include <widgets/messageboxhelper.h>
|
||||||
|
#include "commandlineoptions.h"
|
||||||
|
|
||||||
using namespace vnotex;
|
using namespace vnotex;
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ void loadTranslators(QApplication &p_app);
|
|||||||
|
|
||||||
void initWebEngineSettings();
|
void initWebEngineSettings();
|
||||||
|
|
||||||
|
void showMessageOnCommandLineIfAvailable(const QString &p_msg);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
||||||
@ -76,18 +79,44 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
app.setApplicationName(ConfigMgr::c_appName);
|
app.setApplicationName(ConfigMgr::c_appName);
|
||||||
app.setOrganizationName(ConfigMgr::c_orgName);
|
app.setOrganizationName(ConfigMgr::c_orgName);
|
||||||
|
|
||||||
|
app.setApplicationVersion(ConfigMgr::getApplicationVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandLineOptions cmdOptions;
|
||||||
|
switch (cmdOptions.parse(app.arguments())) {
|
||||||
|
case CommandLineOptions::Ok:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CommandLineOptions::Error:
|
||||||
|
showMessageOnCommandLineIfAvailable(cmdOptions.m_errorMsg);
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
case CommandLineOptions::VersionRequested:
|
||||||
|
{
|
||||||
|
auto versionStr = QString("%1 %2").arg(app.applicationName()).arg(app.applicationVersion());
|
||||||
|
showMessageOnCommandLineIfAvailable(versionStr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CommandLineOptions::HelpRequested:
|
||||||
|
Q_FALLTHROUGH();
|
||||||
|
default:
|
||||||
|
showMessageOnCommandLineIfAvailable(cmdOptions.m_helpText);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guarding.
|
// Guarding.
|
||||||
SingleInstanceGuard guard;
|
SingleInstanceGuard guard;
|
||||||
bool canRun = guard.tryRun();
|
bool canRun = guard.tryRun();
|
||||||
if (!canRun) {
|
if (!canRun) {
|
||||||
|
guard.requestOpenFiles(cmdOptions.m_pathsToOpen);
|
||||||
guard.requestShow();
|
guard.requestShow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.setApplicationVersion(ConfigMgr::getInst().getConfig().getVersion());
|
ConfigMgr::getInst();
|
||||||
} catch (Exception &e) {
|
} catch (Exception &e) {
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Critical,
|
MessageBoxHelper::notify(MessageBoxHelper::Critical,
|
||||||
MainWindow::tr("%1 failed to start.").arg(ConfigMgr::c_appName),
|
MainWindow::tr("%1 failed to start.").arg(ConfigMgr::c_appName),
|
||||||
@ -98,7 +127,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init logger after app info is set.
|
// Init logger after app info is set.
|
||||||
Logger::init(false);
|
Logger::init(cmdOptions.m_verbose);
|
||||||
|
|
||||||
qInfo() << QString("%1 (v%2) started at %3 (%4)").arg(ConfigMgr::c_appName,
|
qInfo() << QString("%1 (v%2) started at %3 (%4)").arg(ConfigMgr::c_appName,
|
||||||
app.applicationVersion(),
|
app.applicationVersion(),
|
||||||
@ -112,8 +141,6 @@ int main(int argc, char *argv[])
|
|||||||
qWarning() << "versions of the built and linked OpenSSL mismatch, network may not work";
|
qWarning() << "versions of the built and linked OpenSSL mismatch, network may not work";
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse command line options.
|
|
||||||
|
|
||||||
// Should set the correct locale before VNoteX::getInst().
|
// Should set the correct locale before VNoteX::getInst().
|
||||||
loadTranslators(app);
|
loadTranslators(app);
|
||||||
|
|
||||||
@ -131,8 +158,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
QObject::connect(&guard, &SingleInstanceGuard::showRequested,
|
QObject::connect(&guard, &SingleInstanceGuard::showRequested,
|
||||||
&window, &MainWindow::showMainWindow);
|
&window, &MainWindow::showMainWindow);
|
||||||
|
QObject::connect(&guard, &SingleInstanceGuard::openFilesRequested,
|
||||||
|
&window, &MainWindow::openFiles);
|
||||||
|
|
||||||
window.kickOffOnStart();
|
window.kickOffOnStart(cmdOptions.m_pathsToOpen);
|
||||||
|
|
||||||
int ret = app.exec();
|
int ret = app.exec();
|
||||||
if (ret == RESTART_EXIT_CODE) {
|
if (ret == RESTART_EXIT_CODE) {
|
||||||
@ -208,3 +237,13 @@ void initWebEngineSettings()
|
|||||||
auto settings = QWebEngineSettings::defaultSettings();
|
auto settings = QWebEngineSettings::defaultSettings();
|
||||||
settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
|
settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showMessageOnCommandLineIfAvailable(const QString &p_msg)
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
MessageBoxHelper::notify(MessageBoxHelper::Information,
|
||||||
|
QString("<pre>%1</pre>").arg(p_msg));
|
||||||
|
#else
|
||||||
|
printf("%s\n", qPrintable(p_msg));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -30,6 +30,7 @@ ICON = data/core/icons/vnote.icns
|
|||||||
TRANSLATIONS += data/core/translations/vnote_zh_CN.ts
|
TRANSLATIONS += data/core/translations/vnote_zh_CN.ts
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
commandlineoptions.cpp \
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
INCLUDEPATH *= $$PWD
|
INCLUDEPATH *= $$PWD
|
||||||
@ -137,3 +138,6 @@ unix:!macx {
|
|||||||
INSTALLS += extraresource
|
INSTALLS += extraresource
|
||||||
message("VNote will be installed in prefix $${PREFIX}")
|
message("VNote will be installed in prefix $${PREFIX}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
commandlineoptions.h
|
||||||
|
@ -70,8 +70,9 @@ MainWindow::~MainWindow()
|
|||||||
m_viewArea = nullptr;
|
m_viewArea = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::kickOffOnStart()
|
void MainWindow::kickOffOnStart(const QStringList &p_paths)
|
||||||
{
|
{
|
||||||
|
QTimer::singleShot(300, [this, p_paths]() {
|
||||||
VNoteX::getInst().initLoad();
|
VNoteX::getInst().initLoad();
|
||||||
|
|
||||||
emit mainWindowStarted();
|
emit mainWindowStarted();
|
||||||
@ -79,6 +80,16 @@ void MainWindow::kickOffOnStart()
|
|||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
|
|
||||||
demoWidget();
|
demoWidget();
|
||||||
|
|
||||||
|
openFiles(p_paths);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openFiles(const QStringList &p_files)
|
||||||
|
{
|
||||||
|
for (const auto &file : p_files) {
|
||||||
|
emit VNoteX::getInst().openFileRequested(file, QSharedPointer<FileOpenParameters>::create());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupUI()
|
void MainWindow::setupUI()
|
||||||
|
@ -33,7 +33,7 @@ namespace vnotex
|
|||||||
MainWindow(const MainWindow &) = delete;
|
MainWindow(const MainWindow &) = delete;
|
||||||
void operator=(const MainWindow &) = delete;
|
void operator=(const MainWindow &) = delete;
|
||||||
|
|
||||||
void kickOffOnStart();
|
void kickOffOnStart(const QStringList &p_paths);
|
||||||
|
|
||||||
void resetStateAndGeometry();
|
void resetStateAndGeometry();
|
||||||
|
|
||||||
@ -53,6 +53,8 @@ namespace vnotex
|
|||||||
|
|
||||||
void quitApp();
|
void quitApp();
|
||||||
|
|
||||||
|
void openFiles(const QStringList &p_files);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mainWindowStarted();
|
void mainWindowStarted();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user