]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/views/dolphinviewactionhandler.cpp
Revert "Configurable Show hidden files and folders last toggle"
[dolphin.git] / src / views / dolphinviewactionhandler.cpp
index a63263bf5822dcbbebb65e8e0c0b3c07775b7b34..c9bab5f82f793e5a66f508a5c3781756fcdbc769 100644 (file)
 #include "kitemviews/kfileitemmodel.h"
 #include "settings/viewpropertiesdialog.h"
 #include "views/zoomlevelinfo.h"
+#include "kconfig_version.h"
 
 #ifdef HAVE_BALOO
 #include <Baloo/IndexerConfig>
 #endif
 #include <KActionCollection>
 #include <KActionMenu>
+#include <KFileItemListProperties>
 #include <KLocalizedString>
 #include <KNewFileMenu>
 #include <KPropertiesDialog>
 #include <KProtocolManager>
+
+#include <QActionGroup>
 #include <QMenu>
 #include <QPointer>
 
@@ -65,6 +69,9 @@ void DolphinViewActionHandler::setCurrentView(DolphinView* view)
             this, &DolphinViewActionHandler::slotZoomLevelChanged);
     connect(view, &DolphinView::writeStateChanged,
             this, &DolphinViewActionHandler::slotWriteStateChanged);
+    connect(view, &DolphinView::selectionChanged,
+            this, &DolphinViewActionHandler::slotSelectionChanged);
+    slotSelectionChanged(m_currentView->selectedItems());
 }
 
 DolphinView* DolphinViewActionHandler::currentView()
@@ -78,7 +85,7 @@ void DolphinViewActionHandler::createActions()
     // KNewFileMenu takes care of the GUI stuff.
     QAction* newDirAction = m_actionCollection->addAction(QStringLiteral("create_dir"));
     newDirAction->setText(i18nc("@action", "Create Folder..."));
-    m_actionCollection->setDefaultShortcut(newDirAction, Qt::Key_F10);
+    m_actionCollection->setDefaultShortcuts(newDirAction, KStandardShortcut::createFolder());
     newDirAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
     newDirAction->setEnabled(false);    // Will be enabled in slotWriteStateChanged(bool) if the current URL is writable
     connect(newDirAction, &QAction::triggered, this, &DolphinViewActionHandler::createDirectoryTriggered);
@@ -139,7 +146,7 @@ void DolphinViewActionHandler::createActions()
         "You can configure advanced options there like managing "
         "read- and write-permissions."));
     propertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-properties")));
-    m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT + Qt::Key_Return, Qt::ALT + Qt::Key_Enter});
+    m_actionCollection->setDefaultShortcuts(propertiesAction, {Qt::ALT | Qt::Key_Return, Qt::ALT | Qt::Key_Enter});
     connect(propertiesAction, &QAction::triggered, this, &DolphinViewActionHandler::slotProperties);
 
     QAction *copyPathAction = m_actionCollection->addAction( QStringLiteral("copy_location") );
@@ -149,9 +156,28 @@ void DolphinViewActionHandler::createActions()
                                 ));
 
     copyPathAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
-    m_actionCollection->setDefaultShortcuts(copyPathAction, {Qt::CTRL + Qt::SHIFT + Qt::Key_C});
+    m_actionCollection->setDefaultShortcuts(copyPathAction, {Qt::CTRL | Qt::ALT | Qt::Key_C});
     connect(copyPathAction, &QAction::triggered, this, &DolphinViewActionHandler::slotCopyPath);
 
+    // This menu makes sure that users who don't know how to open a context menu and haven't
+    // figured out how to enable the menu bar can still perform basic file manipulation.
+    // This only works if they know how to select a file.
+    // The text when nothing is selected at least implies that a selection can /somehow/ be made.
+    // This menu is by default only used in the hamburger menu but created here so users can put
+    // it on their toolbar.
+    KActionMenu *basicActionsMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("basic_actions"), this);
+    // The text is set later depending on the selection in the currently active view.
+    basicActionsMenu->setPopupMode(QToolButton::InstantPopup);
+    basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Cut)));
+    basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Copy)));
+    basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::Paste)));
+    basicActionsMenu->addSeparator();
+    basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::RenameFile)));
+    basicActionsMenu->addAction(m_actionCollection->action(KStandardAction::name(KStandardAction::MoveToTrash)));
+    basicActionsMenu->addSeparator();
+    basicActionsMenu->addAction(m_actionCollection->action(QStringLiteral("properties")));
+    basicActionsMenu->addSeparator(); // We add one more separator because we sometimes add contextual
+                                      // actions in slotSelectionChanged() after the static ones above.
 
     // View menu
     KToggleAction* iconsAction = iconsModeAction();
@@ -197,7 +223,7 @@ void DolphinViewActionHandler::createActions()
     zoomResetAction->setToolTip(i18n("Zoom To Default"));
     zoomResetAction->setWhatsThis(i18nc("@info:whatsthis zoom reset", "This resets the icon size to default."));
     zoomResetAction->setIcon(QIcon::fromTheme(QStringLiteral("zoom-original")));
-    m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL + Qt::Key_0});
+    m_actionCollection->setDefaultShortcuts(zoomResetAction, {Qt::CTRL | Qt::Key_0});
     connect(zoomResetAction, &QAction::triggered, this, &DolphinViewActionHandler::zoomReset);
 
     QAction* zoomOutAction = KStandardAction::zoomOut(this,
@@ -205,6 +231,14 @@ void DolphinViewActionHandler::createActions()
                              m_actionCollection);
     zoomOutAction->setWhatsThis(i18nc("@info:whatsthis zoom out", "This reduces the icon size."));
 
+    KActionMenu* zoomMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("zoom"));
+    zoomMenu->setText(i18nc("@action:inmenu menu of zoom actions", "Zoom"));
+    zoomMenu->setIcon(QIcon::fromTheme(QStringLiteral("zoom")));
+    zoomMenu->setPopupMode(QToolButton::InstantPopup);
+    zoomMenu->addAction(zoomInAction);
+    zoomMenu->addAction(zoomResetAction);
+    zoomMenu->addAction(zoomOutAction);
+
     KToggleAction* showPreview = m_actionCollection->add<KToggleAction>(QStringLiteral("show_preview"));
     showPreview->setText(i18nc("@action:intoolbar", "Show Previews"));
     showPreview->setToolTip(i18nc("@info", "Show preview of files and folders"));
@@ -225,9 +259,10 @@ void DolphinViewActionHandler::createActions()
     KActionMenu* sortByActionMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("sort"));
     sortByActionMenu->setIcon(QIcon::fromTheme(QStringLiteral("view-sort")));
     sortByActionMenu->setText(i18nc("@action:inmenu View", "Sort By"));
-    sortByActionMenu->setDelayed(false);
+    sortByActionMenu->setPopupMode(QToolButton::InstantPopup);
 
-    foreach (QAction* action, sortByActionGroup->actions()) {
+    const auto sortByActionGroupActions = sortByActionGroup->actions();
+    for (QAction* action : sortByActionGroupActions) {
         sortByActionMenu->addAction(action);
     }
 
@@ -259,9 +294,10 @@ void DolphinViewActionHandler::createActions()
     KActionMenu* visibleRolesMenu = m_actionCollection->add<KActionMenu>(QStringLiteral("additional_info"));
     visibleRolesMenu->setText(i18nc("@action:inmenu View", "Show Additional Information"));
     visibleRolesMenu->setIcon(QIcon::fromTheme(QStringLiteral("documentinfo")));
-    visibleRolesMenu->setDelayed(false);
+    visibleRolesMenu->setPopupMode(QToolButton::InstantPopup);
 
-    foreach (QAction* action, visibleRolesGroup->actions()) {
+    const auto visibleRolesGroupActions = visibleRolesGroup->actions();
+    for (QAction* action : visibleRolesGroupActions) {
         visibleRolesMenu->addAction(action);
     }
 
@@ -317,7 +353,7 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt
 #endif
 
     const QList<KFileItemModel::RoleInfo> rolesInfo = KFileItemModel::rolesInformation();
-    foreach (const KFileItemModel::RoleInfo& info, rolesInfo) {
+    for (const KFileItemModel::RoleInfo& info : rolesInfo) {
         if (!isSortGroup && info.role == "text") {
             // It should not be possible to hide the "text" role
             continue;
@@ -379,25 +415,25 @@ void DolphinViewActionHandler::slotViewModeActionTriggered(QAction* action)
 
 void DolphinViewActionHandler::slotRename()
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->renameSelectedItems();
 }
 
 void DolphinViewActionHandler::slotTrashActivated()
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->trashSelectedItems();
 }
 
 void DolphinViewActionHandler::slotDeleteItems()
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->deleteSelectedItems();
 }
 
 void DolphinViewActionHandler::togglePreview(bool show)
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->setPreviewsShown(show);
 }
 
@@ -496,7 +532,7 @@ void DolphinViewActionHandler::slotSortFoldersFirstChanged(bool foldersFirst)
 
 void DolphinViewActionHandler::toggleVisibleRole(QAction* action)
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
 
     const QByteArray toggledRole = action->data().toByteArray();
 
@@ -521,7 +557,7 @@ void DolphinViewActionHandler::slotVisibleRolesChanged(const QList<QByteArray>&
 {
     Q_UNUSED(previous)
 
-    const QSet<QByteArray> checkedRoles = current.toSet();
+    const auto checkedRoles = QSet<QByteArray>(current.constBegin(), current.constEnd());
     QHashIterator<QByteArray, KToggleAction*> it(m_visibleRoles);
     while (it.hasNext()) {
         it.next();
@@ -544,7 +580,7 @@ void DolphinViewActionHandler::slotGroupedSortingChanged(bool groupedSorting)
 
 void DolphinViewActionHandler::toggleShowHiddenFiles(bool show)
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->setHiddenFilesShown(show);
 }
 
@@ -565,7 +601,7 @@ KToggleAction* DolphinViewActionHandler::iconsModeAction()
     KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("icons"));
     iconsView->setText(i18nc("@action:inmenu View Mode", "Icons"));
     iconsView->setToolTip(i18nc("@info", "Icons view mode"));
-    m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_1);
+    m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_1);
     iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-icons")));
     iconsView->setData(QVariant::fromValue(DolphinView::IconsView));
     return iconsView;
@@ -576,7 +612,7 @@ KToggleAction* DolphinViewActionHandler::compactModeAction()
     KToggleAction* iconsView = m_actionCollection->add<KToggleAction>(QStringLiteral("compact"));
     iconsView->setText(i18nc("@action:inmenu View Mode", "Compact"));
     iconsView->setToolTip(i18nc("@info", "Compact view mode"));
-    m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL + Qt::Key_2);
+    m_actionCollection->setDefaultShortcut(iconsView, Qt::CTRL | Qt::Key_2);
     iconsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-details"))); // TODO: discuss with Oxygen-team the wrong (?) name
     iconsView->setData(QVariant::fromValue(DolphinView::CompactView));
     return iconsView;
@@ -587,7 +623,7 @@ KToggleAction* DolphinViewActionHandler::detailsModeAction()
     KToggleAction* detailsView = m_actionCollection->add<KToggleAction>(QStringLiteral("details"));
     detailsView->setText(i18nc("@action:inmenu View Mode", "Details"));
     detailsView->setToolTip(i18nc("@info", "Details view mode"));
-    m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL + Qt::Key_3);
+    m_actionCollection->setDefaultShortcut(detailsView, Qt::CTRL | Qt::Key_3);
     detailsView->setIcon(QIcon::fromTheme(QStringLiteral("view-list-tree")));
     detailsView->setData(QVariant::fromValue(DolphinView::DetailsView));
     return detailsView;
@@ -654,7 +690,8 @@ void DolphinViewActionHandler::slotSortTriggered(QAction* action)
     for (QAction *groupAction : qAsConst(m_sortByActions)) {
         KActionMenu* actionMenu = qobject_cast<KActionMenu*>(groupAction);
         if (actionMenu) {
-            foreach (QAction* subAction, actionMenu->menu()->actions()) {
+            const auto actions = actionMenu->menu()->actions();
+            for (QAction* subAction : actions) {
                 subAction->setChecked(false);
             }
         } else if (groupAction->actionGroup()) {
@@ -670,7 +707,7 @@ void DolphinViewActionHandler::slotSortTriggered(QAction* action)
 
 void DolphinViewActionHandler::slotAdjustViewProperties()
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     QPointer<ViewPropertiesDialog> dialog = new ViewPropertiesDialog(m_currentView);
     dialog->exec();
     delete dialog;
@@ -678,7 +715,7 @@ void DolphinViewActionHandler::slotAdjustViewProperties()
 
 void DolphinViewActionHandler::slotDuplicate()
 {
-    emit actionBeingHandled();
+    Q_EMIT actionBeingHandled();
     m_currentView->duplicateSelectedItems();
 }
 
@@ -703,3 +740,68 @@ void DolphinViewActionHandler::slotCopyPath()
 {
     m_currentView->copyPathToClipboard();
 }
+
+void DolphinViewActionHandler::slotSelectionChanged(const KFileItemList& selection)
+{
+    QString basicActionsMenuText;
+    switch (selection.count()) {
+    case 0:
+        basicActionsMenuText =
+            i18nc("@action:inmenu menu with actions like copy, paste, rename. The user's selection is empty when this text is shown.",
+                  "Actions for Current View");
+        break;
+    case 1:
+        basicActionsMenuText =
+            i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 is the name of the singular selected file/folder.",
+                  "Actions for \"%1\"", selection.first().name());
+        break;
+    case 2:
+        basicActionsMenuText =
+            i18nc("@action:inmenu menu with actions like copy, paste, rename. %1 and %2 are names of files/folders.",
+                  "Actions for \"%1\" and \"%2\"", selection.first().name(), selection.last().name());
+        break;
+    case 3:
+        basicActionsMenuText =
+            i18nc("@action:inmenu menu with actions like copy, paste, rename. %1, %2 and %3 are names of files/folders.",
+                  "Actions for \"%1\", \"%2\" and \"%3\"",
+                  selection.first().name(), selection.at(1).name(), selection.last().name());
+        break;
+    default:
+        basicActionsMenuText = QString();
+        break;
+    }
+
+    // At some point the added clarity from the text starts being less important than the menu width.
+    if (basicActionsMenuText.isEmpty() || basicActionsMenuText.length() > 40) {
+        const KFileItemListProperties properties(selection);
+        if (properties.isFile()) {
+            basicActionsMenuText =
+                i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
+                       "Actions for One Selected File", "Actions for %1 Selected Files", selection.count());
+        } else if (properties.isDirectory()) {
+            basicActionsMenuText =
+                i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
+                       "Actions for One Selected Folder", "Actions for %1 Selected Folders", selection.count());
+        } else {
+            basicActionsMenuText =
+                i18ncp("@action:inmenu menu with actions like copy, paste, rename. %1 is the amount of selected files/folders.",
+                       "Actions for One Selected Item", "Actions for %1 Selected Items", selection.count());
+        }
+    }
+
+    QAction *basicActionsMenu = m_actionCollection->action(QStringLiteral("basic_actions"));
+    basicActionsMenu->setText(basicActionsMenuText);
+
+    // Add or remove contextual actions
+    while (!basicActionsMenu->menu()->actions().constLast()->isSeparator()) {
+        basicActionsMenu->menu()->removeAction(basicActionsMenu->menu()->actions().last());
+    }
+    if (selection.count() == 1) {
+        if (selection.first().isLink()) {
+            basicActionsMenu->menu()->addAction(m_actionCollection->action(QStringLiteral("show_target")));
+        }
+        if (selection.first().isDir()) {
+            basicActionsMenu->menu()->addAction(m_actionCollection->action(QStringLiteral("add_to_places")));
+        }
+    }
+}