+void DolphinMainWindow::setupActions()
+{
+ auto hamburgerMenuAction = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection());
+
+ // setup 'File' menu
+ m_newFileMenu = new DolphinNewFileMenu(nullptr, nullptr, this);
+ actionCollection()->addAction(QStringLiteral("new_menu"), m_newFileMenu);
+ QMenu *menu = m_newFileMenu->menu();
+ menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
+ menu->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
+ m_newFileMenu->setPopupMode(QToolButton::InstantPopup);
+ connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateNewMenu);
+
+ QAction *newWindow = KStandardAction::openNew(this, &DolphinMainWindow::openNewMainWindow, actionCollection());
+ newWindow->setText(i18nc("@action:inmenu File", "New &Window"));
+ newWindow->setToolTip(i18nc("@info", "Open a new Dolphin window"));
+ newWindow->setWhatsThis(xi18nc("@info:whatsthis",
+ "This opens a new "
+ "window just like this one with the current location."
+ "<nl/>You can drag and drop items between windows."));
+ newWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
+
+ QAction *newTab = actionCollection()->addAction(QStringLiteral("new_tab"));
+ newTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
+ newTab->setText(i18nc("@action:inmenu File", "New Tab"));
+ newTab->setWhatsThis(xi18nc("@info:whatsthis",
+ "This opens a new "
+ "<emphasis>Tab</emphasis> with the current location."
+ "<nl/>Tabs allow you to quickly switch between multiple locations and views within this window. "
+ "You can drag and drop items between tabs."));
+ actionCollection()->setDefaultShortcut(newTab, Qt::CTRL | Qt::Key_T);
+ connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab);
+
+ 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);
+
+ QAction *closeTab = KStandardAction::close(m_tabWidget, QOverload<>::of(&DolphinTabWidget::closeTab), actionCollection());
+ closeTab->setText(i18nc("@action:inmenu File", "Close Tab"));
+ closeTab->setToolTip(i18nc("@info", "Close Tab"));
+ closeTab->setWhatsThis(i18nc("@info:whatsthis",
+ "This closes the "
+ "currently viewed tab. If no more tabs are left, this closes "
+ "the whole window instead."));
+
+ QAction *quitAction = KStandardAction::quit(this, &DolphinMainWindow::quit, actionCollection());
+ quitAction->setWhatsThis(i18nc("@info:whatsthis quit", "This closes this window."));
+
+ // 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());
+ m_actionTextHelper->registerTextWhenNothingIsSelected(cutAction, i18nc("@action", "Cut…"));
+ 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());
+ m_actionTextHelper->registerTextWhenNothingIsSelected(copyAction, i18nc("@action", "Copy…"));
+ 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 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 view in focus to the other view. "
+ "(Only available while in Split View mode.)"));
+ copyToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
+ copyToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Copy to Other View"));
+ actionCollection()->setDefaultShortcut(copyToOtherViewAction, Qt::SHIFT | Qt::Key_F5);
+ connect(copyToOtherViewAction, &QAction::triggered, this, &DolphinMainWindow::copyToInactiveSplitView);
+
+ QAction *moveToOtherViewAction = actionCollection()->addAction(QStringLiteral("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 view in focus to the other view. "
+ "(Only available while in Split View mode.)"));
+ moveToOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-cut")));
+ moveToOtherViewAction->setIconText(i18nc("@action:inmenu Edit", "Move to Other View"));
+ actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT | Qt::Key_F6);
+ connect(moveToOtherViewAction, &QAction::triggered, this, &DolphinMainWindow::moveToInactiveSplitView);
+
+ QAction *showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar"));
+ showFilterBar->setText(i18nc("@action:inmenu Tools", "Filter…"));
+ showFilterBar->setToolTip(i18nc("@info:tooltip", "Show 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 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>search bar</emphasis>. "
+ "There you can enter search terms and specify settings to find the "
+ "items you are looking for.</para><para>Use this help again on "
+ "the search 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 *toggleSelectionModeAction = actionCollection()->addAction(QStringLiteral("toggle_selection_mode"));
+ // i18n: This action toggles a selection mode.
+ toggleSelectionModeAction->setText(i18nc("@action:inmenu", "Select Files and Folders"));
+ // i18n: Opens a selection mode for selecting files/folders.
+ // The text is kept so unspecific because it will be shown on the toolbar where space is at a premium.
+ toggleSelectionModeAction->setIconText(i18nc("@action:intoolbar", "Select"));
+ toggleSelectionModeAction->setWhatsThis(xi18nc(
+ "@info:whatsthis",
+ "<para>This application only knows which files or folders should be acted on if they are"
+ " <emphasis>selected</emphasis> first. Press this to toggle a <emphasis>Selection Mode</emphasis> which makes selecting and deselecting as easy as "
+ "pressing an item once.</para><para>While in this mode, a quick access bar at the bottom shows available actions for the currently selected items."
+ "</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
+ // with the selectAllAction and invertSelectionAction.
+ auto *toggleSelectionModeToolBarAction =
+ new KToolBarPopupAction(toggleSelectionModeAction->icon(), toggleSelectionModeAction->iconText(), actionCollection());
+ toggleSelectionModeToolBarAction->setToolTip(toggleSelectionModeAction->text());
+ toggleSelectionModeToolBarAction->setWhatsThis(toggleSelectionModeAction->whatsThis());
+ actionCollection()->addAction(QStringLiteral("toggle_selection_mode_tool_bar"), toggleSelectionModeToolBarAction);
+ toggleSelectionModeToolBarAction->setCheckable(true);
+ toggleSelectionModeToolBarAction->setPopupMode(KToolBarPopupAction::DelayedPopup);
+ connect(toggleSelectionModeToolBarAction, &QAction::triggered, toggleSelectionModeAction, &QAction::trigger);
+ connect(toggleSelectionModeAction, &QAction::toggled, toggleSelectionModeToolBarAction, &QAction::setChecked);
+
+ 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 "
+ "items 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);
+
+ QMenu *toggleSelectionModeActionMenu = new QMenu(this);
+ toggleSelectionModeActionMenu->addAction(selectAllAction);
+ toggleSelectionModeActionMenu->addAction(invertSelection);
+ toggleSelectionModeToolBarAction->setMenu(toggleSelectionModeActionMenu);
+
+ // setup 'View' menu
+ // (note that most of it is set up in DolphinViewActionHandler)
+
+ Admin::WorkerIntegration::createActAsAdminAction(actionCollection(), this);
+
+ m_splitViewAction = actionCollection()->add<KActionMenu>(QStringLiteral("split_view"));
+ m_splitViewMenuAction = actionCollection()->addAction(QStringLiteral("split_view_menu"));
+
+ m_splitViewAction->setWhatsThis(xi18nc("@info:whatsthis split",
+ "<para>This presents "
+ "a second view side-by-side with the current view, so you can see "
+ "the contents of two folders at once and easily move items between "
+ "them.</para><para>The view that is not \"in focus\" will be dimmed. "
+ "</para>Click this button again to close one of the views."));
+ m_splitViewMenuAction->setWhatsThis(m_splitViewAction->whatsThis());
+
+ // only set it for the menu version
+ actionCollection()->setDefaultShortcut(m_splitViewMenuAction, Qt::Key_F3);
+
+ connect(m_splitViewAction, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
+ connect(m_splitViewMenuAction, &QAction::triggered, this, &DolphinMainWindow::toggleSplitView);
+
+ QAction *popoutSplit = actionCollection()->addAction(QStringLiteral("popout_split_view"));
+ popoutSplit->setWhatsThis(xi18nc("@info:whatsthis",
+ "If the view has been split, this will pop the view in focus "
+ "out into a new window."));
+ popoutSplit->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
+ actionCollection()->setDefaultShortcut(popoutSplit, Qt::SHIFT | Qt::Key_F3);
+ connect(popoutSplit, &QAction::triggered, this, &DolphinMainWindow::popoutSplitView);
+
+ 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);
+ QDBusConnectionInterface *sessionInterface = QDBusConnection::sessionBus().interface();
+ stashSplit->setVisible(sessionInterface && sessionInterface->isServiceRegistered(QStringLiteral("org.kde.kio.StashNotifier")));
+ connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
+
+ QAction *redisplay = KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
+ redisplay->setToolTip(i18nc("@info:tooltip", "Refresh view"));
+ redisplay->setWhatsThis(xi18nc("@info:whatsthis refresh",
+ "<para>This refreshes "
+ "the folder view.</para>"
+ "<para>If the contents of this folder have changed, refreshing will re-scan this folder "
+ "and show you a newly-updated view of the files and folders contained here.</para>"
+ "<para>If the view is split, this refreshes the one that is currently in focus.</para>"));
+
+ 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()->setDefaultShortcuts(replaceLocation, {Qt::CTRL | Qt::Key_L, Qt::ALT | Qt::Key_D});
+ 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->setPopupMode(KToolBarPopupAction::DelayedPopup);
+ connect(m_backAction, &QAction::triggered, this, &DolphinMainWindow::goBack);
+ connect(m_backAction->popupMenu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
+ connect(m_backAction->popupMenu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
+ actionCollection()->addAction(m_backAction->objectName(), m_backAction);
+
+ auto backShortcuts = m_backAction->shortcuts();
+ // 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);
+ 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</interface>, <interface>renaming</interface> "
+ "and <interface>moving</interface> them to a different location "
+ "or to the <filename>Trash</filename>. <nl/>Any changes that cannot be undone "
+ "will ask for your confirmation beforehand."));
+ 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->setPopupMode(KToolBarPopupAction::DelayedPopup);
+ connect(m_forwardAction, &QAction::triggered, this, &DolphinMainWindow::goForward);
+ connect(m_forwardAction->popupMenu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
+ connect(m_forwardAction->popupMenu(), &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->popupMenu()->installEventFilter(middleClickEventFilter);
+ m_forwardAction->popupMenu()->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 personal files, "
+ "as well as hidden folders for their applications' data and configuration files."));
+
+ // 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"))) {
+ // Get icon of user default terminal emulator application
+ const KConfigGroup group(KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig), QStringLiteral("General"));
+ const QString terminalDesktopFilename = group.readEntry("TerminalService");
+ // Use utilities-terminal icon from theme if readEntry() has failed
+ const QString terminalIcon = terminalDesktopFilename.isEmpty() ? "utilities-terminal" : KDesktopFile(terminalDesktopFilename).readIcon();
+
+ 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 features in the terminal application.</para>"));
+ openTerminal->setIcon(QIcon::fromTheme(terminalIcon));
+ 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 features in the terminal application.</para>"));
+ openTerminalHere->setIcon(QIcon::fromTheme(terminalIcon));
+ actionCollection()->setDefaultShortcut(openTerminalHere, Qt::SHIFT | Qt::ALT | Qt::Key_F4);
+ connect(openTerminalHere, &QAction::triggered, this, &DolphinMainWindow::openTerminalHere);
+ }
+
+ // 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->setPopupMode(QToolButton::InstantPopup);
+ 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",
+ "<para>This switches between having a <emphasis>Menubar</emphasis> "
+ "and having an <interface>%1</interface> button. Both "
+ "contain mostly the same actions and configuration options.</para>"
+ "<para>The Menubar takes up more space but allows for fast and organized access to all "
+ "actions an application has to offer.</para><para>The %1 button "
+ "is simpler and small which makes triggering advanced actions more time consuming.</para>",
+ hamburgerMenuAction->text().replace('&', "")));
+ connect(showMenuBar,
+ &KToggleAction::triggered, // Fixes #286822
+ this,
+ &DolphinMainWindow::toggleShowMenuBar,
+ Qt::QueuedConnection);
+
+ KStandardAction::keyBindings(this, &DolphinMainWindow::slotKeyBindings, actionCollection());
+ KStandardAction::preferences(this, &DolphinMainWindow::editSettings, actionCollection());
+
+ // 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", "Go to 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));
+ }
+ }
+
+ QAction *activateLastTab = actionCollection()->addAction(QStringLiteral("activate_last_tab"));
+ activateLastTab->setIconText(i18nc("@action:inmenu", "Last Tab"));
+ activateLastTab->setText(i18nc("@action:inmenu", "Go to Last Tab"));
+ activateLastTab->setEnabled(false);
+ connect(activateLastTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activateLastTab);
+ actionCollection()->setDefaultShortcut(activateLastTab, Qt::ALT | Qt::Key_0);
+
+ QAction *activateNextTab = actionCollection()->addAction(QStringLiteral("activate_next_tab"));
+ activateNextTab->setIconText(i18nc("@action:inmenu", "Next Tab"));
+ activateNextTab->setText(i18nc("@action:inmenu", "Go to Next Tab"));
+ activateNextTab->setEnabled(false);
+ connect(activateNextTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activateNextTab);
+ actionCollection()->setDefaultShortcuts(activateNextTab, nextTabKeys);
+
+ QAction *activatePrevTab = actionCollection()->addAction(QStringLiteral("activate_prev_tab"));
+ activatePrevTab->setIconText(i18nc("@action:inmenu", "Previous Tab"));
+ activatePrevTab->setText(i18nc("@action:inmenu", "Go to Previous Tab"));
+ activatePrevTab->setEnabled(false);
+ connect(activatePrevTab, &QAction::triggered, m_tabWidget, &DolphinTabWidget::activatePrevTab);
+ actionCollection()->setDefaultShortcuts(activatePrevTab, prevTabKeys);
+
+ // for context menu
+ QAction *showTarget = actionCollection()->addAction(QStringLiteral("show_target"));
+ showTarget->setText(i18nc("@action:inmenu", "Show Target"));
+ showTarget->setIcon(QIcon::fromTheme(QStringLiteral("document-open-folder")));
+ showTarget->setEnabled(false);
+ connect(showTarget, &QAction::triggered, this, &DolphinMainWindow::showTarget);
+
+ QAction *openInNewTab = actionCollection()->addAction(QStringLiteral("open_in_new_tab"));
+ openInNewTab->setText(i18nc("@action:inmenu", "Open in New Tab"));
+ openInNewTab->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
+ connect(openInNewTab, &QAction::triggered, this, &DolphinMainWindow::openInNewTab);
+
+ QAction *openInNewTabs = actionCollection()->addAction(QStringLiteral("open_in_new_tabs"));
+ openInNewTabs->setText(i18nc("@action:inmenu", "Open in New Tabs"));
+ openInNewTabs->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
+ connect(openInNewTabs, &QAction::triggered, this, &DolphinMainWindow::openInNewTab);
+
+ QAction *openInNewWindow = actionCollection()->addAction(QStringLiteral("open_in_new_window"));
+ openInNewWindow->setText(i18nc("@action:inmenu", "Open in New Window"));
+ openInNewWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
+ connect(openInNewWindow, &QAction::triggered, this, &DolphinMainWindow::openInNewWindow);
+
+ QAction *openInSplitViewAction = actionCollection()->addAction(QStringLiteral("open_in_split_view"));
+ openInSplitViewAction->setText(i18nc("@action:inmenu", "Open in Split View"));
+ openInSplitViewAction->setIcon(QIcon::fromTheme(QStringLiteral("view-split-left-right")));
+ connect(openInSplitViewAction, &QAction::triggered, this, [this]() {
+ openInSplitView(QUrl());
+ });
+
+ m_recentFiles = new KRecentFilesAction(this);
+}
+
+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")));
+ lockLayoutAction->setInactiveText(i18nc("@action:inmenu Panels", "Lock Panels"));
+ lockLayoutAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("object-locked")));
+ lockLayoutAction->setWhatsThis(xi18nc("@info:whatsthis",
+ "This "
+ "switches between having panels <emphasis>locked</emphasis> or "
+ "<emphasis>unlocked</emphasis>.<nl/>Unlocked panels can be "
+ "dragged to the other side of the window and have a close "
+ "button.<nl/>Locked panels are embedded more cleanly."));
+ lockLayoutAction->setActive(lock);
+ connect(lockLayoutAction, &KDualAction::triggered, this, &DolphinMainWindow::togglePanelLockState);
+
+ // Setup "Information"
+ DolphinDockWidget *infoDock = new DolphinDockWidget(i18nc("@title:window", "Information"));
+ infoDock->setLocked(lock);
+ infoDock->setObjectName(QStringLiteral("infoDock"));
+ infoDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+
+#if HAVE_BALOO
+ InformationPanel *infoPanel = new InformationPanel(infoDock);
+ infoPanel->setCustomContextMenuActions({lockLayoutAction});
+ connect(infoPanel, &InformationPanel::urlActivated, this, &DolphinMainWindow::handleUrl);
+ infoDock->setWidget(infoPanel);
+
+ createPanelAction(QIcon::fromTheme(QStringLiteral("documentinfo")), Qt::Key_F11, infoDock, QStringLiteral("show_information_panel"));
+
+ addDockWidget(Qt::RightDockWidgetArea, infoDock);
+ connect(this, &DolphinMainWindow::urlChanged, infoPanel, &InformationPanel::setUrl);
+ connect(this, &DolphinMainWindow::selectionChanged, infoPanel, &InformationPanel::setSelection);
+ connect(this, &DolphinMainWindow::requestItemInfo, infoPanel, &InformationPanel::requestDelayedItemInfo);
+ connect(this, &DolphinMainWindow::fileItemsChanged, infoPanel, &InformationPanel::slotFilesItemChanged);
+ connect(this, &DolphinMainWindow::settingsChanged, infoPanel, &InformationPanel::readSettings);
+#endif
+
+ // i18n: This is the last paragraph for the "What's This"-texts of all four panels.
+ const QString panelWhatsThis = xi18nc("@info:whatsthis",
+ "<para>To show or "
+ "hide panels like this go to <interface>Menu|Panels</interface> "
+ "or <interface>View|Panels</interface>.</para>");
+#if HAVE_BALOO
+ actionCollection()
+ ->action(QStringLiteral("show_information_panel"))
+ ->setWhatsThis(xi18nc("@info:whatsthis",
+ "<para> This toggles the "
+ "<emphasis>information</emphasis> panel at the right side of the "
+ "window.</para><para>The panel provides in-depth information "
+ "about the items your mouse is hovering over or about the selected "
+ "items. Otherwise it informs you about the currently viewed folder.<nl/>"
+ "For single items a preview of their contents is provided.</para>"));
+#endif
+ infoDock->setWhatsThis(xi18nc("@info:whatsthis",
+ "<para>This panel "
+ "provides in-depth information about the items your mouse is "
+ "hovering over or about the selected items. Otherwise it informs "
+ "you about the currently viewed folder.<nl/>For single items a "
+ "preview of their contents is provided.</para><para>You can configure "
+ "which and how details are given here by right-clicking.</para>")
+ + panelWhatsThis);
+
+ // Setup "Folders"
+ DolphinDockWidget *foldersDock = new DolphinDockWidget(i18nc("@title:window", "Folders"));
+ foldersDock->setLocked(lock);
+ foldersDock->setObjectName(QStringLiteral("foldersDock"));
+ foldersDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+ FoldersPanel *foldersPanel = new FoldersPanel(foldersDock);
+ foldersPanel->setCustomContextMenuActions({lockLayoutAction});
+ foldersDock->setWidget(foldersPanel);
+
+ createPanelAction(QIcon::fromTheme(QStringLiteral("folder")), Qt::Key_F7, foldersDock, QStringLiteral("show_folders_panel"));
+
+ addDockWidget(Qt::LeftDockWidgetArea, foldersDock);
+ connect(this, &DolphinMainWindow::urlChanged, foldersPanel, &FoldersPanel::setUrl);
+ connect(foldersPanel, &FoldersPanel::folderActivated, this, &DolphinMainWindow::changeUrl);
+ connect(foldersPanel, &FoldersPanel::folderInNewTab, this, &DolphinMainWindow::openNewTab);
+ connect(foldersPanel, &FoldersPanel::folderInNewActiveTab, this, &DolphinMainWindow::openNewTabAndActivate);
+ connect(foldersPanel, &FoldersPanel::errorMessage, this, &DolphinMainWindow::showErrorMessage);
+
+ actionCollection()
+ ->action(QStringLiteral("show_folders_panel"))
+ ->setWhatsThis(xi18nc("@info:whatsthis",
+ "This toggles the "
+ "<emphasis>folders</emphasis> panel at the left side of the window."
+ "<nl/><nl/>It shows the folders of the <emphasis>file system"
+ "</emphasis> in a <emphasis>tree view</emphasis>."));
+ foldersDock->setWhatsThis(xi18nc("@info:whatsthis",
+ "<para>This panel "
+ "shows the folders of the <emphasis>file system</emphasis> in a "
+ "<emphasis>tree view</emphasis>.</para><para>Click a folder to go "
+ "there. Click the arrow to the left of a folder to see its subfolders. "
+ "This allows quick switching between any folders.</para>")
+ + panelWhatsThis);
+
+ // Setup "Terminal"
+#if HAVE_TERMINAL
+ if (KAuthorized::authorize(QStringLiteral("shell_access"))) {
+ DolphinDockWidget *terminalDock = new DolphinDockWidget(i18nc("@title:window Shell terminal", "Terminal"));
+ terminalDock->setLocked(lock);
+ terminalDock->setObjectName(QStringLiteral("terminalDock"));
+ terminalDock->setContentsMargins(0, 0, 0, 0);
+ m_terminalPanel = new TerminalPanel(terminalDock);
+ m_terminalPanel->setCustomContextMenuActions({lockLayoutAction});
+ terminalDock->setWidget(m_terminalPanel);
+
+ connect(m_terminalPanel, &TerminalPanel::hideTerminalPanel, terminalDock, &DolphinDockWidget::hide);
+ connect(m_terminalPanel, &TerminalPanel::changeUrl, this, &DolphinMainWindow::slotTerminalDirectoryChanged);
+ connect(terminalDock, &DolphinDockWidget::visibilityChanged, m_terminalPanel, &TerminalPanel::dockVisibilityChanged);
+ connect(terminalDock, &DolphinDockWidget::visibilityChanged, this, &DolphinMainWindow::slotTerminalPanelVisibilityChanged);
+
+ createPanelAction(QIcon::fromTheme(QStringLiteral("dialog-scripts")), Qt::Key_F4, terminalDock, QStringLiteral("show_terminal_panel"));
+
+ addDockWidget(Qt::BottomDockWidgetArea, terminalDock);
+ connect(this, &DolphinMainWindow::urlChanged, m_terminalPanel, &TerminalPanel::setUrl);
+
+ if (GeneralSettings::version() < 200) {
+ terminalDock->hide();