diff --git a/src/blackgui/qss/swiftcorectrl.qss b/src/blackgui/qss/swiftcorectrl.qss new file mode 100644 index 000000000..81e3eb2aa --- /dev/null +++ b/src/blackgui/qss/swiftcorectrl.qss @@ -0,0 +1,153 @@ +/** Main window **/ +QWidget { + background-image: url(:/textures/icons/textures/texture-outer.jpg); + background-color: darkslategray; +} + +/** Main window **/ +QMainWindow { + background-image: url(:/textures/icons/textures/texture-outer.jpg); + background-color: darkslategray; +} + +/** separator between info areas and rest **/ +/** this hides them **/ +QMainWindow::separator { + background: transparent; + width: 0px; /* when vertical */ + height: 0px; /* when horizontal */ +} + +QMainWindow::separator:hover { + background: transparent; +} + +QPushButton { + /** background-image: url(:/textures/icons/textures/texture-inner.jpg); **/ + /** need to fix pressed button first **/ + background: black; + border-style: solid; + border-width: 1px; + border-radius:6px; + border-color: green; + max-height:20px; + min-width:60px; + min-height:20px; +} + +QPushButton::disabled { + background-color: grey; + border-style: solid; + border-width: 1px; + border-radius:6px; + border-color: green; + max-height:20px; + min-width:60px; + min-height:20px; +} + +QTextEdit { + background: black; /** background is background color here **/ + background-image: url(:/textures/icons/textures/texture-inner.jpg); + color: grey; +} + +QRadioButton { + background: transparent; +} + +QGroupBox { + border: 1px solid green; + margin-top: 2.5ex; /* leave space at the top for the title */ + border-radius: 5px; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: middle center; /* position at the top center */ + padding: 0 5px; + background: transparent; +} + +QComboBox { + background-color: black; + border: 1px solid yellow; +} + +QTabWidget::pane { /* The tab widget frame */ + border: none; +} + +QTabWidget::tab-bar { + left: 5px; /* move to the right by 5px */ +} + +QTabBar::tab { + border: 1px solid green; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + min-width: 30px; + padding: 2px; + padding-left: 4px; + padding-right: 4px; + margin-right: 3px; +} + +QTabBar::tab::selected { + background-color: grey; +} + +QTabBar::tear { + image: url(:/own/icons/own/transparent1px.png); + max-width: 1px; +} + +QTabBar QToolButton { /* the scroll buttons are tool buttons */ + background-color: rgba(0, 0, 255, 200); + border: 1px solid green; +} + +QHeaderView::section { + border: 1px solid black; + background: transparent; + color: white; /** font **/ + padding: 1px; + margin: 0px; +} + +QTableView, QTreeView { + border: 1px solid green; + border-radius: 5px; + alternate-background-color: darkslategray; + selection-background-color: blue; + margin-left: 2px; + margin-right: 2px; + margin-top: 2px; + margin-bottom: 2px; + padding:0px; + background-image: url(:/textures/icons/textures/texture-inner.jpg); +} + +QSizeGrip { +} + +#le_CommandLineInput { + background-image: url(:/textures/icons/textures/texture-inner.jpg); + margin-bottom: 5px; + padding: 3px; + border-radius: 5px; +} + +#comp_log { + background: transparent; /** background is background color here **/ +} + +#gb_dbusMode { + background: transparent; /** background is background color here **/ + background-image: url(:/textures/icons/textures/texture-inner.jpg); +} + +#gb_Controls { + background: transparent; /** background is background color here **/ + background-image: url(:/textures/icons/textures/texture-inner.jpg); +} \ No newline at end of file diff --git a/src/blackgui/stylesheetutility.cpp b/src/blackgui/stylesheetutility.cpp index a3c1d91e1..19d32eb9b 100644 --- a/src/blackgui/stylesheetutility.cpp +++ b/src/blackgui/stylesheetutility.cpp @@ -274,6 +274,12 @@ namespace BlackGui return f; } + const QString &CStyleSheetUtility::fileNameSwiftCoreCtrl() + { + static const QString f("swiftcorectrl.qss"); + return f; + } + const QString &CStyleSheetUtility::fileNameIniFile() { static const QString f("gui.ini"); diff --git a/src/blackgui/stylesheetutility.h b/src/blackgui/stylesheetutility.h index 28b7bf7c1..e28170752 100644 --- a/src/blackgui/stylesheetutility.h +++ b/src/blackgui/stylesheetutility.h @@ -87,6 +87,9 @@ namespace BlackGui //! File name maininfoarea.qss static const QString &fileNameFilterDialog(); + //! File name swiftcorectrl.qss + static const QString &fileNameSwiftCoreCtrl(); + //! File name ini file static const QString &fileNameIniFile(); diff --git a/src/swiftcorectrl/main.cpp b/src/swiftcorectrl/main.cpp new file mode 100644 index 000000000..6904fcfee --- /dev/null +++ b/src/swiftcorectrl/main.cpp @@ -0,0 +1,167 @@ +#include "swiftcorectrl.h" + +#include "blackcore/context_runtime.h" +#include "blackcore/context_settings.h" +#include "blackcore/context_application.h" +#include "blackcore/context_application_impl.h" +#include "blackcore/dbus_server.h" +#include "blackmisc/icons.h" +#include "blackmisc/worker.h" +#include "blackmisc/networkutils.h" +#include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/project.h" +#include "blackmisc/loghandler.h" +#include "blackgui/stylesheetutility.h" + +#include +#include + +using namespace BlackMisc; +using namespace BlackCore; +using namespace BlackGui; + +enum CommandLineParseResult +{ + CommandLineOk, + CommandLineError, + CommandLineVersionRequested, + CommandLineHelpRequested +}; + +CommandLineParseResult parseCommandLine(QCommandLineParser &parser, CSwiftCoreCtrl::SetupInfo *setup, QString *errorMessage) +{ + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.addOption({{"s", "session"}, QCoreApplication::translate("main", "Use session bus.")}); + parser.addOption({{"y", "system"}, QCoreApplication::translate("main", "Use system bus.")}); + parser.addOption({{"p", "p2p"}, QCoreApplication::translate("main", "Use P2P bus with
."), + QCoreApplication::translate("main", "address") + }); + parser.addOption({{"m", "minimized"}, QCoreApplication::translate("main", "Start minimized in system tray.")}); + + if (!parser.parse(QCoreApplication::arguments())) + { + *errorMessage = parser.errorText(); + return CommandLineError; + } + + if (parser.isSet("session")) + { + if (parser.isSet("system") || parser.isSet("p2p")) + { + *errorMessage = "Multiple DBus types set at the same time."; + return CommandLineError; + } + setup->m_dbusAddress = CDBusServer::sessionDBusServer(); + } + + if (parser.isSet("system")) + { + if (parser.isSet("session") || parser.isSet("p2p")) + { + *errorMessage = "Multiple DBus types set at the same time."; + return CommandLineError; + } + setup->m_dbusAddress = CDBusServer::systemDBusServer(); + } + + if (parser.isSet("p2p")) + { + const QString address = CDBusServer::fixAddressToDBusAddress(parser.value("p2p")); + + if (parser.isSet("session") || parser.isSet("system")) + { + *errorMessage = "Multiple DBus types set at the same time."; + return CommandLineError; + } + } + + if (parser.isSet("minimized")) + { + setup->m_minimzed = true; + } + + return CommandLineOk; +} + +int main(int argc, char *argv[]) +{ + CRuntime::registerMetadata(); // register metadata + QApplication a(argc, argv); + QApplication::setApplicationName("swiftcorectrl"); + QApplication::setApplicationVersion(CProject::version()); + + QCommandLineParser parser; + parser.setApplicationDescription("swiftcore control"); + parser.addHelpOption(); + parser.addVersionOption(); + + CSwiftCoreCtrl::SetupInfo setup; + QString errorMessage; + switch (parseCommandLine(parser, &setup, &errorMessage)) + { + case CommandLineOk: + break; + case CommandLineError: +#ifdef Q_OS_WIN + QMessageBox::warning(0, QGuiApplication::applicationDisplayName(), + "

" + errorMessage + "

"
+                             + parser.helpText() + "
"); +#else + fputs(qPrintable(errorMessage), stderr); + fputs("\n\n", stderr); + fputs(qPrintable(parser.helpText()), stderr); +#endif + return 1; + case CommandLineVersionRequested: +#ifdef Q_OS_WIN + QMessageBox::information(0, QGuiApplication::applicationDisplayName(), + QGuiApplication::applicationDisplayName() + ' '+ QCoreApplication::applicationVersion()); +#else + printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), + qPrintable(QCoreApplication::applicationVersion())); +#endif + return 0; + case CommandLineHelpRequested: +#ifdef Q_OS_WIN + QMessageBox::warning(0, QGuiApplication::applicationDisplayName(), + "
"
+                             + parser.helpText() + "
"); + return 0; +#else + parser.showHelp(); + Q_UNREACHABLE(); +#endif + } + + if (!QSystemTrayIcon::isSystemTrayAvailable()) + { + QMessageBox::critical(0, QObject::tr("Systray"), + QObject::tr("I couldn't detect any system tray on this system.")); + return 1; + } + + // Translations + QFile file(":blackmisc/translations/blackmisc_i18n_de.qm"); + CLogMessage("swift.standardgui.main").debug() << (file.exists() ? "Found translations in resources" : "No translations in resources"); + QTranslator translator; + if (translator.load("blackmisc_i18n_de", ":blackmisc/translations/")) + { + CLogMessage("swift.standardgui.main").debug() << "Translator loaded"; + } + + QIcon icon(BlackMisc::CIcons::swift24()); + QApplication::setWindowIcon(icon); + const QString s = CStyleSheetUtility::instance().styles( + { + CStyleSheetUtility::fileNameFonts(), + CStyleSheetUtility::fileNameSwiftCoreCtrl() + } + ); + a.installTranslator(&translator); + a.setStyleSheet(s); + + CSwiftCoreCtrl w(setup); + if (!setup.m_minimzed) w.show(); + + return a.exec(); +} diff --git a/src/swiftcorectrl/swiftcorectrl.cpp b/src/swiftcorectrl/swiftcorectrl.cpp new file mode 100644 index 000000000..1145d90b4 --- /dev/null +++ b/src/swiftcorectrl/swiftcorectrl.cpp @@ -0,0 +1,142 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#include "swiftcorectrl.h" +#include "ui_swiftcorectrl.h" +#include "blackmisc/icon.h" +#include "blackmisc/loghandler.h" +#include "blackcore/dbus_server.h" +#include "blackgui/stylesheetutility.h" +#include "blackgui/components/enableforruntime.h" +#include +#include +#include + +using namespace BlackMisc; +using namespace BlackCore; +using namespace BlackGui; +using namespace BlackGui::Components; + +CSwiftCoreCtrl::CSwiftCoreCtrl(const SetupInfo &info, QWidget *parent) : + CSystemTrayWindow(BlackMisc::CIcons::swiftNova24(), parent), + ui(new Ui::CSwiftCoreCtrl) +{ + ui->setupUi(this); + + SystemTrayMode mode = MinimizeToTray | QuitOnClose; + setSystemTrayMode(mode); + setToolTip(QStringLiteral("swiftcore")); + + setupLogDisplay(); + + connectSlots(); + ps_onStyleSheetsChanged(); + startCore(info); +} + +CSwiftCoreCtrl::~CSwiftCoreCtrl() +{ +} + +void CSwiftCoreCtrl::ps_startCorePressed() +{ + SetupInfo setup; + setup.m_dbusAddress = getDBusAddress(); + startCore(setup); +} + +void CSwiftCoreCtrl::ps_stopCorePressed() +{ + stopCore(); +} + +void CSwiftCoreCtrl::ps_appendLogMessage(const CStatusMessage &message) +{ + ui->comp_log->appendStatusMessageToList(message); +} + +void CSwiftCoreCtrl::ps_p2pModeToggled(bool checked) +{ + if (checked) + { + ui->le_p2pAddress->setEnabled(true); + } + else + { + ui->le_p2pAddress->setText(QStringLiteral("")); + ui->le_p2pAddress->setEnabled(false); + } +} + +void CSwiftCoreCtrl::ps_onStyleSheetsChanged() +{ + const QString s = CStyleSheetUtility::instance().styles( + { + CStyleSheetUtility::fileNameFonts(), + CStyleSheetUtility::fileNameSwiftCoreCtrl() + } + ); + setStyleSheet(s); +} + +void CSwiftCoreCtrl::connectSlots() +{ + connect(ui->pb_startCore, &QPushButton::clicked, this, &CSwiftCoreCtrl::ps_startCorePressed); + connect(ui->pb_stopCore, &QPushButton::clicked, this, &CSwiftCoreCtrl::ps_stopCorePressed); + connect(ui->rb_p2pBus, &QRadioButton::toggled, this, &CSwiftCoreCtrl::ps_p2pModeToggled); + connect(&CStyleSheetUtility::instance(), &CStyleSheetUtility::styleSheetsChanged, this, &CSwiftCoreCtrl::ps_onStyleSheetsChanged); +} + +void CSwiftCoreCtrl::setupLogDisplay() +{ + CLogHandler::instance()->install(); + CLogHandler::instance()->enableConsoleOutput(false); // default disable + auto logHandler = CLogHandler::instance()->handlerForPattern( + CLogPattern().withSeverityAtOrAbove(CStatusMessage::SeverityInfo) + ); + + logHandler->subscribe(this, &CSwiftCoreCtrl::ps_appendLogMessage); +} + +void CSwiftCoreCtrl::startCore(const SetupInfo &setup) +{ + if (getRuntime()) { return; } + if (setup.m_dbusAddress.isEmpty()) { return; } + + ui->pb_startCore->setEnabled(false); + ui->pb_stopCore->setEnabled(true); + ui->gb_dbusMode->setDisabled(true); + + // context + createRuntime(CRuntimeConfig::forCoreAllLocalInDBus(setup.m_dbusAddress), this); + CEnableForRuntime::setRuntimeForComponents(this->getRuntime(), this); + connect(ui->le_CommandLineInput, &CCommandInput::commandEntered, getRuntime(), &CRuntime::parseCommandLine); +} + +void CSwiftCoreCtrl::stopCore() +{ + if (!getRuntime()) { return; } + + ui->pb_startCore->setEnabled(true); + ui->pb_stopCore->setEnabled(false); + ui->gb_dbusMode->setDisabled(false); + + // Force quit, since we cannot close the runtime + qApp->quit(); +} + +QString CSwiftCoreCtrl::getDBusAddress() const +{ + if (ui->rb_sessionBus->isChecked()) { return CDBusServer::sessionDBusServer(); } + if (ui->rb_systemBus->isChecked()) { return CDBusServer::systemDBusServer(); } + if (ui->rb_p2pBus->isChecked()) { return CDBusServer::fixAddressToDBusAddress(ui->le_p2pAddress->text()); } + + Q_ASSERT_X(false, "CSwiftCoreCtrl::getDBusAddress()", "The impossible happended!"); + return ""; +} diff --git a/src/swiftcorectrl/swiftcorectrl.h b/src/swiftcorectrl/swiftcorectrl.h new file mode 100644 index 000000000..29665d3b5 --- /dev/null +++ b/src/swiftcorectrl/swiftcorectrl.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2015 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef SWIFTCORECTRL_H +#define SWIFTCORECTRL_H + +#include "blackmisc/statusmessage.h" +#include "blackcore/context_runtime.h" +#include "blackgui/systemtraywindow.h" +#include "blackgui/components/enableforruntime.h" +#include + +namespace Ui +{ + class CSwiftCoreCtrl; +} + +//! swift core control +class CSwiftCoreCtrl : + public BlackGui::CSystemTrayWindow, + public BlackGui::Components::CEnableForRuntime +{ + Q_OBJECT + +public: + + //! SwiftCoreCtrl setup information + struct SetupInfo + { + SetupInfo() {} + + bool m_minimzed = false; //!< Start minimized to tray + QString m_dbusAddress; //!< DBus address (session, system, p2p) + }; + + //! Constructor + CSwiftCoreCtrl(const SetupInfo &info, QWidget *parent = nullptr); + + //! Destructor + ~CSwiftCoreCtrl(); + +private slots: + + // PushButton slots + void ps_startCorePressed(); + void ps_stopCorePressed(); + void ps_appendLogMessage(const BlackMisc::CStatusMessage &message); + void ps_p2pModeToggled(bool checked); + + //! Style sheet has changed + virtual void ps_onStyleSheetsChanged(); + +private: + + void connectSlots(); + void setupLogDisplay(); + void startCore(const SetupInfo &setup); + void stopCore(); + + QString getDBusAddress() const; + + QScopedPointer ui; +}; + +#endif // SWIFTCORECTRL_H diff --git a/src/swiftcorectrl/swiftcorectrl.pro b/src/swiftcorectrl/swiftcorectrl.pro new file mode 100644 index 000000000..f78487df1 --- /dev/null +++ b/src/swiftcorectrl/swiftcorectrl.pro @@ -0,0 +1,25 @@ +include (../../config.pri) +include (../../build.pri) + +QT += core dbus network xml multimedia gui svg + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = swiftcorectrl +TEMPLATE = app + +SOURCES += *.cpp +HEADERS += *.h +FORMS += *.ui +CONFIG += blackmisc blacksound blackinput blackcore blackgui + +DEPENDPATH += . $$SourceRoot/src/blackmisc \ + $$SourceRoot/src/blacksound \ + $$SourceRoot/src/blackcore \ + $$SourceRoot/src/blackinput + +INCLUDEPATH += . $$SourceRoot/src +DESTDIR = $$BuildRoot/bin +OTHER_FILES += *.qss + +include (../../libraries.pri) diff --git a/src/swiftcorectrl/swiftcorectrl.ui b/src/swiftcorectrl/swiftcorectrl.ui new file mode 100644 index 000000000..afc97a634 --- /dev/null +++ b/src/swiftcorectrl/swiftcorectrl.ui @@ -0,0 +1,167 @@ + + + CSwiftCoreCtrl + + + + 0 + 0 + 448 + 382 + + + + swiftcorectrl + + + + + + + + + + Controls + + + + + + /** Main window **/ +QTextEdit { + background-color: DimGray; +} + + + Start + + + + + + + false + + + /** Main window **/ +QTextEdit { + background-color: DimGray; +} + + + Stop + + + false + + + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + + + + + + + + DBus Mode + + + + + + Session + + + true + + + + + + + P2P + + + + + + + System + + + + + + + false + + + P2P address + + + + + + + + + + + + + + + 0 + 0 + 448 + 20 + + + + + + + + + BlackGui::CSystemTrayWindow + QMainWindow +
blackgui/systemtraywindow.h
+ 1 +
+ + BlackGui::Components::CInfoBarStatusComponent + QWidget +
blackgui/components/infobarstatuscomponent.h
+ 1 +
+ + BlackGui::Components::CLogComponent + QWidget +
blackgui/components/logcomponent.h
+ 1 +
+ + BlackGui::CCommandInput + QLineEdit +
blackgui/commandinput.h
+ 1 +
+
+ + +
diff --git a/swift.pro b/swift.pro index 6694be942..2a1c532f5 100644 --- a/swift.pro +++ b/swift.pro @@ -22,6 +22,10 @@ contains(BLACK_CONFIG, BlackCore) { contains(BLACK_CONFIG, BlackGui) { SUBDIRS += src/blackgui SUBDIRS += src/swiftgui_standard/swiftgui_standard.pro + + contains(BLACK_CONFIG, BlackCore) { + SUBDIRS += src/swiftcorectrl/swiftcorectrl.pro + } } win32 {