+ // setup 'Edit' menu
+ KStandardAction::undo(this,
+ &DolphinMainWindow::undo,
+ actionCollection());
+
+ // i18n: This will be the last paragraph for the whatsthis for all three:
+ // Cut, Copy and Paste
+ const QString cutCopyPastePara = xi18nc("@info:whatsthis", "<para><emphasis>Cut, "
+ "Copy</emphasis> and <emphasis>Paste</emphasis> work between many "
+ "applications and are among the most used commands. That's why their "
+ "<emphasis>keyboard shortcuts</emphasis> are prominently placed right "
+ "next to each other on the keyboard: <shortcut>Ctrl+X</shortcut>, "
+ "<shortcut>Ctrl+C</shortcut> and <shortcut>Ctrl+V</shortcut>.</para>");
+ QAction* cutAction = KStandardAction::cut(this, &DolphinMainWindow::cut, actionCollection());
+ cutAction->setWhatsThis(xi18nc("@info:whatsthis cut", "This copies the items "
+ "in your current selection to the <emphasis>clipboard</emphasis>.<nl/>"
+ "Use the <emphasis>Paste</emphasis> action afterwards to copy them from "
+ "the clipboard to a new location. The items will be removed from their "
+ "initial location.") + cutCopyPastePara);
+ QAction* copyAction = KStandardAction::copy(this, &DolphinMainWindow::copy, actionCollection());
+ copyAction->setWhatsThis(xi18nc("@info:whatsthis copy", "This copies the "
+ "items in your current selection to the <emphasis>clipboard</emphasis>."
+ "<nl/>Use the <emphasis>Paste</emphasis> action afterwards to copy them "
+ "from the clipboard to a new location.") + cutCopyPastePara);
+ QAction* paste = KStandardAction::paste(this, &DolphinMainWindow::paste, actionCollection());
+ // The text of the paste-action is modified dynamically by Dolphin
+ // (e. g. to "Paste One Folder"). To prevent that the size of the toolbar changes
+ // due to the long text, the text "Paste" is used:
+ paste->setIconText(i18nc("@action:inmenu Edit", "Paste"));
+ paste->setWhatsThis(xi18nc("@info:whatsthis paste", "This copies the items from "
+ "your <emphasis>clipboard</emphasis> to the currently viewed folder.<nl/>"
+ "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* showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
+ showFilterBar->setText(i18nc("@action:inmenu Tools", "Filter..."));
+ showFilterBar->setToolTip(i18nc("@info:tooltip", "Toggle Filter Bar"));
+ showFilterBar->setWhatsThis(xi18nc("@info:whatsthis", "This opens the "
+ "<emphasis>Filter Bar</emphasis> at the bottom of the window.<nl/> "
+ "There you can enter a text to filter the files and folders currently displayed. "
+ "Only those that contain the text in their name will be kept in view."));
+ showFilterBar->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
+ actionCollection()->setDefaultShortcuts(showFilterBar, {Qt::CTRL | Qt::Key_I, Qt::Key_Slash});
+ connect(showFilterBar, &QAction::triggered, this, &DolphinMainWindow::showFilterBar);
+
+ // toggle_filter acts as a copy of the main showFilterBar to be used mainly
+ // in the toolbar, with no default shortcut attached, to avoid messing with
+ // existing workflows (filter bar always open and Ctrl-I to focus)
+ QAction *toggleFilter = actionCollection()->addAction(QStringLiteral("toggle_filter"));
+ toggleFilter->setText(i18nc("@action:inmenu", "Toggle Filter Bar"));
+ toggleFilter->setIconText(i18nc("@action:intoolbar", "Filter"));
+ toggleFilter->setIcon(showFilterBar->icon());
+ toggleFilter->setToolTip(showFilterBar->toolTip());
+ toggleFilter->setWhatsThis(showFilterBar->whatsThis());
+ toggleFilter->setCheckable(true);
+ connect(toggleFilter, &QAction::triggered, this, &DolphinMainWindow::toggleFilterBar);
+
+ QAction *searchAction = KStandardAction::find(this, &DolphinMainWindow::find, actionCollection());
+ searchAction->setText(i18n("Search..."));
+ searchAction->setToolTip(i18nc("@info:tooltip", "Search for files and folders"));
+ searchAction->setWhatsThis(xi18nc("@info:whatsthis find", "<para>This helps you "
+ "find files and folders by opening a <emphasis>find bar</emphasis>. "
+ "There you can enter search terms and specify settings to find the "
+ "objects you are looking for.</para><para>Use this help again on "
+ "the find bar so we can have a look at it while the settings are "
+ "explained.</para>"));
+
+ // toggle_search acts as a copy of the main searchAction to be used mainly
+ // in the toolbar, with no default shortcut attached, to avoid messing with
+ // existing workflows (search bar always open and Ctrl-F to focus)
+ QAction *toggleSearchAction = actionCollection()->addAction(QStringLiteral("toggle_search"));
+ toggleSearchAction->setText(i18nc("@action:inmenu", "Toggle Search Bar"));
+ toggleSearchAction->setIconText(i18nc("@action:intoolbar", "Search"));
+ toggleSearchAction->setIcon(searchAction->icon());
+ toggleSearchAction->setToolTip(searchAction->toolTip());
+ toggleSearchAction->setWhatsThis(searchAction->whatsThis());
+ toggleSearchAction->setCheckable(true);
+
+ QAction* selectAllAction = KStandardAction::selectAll(this, &DolphinMainWindow::selectAll, actionCollection());
+ selectAllAction->setWhatsThis(xi18nc("@info:whatsthis", "This selects all "
+ "files and folders in the current location."));
+
+ QAction* invertSelection = actionCollection()->addAction(QStringLiteral("invert_selection"));
+ invertSelection->setText(i18nc("@action:inmenu Edit", "Invert Selection"));
+ invertSelection->setWhatsThis(xi18nc("@info:whatsthis invert", "This selects all "
+ "objects that you have currently <emphasis>not</emphasis> selected instead."));
+ invertSelection->setIcon(QIcon::fromTheme(QStringLiteral("edit-select-invert")));
+ actionCollection()->setDefaultShortcut(invertSelection, Qt::CTRL | Qt::SHIFT | Qt::Key_A);
+ connect(invertSelection, &QAction::triggered, this, &DolphinMainWindow::invertSelection);
+
+ // setup 'View' menu
+ // (note that most of it is set up in DolphinViewActionHandler)
+
+ QAction* split = actionCollection()->addAction(QStringLiteral("split_view"));
+ split->setWhatsThis(xi18nc("@info:whatsthis find", "<para>This splits "
+ "the folder view below into two autonomous views.</para><para>This "
+ "way you can see two locations at once and move items between them "
+ "quickly.</para>Click this again afterwards to recombine the views."));
+ actionCollection()->setDefaultShortcut(split, Qt::Key_F3);
+ connect(split, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
+
+ QAction* stashSplit = actionCollection()->addAction(QStringLiteral("split_stash"));
+ actionCollection()->setDefaultShortcut(stashSplit, Qt::CTRL | Qt::Key_S);
+ stashSplit->setText(i18nc("@action:intoolbar Stash", "Stash"));
+ stashSplit->setToolTip(i18nc("@info", "Opens the stash virtual directory in a split window"));
+ stashSplit->setIcon(QIcon::fromTheme(QStringLiteral("folder-stash")));
+ stashSplit->setCheckable(false);
+ stashSplit->setVisible(KProtocolInfo::isKnownProtocol("stash"));
+ connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
+
+ KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
+
+ QAction* stop = actionCollection()->addAction(QStringLiteral("stop"));
+ stop->setText(i18nc("@action:inmenu View", "Stop"));
+ stop->setToolTip(i18nc("@info", "Stop loading"));
+ stop->setWhatsThis(i18nc("@info", "This stops the loading of the contents of the current folder."));
+ stop->setIcon(QIcon::fromTheme(QStringLiteral("process-stop")));
+ connect(stop, &QAction::triggered, this, &DolphinMainWindow::stopLoading);
+
+ KToggleAction* editableLocation = actionCollection()->add<KToggleAction>(QStringLiteral("editable_location"));
+ editableLocation->setText(i18nc("@action:inmenu Navigation Bar", "Editable Location"));
+ editableLocation->setWhatsThis(xi18nc("@info:whatsthis",
+ "This toggles the <emphasis>Location Bar</emphasis> to be "
+ "editable so you can directly enter a location you want to go to.<nl/>"
+ "You can also switch to editing by clicking to the right of the "
+ "location and switch back by confirming the edited location."));
+ actionCollection()->setDefaultShortcut(editableLocation, Qt::Key_F6);
+ connect(editableLocation, &KToggleAction::triggered, this, &DolphinMainWindow::toggleEditLocation);
+
+ QAction* replaceLocation = actionCollection()->addAction(QStringLiteral("replace_location"));
+ replaceLocation->setText(i18nc("@action:inmenu Navigation Bar", "Replace Location"));
+ // i18n: "enter" is used both in the meaning of "writing" and "going to" a new location here.
+ // Both meanings are useful but not necessary to understand the use of "Replace Location".
+ // So you might want to be more verbose in your language to convey the meaning but it's up to you.
+ replaceLocation->setWhatsThis(xi18nc("@info:whatsthis",
+ "This switches to editing the location and selects it "
+ "so you can quickly enter a different location."));
+ actionCollection()->setDefaultShortcut(replaceLocation, Qt::CTRL | Qt::Key_L);
+ connect(replaceLocation, &QAction::triggered, this, &DolphinMainWindow::replaceLocation);
+
+ // setup 'Go' menu
+ {
+ QScopedPointer<QAction> backAction(KStandardAction::back(nullptr, nullptr, nullptr));
+ m_backAction = new KToolBarPopupAction(backAction->icon(), backAction->text(), actionCollection());
+ m_backAction->setObjectName(backAction->objectName());
+ m_backAction->setShortcuts(backAction->shortcuts());
+ }
+ m_backAction->setDelayed(true);
+ m_backAction->setStickyMenu(false);
+ connect(m_backAction, &QAction::triggered, this, &DolphinMainWindow::goBack);
+ connect(m_backAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
+ connect(m_backAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
+ actionCollection()->addAction(m_backAction->objectName(), m_backAction);
+
+ auto backShortcuts = m_backAction->shortcuts();
+ backShortcuts.append(QKeySequence(Qt::Key_Backspace));
+ actionCollection()->setDefaultShortcuts(m_backAction, backShortcuts);
+
+ DolphinRecentTabsMenu* recentTabsMenu = new DolphinRecentTabsMenu(this);
+ actionCollection()->addAction(QStringLiteral("closed_tabs"), recentTabsMenu);
+ connect(m_tabWidget, &DolphinTabWidget::rememberClosedTab,
+ recentTabsMenu, &DolphinRecentTabsMenu::rememberClosedTab);
+ connect(recentTabsMenu, &DolphinRecentTabsMenu::restoreClosedTab,
+ m_tabWidget, &DolphinTabWidget::restoreClosedTab);
+ connect(recentTabsMenu, &DolphinRecentTabsMenu::closedTabsCountChanged,
+ this, &DolphinMainWindow::closedTabsCountChanged);
+
+ QAction* undoCloseTab = actionCollection()->addAction(QStringLiteral("undo_close_tab"));
+ undoCloseTab->setText(i18nc("@action:inmenu File", "Undo close tab"));
+ undoCloseTab->setWhatsThis(i18nc("@info:whatsthis undo close tab",
+ "This returns you to the previously closed tab."));
+ actionCollection()->setDefaultShortcut(undoCloseTab, Qt::CTRL | Qt::SHIFT | Qt::Key_T);
+ undoCloseTab->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo")));
+ undoCloseTab->setEnabled(false);
+ connect(undoCloseTab, &QAction::triggered, recentTabsMenu, &DolphinRecentTabsMenu::undoCloseTab);
+
+ auto undoAction = actionCollection()->action(KStandardAction::name(KStandardAction::Undo));
+ undoAction->setWhatsThis(xi18nc("@info:whatsthis", "This undoes "
+ "the last change you made to files or folders.<nl/>"
+ "Such changes include <interface>creating, renaming</interface> "
+ "and <interface>moving</interface> them to a different location "
+ "or to the <filename>Trash</filename>. <nl/>Changes that can't "
+ "be undone will ask for your confirmation."));
+ undoAction->setEnabled(false); // undo should be disabled by default
+
+ {
+ QScopedPointer<QAction> forwardAction(KStandardAction::forward(nullptr, nullptr, nullptr));
+ m_forwardAction = new KToolBarPopupAction(forwardAction->icon(), forwardAction->text(), actionCollection());
+ m_forwardAction->setObjectName(forwardAction->objectName());
+ m_forwardAction->setShortcuts(forwardAction->shortcuts());
+ }
+ m_forwardAction->setDelayed(true);
+ m_forwardAction->setStickyMenu(false);
+ connect(m_forwardAction, &QAction::triggered, this, &DolphinMainWindow::goForward);
+ connect(m_forwardAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
+ connect(m_forwardAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
+ actionCollection()->addAction(m_forwardAction->objectName(), m_forwardAction);
+ actionCollection()->setDefaultShortcuts(m_forwardAction, m_forwardAction->shortcuts());
+
+ // enable middle-click to open in a new tab
+ auto *middleClickEventFilter = new MiddleClickActionEventFilter(this);
+ connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotBackForwardActionMiddleClicked);
+ m_backAction->menu()->installEventFilter(middleClickEventFilter);
+ m_forwardAction->menu()->installEventFilter(middleClickEventFilter);
+ KStandardAction::up(this, &DolphinMainWindow::goUp, actionCollection());
+ QAction* homeAction = KStandardAction::home(this, &DolphinMainWindow::goHome, actionCollection());
+ homeAction->setWhatsThis(xi18nc("@info:whatsthis", "Go to your "
+ "<filename>Home</filename> folder.<nl/>Every user account "
+ "has their own <filename>Home</filename> that contains their data "
+ "including folders that contain personal application data."));
+
+ // setup 'Tools' menu
+ QAction* compareFiles = actionCollection()->addAction(QStringLiteral("compare_files"));
+ compareFiles->setText(i18nc("@action:inmenu Tools", "Compare Files"));
+ compareFiles->setIcon(QIcon::fromTheme(QStringLiteral("kompare")));
+ compareFiles->setEnabled(false);
+ connect(compareFiles, &QAction::triggered, this, &DolphinMainWindow::compareFiles);
+
+ 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"));
+ openTerminal->setWhatsThis(xi18nc("@info:whatsthis",
+ "<para>This opens a <emphasis>terminal</emphasis> application for the viewed location.</para>"
+ "<para>To learn more about terminals use the help in the terminal application.</para>"));
+ openTerminal->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
+ 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);
+ bookmarkMenu->setIcon(QIcon::fromTheme(QStringLiteral("bookmarks")));
+ // Make the toolbar button version work properly on click
+ bookmarkMenu->setDelayed(false);
+ m_bookmarkHandler = new DolphinBookmarkHandler(this, actionCollection(), bookmarkMenu->menu(), this);
+ actionCollection()->addAction(QStringLiteral("bookmarks"), bookmarkMenu);
+
+ // setup 'Settings' menu
+ KToggleAction* showMenuBar = KStandardAction::showMenubar(nullptr, nullptr, actionCollection());
+ showMenuBar->setWhatsThis(xi18nc("@info:whatsthis",
+ "This switches between having a <emphasis>Menubar</emphasis> "
+ "and having a <interface>Control</interface> button. Both "
+ "contain mostly the same commands and configuration options."));
+ connect(showMenuBar, &KToggleAction::triggered, // Fixes #286822
+ this, &DolphinMainWindow::toggleShowMenuBar, Qt::QueuedConnection);
+ KStandardAction::preferences(this, &DolphinMainWindow::editSettings, actionCollection());
+
+ // setup 'Help' menu for the m_controlButton. The other one is set up in the base class.
+ m_helpMenu = new KHelpMenu(nullptr);
+ m_helpMenu->menu()->installEventFilter(this);
+ // remove duplicate shortcuts
+ m_helpMenu->action(KHelpMenu::menuHelpContents)->setShortcut(QKeySequence());
+ m_helpMenu->action(KHelpMenu::menuWhatsThis)->setShortcut(QKeySequence());
+
+ // not in menu actions
+ QList<QKeySequence> nextTabKeys = KStandardShortcut::tabNext();
+ nextTabKeys.append(QKeySequence(Qt::CTRL | Qt::Key_Tab));
+
+ QList<QKeySequence> prevTabKeys = KStandardShortcut::tabPrev();
+ prevTabKeys.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab));
+
+ for (int i = 0; i < MaxActivateTabShortcuts; ++i) {
+ QAction* activateTab = actionCollection()->addAction(QStringLiteral("activate_tab_%1").arg(i));
+ activateTab->setText(i18nc("@action:inmenu", "Activate Tab %1", i + 1));
+ activateTab->setEnabled(false);
+ connect(activateTab, &QAction::triggered, this, [this, i]() { m_tabWidget->activateTab(i); });
+
+ // only add default shortcuts for the first 9 tabs regardless of MaxActivateTabShortcuts
+ if (i < 9) {
+ actionCollection()->setDefaultShortcut(activateTab, QStringLiteral("Alt+%1").arg(i + 1));