#include <KActionCollection>
#include <KFileItemActions>
#include <KFileItemListProperties>
+#include <KHamburgerMenu>
#include <KIO/EmptyTrashJob>
#include <KIO/JobUiDelegate>
#include <KIO/Paste>
m_selectedItems = view->selectedItems();
installEventFilter(this);
+
+ static_cast<KHamburgerMenu *>(m_mainWindow->actionCollection()->
+ action(QStringLiteral("hamburger_menu")))->addToMenu(this);
}
DolphinContextMenu::~DolphinContextMenu()
QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties"));
addAction(propertiesAction);
- addShowMenuBarAction();
-
if (exec(m_pos) == emptyTrashAction) {
Trash::empty(m_mainWindow);
}
QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties"));
addAction(propertiesAction);
- addShowMenuBarAction();
-
exec(m_pos);
}
}
}
-void DolphinContextMenu::addShowMenuBarAction()
-{
- const KActionCollection* ac = m_mainWindow->actionCollection();
- QAction* showMenuBar = ac->action(KStandardAction::name(KStandardAction::ShowMenubar));
- if (!m_mainWindow->menuBar()->isVisible() && !m_mainWindow->toolBar()->isVisible()) {
- addSeparator();
- addAction(showMenuBar);
- }
-}
-
bool DolphinContextMenu::placeExists(const QUrl& url) const
{
const KFilePlacesModel* placesModel = DolphinPlacesModelSingleton::instance().placesModel();
auto hamburgerMenu = static_cast<KHamburgerMenu *>(actionCollection()->action(
KStandardAction::name(KStandardAction::HamburgerMenu)));
hamburgerMenu->setMenuBar(menuBar());
- hamburgerMenu->setMenuBarAdvertised(false); // This line will soon be removed when the
- // hamburger menu contents are re-arranged.
+ hamburgerMenu->setShowMenuBarAction(showMenuBarAction);
connect(hamburgerMenu, &KHamburgerMenu::aboutToShowMenu,
this, &DolphinMainWindow::updateHamburgerMenu);
hamburgerMenu->hideActionsOf(toolBar());
if (!menu) {
menu = new QMenu(this);
hamburgerMenu->setMenu(menu);
+ hamburgerMenu->hideActionsOf(ac->action(QStringLiteral("basic_actions"))->menu());
+ hamburgerMenu->hideActionsOf(ac->action(QStringLiteral("zoom"))->menu());
} else {
menu->clear();
}
+ const QList<QAction *> toolbarActions = toolBar()->actions();
- menu->addMenu(m_newFileMenu->menu());
- menu->addAction(ac->action(QStringLiteral("file_new")));
- menu->addAction(ac->action(QStringLiteral("new_tab")));
- menu->addAction(ac->action(QStringLiteral("closed_tabs")));
-
- menu->addSeparator();
-
- // Add "Edit" actions
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::Undo)));
- menu->addAction(ac->action(QString("copy_location")));
- menu->addAction(ac->action(QStringLiteral("copy_to_inactive_split_view")));
- menu->addAction(ac->action(QStringLiteral("move_to_inactive_split_view")));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::SelectAll)));
- menu->addAction(ac->action(QStringLiteral("invert_selection")));
-
- menu->addSeparator();
-
- // Add "View" actions
- if (!GeneralSettings::showZoomSlider()) {
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomIn)));
- menu->addAction(ac->action(QStringLiteral("view_zoom_reset")));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomOut)));
+ if (!toolBar()->isVisible()) {
+ // If neither the menu bar nor the toolbar are visible, these actions should be available.
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)));
+ menu->addAction(toolBarMenuAction());
menu->addSeparator();
}
- menu->addAction(ac->action(QStringLiteral("show_preview")));
- menu->addAction(ac->action(QStringLiteral("show_in_groups")));
- menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
- menu->addAction(ac->action(QStringLiteral("additional_info")));
- menu->addAction(ac->action(QStringLiteral("view_properties")));
+ // This group of actions (until the next separator) contains all the most basic actions
+ // necessary to use Dolphin effectively.
+ menu->addAction(ac->action(QStringLiteral("go_back")));
+ menu->addAction(ac->action(QStringLiteral("go_forward")));
+ menu->addMenu(m_newFileMenu->menu());
+ menu->addAction(ac->action(QStringLiteral("basic_actions")));
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::Undo)));
+ if (!toolBar()->isVisible()
+ || (!toolbarActions.contains(ac->action(QStringLiteral("toggle_search")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("open_preferred_search_tool"))))
+ ) {
+ menu->addAction(ac->action(KStandardAction::name(KStandardAction::Find)));
+ // This way a search action will only be added if none of the three available
+ // search actions is present on the toolbar.
+ }
+ if (!toolBar()->isVisible()
+ || !toolbarActions.contains(ac->action(QStringLiteral("toggle_filter")))
+ ) {
+ menu->addAction(ac->action(QStringLiteral("show_filter_bar")));
+ // This way a filter action will only be added if none of the two available
+ // filter actions is present on the toolbar.
+ }
menu->addSeparator();
- // Add a curated assortment of items from the "Tools" menu
- menu->addAction(ac->action(QStringLiteral("show_filter_bar")));
- menu->addAction(ac->action(QStringLiteral("open_preferred_search_tool")));
+ // The second group of actions (up until the next separator) contains actions for opening
+ // additional views to interact with the file system.
+ menu->addAction(ac->action(QStringLiteral("file_new")));
+ menu->addAction(ac->action(QStringLiteral("new_tab")));
+ if (ac->action(QStringLiteral("undo_close_tab"))->isEnabled()) {
+ menu->addAction(ac->action(QStringLiteral("closed_tabs")));
+ }
menu->addAction(ac->action(QStringLiteral("open_terminal")));
-
menu->addSeparator();
- // Add "Show Panels" menu
+ // The third group contains actions to change what one sees in the view
+ // and to change the more general UI.
+ if (!toolBar()->isVisible()
+ || (!toolbarActions.contains(ac->action(QStringLiteral("icons")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("compact")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("details")))
+ && !toolbarActions.contains(ac->action(QStringLiteral("view_mode"))))
+ ) {
+ menu->addAction(ac->action(QStringLiteral("view_mode")));
+ }
+ menu->addAction(ac->action(QStringLiteral("show_hidden_files")));
+ menu->addAction(ac->action(QStringLiteral("additional_info")));
+ if (!GeneralSettings::showStatusBar() || !GeneralSettings::showZoomSlider()) {
+ menu->addAction(ac->action(QStringLiteral("zoom")));
+ }
menu->addAction(ac->action(QStringLiteral("panels")));
- // Add "Settings" menu entries
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::KeyBindings)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::Preferences)));
- menu->addAction(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)));
+ // The "Configure" menu is not added to the actionCollection() because there is hardly
+ // a good reason for users to put it on their toolbar.
+ auto configureMenu = menu->addMenu(QIcon::fromTheme(QStringLiteral("configure")),
+ i18nc("@action:inmenu menu for configure actions", "Configure"));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::SwitchApplicationLanguage)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::KeyBindings)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)));
+ configureMenu->addAction(ac->action(KStandardAction::name(KStandardAction::Preferences)));
+ hamburgerMenu->hideActionsOf(configureMenu);
}
void DolphinMainWindow::slotPlaceActivated(const QUrl& url)
/**
* Updates the menu that is by default at the right end of the toolbar.
+ *
+ * In true "simple by default" fashion, the menu only contains the most important
+ * and necessary actions to be able to use Dolphin. This is supposed to hold true even
+ * if the user does not know how to open a context menu. More advanced actions can be
+ * discovered through a sub-menu (@see KConfigWidgets::KHamburgerMenu::setMenuBarAdvertised()).
*/
void updateHamburgerMenu();
#endif
#include <KActionCollection>
#include <KActionMenu>
+#include <KFileItemListProperties>
#include <KLocalizedString>
#include <KNewFileMenu>
#include <KPropertiesDialog>
this, &DolphinViewActionHandler::slotZoomLevelChanged);
connect(view, &DolphinView::writeStateChanged,
this, &DolphinViewActionHandler::slotWriteStateChanged);
+ connect(view, &DolphinView::selectionChanged,
+ this, &DolphinViewActionHandler::slotSelectionChanged);
+ slotSelectionChanged(m_currentView->selectedItems());
}
DolphinView* DolphinViewActionHandler::currentView()
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();
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"));
{
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
+ auto basicActionsMenuActions = basicActionsMenu->menu()->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")));
+ }
+ }
+}
class QActionGroup;
class DolphinView;
class KActionCollection;
+class KFileItemList;
/**
* @short Handles all actions for DolphinView
*/
void slotCopyPath();
+ /**
+ * Changes the name of the menu that contains basic actions like "Copy", "Rename", ...
+ * The name is changed to something like "Actions for 3 Selected Items" to be extra
+ * explicit of how these basic actions are used.
+ */
+ void slotSelectionChanged(const KFileItemList& selection);
+
private:
/**
* Create all the actions.