]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
Show home folder if needed after unmounting mounted disk
[dolphin.git] / src / dolphinmainwindow.cpp
index 2f11d7aabc162653f637ab6af671eb825c17fd6f..2c91cd07a7a846b1d718cdf61f38736d0e54928c 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>
@@ -79,7 +70,6 @@
 #include <QDialog>
 #include <QFileInfo>
 #include <QLineEdit>
-#include <QMenu>
 #include <QMenuBar>
 #include <QPushButton>
 #include <QShowEvent>
@@ -110,7 +100,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),
@@ -118,6 +108,9 @@ DolphinMainWindow::DolphinMainWindow() :
     m_forwardAction(nullptr)
 {
     Q_INIT_RESOURCE(dolphin);
+
+    new MainWindowAdaptor(this);
+
 #ifndef Q_OS_WIN
        setWindowFlags(Qt::WindowContextHelpButtonHint);
 #endif
@@ -199,7 +192,9 @@ DolphinMainWindow::DolphinMainWindow() :
 
     setupWhatsThis();
 
-    QTimer::singleShot(0, this, &DolphinMainWindow::setupUpdateOpenPreferredSearchToolAction);
+    connect(KSycoca::self(), QOverload<>::of(&KSycoca::databaseChanged), this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
+
+    QTimer::singleShot(0, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
 }
 
 DolphinMainWindow::~DolphinMainWindow()
@@ -209,9 +204,14 @@ DolphinMainWindow::~DolphinMainWindow()
 QVector<DolphinViewContainer*> DolphinMainWindow::viewContainers() const
 {
     QVector<DolphinViewContainer*> viewContainers;
-    viewContainers.reserve(m_tabWidget->count());
+
     for (int i = 0; i < m_tabWidget->count(); ++i) {
-        viewContainers << m_tabWidget->tabPageAt(i)->activeViewContainer();
+        DolphinTabPage *tabPage = m_tabWidget->tabPageAt(i);
+
+        viewContainers << tabPage->primaryViewContainer();
+        if (tabPage->splitViewEnabled()) {
+            viewContainers << tabPage->secondaryViewContainer();
+        }
     }
     return viewContainers;
 }
@@ -479,7 +479,10 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
         closedByUser = false;
     }
 
-    if (m_tabWidget->count() > 1 && GeneralSettings::confirmClosingMultipleTabs() && closedByUser) {
+    if (m_tabWidget->count() > 1
+        && GeneralSettings::confirmClosingMultipleTabs()
+        && !GeneralSettings::rememberOpenedTabs()
+        && closedByUser) {
         // Ask the user if he really wants to quit and close all tabs.
         // Open a confirmation dialog with 3 buttons:
         // QDialogButtonBox::Yes    -> Quit
@@ -575,6 +578,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();
 
@@ -640,12 +651,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()
@@ -922,7 +933,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()
@@ -936,23 +950,11 @@ void DolphinMainWindow::toggleShowMenuBar()
     }
 }
 
-QString DolphinMainWindow::activeContainerLocalPath()
-{
-    KIO::StatJob* statJob = KIO::mostLocalUrl(m_activeViewContainer->url());
-    KJobWidgets::setWindow(statJob, this);
-    statJob->exec();
-    QUrl url = statJob->mostLocalUrl();
-    if (url.isLocalFile()) {
-        return url.toLocalFile();
-    }
-    return QDir::homePath();
-}
-
 QPointer<QAction> DolphinMainWindow::preferredSearchTool()
 {
     m_searchTools.clear();
     KMoreToolsMenuFactory("dolphin/search-tools").fillMenuFromGroupingNames(
-        &m_searchTools, { "files-find" }, QUrl::fromLocalFile(activeContainerLocalPath())
+        &m_searchTools, { "files-find" }, m_activeViewContainer->url()
     );
     QList<QAction*> actions = m_searchTools.actions();
     if (actions.isEmpty()) {
@@ -965,29 +967,6 @@ QPointer<QAction> DolphinMainWindow::preferredSearchTool()
     return action;
 }
 
-void DolphinMainWindow::setupUpdateOpenPreferredSearchToolAction()
-{
-    QAction* openPreferredSearchTool = actionCollection()->action(QStringLiteral("open_preferred_search_tool"));
-    const QList<QWidget*> widgets = openPreferredSearchTool->associatedWidgets();
-    for (QWidget* widget : widgets) {
-        QMenu* menu = qobject_cast<QMenu*>(widget);
-        if (menu) {
-            connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
-        }
-    }
-
-    // Update the open_preferred_search_tool action *before* the Configure Shortcuts window is shown,
-    // since this action is then listed in that window and it should be up-to-date when it is displayed.
-    // This update is instantaneous if user made no changes to the search tools in the meantime.
-    // Maybe all KStandardActions should defer calls to their slots, so that we could simply connect() to trigger()?
-    connect(
-        actionCollection()->action(KStandardAction::name(KStandardAction::KeyBindings)), &QAction::hovered,
-        this, &DolphinMainWindow::updateOpenPreferredSearchToolAction
-    );
-
-    updateOpenPreferredSearchToolAction();
-}
-
 void DolphinMainWindow::updateOpenPreferredSearchToolAction()
 {
     QAction* openPreferredSearchTool = actionCollection()->action(QStringLiteral("open_preferred_search_tool"));
@@ -1017,7 +996,31 @@ void DolphinMainWindow::openPreferredSearchTool()
 
 void DolphinMainWindow::openTerminal()
 {
-    KToolInvocation::invokeTerminal(QString(), activeContainerLocalPath());
+    const QUrl url = m_activeViewContainer->url();
+
+    if (url.isLocalFile()) {
+        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;
+    }
+
+    // Nothing worked, just use $HOME
+    KToolInvocation::invokeTerminal(QString(), QDir::homePath());
 }
 
 void DolphinMainWindow::editSettings()
@@ -1039,34 +1042,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();
     }
 }
 
@@ -1132,6 +1132,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);
 
@@ -1161,7 +1164,6 @@ void DolphinMainWindow::updateControlMenu()
     addActionToMenu(ac->action(QStringLiteral("show_filter_bar")), menu);
     addActionToMenu(ac->action(QStringLiteral("open_preferred_search_tool")), menu);
     addActionToMenu(ac->action(QStringLiteral("open_terminal")), menu);
-    connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateOpenPreferredSearchToolAction);
 
     menu->addSeparator();
 
@@ -1261,7 +1263,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);
     }
@@ -1269,6 +1271,10 @@ void DolphinMainWindow::updateWindowTitle()
 
 void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mountPath)
 {
+    connect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, this, [this, mountPath]() {
+        setViewsToHomeIfMountPathOpen(mountPath);
+    });
+
     if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
         m_tearDownFromPlacesRequested = true;
         m_terminalPanel->goHome();
@@ -1280,12 +1286,27 @@ void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString& mo
 
 void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString& mountPath)
 {
+    connect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, this, [this, mountPath]() {
+        setViewsToHomeIfMountPathOpen(mountPath);
+    });
+
     if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
         m_tearDownFromPlacesRequested = false;
         m_terminalPanel->goHome();
     }
 }
 
+void DolphinMainWindow::setViewsToHomeIfMountPathOpen(const QString& mountPath)
+{
+    const QVector<DolphinViewContainer*> theViewContainers = viewContainers();
+    for (DolphinViewContainer *viewContainer : theViewContainers) {
+        if (viewContainer && viewContainer->url().toLocalFile().startsWith(mountPath)) {
+            viewContainer->setUrl(QUrl::fromLocalFile(QDir::homePath()));
+        }
+    }
+    disconnect(m_placesPanel, &PlacesPanel::storageTearDownSuccessful, nullptr, nullptr);
+}
+
 void DolphinMainWindow::setupActions()
 {
     // setup 'File' menu
@@ -1317,6 +1338,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);
@@ -1364,6 +1386,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"));
@@ -1544,7 +1584,6 @@ void DolphinMainWindow::setupActions()
     actionCollection()->setDefaultShortcut(openPreferredSearchTool, Qt::CTRL + Qt::SHIFT + Qt::Key_F);
     connect(openPreferredSearchTool, &QAction::triggered, this, &DolphinMainWindow::openPreferredSearchTool);
 
-#ifdef HAVE_TERMINAL
     if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
         QAction* openTerminal = actionCollection()->addAction(QStringLiteral("open_terminal"));
         openTerminal->setText(i18nc("@action:inmenu Tools", "Open Terminal"));
@@ -1555,13 +1594,14 @@ void DolphinMainWindow::setupActions()
         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);
@@ -1889,13 +1929,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"));
 
@@ -1905,24 +1952,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());
     }
 }
 
@@ -2069,6 +2133,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,
@@ -2293,8 +2359,6 @@ bool DolphinMainWindow::event(QEvent *event)
         QWhatsThisClickedEvent* whatsThisEvent = dynamic_cast<QWhatsThisClickedEvent*>(event);
         QDesktopServices::openUrl(QUrl(whatsThisEvent->href()));
         return true;
-    } else if (event->type() == QEvent::WindowActivate) {
-        updateOpenPreferredSearchToolAction();
     }
     return KXmlGuiWindow::event(event);
 }