diff --git a/applications/kube/main.cpp b/applications/kube/main.cpp index 336b259e..7f6c57ae 100644 --- a/applications/kube/main.cpp +++ b/applications/kube/main.cpp @@ -1,223 +1,223 @@ /* Copyright (c) 2017 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #ifndef Q_OS_WIN #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "backtrace.h" #include "framework/src/keyring.h" #include "kube_version.h" #include "dbusinterface.h" static int sCounter = 0; void crashHandler(int signal) { //Guard against crashing in here if (sCounter > 1) { std::_Exit(EXIT_FAILURE); } sCounter++; if (signal == SIGABRT) { std::cerr << "SIGABRT received\n"; } else if (signal == SIGSEGV) { std::cerr << "SIGSEV received\n"; } else { std::cerr << "Unexpected signal " << signal << " received\n"; } printStacktrace(); std::fprintf(stdout, "Sleeping for 10s to attach a debugger: gdb attach %i\n", getpid()); std::this_thread::sleep_for(std::chrono::seconds(10)); // std::system("exec gdb -p \"$PPID\" -ex \"thread apply all bt\""); // This only works if we actually have xterm and X11 available // std::system("exec xterm -e gdb -p \"$PPID\""); std::_Exit(EXIT_FAILURE); } void terminateHandler() { // std::exception_ptr exptr = std::current_exception(); // if (exptr != 0) // { // // the only useful feature of std::exception_ptr is that it can be rethrown... // try { // std::rethrow_exception(exptr); // } catch (std::exception &ex) { // std::fprintf(stderr, "Terminated due to exception: %s\n", ex.what()); // } catch (...) { // std::fprintf(stderr, "Terminated due to unknown exception\n"); // } // } else { std::fprintf(stderr, "Terminated due to unknown reason.\n"); // } std::abort(); } QString findFile(const QString file, const QStringList importPathList) { for (const auto &path : importPathList) { const QString f = path + file; if (QFileInfo::exists(f)) { return f; } } return {}; } int main(int argc, char *argv[]) { std::signal(SIGSEGV, crashHandler); std::signal(SIGABRT, crashHandler); std::set_terminate(terminateHandler); //Instead of QtWebEngine::initialize(); QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true); QCoreApplication::setApplicationVersion(QString("%1 Branch: %2 Commit: %3").arg(kube_VERSION_STRING).arg(kube_BRANCH).arg(kube_COMMIT)); QCoreApplication::setOrganizationName("kube"); QCoreApplication::setOrganizationDomain("kube-project.com"); QCoreApplication::setApplicationName("kube"); QApplication app(argc, argv); auto fontSize = app.font().pointSize(); #if defined(Q_OS_UNIX) && (!defined(Q_OS_MAC)) if (qEnvironmentVariableIsEmpty("QT_QPA_PLATFORMTHEME")) { //The hardcoded default in qgenericunixthemes.cpp of 9 is tiny, so we default to something larger. fontSize = 11; } #endif app.setFont(QFont{"Noto Sans", fontSize, QFont::Normal}); //Get info about actually used font const QFontInfo fontInfo{app.font()}; qInfo() << "Font name:" << fontInfo.family(); qInfo() << "Font size:" << fontInfo.pointSize(); qInfo() << "Device pixel ratio:" << app.devicePixelRatio(); QCommandLineParser parser; parser.setApplicationDescription("A communication and collaboration client."); parser.addHelpOption(); parser.addVersionOption(); parser.addOption({{"k", "keyring"}, QCoreApplication::translate("main", "To automatically unlock the keyring pass in a keyring in the form of {\"accountId\": {\"resourceId\": \"secret\", *}}"), "keyring dictionary"} ); parser.addOption({{"l", "lockfile"}, "Use a lockfile to enforce that only a single instance can be started.", ""}); parser.process(app); //Only relevant for flatpak DBusInterface interface; if (parser.isSet("lockfile")) { if (!interface.registerService()) { qInfo() << "Can't start multiple instances of kube in flatpak."; interface.activate(); return -1; } QObject::connect(&interface, &DBusInterface::activated, [&] { qDebug() << "Activated"; for (auto w : QApplication::topLevelWindows()) { //QWindow::alert and QWindow::requestActivate don't work with wayland. But hide and show does. w->setVisible(false); w->setVisible(true); } }); } if (parser.isSet("keyring")) { auto keyringDict = parser.value("keyring"); auto json = QJsonDocument::fromJson(keyringDict.toUtf8()); if (!json.isObject()) { qWarning() << "Not a valid keyring dict " << keyringDict; return -1; } auto object = json.object(); - for (const auto accountId : object.keys()) { + for (const auto &accountId : object.keys()) { auto dict = object.value(accountId).toObject(); - for (const auto resourceId : dict.keys()) { + for (const auto &resourceId : dict.keys()) { Kube::AccountKeyring{accountId.toUtf8()}.addPassword(resourceId.toUtf8(), dict.value(resourceId).toString().toUtf8()); } } } { QQmlContext *rootContext = nullptr; bool upgradeComplete = false; Sink::Store::upgrade().then([&] (Sink::Store::UpgradeResult upgradeExecuted) { upgradeComplete = !upgradeExecuted.upgradeExecuted; if (rootContext) { rootContext->setContextProperty("upgradeComplete", true); } }).exec(); if (!upgradeComplete) { QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("upgradeComplete", false); rootContext = engine.rootContext(); engine.load(QUrl::fromLocalFile(findFile("/org/kube/components/kube/upgrade.qml", engine.importPathList()))); return app.exec(); } } QQmlApplicationEngine engine; //For windows engine.addImportPath(QCoreApplication::applicationDirPath() + QStringLiteral("/../qml")); const auto file = "/org/kube/components/kube/main.qml"; const auto mainFile = findFile(file, engine.importPathList()); if (mainFile.isEmpty()) { qWarning() << "Failed to find " << file; qWarning() << "Searched: " << engine.importPathList(); return -1; } engine.load(QUrl::fromLocalFile(mainFile)); return app.exec(); } diff --git a/framework/src/logmodel.cpp b/framework/src/logmodel.cpp index 2e269e8b..a20e09bc 100644 --- a/framework/src/logmodel.cpp +++ b/framework/src/logmodel.cpp @@ -1,77 +1,77 @@ /* Copyright (c) 2018 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "logmodel.h" #include #include #include LogModel::LogModel(QObject *parent) : QStandardItemModel(parent) { QByteArrayList roles{"type", "subtype", "timestamp", "message", "details", "entities", "resource"}; int role = Qt::UserRole + 1; mRoles.insert("id", role); role++; for (const auto &r : roles) { mRoles.insert(r, role); role++; } QHash roleNames; - for (const auto r : mRoles.keys()) { + for (const auto &r : mRoles.keys()) { roleNames.insert(mRoles[r], r); } setItemRoleNames(roleNames); } LogModel::~LogModel() { } void LogModel::insert(const QVariantMap &message) { if (rowCount() > 0) { auto i = item(0); const auto subtype = i->data(mRoles["subtype"]).toString(); if (!subtype.isEmpty() && (subtype == message.value("subtype").toString())) { //TODO merge message into this entry return; } } auto item = new QStandardItem; auto addProperty = [&] (const QByteArray &key) { item->setData(message.value(key), mRoles[key]); }; item->setData(QDateTime::currentDateTime(), mRoles["timestamp"]); addProperty("type"); addProperty("subtype"); addProperty("message"); addProperty("details"); addProperty("resource"); addProperty("entities"); insertRow(0, item); emit entryAdded(message); }