]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
Check protocol Class before creating a StatJob
[dolphin.git] / src / dolphinmainwindow.cpp
index 56ea93e1043e8408f925d2a4cece8615d8f53f73..92d673a956b067c7aa881d468bfb0279d9a2c7e4 100644 (file)
@@ -1,26 +1,14 @@
-/***************************************************************************
- *   Copyright (C) 2006 by Peter Penz <peter.penz19@gmail.com>             *
- *   Copyright (C) 2006 by Stefan Monov <logixoul@gmail.com>               *
- *   Copyright (C) 2006 by Cvetoslav Ludmiloff <ludmiloff@gmail.com>       *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
- ***************************************************************************/
+/*
+ * SPDX-FileCopyrightText: 2006 Peter Penz <peter.penz19@gmail.com>
+ * SPDX-FileCopyrightText: 2006 Stefan Monov <logixoul@gmail.com>
+ * SPDX-FileCopyrightText: 2006 Cvetoslav Ludmiloff <ludmiloff@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
 
 #include "dolphinmainwindow.h"
 
+#include "dolphinmainwindowadaptor.h"
 #include "config-terminal.h"
 #include "global.h"
 #include "dolphinbookmarkhandler.h"
 #include <KActionMenu>
 #include <KAuthorized>
 #include <KConfig>
+#include <KConfigGui>
 #include <KDualAction>
 #include <KFileItemListProperties>
 #include <KHelpMenu>
+#include <KIO/CommandLauncherJob>
 #include <KIO/JobUiDelegate>
 #include <KIO/OpenFileManagerWindowJob>
+#include <KIO/OpenUrlJob>
 #include <KJobWidgets>
 #include <KLocalizedString>
 #include <KMessageBox>
+#include <KNS3/KMoreToolsMenuFactory>
 #include <KProtocolInfo>
 #include <KProtocolManager>
-#include <KRun>
 #include <KShell>
 #include <KStandardAction>
 #include <KStartupInfo>
+#include <KSycoca>
 #include <KToggleAction>
 #include <KToolBar>
 #include <KToolBarPopupAction>
@@ -109,7 +101,7 @@ DolphinMainWindow::DolphinMainWindow() :
     m_bookmarkHandler(nullptr),
     m_controlButton(nullptr),
     m_updateToolBarTimer(nullptr),
-    m_lastHandleUrlStatJob(nullptr),
+    m_lastHandleUrlOpenJob(nullptr),
     m_terminalPanel(nullptr),
     m_placesPanel(nullptr),
     m_tearDownFromPlacesRequested(false),
@@ -117,6 +109,9 @@ DolphinMainWindow::DolphinMainWindow() :
     m_forwardAction(nullptr)
 {
     Q_INIT_RESOURCE(dolphin);
+
+    new MainWindowAdaptor(this);
+
 #ifndef Q_OS_WIN
        setWindowFlags(Qt::WindowContextHelpButtonHint);
 #endif
@@ -197,6 +192,10 @@ DolphinMainWindow::DolphinMainWindow() :
     toolBar()->installEventFilter(middleClickEventFilter);
 
     setupWhatsThis();
+
+    connect(KSycoca::self(), QOverload<>::of(&KSycoca::databaseChanged), this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
+
+    QTimer::singleShot(0, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
 }
 
 DolphinMainWindow::~DolphinMainWindow()
@@ -572,6 +571,14 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
         }
     }
 
+    if (GeneralSettings::rememberOpenedTabs())  {
+        KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin"));
+        KConfig *config = KConfigGui::sessionConfig();
+        saveGlobalProperties(config);
+        savePropertiesInternal(config, 1);
+        config->sync();
+    }
+
     GeneralSettings::setVersion(CurrentDolphinVersion);
     GeneralSettings::self()->save();
 
@@ -592,13 +599,13 @@ void DolphinMainWindow::updateNewMenu()
 {
     m_newFileMenu->setViewShowsHiddenFiles(activeViewContainer()->view()->hiddenFilesShown());
     m_newFileMenu->checkUpToDate();
-    m_newFileMenu->setPopupFiles(activeViewContainer()->url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
 }
 
 void DolphinMainWindow::createDirectory()
 {
     m_newFileMenu->setViewShowsHiddenFiles(activeViewContainer()->view()->hiddenFilesShown());
-    m_newFileMenu->setPopupFiles(activeViewContainer()->url());
+    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
     m_newFileMenu->createDirectory();
 }
 
@@ -637,12 +644,12 @@ void DolphinMainWindow::undo()
 
 void DolphinMainWindow::cut()
 {
-    m_activeViewContainer->view()->cutSelectedItems();
+    m_activeViewContainer->view()->cutSelectedItemsToClipboard();
 }
 
 void DolphinMainWindow::copy()
 {
-    m_activeViewContainer->view()->copySelectedItems();
+    m_activeViewContainer->view()->copySelectedItemsToClipboard();
 }
 
 void DolphinMainWindow::paste()
@@ -919,7 +926,10 @@ void DolphinMainWindow::compareFiles()
     command.append("\" \"");
     command.append(urlB.toDisplayString(QUrl::PreferLocalFile));
     command.append('\"');
-    KRun::runCommand(command, QStringLiteral("Kompare"), QStringLiteral("kompare"), this);
+
+    KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(command, this);
+    job->setDesktopName(QStringLiteral("org.kde.kompare"));
+    job->start();
 }
 
 void DolphinMainWindow::toggleShowMenuBar()
@@ -933,23 +943,77 @@ void DolphinMainWindow::toggleShowMenuBar()
     }
 }
 
-void DolphinMainWindow::openTerminal()
+QPointer<QAction> DolphinMainWindow::preferredSearchTool()
+{
+    m_searchTools.clear();
+    KMoreToolsMenuFactory("dolphin/search-tools").fillMenuFromGroupingNames(
+        &m_searchTools, { "files-find" }, m_activeViewContainer->url()
+    );
+    QList<QAction*> actions = m_searchTools.actions();
+    if (actions.isEmpty()) {
+        return nullptr;
+    }
+    QAction* action = actions.first();
+    if (action->isSeparator()) {
+        return nullptr;
+    }
+    return action;
+}
+
+void DolphinMainWindow::updateOpenPreferredSearchToolAction()
+{
+    QAction* openPreferredSearchTool = actionCollection()->action(QStringLiteral("open_preferred_search_tool"));
+    if (!openPreferredSearchTool) {
+        return;
+    }
+    QPointer<QAction> tool = preferredSearchTool();
+    if (tool) {
+        openPreferredSearchTool->setVisible(true);
+        openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open %1", tool->text()));
+        openPreferredSearchTool->setIcon(tool->icon());
+    } else {
+        openPreferredSearchTool->setVisible(false);
+        // still visible in Shortcuts configuration window
+        openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open Preferred Search Tool"));
+        openPreferredSearchTool->setIcon(QIcon::fromTheme(QStringLiteral("search")));
+    }
+}
+
+void DolphinMainWindow::openPreferredSearchTool()
 {
-    QString dir(QDir::homePath());
+    QPointer<QAction> tool = preferredSearchTool();
+    if (tool) {
+        tool->trigger();
+    }
+}
 
-    // If the given directory is not local, it can still be the URL of an
-    // ioslave using UDS_LOCAL_PATH which to be converted first.
-    KIO::StatJob* statJob = KIO::mostLocalUrl(m_activeViewContainer->url());
-    KJobWidgets::setWindow(statJob, this);
-    statJob->exec();
-    QUrl url = statJob->mostLocalUrl();
+void DolphinMainWindow::openTerminal()
+{
+    const QUrl url = m_activeViewContainer->url();
 
-    //If the URL is local after the above conversion, set the directory.
     if (url.isLocalFile()) {
-        dir = url.toLocalFile();
+        KToolInvocation::invokeTerminal(QString(), url.toLocalFile());
+        return;
+    }
+
+     // Not a local file, with protocol Class ":local", try stat'ing
+    if (KProtocolInfo::protocolClass(url.scheme()) == QLatin1String(":local")) {
+        KIO::StatJob *job = KIO::mostLocalUrl(url);
+        KJobWidgets::setWindow(job, this);
+        connect(job, &KJob::result, this, [job]() {
+            QUrl statUrl;
+            if (!job->error()) {
+                statUrl = job->mostLocalUrl();
+            }
+
+            KToolInvocation::invokeTerminal(QString(), statUrl.isLocalFile() ? statUrl.toLocalFile() : QDir::homePath());
+        });
+
+        return;
     }
 
-    KToolInvocation::invokeTerminal(QString(), dir);
+    // Nothing worked, just use $HOME
+    KToolInvocation::invokeTerminal(QString(), QDir::homePath());
 }
 
 void DolphinMainWindow::editSettings()
@@ -971,34 +1035,31 @@ void DolphinMainWindow::editSettings()
 
 void DolphinMainWindow::handleUrl(const QUrl& url)
 {
-    delete m_lastHandleUrlStatJob;
-    m_lastHandleUrlStatJob = nullptr;
+    delete m_lastHandleUrlOpenJob;
+    m_lastHandleUrlOpenJob = nullptr;
 
     if (url.isLocalFile() && QFileInfo(url.toLocalFile()).isDir()) {
         activeViewContainer()->setUrl(url);
-    } else if (KProtocolManager::supportsListing(url)) {
-        // stat the URL to see if it is a dir or not
-        m_lastHandleUrlStatJob = KIO::stat(url, KIO::HideProgressInfo);
-        if (m_lastHandleUrlStatJob->uiDelegate()) {
-            KJobWidgets::setWindow(m_lastHandleUrlStatJob, this);
-        }
-        connect(m_lastHandleUrlStatJob, &KIO::Job::result,
-                this, &DolphinMainWindow::slotHandleUrlStatFinished);
-
     } else {
-        new KRun(url, this); // Automatically deletes itself after being finished
-    }
-}
+        m_lastHandleUrlOpenJob = new KIO::OpenUrlJob(url);
+        m_lastHandleUrlOpenJob->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
+        m_lastHandleUrlOpenJob->setRunExecutables(true);
 
-void DolphinMainWindow::slotHandleUrlStatFinished(KJob* job)
-{
-    m_lastHandleUrlStatJob = nullptr;
-    const KIO::UDSEntry entry = static_cast<KIO::StatJob*>(job)->statResult();
-    const QUrl url = static_cast<KIO::StatJob*>(job)->url();
-    if (entry.isDir()) {
-        activeViewContainer()->setUrl(url);
-    } else {
-        new KRun(url, this);  // Automatically deletes itself after being finished
+        connect(m_lastHandleUrlOpenJob, &KIO::OpenUrlJob::mimeTypeFound, this,
+                [this, url](const QString &mimetype) {
+                    if (mimetype == QLatin1String("inode/directory")) {
+                        // If it's a dir, we'll take it from here
+                        m_lastHandleUrlOpenJob->kill();
+                        m_lastHandleUrlOpenJob = nullptr;
+                        activeViewContainer()->setUrl(url);
+                    }
+        });
+
+        connect(m_lastHandleUrlOpenJob, &KIO::OpenUrlJob::result, this, [this]() {
+            m_lastHandleUrlOpenJob = nullptr;
+        });
+
+        m_lastHandleUrlOpenJob->start();
     }
 }
 
@@ -1064,6 +1125,9 @@ void DolphinMainWindow::updateControlMenu()
 
     // Add "Edit" actions
     bool added = addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Undo)), menu) |
+                 addActionToMenu(ac->action(QString("copy_location")), menu) |
+                 addActionToMenu(ac->action(QStringLiteral("copy_to_inactive_split_view")), menu) |
+                 addActionToMenu(ac->action(QStringLiteral("move_to_inactive_split_view")), menu) |
                  addActionToMenu(ac->action(KStandardAction::name(KStandardAction::SelectAll)), menu) |
                  addActionToMenu(ac->action(QStringLiteral("invert_selection")), menu);
 
@@ -1091,6 +1155,7 @@ void DolphinMainWindow::updateControlMenu()
 
     // Add a curated assortment of items from the "Tools" menu
     addActionToMenu(ac->action(QStringLiteral("show_filter_bar")), menu);
+    addActionToMenu(ac->action(QStringLiteral("open_preferred_search_tool")), menu);
     addActionToMenu(ac->action(QStringLiteral("open_terminal")), menu);
 
     menu->addSeparator();
@@ -1191,7 +1256,7 @@ void DolphinMainWindow::tabCountChanged(int count)
 
 void DolphinMainWindow::updateWindowTitle()
 {
-    const QString newTitle = m_activeViewContainer->caption();
+    const QString newTitle = m_activeViewContainer->captionWindowTitle();
     if (windowTitle() != newTitle) {
         setWindowTitle(newTitle);
     }
@@ -1247,6 +1312,7 @@ void DolphinMainWindow::setupActions()
 
     QAction* addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
     addToPlaces->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new")));
+    addToPlaces->setText(i18nc("@action:inmenu Add current folder to places", "Add to Places"));
     addToPlaces->setWhatsThis(xi18nc("@info:whatsthis", "This adds the selected folder "
         "to the Places panel."));
     connect(addToPlaces, &QAction::triggered, this, &DolphinMainWindow::addToPlaces);
@@ -1294,6 +1360,24 @@ void DolphinMainWindow::setupActions()
         "If the items were added to the clipboard by the <emphasis>Cut</emphasis> "
         "action they are removed from their old location.") +  cutCopyPastePara);
 
+    QAction* copyToOtherViewAction = actionCollection()->addAction(QStringLiteral("copy_to_inactive_split_view"));
+    copyToOtherViewAction->setText(i18nc("@action:inmenu", "Copy to Inactive Split View"));
+    copyToOtherViewAction->setWhatsThis(xi18nc("@info:whatsthis Copy", "This copies the selected items from "
+        "the <emphasis>active</emphasis> view to the inactive split view."));
+    copyToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
+    copyToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Copy to Inactive Split View"));
+    actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT + Qt::Key_F5 );
+    connect(copyToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::copyToInactiveSplitView);
+
+    QAction* moveToOtherViewAction = actionCollection()->addAction(QStringLiteral("move_to_inactive_split_view"));
+    moveToOtherViewAction->setText(i18nc("@action:inmenu", "Move to Inactive Split View"));
+    moveToOtherViewAction->setWhatsThis(xi18nc("@info:whatsthis Move", "This moves the selected items from "
+        "the <emphasis>active</emphasis> view to the inactive split view."));
+    moveToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut")));
+    moveToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Move to Inactive Split View"));
+    actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT + Qt::Key_F6 );
+    connect(moveToOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::moveToInactiveSplitView);
+
     QAction *searchAction = KStandardAction::find(this, &DolphinMainWindow::find, actionCollection());
     searchAction->setText(i18n("Search..."));
     searchAction->setToolTip(i18nc("@info:tooltip", "Search for files and folders"));
@@ -1465,7 +1549,15 @@ void DolphinMainWindow::setupActions()
     compareFiles->setEnabled(false);
     connect(compareFiles, &QAction::triggered, this, &DolphinMainWindow::compareFiles);
 
-#ifdef HAVE_TERMINAL
+    QAction* openPreferredSearchTool = actionCollection()->addAction(QStringLiteral("open_preferred_search_tool"));
+    openPreferredSearchTool->setText(i18nc("@action:inmenu Tools", "Open Preferred Search Tool"));
+    openPreferredSearchTool->setWhatsThis(xi18nc("@info:whatsthis",
+        "<para>This opens a preferred search tool for the viewed location.</para>"
+        "<para>Use <emphasis>More Search Tools</emphasis> menu to configure it.</para>"));
+    openPreferredSearchTool->setIcon(QIcon::fromTheme(QStringLiteral("search")));
+    actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL + Qt::SHIFT + Qt::Key_F);
+    connect(openPreferredSearchTool, &QAction::triggered, this, &DolphinMainWindow::openPreferredSearchTool);
+
     if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
         QAction* openTerminal = actionCollection()->addAction(QStringLiteral("open_terminal"));
         openTerminal->setText(i18nc("@action:inmenu Tools", "Open Terminal"));
@@ -1475,8 +1567,15 @@ void DolphinMainWindow::setupActions()
         openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("dialog-scripts")));
         actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT + Qt::Key_F4);
         connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
-    }
+
+#ifdef HAVE_TERMINAL
+        QAction* focusTerminalPanel = actionCollection()->addAction(QStringLiteral("focus_terminal_panel"));
+        focusTerminalPanel->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
+        focusTerminalPanel->setIcon(QIcon::fromTheme(QStringLiteral("swap-panels")));
+        actionCollection()->setDefaultShortcut(focusTerminalPanel, Qt::CTRL + Qt::SHIFT + Qt::Key_F4);
+        connect(focusTerminalPanel, &QAction::triggered, this, &DolphinMainWindow::focusTerminalPanel);
 #endif
+    }
 
     // setup 'Bookmarks' menu
     KActionMenu *bookmarkMenu = new KActionMenu(i18nc("@title:menu", "&Bookmarks"), this);
@@ -1804,13 +1903,20 @@ void DolphinMainWindow::updateFileAndEditActions()
 {
     const KFileItemList list = m_activeViewContainer->view()->selectedItems();
     const KActionCollection* col = actionCollection();
+    KFileItemListProperties capabilitiesSource(list);
+
     QAction* addToPlacesAction = col->action(QStringLiteral("add_to_places"));
+    QAction* copyToOtherViewAction   = col->action(QStringLiteral("copy_to_inactive_split_view"));
+    QAction* moveToOtherViewAction   = col->action(QStringLiteral("move_to_inactive_split_view"));
+    QAction* copyLocation            = col->action(QString("copy_location"));
 
     if (list.isEmpty()) {
         stateChanged(QStringLiteral("has_no_selection"));
 
         addToPlacesAction->setEnabled(true);
-        addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", m_activeViewContainer->placesText()));
+        copyToOtherViewAction->setEnabled(false);
+        moveToOtherViewAction->setEnabled(false);
+        copyLocation->setEnabled(false);
     } else {
         stateChanged(QStringLiteral("has_selection"));
 
@@ -1820,24 +1926,41 @@ void DolphinMainWindow::updateFileAndEditActions()
         QAction* cutAction               = col->action(KStandardAction::name(KStandardAction::Cut));
         QAction* deleteWithTrashShortcut = col->action(QStringLiteral("delete_shortcut")); // see DolphinViewActionHandler
         QAction* showTarget              = col->action(QStringLiteral("show_target"));
+        QAction* duplicateAction         = col->action(QStringLiteral("duplicate")); // see DolphinViewActionHandler
 
         if (list.length() == 1 && list.first().isDir()) {
             addToPlacesAction->setEnabled(true);
-            addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add '%1' to Places", list.first().name()));
         } else {
             addToPlacesAction->setEnabled(false);
-            addToPlacesAction->setText(i18nc("@action:inmenu Add current folder to places", "Add to Places"));
         }
 
-        KFileItemListProperties capabilities(list);
-        const bool enableMoveToTrash = capabilities.isLocal() && capabilities.supportsMoving();
+        if (m_tabWidget->currentTabPage()->splitViewEnabled()) {
+            DolphinTabPage* tabPage = m_tabWidget->currentTabPage();
+            KFileItem capabilitiesDestination;
+
+            if (tabPage->primaryViewActive()) {
+                capabilitiesDestination = tabPage->secondaryViewContainer()->url();
+            } else {
+                capabilitiesDestination = tabPage->primaryViewContainer()->url();
+            }
+
+            copyToOtherViewAction->setEnabled(capabilitiesDestination.isWritable());
+            moveToOtherViewAction->setEnabled(capabilitiesSource.supportsMoving() && capabilitiesDestination.isWritable());
+        } else {
+            copyToOtherViewAction->setEnabled(false);
+            moveToOtherViewAction->setEnabled(false);
+        }
+
+        const bool enableMoveToTrash = capabilitiesSource.isLocal() && capabilitiesSource.supportsMoving();
 
-        renameAction->setEnabled(capabilities.supportsMoving());
+        renameAction->setEnabled(capabilitiesSource.supportsMoving());
         moveToTrashAction->setEnabled(enableMoveToTrash);
-        deleteAction->setEnabled(capabilities.supportsDeleting());
-        deleteWithTrashShortcut->setEnabled(capabilities.supportsDeleting() && !enableMoveToTrash);
-        cutAction->setEnabled(capabilities.supportsMoving());
+        deleteAction->setEnabled(capabilitiesSource.supportsDeleting());
+        deleteWithTrashShortcut->setEnabled(capabilitiesSource.supportsDeleting() && !enableMoveToTrash);
+        cutAction->setEnabled(capabilitiesSource.supportsMoving());
+        copyLocation->setEnabled(list.length() == 1);
         showTarget->setEnabled(list.length() == 1 && list.at(0).isLink());
+        duplicateAction->setEnabled(capabilitiesSource.supportsWriting());
     }
 }
 
@@ -1984,6 +2107,8 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
             this, &DolphinMainWindow::goForward);
     connect(view, &DolphinView::urlActivated,
             this, &DolphinMainWindow::handleUrl);
+    connect(view, &DolphinView::goUpRequested,
+            this, &DolphinMainWindow::goUp);
 
     const KUrlNavigator* navigator = container->urlNavigator();
     connect(navigator, &KUrlNavigator::urlChanged,
@@ -2224,6 +2349,22 @@ bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event)
     return false;
 }
 
+void DolphinMainWindow::focusTerminalPanel()
+{
+    if (m_terminalPanel->isVisible()) {
+        if (m_terminalPanel->terminalHasFocus()) {
+            m_activeViewContainer->view()->setFocus(Qt::FocusReason::ShortcutFocusReason);
+            actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
+        } else {
+            m_terminalPanel->setFocus(Qt::FocusReason::ShortcutFocusReason);
+            actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Defocus Terminal Panel"));
+        }
+    } else {
+        actionCollection()->action(QStringLiteral("show_terminal_panel"))->trigger();
+        actionCollection()->action(QStringLiteral("focus_terminal_panel"))->setText(i18nc("@action:inmenu Tools", "Defocus Terminal Panel"));
+    }
+}
+
 DolphinMainWindow::UndoUiInterface::UndoUiInterface() :
     KIO::FileUndoManager::UiInterface()
 {