]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinmainwindow.cpp
Merge branch 'master' into kf6
[dolphin.git] / src / dolphinmainwindow.cpp
index 5d31a55dc482417c2edc2a814396d005b1cae2e9..415f2e8b3700edad1c737372491a64b4b2d56822 100644 (file)
@@ -88,6 +88,8 @@
 #include <QTimer>
 #include <QToolButton>
 
+#include <algorithm>
+
 namespace
 {
 // Used for GeneralSettings::version() to determine whether
@@ -163,6 +165,10 @@ DolphinMainWindow::DolphinMainWindow()
     connect(m_actionHandler, &DolphinViewActionHandler::createDirectoryTriggered, this, &DolphinMainWindow::createDirectory);
     connect(m_actionHandler, &DolphinViewActionHandler::selectionModeChangeTriggered, this, &DolphinMainWindow::slotSetSelectionMode);
 
+#if KIO_VERSION >= QT_VERSION_CHECK(5, 100, 0)
+    m_newFileMenu->setNewFolderShortcutAction(actionCollection()->action("create_dir"));
+#endif
+
     m_remoteEncoding = new DolphinRemoteEncoding(this, m_actionHandler);
     connect(this, &DolphinMainWindow::urlChanged, m_remoteEncoding, &DolphinRemoteEncoding::slotAboutToOpenUrl);
 
@@ -265,11 +271,41 @@ bool DolphinMainWindow::isInformationPanelEnabled() const
 #endif
 }
 
+bool DolphinMainWindow::isSplitViewEnabledInCurrentTab() const
+{
+    return m_tabWidget->currentTabPage()->splitViewEnabled();
+}
+
 void DolphinMainWindow::openFiles(const QStringList &files, bool splitView)
 {
     openFiles(QUrl::fromStringList(files), splitView);
 }
 
+bool DolphinMainWindow::isOnCurrentDesktop() const
+{
+#if HAVE_X11
+    if (KWindowSystem::isPlatformX11()) {
+        const NET::Properties properties = NET::WMDesktop;
+        KWindowInfo info(this->winId(), properties);
+        return info.isOnCurrentDesktop();
+    }
+#endif
+    return true;
+}
+
+bool DolphinMainWindow::isOnActivity(const QString &activityId) const
+{
+#if HAVE_X11 && HAVE_KACTIVITIES
+    if (KWindowSystem::isPlatformX11()) {
+        const NET::Properties properties = NET::Supported;
+        const NET::Properties2 properties2 = NET::WM2Activities;
+        KWindowInfo info(this->winId(), properties, properties2);
+        return info.activities().contains(activityId);
+    }
+#endif
+    return true;
+}
+
 void DolphinMainWindow::activateWindow(const QString &activationToken)
 {
     window()->setAttribute(Qt::WA_NativeWindow, true);
@@ -499,17 +535,33 @@ void DolphinMainWindow::openInNewWindow()
 
 void DolphinMainWindow::showTarget()
 {
-    const auto link = m_activeViewContainer->view()->selectedItems().at(0);
-    const auto linkLocationDir = QFileInfo(link.localPath()).absoluteDir();
-    auto linkDestination = link.linkDest();
-    if (QFileInfo(linkDestination).isRelative()) {
-        linkDestination = linkLocationDir.filePath(linkDestination);
-    }
-    if (QFileInfo::exists(linkDestination)) {
-        KIO::highlightInFileManager({QUrl::fromLocalFile(linkDestination).adjusted(QUrl::StripTrailingSlash)});
-    } else {
-        m_activeViewContainer->showMessage(xi18nc("@info", "Could not access <filename>%1</filename>.", linkDestination), DolphinViewContainer::Warning);
+    const KFileItem link = m_activeViewContainer->view()->selectedItems().at(0);
+    const QUrl destinationUrl = link.url().resolved(QUrl(link.linkDest()));
+
+    auto job = KIO::statDetails(destinationUrl, KIO::StatJob::SourceSide, KIO::StatNoDetails);
+
+    connect(job, &KJob::finished, this, [this, destinationUrl](KJob *job) {
+        KIO::StatJob *statJob = static_cast<KIO::StatJob *>(job);
+
+        if (statJob->error()) {
+            m_activeViewContainer->showMessage(job->errorString(), DolphinViewContainer::Error);
+        } else {
+            KIO::highlightInFileManager({destinationUrl});
+        }
+    });
+}
+
+bool DolphinMainWindow::event(QEvent *event)
+{
+    if (event->type() == QEvent::ShortcutOverride) {
+        const QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+        if (keyEvent->key() == Qt::Key_Space && m_activeViewContainer->view()->handleSpaceAsNormalKey()) {
+            event->accept();
+            return true;
+        }
     }
+
+    return KXmlGuiWindow::event(event);
 }
 
 void DolphinMainWindow::showEvent(QShowEvent *event)
@@ -1423,7 +1475,7 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer *viewContainer)
         connect(oldViewContainer->view(), &DolphinView::requestItemInfo, this, &DolphinMainWindow::requestItemInfo);
 
         // Disconnect other slots.
-        disconnect(nullptr,
+        disconnect(oldViewContainer,
                    &DolphinViewContainer::selectionModeChanged,
                    actionCollection()->action(QStringLiteral("toggle_selection_mode")),
                    &QAction::setChecked);
@@ -1469,7 +1521,7 @@ void DolphinMainWindow::slotStorageTearDownFromPlacesRequested(const QString &mo
         setViewsToHomeIfMountPathOpen(mountPath);
     });
 
-    if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+    if (m_terminalPanel && m_terminalPanel->currentWorkingDirectoryIsChildOf(mountPath)) {
         m_tearDownFromPlacesRequested = true;
         m_terminalPanel->goHome();
         // m_placesPanel->proceedWithTearDown() will be called in slotTerminalDirectoryChanged
@@ -1484,7 +1536,7 @@ void DolphinMainWindow::slotStorageTearDownExternallyRequested(const QString &mo
         setViewsToHomeIfMountPathOpen(mountPath);
     });
 
-    if (m_terminalPanel && m_terminalPanel->currentWorkingDirectory().startsWith(mountPath)) {
+    if (m_terminalPanel && m_terminalPanel->currentWorkingDirectoryIsChildOf(mountPath)) {
         m_tearDownFromPlacesRequested = false;
         m_terminalPanel->goHome();
     }
@@ -1606,8 +1658,8 @@ void DolphinMainWindow::setupActions()
                         + cutCopyPastePara);
 
     QAction *copyToOtherViewAction = actionCollection()->addAction(QStringLiteral("copy_to_inactive_split_view"));
-    copyToOtherViewAction->setText(i18nc("@action:inmenu", "Copy to Inactive Split View"));
-    m_actionTextHelper->registerTextWhenNothingIsSelected(copyToOtherViewAction, i18nc("@action:inmenu", "Copy to Inactive Split View…"));
+    copyToOtherViewAction->setText(i18nc("@action:inmenu", "Copy to Other View"));
+    m_actionTextHelper->registerTextWhenNothingIsSelected(copyToOtherViewAction, i18nc("@action:inmenu", "Copy to Other View…"));
     copyToOtherViewAction->setWhatsThis(xi18nc("@info:whatsthis Copy",
                                                "This copies the selected items from "
                                                "the <emphasis>active</emphasis> view to the inactive split view."));
@@ -1617,8 +1669,8 @@ void DolphinMainWindow::setupActions()
     connect(copyToOtherViewAction, &QAction::triggered, this, &DolphinMainWindow::copyToInactiveSplitView);
 
     QAction *moveToOtherViewAction = actionCollection()->addAction(QStringLiteral("move_to_inactive_split_view"));
-    moveToOtherViewAction->setText(i18nc("@action:inmenu", "Move to Inactive Split View"));
-    m_actionTextHelper->registerTextWhenNothingIsSelected(moveToOtherViewAction, i18nc("@action:inmenu", "Move to Inactive Split View…"));
+    moveToOtherViewAction->setText(i18nc("@action:inmenu", "Move to Other View"));
+    m_actionTextHelper->registerTextWhenNothingIsSelected(moveToOtherViewAction, i18nc("@action:inmenu", "Move to Other View…"));
     moveToOtherViewAction->setWhatsThis(xi18nc("@info:whatsthis Move",
                                                "This moves the selected items from "
                                                "the <emphasis>active</emphasis> view to the inactive split view."));
@@ -1687,6 +1739,7 @@ void DolphinMainWindow::setupActions()
         "</para>"));
     toggleSelectionModeAction->setIcon(QIcon::fromTheme(QStringLiteral("quickwizard")));
     toggleSelectionModeAction->setCheckable(true);
+    actionCollection()->setDefaultShortcut(toggleSelectionModeAction, Qt::Key_Space );
     connect(toggleSelectionModeAction, &QAction::triggered, this, &DolphinMainWindow::toggleSelectionMode);
 
     // A special version of the toggleSelectionModeAction for the toolbar that also contains a menu
@@ -1786,7 +1839,8 @@ void DolphinMainWindow::setupActions()
     actionCollection()->addAction(m_backAction->objectName(), m_backAction);
 
     auto backShortcuts = m_backAction->shortcuts();
-    backShortcuts.append(QKeySequence(Qt::Key_Backspace));
+    // Prepend this shortcut, to avoid being hidden by the two-slot UI (#371130)
+    backShortcuts.prepend(QKeySequence(Qt::Key_Backspace));
     actionCollection()->setDefaultShortcuts(m_backAction, backShortcuts);
 
     DolphinRecentTabsMenu *recentTabsMenu = new DolphinRecentTabsMenu(this);
@@ -2276,18 +2330,24 @@ void DolphinMainWindow::updateFileAndEditActions()
         duplicateAction->setEnabled(capabilitiesSource.supportsWriting());
     }
 
-    if (m_tabWidget->currentTabPage()->splitViewEnabled()) {
+    if (m_tabWidget->currentTabPage()->splitViewEnabled() && !list.isEmpty()) {
         DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
         KFileItem capabilitiesDestination;
 
         if (tabPage->primaryViewActive()) {
-            capabilitiesDestination = tabPage->secondaryViewContainer()->url();
+            capabilitiesDestination = tabPage->secondaryViewContainer()->rootItem();
         } else {
-            capabilitiesDestination = tabPage->primaryViewContainer()->url();
+            capabilitiesDestination = tabPage->primaryViewContainer()->rootItem();
         }
 
-        copyToOtherViewAction->setEnabled(capabilitiesDestination.isWritable());
-        moveToOtherViewAction->setEnabled((list.isEmpty() || capabilitiesSource.supportsMoving()) && capabilitiesDestination.isWritable());
+        const auto destUrl = capabilitiesDestination.url();
+        const bool allNotTargetOrigin = std::all_of(list.cbegin(), list.cend(), [destUrl](const KFileItem &item) {
+            return item.url().adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash) != destUrl;
+        });
+
+        copyToOtherViewAction->setEnabled(capabilitiesDestination.isWritable() && allNotTargetOrigin);
+        moveToOtherViewAction->setEnabled((list.isEmpty() || capabilitiesSource.supportsMoving()) && capabilitiesDestination.isWritable()
+                                          && allNotTargetOrigin);
     } else {
         copyToOtherViewAction->setEnabled(false);
         moveToOtherViewAction->setEnabled(false);
@@ -2504,15 +2564,23 @@ void DolphinMainWindow::setupWhatsThis()
 
     // Help menu
 
+    auto setStandardActionWhatsThis = [this](KStandardAction::StandardAction actionId,
+                                             const QString &whatsThis) {
+        // Check for the existence of an action since it can be restricted through the Kiosk system
+        if (auto *action = actionCollection()->action(KStandardAction::name(actionId))) {
+            action->setWhatsThis(whatsThis);
+        }
+    };
+
     // i18n: If the external link isn't available in your language it might make
     // sense to state the external link's language in brackets to not
     // frustrate the user. If there are multiple languages that the user might
     // know with a reasonable chance you might want to have 2 external links.
     // The same might be true for any external link you translate.
-    actionCollection()->action(KStandardAction::name(KStandardAction::HelpContents))->setWhatsThis(xi18nc("@info:whatsthis handbook", "<para>This opens the Handbook for this application. It provides explanations for every part of <emphasis>Dolphin</emphasis>.</para><para>If you want more elaborate introductions to the different features of <emphasis>Dolphin</emphasis> <link url='https://userbase.kde.org/Dolphin/File_Management'>click here</link>. It will open the dedicated page in the KDE UserBase Wiki.</para>"));
+    setStandardActionWhatsThis(KStandardAction::HelpContents, xi18nc("@info:whatsthis handbook", "<para>This opens the Handbook for this application. It provides explanations for every part of <emphasis>Dolphin</emphasis>.</para><para>If you want more elaborate introductions to the different features of <emphasis>Dolphin</emphasis> <link url='https://userbase.kde.org/Dolphin/File_Management'>click here</link>. It will open the dedicated page in the KDE UserBase Wiki.</para>"));
     // (The i18n call should be completely in the line following the i18n: comment without any line breaks within the i18n call or the comment might not be correctly extracted. See: https://commits.kde.org/kxmlgui/a31135046e1b3335b5d7bbbe6aa9a883ce3284c1 )
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::WhatsThis))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::WhatsThis,
         xi18nc("@info:whatsthis whatsthis button",
         "<para>This is the button that invokes the help feature you are "
         "using right now! Click it, then click any component of this "
@@ -2524,7 +2592,7 @@ void DolphinMainWindow::setupWhatsThis()
         "UserBase Wiki</link>.</para><para>The \"What's this?\" help is "
         "missing in most other windows so don't get too used to this.</para>"));
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::ReportBug))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::ReportBug,
         xi18nc("@info:whatsthis","<para>This opens a "
         "window that will guide you through reporting errors or flaws "
         "in this application or in other KDE software.</para>"
@@ -2533,7 +2601,7 @@ void DolphinMainWindow::setupWhatsThis()
         "<link url='https://community.kde.org/Get_Involved/Bug_Reporting'>"
         "click here</link>.</para>"));
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::Donate))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::Donate,
         xi18nc("@info:whatsthis", "<para>This opens a "
         "<emphasis>web page</emphasis> where you can donate to "
         "support the continued work on this application and many "
@@ -2545,18 +2613,18 @@ void DolphinMainWindow::setupWhatsThis()
         "<para><emphasis>KDE e.V.</emphasis> is the non-profit "
         "organization behind the KDE community.</para>"));
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::SwitchApplicationLanguage))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::SwitchApplicationLanguage,
         xi18nc("@info:whatsthis",
         "With this you can change the language this application uses."
         "<nl/>You can even set secondary languages which will be used "
         "if texts are not available in your preferred language."));
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::AboutApp))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::AboutApp,
         xi18nc("@info:whatsthis","This opens a "
         "window that informs you about the version, license, "
         "used libraries and maintainers of this application."));
 
-    actionCollection()->action(KStandardAction::name(KStandardAction::AboutKDE))->setWhatsThis(
+    setStandardActionWhatsThis(KStandardAction::AboutKDE,
         xi18nc("@info:whatsthis","This opens a "
         "window with information about <emphasis>KDE</emphasis>. "
         "The KDE community are the people behind this free software."