diff --git a/CMakeLists.txt b/CMakeLists.txt index 4336205fc3..11ab06ddaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ set (RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE project(Dolphin VERSION ${RELEASE_SERVICE_VERSION}) set(QT_MIN_VERSION "5.14.0") -set(KF5_MIN_VERSION "5.77.0") +set(KF5_MIN_VERSION "5.81.0") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index f14849e6d4..80c6aa320e 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -63,12 +63,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -82,7 +84,7 @@ namespace { // Used for GeneralSettings::version() to determine whether // an updated version of Dolphin is running. - const int CurrentDolphinVersion = 200; + const int CurrentDolphinVersion = 201; // The maximum number of entries in the back/forward popup menu const int MaxNumberOfNavigationentries = 12; // The maximum number of "Activate Tab" shortcuts @@ -183,8 +185,17 @@ DolphinMainWindow::DolphinMainWindow() : const bool showMenu = !menuBar()->isHidden(); QAction* showMenuBarAction = actionCollection()->action(KStandardAction::name(KStandardAction::ShowMenubar)); showMenuBarAction->setChecked(showMenu); // workaround for bug #171080 - if (!showMenu) { - createControlButton(); + + auto hamburgerMenu = static_cast(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. + connect(hamburgerMenu, &KHamburgerMenu::aboutToShowMenu, + this, &DolphinMainWindow::updateHamburgerMenu); + hamburgerMenu->hideActionsOf(toolBar()); + if (GeneralSettings::version() < 201 && !toolBar()->actions().contains(hamburgerMenu)) { + addHamburgerMenuToToolbar(); } updateAllowedToolbarAreas(); @@ -979,11 +990,6 @@ void DolphinMainWindow::toggleShowMenuBar() { const bool visible = menuBar()->isVisible(); menuBar()->setVisible(!visible); - if (visible) { - createControlButton(); - } else { - deleteControlButton(); - } } QPointer DolphinMainWindow::preferredSearchTool() @@ -1150,87 +1156,67 @@ void DolphinMainWindow::openContextMenu(const QPoint& pos, } } -void DolphinMainWindow::updateControlMenu() +void DolphinMainWindow::updateHamburgerMenu() { - QMenu* menu = qobject_cast(sender()); - Q_ASSERT(menu); - - // All actions get cleared by QMenu::clear(). This includes the sub-menus - // because 'menu' is their parent. - menu->clear(); - KActionCollection* ac = actionCollection(); + auto hamburgerMenu = static_cast( + ac->action(KStandardAction::name(KStandardAction::HamburgerMenu))); + auto menu = hamburgerMenu->menu(); + if (!menu) { + menu = new QMenu(this); + hamburgerMenu->setMenu(menu); + } else { + menu->clear(); + } menu->addMenu(m_newFileMenu->menu()); - addActionToMenu(ac->action(QStringLiteral("file_new")), menu); - addActionToMenu(ac->action(QStringLiteral("new_tab")), menu); - addActionToMenu(ac->action(QStringLiteral("closed_tabs")), 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 - bool added = addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Undo)), menu) | - addActionToMenu(ac->action(QString("copy_location")), menu) | - addActionToMenu(ac->action(QStringLiteral("copy_to_inactive_split_view")), menu) | - addActionToMenu(ac->action(QStringLiteral("move_to_inactive_split_view")), menu) | - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::SelectAll)), menu) | - addActionToMenu(ac->action(QStringLiteral("invert_selection")), menu); + 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"))); - if (added) { - menu->addSeparator(); - } + menu->addSeparator(); // Add "View" actions if (!GeneralSettings::showZoomSlider()) { - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ZoomIn)), menu); - addActionToMenu(ac->action(QStringLiteral("view_zoom_reset")), menu); - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ZoomOut)), menu); + menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomIn))); + menu->addAction(ac->action(QStringLiteral("view_zoom_reset"))); + menu->addAction(ac->action(KStandardAction::name(KStandardAction::ZoomOut))); menu->addSeparator(); } - added = addActionToMenu(ac->action(QStringLiteral("show_preview")), menu) | - addActionToMenu(ac->action(QStringLiteral("show_in_groups")), menu) | - addActionToMenu(ac->action(QStringLiteral("show_hidden_files")), menu) | - addActionToMenu(ac->action(QStringLiteral("additional_info")), menu) | - addActionToMenu(ac->action(QStringLiteral("view_properties")), menu); + 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"))); - if (added) { - menu->addSeparator(); - } + menu->addSeparator(); // Add a curated assortment of items from the "Tools" menu - addActionToMenu(ac->action(QStringLiteral("show_filter_bar")), menu); - addActionToMenu(ac->action(QStringLiteral("open_preferred_search_tool")), menu); - addActionToMenu(ac->action(QStringLiteral("open_terminal")), menu); + menu->addAction(ac->action(QStringLiteral("show_filter_bar"))); + menu->addAction(ac->action(QStringLiteral("open_preferred_search_tool"))); + menu->addAction(ac->action(QStringLiteral("open_terminal"))); menu->addSeparator(); // Add "Show Panels" menu - addActionToMenu(ac->action(QStringLiteral("panels")), menu); + menu->addAction(ac->action(QStringLiteral("panels"))); // Add "Settings" menu entries - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::KeyBindings)), menu); - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ConfigureToolbars)), menu); - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::Preferences)), menu); - addActionToMenu(ac->action(KStandardAction::name(KStandardAction::ShowMenubar)), menu); - - // Add "Help" menu - auto helpMenu = m_helpMenu->menu(); - helpMenu->setIcon(QIcon::fromTheme(QStringLiteral("system-help"))); - menu->addMenu(helpMenu); -} - -void DolphinMainWindow::updateToolBar() -{ - if (!menuBar()->isVisible()) { - createControlButton(); - } -} - -void DolphinMainWindow::slotControlButtonDeleted() -{ - m_controlButton = nullptr; - m_updateToolBarTimer->start(); + 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))); } void DolphinMainWindow::slotPlaceActivated(const QUrl& url) @@ -1354,6 +1340,8 @@ void DolphinMainWindow::setViewsToHomeIfMountPathOpen(const QString& mountPath) void DolphinMainWindow::setupActions() { + KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection()); + // setup 'File' menu m_newFileMenu = new DolphinNewFileMenu(actionCollection(), this); QMenu* menu = m_newFileMenu->menu(); @@ -2077,65 +2065,6 @@ void DolphinMainWindow::updateGoActions() goUpAction->setEnabled(KIO::upUrl(currentUrl) != currentUrl); } -void DolphinMainWindow::createControlButton() -{ - if (m_controlButton) { - return; - } - Q_ASSERT(!m_controlButton); - - m_controlButton = new QToolButton(this); - m_controlButton->setAccessibleName(i18nc("@action:intoolbar", "Control")); - m_controlButton->setIcon(QIcon::fromTheme(QStringLiteral("application-menu"))); - m_controlButton->setToolTip(i18nc("@action", "Show menu")); - m_controlButton->setAttribute(Qt::WidgetAttribute::WA_CustomWhatsThis); - m_controlButton->setPopupMode(QToolButton::InstantPopup); - - QMenu* controlMenu = new QMenu(m_controlButton); - connect(controlMenu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateControlMenu); - controlMenu->installEventFilter(this); - - m_controlButton->setMenu(controlMenu); - - toolBar()->addWidget(m_controlButton); - connect(toolBar(), &KToolBar::iconSizeChanged, - m_controlButton, &QToolButton::setIconSize); - - // The added widgets are owned by the toolbar and may get deleted when e.g. the toolbar - // gets edited. In this case we must add them again. The adding is done asynchronously by - // m_updateToolBarTimer. - connect(m_controlButton, &QToolButton::destroyed, this, &DolphinMainWindow::slotControlButtonDeleted); - m_updateToolBarTimer = new QTimer(this); - m_updateToolBarTimer->setInterval(500); - connect(m_updateToolBarTimer, &QTimer::timeout, this, &DolphinMainWindow::updateToolBar); -} - -void DolphinMainWindow::deleteControlButton() -{ - delete m_controlButton; - m_controlButton = nullptr; - - delete m_updateToolBarTimer; - m_updateToolBarTimer = nullptr; -} - -bool DolphinMainWindow::addActionToMenu(QAction* action, QMenu* menu) -{ - Q_ASSERT(action); - Q_ASSERT(menu); - - const KToolBar* toolBarWidget = toolBar(); - const auto associatedWidgets = action->associatedWidgets(); - for (const QWidget* widget : associatedWidgets) { - if (widget == toolBarWidget) { - return false; - } - } - - menu->addAction(action); - return true; -} - void DolphinMainWindow::refreshViews() { m_tabWidget->refreshViews(); @@ -2437,6 +2366,29 @@ void DolphinMainWindow::setupWhatsThis() m_helpMenu->action(KHelpMenu::menuAboutKDE)->setWhatsThis(whatsThisAboutKDE); } +bool DolphinMainWindow::addHamburgerMenuToToolbar() +{ + QDomDocument domDocument = KXMLGUIClient::domDocument(); + if (domDocument.isNull()) { + return false; + } + QDomNode toolbar = domDocument.elementsByTagName(QStringLiteral("ToolBar")).at(0); + if (toolbar.isNull()) { + return false; + } + + QDomElement hamburgerMenuElement = domDocument.createElement(QStringLiteral("Action")); + hamburgerMenuElement.setAttribute(QStringLiteral("name"), QStringLiteral("hamburger_menu")); + toolbar.appendChild(hamburgerMenuElement); + + KXMLGUIFactory::saveConfigFile(domDocument, xmlFile()); + reloadXML(); + createGUI(); + return true; + // Make sure to also remove the and include + // whenever this method is removed (maybe in the year ~2026). +} + bool DolphinMainWindow::event(QEvent *event) { if (event->type() == QEvent::WhatsThisClicked) { @@ -2471,6 +2423,8 @@ void DolphinMainWindow::saveNewToolbarConfig() m_tabWidget->currentTabPage()->insertNavigatorsWidget(navigators); } updateAllowedToolbarAreas(); + (static_cast(actionCollection()->action(KStandardAction::name( + KStandardAction::HamburgerMenu))))->hideActionsOf(toolBar()); } void DolphinMainWindow::focusTerminalPanel() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index f351cc992f..40101852ba 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -468,9 +468,10 @@ private Q_SLOTS: const QUrl& url, const QList& customActions); - void updateControlMenu(); - void updateToolBar(); - void slotControlButtonDeleted(); + /** + * Updates the menu that is by default at the right end of the toolbar. + */ + void updateHamburgerMenu(); /** * Is called if the user clicked an item in the Places Panel. @@ -575,16 +576,6 @@ private: void updateViewActions(); void updateGoActions(); - void createControlButton(); - void deleteControlButton(); - - /** - * Adds the action \p action to the menu \p menu in - * case if it has not added already to the toolbar. - * @return True if the action has been added to the menu. - */ - bool addActionToMenu(QAction* action, QMenu* menu); - /** * Connects the signals from the created DolphinView with * the DolphinViewContainer \a container with the corresponding slots of @@ -625,6 +616,16 @@ private: /** Returns preferred search tool as configured in "More Search Tools" menu. */ QPointer preferredSearchTool(); + /** + * Adds this action to the mainWindow's toolbar and saves the change + * in the users ui configuration file. + * This method is only needed for migration and should be removed once we can expect + * that pretty much all users have been migrated. Remove in 2026 because that's when + * even the most risk-averse distros will already have been forced to upgrade. + * @return true if successful. Otherwise false. + */ + bool addHamburgerMenuToToolbar(); + private: /** * Implements a custom error handling for the undo manager. This diff --git a/src/dolphinui.rc b/src/dolphinui.rc index e749abae09..ac7f301b83 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -1,6 +1,6 @@ - + @@ -125,6 +125,7 @@ +