]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
Re-add "Open Terminal Here" feature
[dolphin.git] / src / dolphinmainwindow.cpp
index 644989be02f7995a2bb3c9bf9b80986ec13b9eeb..3e9d463d252d67f5cccb94784ded2efa945945f3 100644 (file)
@@ -53,6 +53,7 @@
 #include <KProtocolInfo>
 #include <KProtocolManager>
 #include <KShell>
+#include <KShortcutsDialog>
 #include <KStandardAction>
 #include <KStartupInfo>
 #include <KSycoca>
@@ -64,7 +65,6 @@
 #include <KUrlNavigator>
 #include <KWindowSystem>
 #include <KXMLGUIFactory>
-#include <kxmlgui_version.h>
 
 #include <kio_version.h>
 
@@ -123,9 +123,7 @@ DolphinMainWindow::DolphinMainWindow() :
     setComponentName(QStringLiteral("dolphin"), QGuiApplication::applicationDisplayName());
     setObjectName(QStringLiteral("Dolphin#"));
 
-#if KXMLGUI_VERSION >= QT_VERSION_CHECK(5, 88, 0)
     setStateConfigGroup("State");
-#endif
 
     connect(&DolphinNewFileMenuObserver::instance(), &DolphinNewFileMenuObserver::errorMessage,
             this, &DolphinMainWindow::showErrorMessage);
@@ -173,7 +171,7 @@ DolphinMainWindow::DolphinMainWindow() :
 
     setupDockWidgets();
 
-    setupGUI(Keys | Save | Create | ToolBar);
+    setupGUI(Save | Create | ToolBar);
     stateChanged(QStringLiteral("new_file"));
 
     QClipboard* clipboard = QApplication::clipboard();
@@ -751,13 +749,45 @@ void DolphinMainWindow::slotToolBarActionMiddleClicked(QAction *action)
     }
 }
 
+QAction *DolphinMainWindow::urlNavigatorHistoryAction(const KUrlNavigator *urlNavigator, int historyIndex, QObject *parent)
+{
+    const QUrl url = urlNavigator->locationUrl(historyIndex);
+
+    QString text = url.toDisplayString(QUrl::PreferLocalFile);
+
+    if (!urlNavigator->showFullPath()) {
+        const KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
+
+        const QModelIndex closestIdx = placesModel->closestItem(url);
+        if (closestIdx.isValid()) {
+            const QUrl placeUrl = placesModel->url(closestIdx);
+
+            text = placesModel->text(closestIdx);
+
+            QString pathInsidePlace = url.path().mid(placeUrl.path().length());
+
+            if (!pathInsidePlace.isEmpty() && !pathInsidePlace.startsWith(QLatin1Char('/'))) {
+                pathInsidePlace.prepend(QLatin1Char('/'));
+            }
+
+            if (pathInsidePlace != QLatin1Char('/')) {
+                text.append(pathInsidePlace);
+            }
+        }
+    }
+
+    QAction *action = new QAction(QIcon::fromTheme(KIO::iconNameForUrl(url)), text, parent);
+    action->setData(historyIndex);
+    return action;
+}
+
 void DolphinMainWindow::slotAboutToShowBackPopupMenu()
 {
     const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
     int entries = 0;
     m_backAction->menu()->clear();
     for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) {
-        QAction* action = new QAction(urlNavigator->locationUrl(i).toDisplayString(QUrl::PreferLocalFile), m_backAction->menu());
+        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_backAction->menu());
         action->setData(i);
         m_backAction->menu()->addAction(action);
     }
@@ -786,7 +816,7 @@ void DolphinMainWindow::slotAboutToShowForwardPopupMenu()
     int entries = 0;
     m_forwardAction->menu()->clear();
     for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) {
-        QAction* action = new QAction(urlNavigator->locationUrl(i).toDisplayString(QUrl::PreferLocalFile), m_forwardAction->menu());
+        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_forwardAction->menu());
         action->setData(i);
         m_forwardAction->menu()->addAction(action);
     }
@@ -914,6 +944,8 @@ void DolphinMainWindow::togglePanelLockState()
         }
     }
 
+    DolphinPlacesModelSingleton::instance().placesModel()->setPanelsLocked(newLockState);
+
     GeneralSettings::setLockPanels(newLockState);
 }
 
@@ -1055,8 +1087,45 @@ void DolphinMainWindow::openPreferredSearchTool()
 
 void DolphinMainWindow::openTerminal()
 {
-    const QUrl url = m_activeViewContainer->url();
+    openTerminalJob(m_activeViewContainer->url());
+}
+
+void DolphinMainWindow::openTerminalHere()
+{
+    QList<QUrl> urls = {};
+
+    for (const KFileItem& item : m_activeViewContainer->view()->selectedItems()) {
+        QUrl url = item.url();
+        if (item.isFile()) {
+            url.setPath(QFileInfo(url.path()).absolutePath());
+        }
+        if (!urls.contains(url)) {
+            urls << url;
+        }
+    }
+
+    // No items are selected. Open a terminal window for the current location.
+    if (urls.count() == 0) {
+        openTerminal();
+        return;
+    }
+
+    if (urls.count() > 5) {
+        QString question = i18np("Are you sure you want to open 1 terminal window?",
+                                 "Are you sure you want to open %1 terminal windows?", urls.count());
+        const int answer = KMessageBox::warningYesNo(this, question);
+        if (answer != KMessageBox::Yes) {
+            return;
+        }
+    }
+
+    for (const QUrl& url : urls) {
+        openTerminalJob(url);
+    }
+}
 
+void DolphinMainWindow::openTerminalJob(const QUrl& url)
+{
     if (url.isLocalFile()) {
         auto job = new KTerminalLauncherJob(QString());
         job->setWorkingDirectory(url.toLocalFile());
@@ -1146,32 +1215,11 @@ void DolphinMainWindow::slotWriteStateChanged(bool isFolderWritable)
 
 void DolphinMainWindow::openContextMenu(const QPoint& pos,
                                         const KFileItem& item,
-                                        const QUrl& url,
-                                        const QList<QAction*>& customActions)
+                                        const KFileItemList &selectedItems,
+                                        const QUrl& url)
 {
-    QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, pos, item, url, &m_fileItemActions);
-    contextMenu.data()->setCustomActions(customActions);
-    const DolphinContextMenu::Command command = contextMenu.data()->open();
-
-    switch (command) {
-    case DolphinContextMenu::OpenParentFolder:
-        changeUrl(KIO::upUrl(item.url()));
-        m_activeViewContainer->view()->markUrlsAsSelected({item.url()});
-        m_activeViewContainer->view()->markUrlAsCurrent(item.url());
-        break;
-
-    case DolphinContextMenu::OpenParentFolderInNewWindow:
-        Dolphin::openNewWindow({item.url()}, this, Dolphin::OpenNewWindowFlag::Select);
-        break;
-
-    case DolphinContextMenu::OpenParentFolderInNewTab:
-        openNewTab(KIO::upUrl(item.url()));
-        break;
-
-    case DolphinContextMenu::None:
-    default:
-        break;
-    }
+    QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, item, selectedItems, url, &m_fileItemActions);
+    contextMenu.data()->exec(pos);
 
     // Delete the menu, unless it has been deleted in its own nested event loop already.
     if (contextMenu) {
@@ -1179,6 +1227,16 @@ void DolphinMainWindow::openContextMenu(const QPoint& pos,
     }
 }
 
+QMenu *DolphinMainWindow::createPopupMenu()
+{
+    QMenu *menu = KXmlGuiWindow::createPopupMenu();
+
+    menu->addSeparator();
+    menu->addAction(actionCollection()->action(QStringLiteral("lock_panels")));
+
+    return menu;
+}
+
 void DolphinMainWindow::updateHamburgerMenu()
 {
     KActionCollection* ac = actionCollection();
@@ -1375,6 +1433,19 @@ void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString& mo
     }
 }
 
+void DolphinMainWindow::slotKeyBindings()
+{
+    KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this);
+    dialog.addCollection(actionCollection());
+    if (m_terminalPanel) {
+        KActionCollection *konsolePartActionCollection = m_terminalPanel->actionCollection();
+        if (konsolePartActionCollection) {
+            dialog.addCollection(konsolePartActionCollection, QStringLiteral("KonsolePart"));
+        }
+    }
+    dialog.configure();
+}
+
 void DolphinMainWindow::setViewsToHomeIfMountPathOpen(const QString& mountPath)
 {
     const QVector<DolphinViewContainer*> theViewContainers = viewContainers();
@@ -1687,6 +1758,16 @@ void DolphinMainWindow::setupActions()
         actionCollection()->setDefaultShortcut(openTerminal, Qt::SHIFT | Qt::Key_F4);
         connect(openTerminal, &QAction::triggered, this, &DolphinMainWindow::openTerminal);
 
+        QAction* openTerminalHere = actionCollection()->addAction(QStringLiteral("open_terminal_here"));
+        // i18n: "Here" refers to the location(s) of the currently selected item(s) or the currently viewed location if nothing is selected.
+        openTerminalHere->setText(i18nc("@action:inmenu Tools", "Open Terminal Here"));
+        openTerminalHere->setWhatsThis(xi18nc("@info:whatsthis",
+            "<para>This opens <emphasis>terminal</emphasis> applications for the selected items' locations.</para>"
+            "<para>To learn more about terminals use the help in the terminal application.</para>"));
+        openTerminalHere->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+        actionCollection()->setDefaultShortcut(openTerminalHere, Qt::SHIFT | Qt::ALT | Qt::Key_F4);
+        connect(openTerminalHere, &QAction::triggered, this, &DolphinMainWindow::openTerminalHere);
+
 #ifdef HAVE_TERMINAL
         QAction* focusTerminalPanel = actionCollection()->addAction(QStringLiteral("focus_terminal_panel"));
         focusTerminalPanel->setText(i18nc("@action:inmenu Tools", "Focus Terminal Panel"));
@@ -1712,6 +1793,7 @@ void DolphinMainWindow::setupActions()
             "contain mostly the same commands and configuration options."));
     connect(showMenuBar, &KToggleAction::triggered,                   // Fixes #286822
             this, &DolphinMainWindow::toggleShowMenuBar, Qt::QueuedConnection);
+    KStandardAction::keyBindings(this, &DolphinMainWindow::slotKeyBindings, actionCollection());
     KStandardAction::preferences(this, &DolphinMainWindow::editSettings, actionCollection());
 
     // setup 'Help' menu for the m_controlButton. The other one is set up in the base class.
@@ -1792,6 +1874,8 @@ void DolphinMainWindow::setupDockWidgets()
 {
     const bool lock = GeneralSettings::lockPanels();
 
+    DolphinPlacesModelSingleton::instance().placesModel()->setPanelsLocked(lock);
+
     KDualAction* lockLayoutAction = actionCollection()->add<KDualAction>(QStringLiteral("lock_panels"));
     lockLayoutAction->setActiveText(i18nc("@action:inmenu Panels", "Unlock Panels"));
     lockLayoutAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("object-unlocked")));
@@ -2266,6 +2350,7 @@ void DolphinMainWindow::createPanelAction(const QIcon& icon,
     panelAction->setChecked(dockAction->isChecked());
     panelAction->setText(dockAction->text());
     panelAction->setIcon(icon);
+    dockAction->setIcon(icon);
     actionCollection()->setDefaultShortcut(panelAction, shortcut);
 
     connect(panelAction, &QAction::triggered, dockAction, &QAction::trigger);