feather/src/main.cpp

241 lines
7.4 KiB
C++
Raw Normal View History

// SPDX-License-Identifier: BSD-3-Clause
2023-01-02 19:30:11 +00:00
// SPDX-FileCopyrightText: 2020-2023 The Monero Project
#include <QResource>
#include <QApplication>
#include <QtCore>
#include <QtGui>
2022-03-03 22:27:54 +00:00
#include <singleapplication.h>
#include "config-feather.h"
2021-05-18 15:59:18 +00:00
#include "constants.h"
2021-06-28 17:48:23 +00:00
#include "MainWindow.h"
2022-03-04 16:20:17 +00:00
#include "utils/EventFilter.h"
2023-02-11 17:11:21 +00:00
#include "utils/os/Prestium.h"
2021-05-18 15:59:18 +00:00
#include "WindowManager.h"
2023-01-26 12:12:33 +00:00
#include "config.h"
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
#define BOOST_STACKTRACE_LINK
#include <signal.h>
#include <boost/stacktrace.hpp>
#include <fstream>
#endif
#include <QObject>
2020-12-08 16:02:11 +00:00
#if defined(Q_OS_WIN)
#include <windows.h>
2021-06-25 14:14:49 +00:00
#include <vfw.h>
2020-12-08 16:02:11 +00:00
#endif
#if defined(Q_OS_LINUX) && defined(STATIC)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
#endif
2023-01-26 12:12:33 +00:00
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
void signal_handler(int signum) {
::signal(signum, SIG_DFL);
std::stringstream keyStream;
keyStream << boost::stacktrace::stacktrace();
std::cout << keyStream.str();
// Write stack trace to disk
2023-02-11 17:11:21 +00:00
if (config()->get(Config::writeStackTraceToDisk).toBool()) {
QString crashLogPath{Config::defaultConfigDir().path() + "/crash_report.txt"};
std::ofstream out(crashLogPath.toStdString());
out << keyStream.str();
out.close();
}
2023-01-26 12:12:33 +00:00
// Make a last ditch attempt to restart the application
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
::raise(SIGABRT);
}
#endif
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(assets);
2023-01-26 12:12:33 +00:00
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
::signal(SIGSEGV, &signal_handler);
::signal(SIGABRT, &signal_handler);
#endif
2022-02-23 16:04:23 +00:00
#if defined(HAS_TOR_BIN)
Q_INIT_RESOURCE(assets_tor);
#endif
2020-12-08 16:02:11 +00:00
#ifdef _WIN32
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}
#endif
2023-01-22 22:19:23 +00:00
// #TODO: Fix Windows dark mode handling Qt 6.5 beta1
// darkmode=2 (default) causes some text to become unreadable
#if defined(Q_OS_WIN)
qputenv("QT_QPA_PLATFORM", "windows:darkmode=1");
#endif
QStringList argv_;
for(int i = 0; i != argc; i++){
argv_ << QString::fromStdString(argv[i]);
}
QCommandLineParser parser;
parser.setApplicationDescription("feather");
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption useLocalTorOption(QStringList() << "use-local-tor", "Use system wide installed Tor instead of the bundled.");
parser.addOption(useLocalTorOption);
QCommandLineOption quietModeOption(QStringList() << "quiet", "Limit console output");
parser.addOption(quietModeOption);
QCommandLineOption stagenetOption(QStringList() << "stagenet", "Stagenet is for development purposes only.");
parser.addOption(stagenetOption);
QCommandLineOption testnetOption(QStringList() << "testnet", "Testnet is for development purposes only.");
parser.addOption(testnetOption);
2021-05-18 15:59:18 +00:00
bool parsed = parser.parse(argv_);
if (!parsed) {
qCritical() << parser.errorText();
exit(1);
}
bool stagenet = parser.isSet(stagenetOption);
bool testnet = parser.isSet(testnetOption);
bool quiet = parser.isSet(quietModeOption);
2021-05-18 15:59:18 +00:00
// Setup networkType
if (stagenet)
constants::networkType = NetworkType::STAGENET;
else if (testnet)
constants::networkType = NetworkType::TESTNET;
else
constants::networkType = NetworkType::MAINNET;
2021-05-18 15:59:18 +00:00
// Setup QApplication
2022-05-24 15:34:52 +00:00
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
2020-10-11 18:02:23 +00:00
QApplication::setAttribute(Qt::AA_DisableWindowContextHelpButton);
2022-05-24 15:34:52 +00:00
#endif
QApplication::setDesktopSettingsAware(true); // use system font
QApplication::setApplicationVersion(FEATHER_VERSION);
2023-01-12 22:40:12 +00:00
#if defined(Q_OS_LINUX)
// PassThrough results in muddy text
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::Round);
#endif
2022-03-03 22:27:54 +00:00
SingleApplication app(argc, argv);
2021-05-18 15:59:18 +00:00
QApplication::setQuitOnLastWindowClosed(false);
2021-03-24 01:37:54 +00:00
QApplication::setApplicationName("FeatherWallet");
2023-01-12 22:40:12 +00:00
2021-05-18 15:59:18 +00:00
// Setup config directories
QString configDir = Config::defaultConfigDir().path();
2022-02-11 11:50:09 +00:00
QString config_dir_tor = QString("%1/%2").arg(configDir, "tor");
QString config_dir_tordata = QString("%1/%2").arg(configDir, "tor/data");
2021-05-18 15:59:18 +00:00
QStringList createDirs({configDir, config_dir_tor, config_dir_tordata});
for (const auto &d: createDirs) {
if (!Utils::dirExists(d)) {
qDebug() << QString("Creating directory: %1").arg(d);
if (!QDir().mkpath(d)) {
qCritical() << "Could not create directory " << d;
}
}
}
// Setup logging
2021-08-14 14:22:21 +00:00
QString logPath = QString("%1/libwallet.log").arg(configDir);
2021-05-18 15:59:18 +00:00
Monero::Utils::onStartup();
Monero::Wallet::init("", "feather", logPath.toStdString(), true);
bool logLevelFromEnv;
int logLevel = qEnvironmentVariableIntValue("MONERO_LOG_LEVEL", &logLevelFromEnv);
2023-02-11 17:11:21 +00:00
if (logLevelFromEnv) {
config()->set(Config::logLevel, logLevel);
} else {
logLevel = config()->get(Config::logLevel).toInt();
}
2021-05-18 15:59:18 +00:00
if (parser.isSet("quiet") || config()->get(Config::disableLogging).toBool()) {
qWarning() << "Logging is disabled";
2021-05-18 15:59:18 +00:00
WalletManager::instance()->setLogLevel(-1);
}
2023-02-11 17:11:21 +00:00
else if (logLevel >= 0 && logLevel <= Monero::WalletManagerFactory::LogLevel_Max) {
2021-05-18 15:59:18 +00:00
Monero::WalletManagerFactory::setLogLevel(logLevel);
}
2021-05-18 15:59:18 +00:00
// Setup wallet directory
QString walletDir = config()->get(Config::walletDirectory).toString();
if (walletDir.isEmpty() || Utils::isPortableMode()) {
2021-05-18 15:59:18 +00:00
walletDir = Utils::defaultWalletDir();
config()->set(Config::walletDirectory, walletDir);
}
if (!QDir().mkpath(walletDir))
qCritical() << "Unable to create dir: " << walletDir;
2023-02-11 17:11:21 +00:00
// Prestium initial config
if (config()->get(Config::firstRun).toBool() && Prestium::detect()) {
config()->set(Config::proxy, Config::Proxy::i2p);
config()->set(Config::socks5Port, 4448);
}
2021-05-18 15:59:18 +00:00
if (parser.isSet("use-local-tor"))
config()->set(Config::useLocalTor, true);
parser.process(app); // Parse again for --help and --version
2021-05-18 15:59:18 +00:00
if (!quiet) {
QMap<QString, QString> info;
info["Qt"] = QT_VERSION_STR;
info["Feather"] = FEATHER_VERSION;
if (stagenet) info["Mode"] = "Stagenet";
else if (testnet) info["Mode"] = "Testnet";
else info["Mode"] = "Mainnet";
info["SSL"] = QSslSocket::sslLibraryVersionString();
info["SSL build"] = QSslSocket::sslLibraryBuildVersionString();
2022-02-23 16:04:23 +00:00
#if defined(TOR_VERSION)
info["Tor version"] = TOR_VERSION;
#else
info["Tor version"] = "Not bundled";
#endif
2022-02-11 11:50:09 +00:00
for (const QString &k: info.keys()) {
qWarning().nospace().noquote() << QString("%1: %2").arg(k, info[k]);
}
}
#if defined(Q_OS_MAC)
// For some odd reason, if we don't do this, QPushButton's
// need to be clicked *twice* in order to fire ?!
QFont fontDef = QApplication::font();
fontDef.setPointSize(fontDef.pointSize() + 1);
QApplication::setFont(fontDef);
#endif
qInstallMessageHandler(Utils::applicationLogHandler);
2021-01-26 23:55:27 +00:00
qRegisterMetaType<QVector<QString>>();
qRegisterMetaType<TxProofResult>("TxProofResult");
qRegisterMetaType<QPair<bool, bool>>();
2022-03-04 16:20:17 +00:00
EventFilter filter;
app.installEventFilter(&filter);
WindowManager windowManager(&filter);
2021-05-18 15:59:18 +00:00
2022-03-03 22:27:54 +00:00
QObject::connect(&app, &SingleApplication::instanceStarted, [&windowManager]() {
windowManager.raise();
});
return QApplication::exec();
}