/** * @RDE_HEADER@ * $Id$ * $HeadURL$ * $Author$ * * Created by Mike Wille, SLSE, 2017-11-15 */ #include "dev_gui_plugin.h" #include "dev_dialog.h" #include "dev_permissions_dialog.h" #include "dev_debug_flags_dialog.h" #include "dev_ftcmock.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DeveloperTools { std::shared_ptr GuiPlugin::createGuiInterface(LtsSession::LtsSession *session) { return std::make_shared(session); } bool InterfaceImpl::s_devDialogVisible = false; InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session) : GuiPluginBase::Interface(session, NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("Plugins.Gui.Dev")) { #ifdef LTS_DEBUG if (QGuiApplication::queryKeyboardModifiers() == Qt::ControlModifier) showDevTools(); #endif auto *t1 = new QTimer(this); t1->setInterval(1000); connect(t1, &QTimer::timeout, this, &InterfaceImpl::slotCheckFlags); t1->start(); connect(LtsAppManager::LtsAppManager::getInstance(), &LtsAppManager::LtsAppManager::signalCommand, this, &InterfaceImpl::slotCommand, Qt::UniqueConnection); } InterfaceImpl::~InterfaceImpl() { delete m_noti; if (m_ftcMock != nullptr) { m_ftcMock->deleteLater(); m_ftcMock = nullptr; } } void InterfaceImpl::slotCommand(QTcpSocket *client, const QStringList &argList) { if (argList.at(0) != QStringLiteral("ftcmock")) { return; } bool k = false; const int sessionId = argList.at(2).toInt(&k); if (!k || sessionId != m_session->id()) { return; } switch (QStringList({QStringLiteral("start"), QStringLiteral("stop")}).indexOf(argList.at(1))) { case 0: // start { if (m_ftcMock != nullptr) { client->write("ftcmock already running for this session"); return; } const int min = argList.at(3).toInt(&k); if (!k || min < 0) { return; } const int max = argList.at(4).toInt(&k); if (!k || max < 0) { return; } const int timers = argList.at(5).toInt(&k); if (!k || timers < 1) { return; } m_ftcMock = new FtcMock(m_session, min, max, timers); client->write("ftcmock now running"); return; } case 1: // stop { if (m_ftcMock == nullptr) { client->write("ftcmock not running for this session"); return; } m_ftcMock->deleteLater(); m_ftcMock = nullptr; return; } } client->write("Usage: ftcmock "); } void InterfaceImpl::slotCheckFlags() { LtsSessionData::LtsSessionData *sessionData = LtsSessionData::LtsSessionData::getInstance(); if (sessionData->debugFlagValue(QStringLiteral("DeveloperTools.ShowSessionsOnce")) == QVariant(true)) // first DevGuiPlugin wins! { if (!m_processedFlags.contains(QStringLiteral("DeveloperTools.ShowSessionsOnce"))) { m_processedFlags.append(QStringLiteral("DeveloperTools.ShowSessionsOnce")); showDevTools(); } } if (sessionData->debugFlagValue(QStringLiteral("LanguageChangeViaKey")) == QVariant(true)) // first DevGuiPlugin wins! { if (!m_processedFlags.contains(QStringLiteral("LanguageChangeViaKey"))) { if (m_session->baseLayout() != nullptr) { m_processedFlags.append(QStringLiteral("LanguageChangeViaKey")); QShortcut *shortcutGer = new QShortcut(QKeySequence(QStringLiteral("F1"), QKeySequence::SequenceFormat::NativeText), m_session->baseLayout(), nullptr, nullptr, Qt::ShortcutContext::WindowShortcut); connect(shortcutGer, &QShortcut::activated, this, []() { #ifdef AFTER_FAT LtsTranslator::LtsTranslator::getInstance()->setLocale(QLocale::German, QLocale::Germany); #else NGL::setTranslationLocale(QByteArray("de_DE")); #endif }); QShortcut *shortcutEng = new QShortcut(QKeySequence(QStringLiteral("F3"), QKeySequence::SequenceFormat::NativeText), m_session->baseLayout(), nullptr, nullptr, Qt::ShortcutContext::WindowShortcut); connect(shortcutEng, &QShortcut::activated, this, []() { #ifdef AFTER_FAT LtsTranslator::LtsTranslator::getInstance()->setLocale(QLocale::English, QLocale::UnitedKingdom); #else NGL::setTranslationLocale(QByteArray("en_GB")); #endif }); } } } #ifndef LTS_DEBUG if (!LtsSessionData::LtsSessionData::getInstance()->hasDebugFlag(QStringLiteral("DeveloperTools.Active"))) { return; } else { if (m_noti != nullptr) { delete m_noti; m_noti = nullptr; } } #endif int count = m_session->missingRightActions().count(); if (count > 0) { if (m_noti == nullptr) { m_noti = m_session->createNotification(QStringLiteral("DevPermissions")); m_noti->setIcon(QIcon(QStringLiteral("icon:lock.svg"))); m_noti->setAction([this]() { m_session->addWidget(LtsWidgets::initDialog(new PermissionsDialog(), m_session), menuGroup(), QStringLiteral("devPermissions")); }); } m_noti->setCount(count); } else { delete m_noti; m_noti = nullptr; } } void InterfaceImpl::showAutoRestart() { QMessageBox::warning(nullptr, QStringLiteral("DEV"), QStringLiteral("Warning: Auto restart can not be stopped (not yet implemented), hard kill required!")); const LtsAppDescriptor::AppDescriptionVector apps = LtsAppManager::LtsAppManager::getInstance()->getAvailableApps(); QStringList listApps; listApps.reserve(apps.count()); QMap mapApp2Id; for (const LtsAppDescriptor::AppDescription &app : apps) { listApps.append(app.appName); mapApp2Id[app.appName] = app.id; } QInputDialog dialog; dialog.setComboBoxItems(listApps); dialog.setLabelText(QStringLiteral("Select app to debug: ")); dialog.setWindowTitle(QStringLiteral("Select app to debug: ")); if (!dialog.exec()) return; QString strApp = dialog.textValue(); QInputDialog dialogInt; dialogInt.setLabelText(QStringLiteral("Select restart timeout value: ")); dialogInt.setInputMode(QInputDialog::InputMode::IntInput); dialogInt.setIntMinimum(1000); dialogInt.setIntMaximum(600000); dialogInt.setIntStep(1000); dialogInt.setIntValue(4000); if (!dialogInt.exec()) return; int timeoutValue = dialogInt.intValue(); LtsSession::DdsConnectionParams hackParams(m_session->connParams()); QTimer *t = new QTimer(this); connect(t, &QTimer::timeout, this, [=] { LtsPluginManager::LtsPluginManager *pApp = LtsAppManager::LtsAppManager::getInstance()->createApp(mapApp2Id.value(strApp), hackParams); if (pApp == nullptr) { LtsWidgets::LtsMessageDialog::showMessage(m_session->baseLayoutWidget(), tr("App not could not be started")); return; } connect(pApp, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this, [this, pApp, timeoutValue]() { QTimer *k = new QTimer(this); connect(pApp, &LtsPluginManager::LtsPluginManager::destroyed, k, &QTimer::deleteLater); connect(k, &QTimer::timeout, pApp, &LtsPluginManager::LtsPluginManager::deleteLater); k->setSingleShot(true); k->setInterval(timeoutValue); k->start(); }); }); t->setInterval(timeoutValue); t->start(); } void InterfaceImpl::showDevTools() { if (!s_devDialogVisible) { QDialog *d = new DevDialog(); connect(d, &QDialog::destroyed, this, []() { qWarning() << "Developer Tools destroyed"; s_devDialogVisible = false; }); d->setWindowFlags(Qt::Dialog | /*Qt::X11BypassWindowManagerHint |*/ Qt::WindowStaysOnTopHint); d->show(); qWarning() << "Developer Tools started"; s_devDialogVisible = true; } } QVector InterfaceImpl::getActions() { #ifdef LTS_DEBUG bool actions = true; #else bool actions = false; #endif if (LtsSessionData::LtsSessionData::getInstance()->hasDebugFlag(QStringLiteral("DeveloperTools.Actions"))) actions = true; QVector ret; if (!actions) return ret; { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("Show Debug Dialog"); plData.identifier = QStringLiteral("devTools"); plData.directFunc = [this](const LtsWidgets::PluginData &) { showDevTools(); }; ret.append(plData); } { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("Show Debug Flags"); plData.identifier = QStringLiteral("devFlags"); plData.createWidgetFunc = [this](QWidget *) { return LtsWidgets::initDialog(new DebugFlagsDialog(menuGroup())); }; ret.append(plData); } { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("App Auto Restart"); plData.identifier = QStringLiteral("devAutoRestart"); plData.directFunc = [this](const LtsWidgets::PluginData &) { showAutoRestart(); }; ret.append(plData); } { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("Start App ..."); plData.identifier = QStringLiteral("devStartAppByAppId"); plData.directFunc = [this](const LtsWidgets::PluginData &) { bool k = false; int appId = QInputDialog::getInt(m_session->baseLayout(), QStringLiteral("Start App - AppId"), QStringLiteral("AppId"), (int)m_session->app(), 0, 999, 1, &k); if (!k) return; int dId = QInputDialog::getInt(m_session->baseLayout(), QStringLiteral("Start App - Domain Id"), QStringLiteral("Domain Id"), m_session->domainId(), 0, 999, 1, &k); if (!k) return; int exId = QInputDialog::getInt(m_session->baseLayout(), QStringLiteral("Start App - Exercise Id"), QStringLiteral("Exercise Id"), m_session->exerciseId(), 0, 999, 1, &k); if (!k) return; int pId = QInputDialog::getInt(m_session->baseLayout(), QStringLiteral("Start App - Partition Id"), QStringLiteral("Partition Id"), m_session->exerciseId(), 0, 999, 1, &k); if (!k) return; LtsSession::DdsConnectionParams params(m_session->connParams()); params.domainId = dId; params.exerciseId = exId; params.partitionId = pId; if (pId != exId) params.partitionType = IDL::PartitionType::Replay; else if (pId == exId && exId != 0) params.partitionType = IDL::PartitionType::Exercise; else params.partitionType = IDL::PartitionType::Global; LtsAppManager::LtsAppManager::getInstance()->createApp(LtsAppDescriptor::LtsAppDescriptor::appFromInteger(appId), params); }; ret.append(plData); } { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("Show Notification Box"); plData.identifier = QStringLiteral("devShowNotiBox"); plData.directFunc = [this](const LtsWidgets::PluginData &) { m_session->baseLayout()->showMessage(QStringLiteral("Test Title"), QStringLiteral("A long test text that notifies the user about something
that spreads over two lines to fit even more text."), LtsWidgets::LtsNotificationBox::MessageType::Info, [this](const QString &) { new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), QStringLiteral("You clicked the link!")); }); }; ret.append(plData); } return ret; } } // namespace DeveloperTools