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;
|
||||
switch (p_src) {
|
||||
case Source::Default:
|
||||
configPath = QStringLiteral(":/vnotex/data/core/") + c_configFileName;
|
||||
configPath = getDefaultConfigFilePath();
|
||||
break;
|
||||
|
||||
case Source::App:
|
||||
@ -255,9 +255,13 @@ QString ConfigMgr::getConfigFilePath(Source p_src) const
|
||||
return configPath;
|
||||
}
|
||||
|
||||
QString ConfigMgr::getDefaultConfigFilePath()
|
||||
{
|
||||
return QStringLiteral(":/vnotex/data/core/") + c_configFileName;
|
||||
}
|
||||
|
||||
QSharedPointer<ConfigMgr::Settings> ConfigMgr::getSettings(Source p_src) const
|
||||
{
|
||||
|
||||
return ConfigMgr::Settings::fromFile(getConfigFilePath(p_src));
|
||||
}
|
||||
|
||||
@ -433,3 +437,18 @@ QString ConfigMgr::getDocumentOrHomePath()
|
||||
|
||||
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 getApplicationVersion();
|
||||
|
||||
static const QString c_orgName;
|
||||
|
||||
static const QString c_appName;
|
||||
@ -129,6 +131,8 @@ namespace vnotex
|
||||
// Update it if in need.
|
||||
void checkAppConfig();
|
||||
|
||||
static QString getDefaultConfigFilePath();
|
||||
|
||||
QScopedPointer<MainConfig> m_config;;
|
||||
|
||||
// Session config.
|
||||
|
@ -12,6 +12,8 @@ using namespace vnotex;
|
||||
|
||||
const QString SingleInstanceGuard::c_serverName = "vnote";
|
||||
|
||||
const QChar SingleInstanceGuard::c_stringListSeparator = '>';
|
||||
|
||||
SingleInstanceGuard::SingleInstanceGuard()
|
||||
{
|
||||
qInfo() << "guarding is on";
|
||||
@ -54,6 +56,14 @@ void SingleInstanceGuard::requestOpenFiles(const QStringList &p_files)
|
||||
if (p_files.isEmpty()) {
|
||||
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()
|
||||
@ -157,6 +167,7 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
||||
inStream.setDevice(p_socket);
|
||||
inStream.setVersion(QDataStream::Qt_5_12);
|
||||
|
||||
while (p_socket->bytesAvailable() > 0) {
|
||||
if (m_command.m_opCode == OpCode::Null) {
|
||||
// Relies on the fact that QDataStream serializes a quint32 into
|
||||
// sizeof(quint32) bytes.
|
||||
@ -174,7 +185,7 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
||||
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) {
|
||||
case OpCode::Show:
|
||||
@ -182,9 +193,23 @@ void SingleInstanceGuard::receiveCommand(QLocalSocket *p_socket)
|
||||
emit showRequested();
|
||||
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:
|
||||
qWarning() << "unknown op code" << m_command.m_opCode;
|
||||
break;
|
||||
m_command.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
m_command.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,8 @@ namespace vnotex
|
||||
enum OpCode
|
||||
{
|
||||
Null = 0,
|
||||
Show
|
||||
Show,
|
||||
OpenFiles
|
||||
};
|
||||
|
||||
struct Command
|
||||
@ -78,6 +79,8 @@ namespace vnotex
|
||||
Command m_command;
|
||||
|
||||
static const QString c_serverName;
|
||||
|
||||
static const QChar c_stringListSeparator;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
49
src/main.cpp
49
src/main.cpp
@ -21,6 +21,7 @@
|
||||
#include <QWebEngineSettings>
|
||||
#include <core/exception.h>
|
||||
#include <widgets/messageboxhelper.h>
|
||||
#include "commandlineoptions.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -28,6 +29,8 @@ void loadTranslators(QApplication &p_app);
|
||||
|
||||
void initWebEngineSettings();
|
||||
|
||||
void showMessageOnCommandLineIfAvailable(const QString &p_msg);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QTextCodec *codec = QTextCodec::codecForName("UTF8");
|
||||
@ -76,18 +79,44 @@ int main(int argc, char *argv[])
|
||||
|
||||
app.setApplicationName(ConfigMgr::c_appName);
|
||||
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.
|
||||
SingleInstanceGuard guard;
|
||||
bool canRun = guard.tryRun();
|
||||
if (!canRun) {
|
||||
guard.requestOpenFiles(cmdOptions.m_pathsToOpen);
|
||||
guard.requestShow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
app.setApplicationVersion(ConfigMgr::getInst().getConfig().getVersion());
|
||||
ConfigMgr::getInst();
|
||||
} catch (Exception &e) {
|
||||
MessageBoxHelper::notify(MessageBoxHelper::Critical,
|
||||
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.
|
||||
Logger::init(false);
|
||||
Logger::init(cmdOptions.m_verbose);
|
||||
|
||||
qInfo() << QString("%1 (v%2) started at %3 (%4)").arg(ConfigMgr::c_appName,
|
||||
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";
|
||||
}
|
||||
|
||||
// TODO: parse command line options.
|
||||
|
||||
// Should set the correct locale before VNoteX::getInst().
|
||||
loadTranslators(app);
|
||||
|
||||
@ -131,8 +158,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
QObject::connect(&guard, &SingleInstanceGuard::showRequested,
|
||||
&window, &MainWindow::showMainWindow);
|
||||
QObject::connect(&guard, &SingleInstanceGuard::openFilesRequested,
|
||||
&window, &MainWindow::openFiles);
|
||||
|
||||
window.kickOffOnStart();
|
||||
window.kickOffOnStart(cmdOptions.m_pathsToOpen);
|
||||
|
||||
int ret = app.exec();
|
||||
if (ret == RESTART_EXIT_CODE) {
|
||||
@ -208,3 +237,13 @@ void initWebEngineSettings()
|
||||
auto settings = QWebEngineSettings::defaultSettings();
|
||||
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
|
||||
|
||||
SOURCES += \
|
||||
commandlineoptions.cpp \
|
||||
main.cpp
|
||||
|
||||
INCLUDEPATH *= $$PWD
|
||||
@ -137,3 +138,6 @@ unix:!macx {
|
||||
INSTALLS += extraresource
|
||||
message("VNote will be installed in prefix $${PREFIX}")
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
commandlineoptions.h
|
||||
|
@ -70,8 +70,9 @@ MainWindow::~MainWindow()
|
||||
m_viewArea = nullptr;
|
||||
}
|
||||
|
||||
void MainWindow::kickOffOnStart()
|
||||
void MainWindow::kickOffOnStart(const QStringList &p_paths)
|
||||
{
|
||||
QTimer::singleShot(300, [this, p_paths]() {
|
||||
VNoteX::getInst().initLoad();
|
||||
|
||||
emit mainWindowStarted();
|
||||
@ -79,6 +80,16 @@ void MainWindow::kickOffOnStart()
|
||||
emit layoutChanged();
|
||||
|
||||
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()
|
||||
|
@ -33,7 +33,7 @@ namespace vnotex
|
||||
MainWindow(const MainWindow &) = delete;
|
||||
void operator=(const MainWindow &) = delete;
|
||||
|
||||
void kickOffOnStart();
|
||||
void kickOffOnStart(const QStringList &p_paths);
|
||||
|
||||
void resetStateAndGeometry();
|
||||
|
||||
@ -53,6 +53,8 @@ namespace vnotex
|
||||
|
||||
void quitApp();
|
||||
|
||||
void openFiles(const QStringList &p_files);
|
||||
|
||||
signals:
|
||||
void mainWindowStarted();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user