X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/bd47eb2e6d80315115bb3f58987162fcb4911b10..d6c086ad04:/src/panels/terminal/terminalpanel.cpp diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp index b7d3605aa..8dedd0be1 100644 --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -19,35 +19,41 @@ #include "terminalpanel.h" -#include - -#include -#include -#include -#include -#include -#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include +#include #include TerminalPanel::TerminalPanel(QWidget* parent) : Panel(parent), m_clearTerminal(true), - m_mostLocalUrlJob(0), - m_layout(0), - m_terminal(0), - m_terminalWidget(0), - m_konsolePart(0), + m_mostLocalUrlJob(nullptr), + m_layout(nullptr), + m_terminal(nullptr), + m_terminalWidget(nullptr), + m_konsolePartMissingMessage(nullptr), + m_konsolePart(nullptr), m_konsolePartCurrentDirectory(), m_sendCdToTerminalHistory() { m_layout = new QVBoxLayout(this); - m_layout->setMargin(0); + m_layout->setContentsMargins(0, 0, 0, 0); } TerminalPanel::~TerminalPanel() @@ -69,16 +75,23 @@ QString TerminalPanel::currentWorkingDirectory() void TerminalPanel::terminalExited() { - m_terminal = 0; + m_terminal = nullptr; emit hideTerminalPanel(); } +bool TerminalPanel::isHiddenInVisibleWindow() const +{ + return parentWidget() + && parentWidget()->isHidden() + && m_terminal + && !hasProgramRunning(); +} + void TerminalPanel::dockVisibilityChanged() { // Only react when the DockWidget itself (not some parent) is hidden. This way we don't // respond when e.g. Dolphin is minimized. - if (parentWidget() && parentWidget()->isHidden() && - m_terminal && (m_terminal->foregroundProcessId() == -1)) { + if (isHiddenInVisibleWindow()) { // Make sure that the following "cd /" command will not affect the view. disconnect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)), this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString))); @@ -94,13 +107,23 @@ void TerminalPanel::dockVisibilityChanged() } } +QString TerminalPanel::runningProgramName() const +{ + return m_terminal ? m_terminal->foregroundProcessName() : QString(); +} + +bool TerminalPanel::hasProgramRunning() const +{ + return m_terminal && (m_terminal->foregroundProcessId() != -1); +} + bool TerminalPanel::urlChanged() { if (!url().isValid()) { return false; } - const bool sendInput = m_terminal && (m_terminal->foregroundProcessId() == -1) && isVisible(); + const bool sendInput = m_terminal && !hasProgramRunning() && isVisible(); if (sendInput) { changeDir(url()); } @@ -117,17 +140,39 @@ void TerminalPanel::showEvent(QShowEvent* event) if (!m_terminal) { m_clearTerminal = true; - KPluginFactory* factory = 0; + KPluginFactory* factory = nullptr; KService::Ptr service = KService::serviceByDesktopName(QStringLiteral("konsolepart")); if (service) { factory = KPluginLoader(service->library()).factory(); } - m_konsolePart = factory ? (factory->create(this)) : 0; + 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_konsolePartMissingMessage) { + const auto konsoleInstallUrl = QUrl("appstream://org.kde.konsole.desktop"); + const auto konsoleNotInstalledText = i18n("Terminal cannot be shown because Konsole is not installed. " + "Please install it and then reopen the panel."); + m_konsolePartMissingMessage = new KMessageWidget(konsoleNotInstalledText, this); + m_konsolePartMissingMessage->setCloseButtonVisible(false); + m_konsolePartMissingMessage->hide(); + if (KIO::DesktopExecParser::hasSchemeHandler(konsoleInstallUrl)) { + auto installKonsoleAction = new QAction(i18n("Install Konsole"), this); + 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 { + m_konsolePartMissingMessage->animatedShow(); } } if (m_terminal) { @@ -144,7 +189,7 @@ void TerminalPanel::showEvent(QShowEvent* event) void TerminalPanel::changeDir(const QUrl& url) { delete m_mostLocalUrlJob; - m_mostLocalUrlJob = 0; + m_mostLocalUrlJob = nullptr; if (url.isLocalFile()) { sendCdToTerminal(url.toLocalFile()); @@ -164,16 +209,18 @@ void TerminalPanel::sendCdToTerminal(const QString& dir, HistoryPolicy addToHist return; } +#ifndef Q_OS_WIN if (!m_clearTerminal) { // The TerminalV2 interface does not provide a way to delete the // current line before sending a new input. This is mandatory, // otherwise sending a 'cd x' to a existing 'rm -rf *' might - // result in data loss. As workaround SIGINT is send. + // result in data loss. As workaround SIGINT is sent. const int processId = m_terminal->terminalProcessId(); if (processId > 0) { kill(processId, SIGINT); } } +#endif m_terminal->sendInput(" cd " + KShell::quoteArg(dir) + '\n'); @@ -198,7 +245,7 @@ void TerminalPanel::slotMostLocalUrlResult(KJob* job) sendCdToTerminal(url.toLocalFile()); } - m_mostLocalUrlJob = 0; + m_mostLocalUrlJob = nullptr; } void TerminalPanel::slotKonsolePartCurrentDirectoryChanged(const QString& dir)