X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/ed2d352c42a6d517d4f29b3582c0e00aa34fe647..b19b50fff1a17cca0443a6b09bd9caedca19f403:/src/panels/terminal/terminalpanel.cpp diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp index 06ad89547..92ba18bf5 100644 --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -47,6 +47,11 @@ TerminalPanel::TerminalPanel(QWidget *parent) TerminalPanel::~TerminalPanel() { + if (m_konsolePart) { + // Avoid when QObject cleanup, which comes after our destructor, deletes the konsolePart + // and subsequently calls back into our slot when the destructor has already run. + disconnect(m_konsolePart, &KParts::ReadOnlyPart::destroyed, this, &TerminalPanel::terminalExited); + } } void TerminalPanel::goHome() @@ -65,6 +70,7 @@ bool TerminalPanel::currentWorkingDirectoryIsChildOf(const QString &path) const void TerminalPanel::terminalExited() { m_terminal = nullptr; + m_konsolePart = nullptr; Q_EMIT hideTerminalPanel(); } @@ -77,18 +83,22 @@ 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 (isHiddenInVisibleWindow() && m_terminal && !hasProgramRunning()) { - // Make sure that the following "cd /" command will not affect the view. - disconnect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)), this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString))); - - // Make sure this terminal does not prevent unmounting any removable drives - changeDir(QUrl::fromLocalFile(QStringLiteral("/"))); - - // Because we have disconnected from the part's currentDirectoryChanged() - // signal, we have to update m_konsolePartCurrentDirectory manually. If this - // was not done, showing the panel again might not set the part's working - // directory correctly. - m_konsolePartCurrentDirectory = '/'; + if (isHiddenInVisibleWindow()) { + if (m_konsolePartMissingMessage) { + m_konsolePartMissingMessage->hide(); + } else if (m_terminal && !hasProgramRunning()) { + // Make sure that the following "cd /" command will not affect the view. + disconnect(m_konsolePart, SIGNAL(currentDirectoryChanged(QString)), this, SLOT(slotKonsolePartCurrentDirectoryChanged(QString))); + + // Make sure this terminal does not prevent unmounting any removable drives + changeDir(QUrl::fromLocalFile(QStringLiteral("/"))); + + // Because we have disconnected from the part's currentDirectoryChanged() + // signal, we have to update m_konsolePartCurrentDirectory manually. If this + // was not done, showing the panel again might not set the part's working + // directory correctly. + m_konsolePartCurrentDirectory = '/'; + } } } @@ -140,7 +150,7 @@ void TerminalPanel::showEvent(QShowEvent *event) if (!m_terminal) { m_clearTerminal = true; - KPluginFactory *factory = KPluginFactory::loadFactory(KPluginMetaData(QStringLiteral("konsolepart"))).plugin; + KPluginFactory *factory = KPluginFactory::loadFactory(KPluginMetaData(QStringLiteral("kf6/parts/konsolepart"))).plugin; m_konsolePart = factory ? (factory->create(this)) : nullptr; if (m_konsolePart) { connect(m_konsolePart, &KParts::ReadOnlyPart::destroyed, this, &TerminalPanel::terminalExited); @@ -168,25 +178,27 @@ void TerminalPanel::showEvent(QShowEvent *event) }); } - } 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 { + 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->setPosition(KMessageWidget::Footer); + 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->setSizeConstraint(QLayout::SetMaximumSize); + } + m_konsolePartMissingMessage->animatedShow(); } } @@ -207,6 +219,10 @@ void TerminalPanel::changeDir(const QUrl &url) delete m_mostLocalUrlJob; m_mostLocalUrlJob = nullptr; + if (url.isEmpty()) { + return; + } + if (url.isLocalFile()) { sendCdToTerminal(url.toLocalFile()); return; @@ -262,7 +278,7 @@ void TerminalPanel::sendCdToTerminalKIOFuse(const QUrl &url) // If we can't do that for any reason, silently fail. auto reply = m_kiofuseInterface.mountUrl(url.toString()); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *watcher) { + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=, this](QDBusPendingCallWatcher *watcher) { watcher->deleteLater(); if (!reply.isError()) { // Successfully mounted, point to the KIOFuse equivalent path. @@ -310,7 +326,7 @@ void TerminalPanel::slotKonsolePartCurrentDirectoryChanged(const QString &dir) auto reply = m_kiofuseInterface.remoteUrl(m_konsolePartCurrentDirectory); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=](QDBusPendingCallWatcher *watcher) { + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=, this](QDBusPendingCallWatcher *watcher) { watcher->deleteLater(); if (reply.isError()) { // KIOFuse errored out... just show the normal URL