diff --git a/src/panels/terminal/terminalpanel.h b/src/panels/terminal/terminalpanel.h --- a/src/panels/terminal/terminalpanel.h +++ b/src/panels/terminal/terminalpanel.h @@ -22,9 +22,12 @@ #include "panels/panel.h" +#include + #include class TerminalInterface; +class KMessageWidget; class QVBoxLayout; class QWidget; @@ -72,6 +75,7 @@ bool urlChanged() override; void showEvent(QShowEvent* event) override; + void hideEvent(QHideEvent *event) override; private slots: void slotMostLocalUrlResult(KJob* job); @@ -96,6 +100,10 @@ KParts::ReadOnlyPart* m_konsolePart; QString m_konsolePartCurrentDirectory; QQueue m_sendCdToTerminalHistory; + KMessageWidget* m_konsolePartMissingMessage; + QTimer* m_isKonsoleInstalledTimer; + + KPluginFactory* konsolePartFactory(); }; #endif // TERMINALPANEL_H diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -19,18 +19,25 @@ #include "terminalpanel.h" +#include #include #include #include +#include +#include #include #include #include #include #include #include +#include +#include +#include #include #include +#include #include TerminalPanel::TerminalPanel(QWidget* parent) : @@ -42,7 +49,9 @@ m_terminalWidget(nullptr), m_konsolePart(nullptr), m_konsolePartCurrentDirectory(), - m_sendCdToTerminalHistory() + m_sendCdToTerminalHistory(), + m_konsolePartMissingMessage(nullptr), + m_isKonsoleInstalledTimer(nullptr) { m_layout = new QVBoxLayout(this); m_layout->setMargin(0); @@ -113,6 +122,21 @@ return true; } +KPluginFactory* TerminalPanel::konsolePartFactory() +{ + KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("konsolepart")); + return service ? KPluginLoader(service->library()).factory() : nullptr; +} + +void TerminalPanel::hideEvent(QHideEvent *event) +{ + Panel::hideEvent(event); + + if (m_isKonsoleInstalledTimer) { + m_isKonsoleInstalledTimer->stop(); + } +} + void TerminalPanel::showEvent(QShowEvent* event) { if (event->spontaneous()) { @@ -122,17 +146,53 @@ if (!m_terminal) { m_clearTerminal = true; - KPluginFactory* factory = nullptr; - KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("konsolepart")); - if (service) { - factory = KPluginLoader(service->library()).factory(); - } + auto factory = konsolePartFactory(); m_konsolePart = factory ? (factory->create(this)) : nullptr; if (m_konsolePart) { connect(m_konsolePart, &KParts::ReadOnlyPart::destroyed, this, &TerminalPanel::terminalExited); m_terminalWidget = m_konsolePart->widget(); m_layout->addWidget(m_terminalWidget); + if (m_konsolePartMissingMessage) { + m_layout->removeWidget(m_konsolePartMissingMessage); + } m_terminal = qobject_cast(m_konsolePart); + } else { + if (!m_isKonsoleInstalledTimer) { + m_isKonsoleInstalledTimer = new QTimer(this); + connect(m_isKonsoleInstalledTimer, &QTimer::timeout, [this]() { + if (konsolePartFactory()) { + m_isKonsoleInstalledTimer->stop(); + QApplication::sendEvent(this, new QShowEvent{}); + } + }); + } + if (!m_isKonsoleInstalledTimer->isActive()) { + constexpr auto isKonsoleInstalledPollingTime = 1000; + m_isKonsoleInstalledTimer->start(isKonsoleInstalledPollingTime); + } + if (!m_konsolePartMissingMessage) { + const auto konsoleInstallUrl = QUrl("appstream://org.kde.konsole.desktop"); + auto konsoleNotInstalledText = i18n("Terminal cannot be shown because Konsole is not installed."); + const auto doesOsHandleAppstream = KIO::DesktopExecParser::hasSchemeHandler(konsoleInstallUrl); + if (!doesOsHandleAppstream) { + konsoleNotInstalledText += i18n("\nTry installing the 'konsole' package with your package manager."); + } + m_konsolePartMissingMessage = new KMessageWidget(konsoleNotInstalledText); + m_konsolePartMissingMessage->setCloseButtonVisible(false); + m_konsolePartMissingMessage->hide(); + if (doesOsHandleAppstream) { + auto installKonsoleAction = new QAction(i18n("Install Konsole")); + connect(installKonsoleAction, &QAction::triggered, [konsoleInstallUrl]() { + QDesktopServices::openUrl(konsoleInstallUrl); + }); + m_konsolePartMissingMessage->addAction(installKonsoleAction); + } + m_layout->addWidget(m_konsolePartMissingMessage); + m_layout->addStretch(); + QTimer::singleShot(0, m_konsolePartMissingMessage, &KMessageWidget::animatedShow); + } else if (!m_konsolePartMissingMessage->isVisible()) { + m_konsolePartMissingMessage->animatedShow(); + } } } if (m_terminal) {