diff options
Diffstat (limited to 'src')
59 files changed, 849 insertions, 400 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f3ecfff2..46dbaa152 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,11 +21,12 @@ remove_definitions( ########################################## -set(dolphinvcs_LIB_SRCS +add_library(dolphinvcs SHARED) + +target_sources(dolphinvcs PRIVATE views/versioncontrol/kversioncontrolplugin.cpp ) -add_library(dolphinvcs ${dolphinvcs_LIB_SRCS}) generate_export_header(dolphinvcs BASE_NAME dolphinvcs) target_link_libraries( @@ -34,7 +35,7 @@ target_link_libraries( ) set_target_properties(dolphinvcs PROPERTIES - VERSION ${DOLPHINVCS_VERSION_STRING} + VERSION ${DOLPHINVCS_VERSION} SOVERSION ${DOLPHINVCS_SOVERSION} EXPORT_NAME DolphinVcs ) @@ -55,7 +56,9 @@ install(FILES ${dolphinvcs_LIB_HEADERS} DESTINATION "${KDE_INSTALL_INCLUDEDIR}/D ########### next target ############### -set(dolphinprivate_LIB_SRCS +add_library(dolphinprivate SHARED) + +target_sources(dolphinprivate PRIVATE kitemviews/kfileitemlistview.cpp kitemviews/kfileitemlistwidget.cpp kitemviews/kfileitemmodel.cpp @@ -114,19 +117,23 @@ set(dolphinprivate_LIB_SRCS dolphinnewfilemenu.cpp ) -ecm_qt_declare_logging_category(dolphinprivate_LIB_SRCS HEADER dolphindebug.h IDENTIFIER DolphinDebug CATEGORY_NAME org.kde.dolphin - DESCRIPTION "dolphin" EXPORT DOLPHIN) +ecm_qt_declare_logging_category(dolphinprivate + HEADER dolphindebug.h + IDENTIFIER DolphinDebug + CATEGORY_NAME org.kde.dolphin + DESCRIPTION "dolphin" + EXPORT DOLPHIN +) if(HAVE_BALOO) - set(dolphinprivate_LIB_SRCS - ${dolphinprivate_LIB_SRCS} + target_sources(dolphinprivate PRIVATE views/tooltips/dolphinfilemetadatawidget.cpp views/tooltips/tooltipmanager.cpp kitemviews/private/kbaloorolesprovider.cpp ) endif() -kconfig_add_kcfg_files(dolphinprivate_LIB_SRCS GENERATE_MOC +kconfig_add_kcfg_files(dolphinprivate settings/dolphin_compactmodesettings.kcfgc settings/dolphin_directoryviewpropertysettings.kcfgc settings/dolphin_detailsmodesettings.kcfgc @@ -136,7 +143,6 @@ kconfig_add_kcfg_files(dolphinprivate_LIB_SRCS GENERATE_MOC settings/dolphin_versioncontrolsettings.kcfgc ) -add_library(dolphinprivate ${dolphinprivate_LIB_SRCS}) generate_export_header(dolphinprivate BASE_NAME dolphin) target_link_libraries( @@ -167,7 +173,7 @@ if(HAVE_BALOO) endif() set_target_properties(dolphinprivate PROPERTIES - VERSION ${DOLPHINPRIVATE_VERSION_STRING} + VERSION ${DOLPHINPRIVATE_VERSION} SOVERSION ${DOLPHINPRIVATE_SOVERSION} ) @@ -177,15 +183,16 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphin_export.h DESTINATION ${KDE_INS ########################################## configure_file(dolphinpart.desktop.in ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop @ONLY) -set(dolphinpart_SRCS - dolphinpart.cpp - dolphinpart_ext.cpp - dolphindebug.cpp -) +add_library(dolphinpart MODULE) -qt5_add_resources(dolphinpart_SRCS dolphinpart.qrc) +target_sources(dolphinpart PRIVATE + dolphinpart.cpp + dolphinpart_ext.cpp + dolphindebug.cpp + + dolphinpart.qrc +) -add_library(dolphinpart MODULE ${dolphinpart_SRCS}) kcoreaddons_desktop_to_json(dolphinpart ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop) target_link_libraries(dolphinpart @@ -198,7 +205,9 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dolphinpart.desktop DESTINATION ${KDE_ ########################################## -set(dolphinstatic_SRCS +add_library(dolphinstatic STATIC) + +target_sources(dolphinstatic PRIVATE dolphinbookmarkhandler.cpp dolphindockwidget.cpp dolphinmainwindow.cpp @@ -255,11 +264,11 @@ set(dolphinstatic_SRCS views/zoomlevelinfo.cpp dolphindebug.cpp global.cpp + dolphin.qrc ) if(HAVE_BALOO) - set(dolphinstatic_SRCS - ${dolphinstatic_SRCS} + target_sources(dolphinstatic PRIVATE panels/information/informationpanel.cpp panels/information/informationpanelcontent.cpp panels/information/pixmapviewer.cpp @@ -268,8 +277,7 @@ if(HAVE_BALOO) endif() if(HAVE_KUSERFEEDBACK) - set(dolphinstatic_SRCS - ${dolphinstatic_SRCS} + target_sources(dolphinstatic PRIVATE userfeedback/dolphinfeedbackprovider.cpp userfeedback/settingsdatasource.cpp userfeedback/placesdatasource.cpp @@ -277,27 +285,29 @@ if(HAVE_KUSERFEEDBACK) ) endif() -kconfig_add_kcfg_files(dolphinstatic_SRCS GENERATE_MOC +kconfig_add_kcfg_files(dolphinstatic panels/folders/dolphin_folderspanelsettings.kcfgc panels/information/dolphin_informationpanelsettings.kcfgc panels/places/dolphin_placespanelsettings.kcfgc settings/dolphin_compactmodesettings.kcfgc settings/dolphin_detailsmodesettings.kcfgc - settings/dolphin_generalsettings.kcfgc settings/dolphin_contextmenusettings.kcfgc settings/dolphin_iconsmodesettings.kcfgc search/dolphin_searchsettings.kcfgc settings/dolphin_versioncontrolsettings.kcfgc ) - -qt5_add_resources(dolphinstatic_SRCS dolphin.qrc) +kconfig_add_kcfg_files(dolphinstatic GENERATE_MOC + settings/dolphin_generalsettings.kcfgc +) qt5_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/dolphinmainwindow.h org.kde.DolphinMainWindow.xml) -qt5_add_dbus_adaptor(dolphinstatic_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindow.h DolphinMainWindow) -qt5_add_dbus_interface(dolphinstatic_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindowinterface) -qt5_add_dbus_interface(dolphinstatic_SRCS panels/terminal/org.kde.KIOFuse.VFS.xml kiofuse_interface) +qt5_add_dbus_adaptor(dolphin_dbus_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindow.h DolphinMainWindow) +qt5_add_dbus_interface(dolphin_dbus_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindowinterface) +qt5_add_dbus_interface(dolphin_dbus_SRCS panels/terminal/org.kde.KIOFuse.VFS.xml kiofuse_interface) -add_library(dolphinstatic STATIC ${dolphinstatic_SRCS}) +target_sources(dolphinstatic PRIVATE + ${dolphin_dbus_SRCS} +) target_include_directories(dolphinstatic SYSTEM PRIVATE ${PHONON_INCLUDES}) target_link_libraries(dolphinstatic @@ -324,21 +334,24 @@ if (HAVE_KUSERFEEDBACK) ) endif() -set(dolphin_SRCS +add_executable(dolphin) + +target_sources(dolphin PRIVATE dbusinterface.cpp main.cpp ) # Sets the icon on Windows and OSX file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*system-file-manager.png") -ecm_add_app_icon(dolphin_SRCS ICONS ${ICONS_SRCS}) - -kf5_add_kdeinit_executable(dolphin ${dolphin_SRCS}) - +ecm_add_app_icon(dolphin_APPICON_SRCS ICONS ${ICONS_SRCS}) +# ecm_add_app_icon 5.83 will take target as arg, use that once it is min req. +target_sources(dolphin PRIVATE + ${dolphin_APPICON_SRCS} +) -target_link_libraries(kdeinit_dolphin PUBLIC - dolphinprivate +target_link_libraries(dolphin PRIVATE + dolphinprivate dolphinstatic KF5::Crash ) @@ -346,60 +359,58 @@ target_link_libraries(kdeinit_dolphin PUBLIC include(DbusInterfaceMacros) generate_and_install_dbus_interface( - kdeinit_dolphin + dolphin dbusinterface.h org.freedesktop.FileManager1.xml OPTIONS -a ) -install(TARGETS kdeinit_dolphin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS dolphin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) ########################################## -set(kcm_dolphinviewmodes_PART_SRCS - settings/kcm/kcmdolphinviewmodes.cpp - settings/viewmodes/dolphinfontrequester.cpp - settings/viewmodes/viewmodesettings.cpp - settings/viewmodes/viewsettingstab.cpp - views/zoomlevelinfo.cpp) - -set(kcm_dolphinnavigation_PART_SRCS - settings/kcm/kcmdolphinnavigation.cpp - settings/navigation/navigationsettingspage.cpp - settings/settingspagebase.cpp) +if(NOT WIN32) + # The settings are still accessible from the hamburger menu + add_library(kcm_dolphinviewmodes MODULE) + add_library(kcm_dolphinnavigation MODULE) + add_library(kcm_dolphingeneral MODULE) -set(kcm_dolphingeneral_PART_SRCS - settings/kcm/kcmdolphingeneral.cpp - settings/general/behaviorsettingspage.cpp - settings/general/previewssettingspage.cpp - settings/general/configurepreviewplugindialog.cpp - settings/general/confirmationssettingspage.cpp - settings/settingspagebase.cpp - settings/serviceitemdelegate.cpp - settings/servicemodel.cpp) + target_sources(kcm_dolphinviewmodes PRIVATE + settings/kcm/kcmdolphinviewmodes.cpp + settings/viewmodes/dolphinfontrequester.cpp + settings/viewmodes/viewmodesettings.cpp + settings/viewmodes/viewsettingstab.cpp + views/zoomlevelinfo.cpp) -kconfig_add_kcfg_files(kcm_dolphinviewmodes_PART_SRCS - settings/dolphin_compactmodesettings.kcfgc - settings/dolphin_directoryviewpropertysettings.kcfgc - settings/dolphin_detailsmodesettings.kcfgc - settings/dolphin_iconsmodesettings.kcfgc - settings/dolphin_generalsettings.kcfgc - settings/dolphin_versioncontrolsettings.kcfgc -) + target_sources(kcm_dolphinnavigation PRIVATE + settings/kcm/kcmdolphinnavigation.cpp + settings/navigation/navigationsettingspage.cpp + settings/settingspagebase.cpp) -kconfig_add_kcfg_files(kcm_dolphinnavigation_PART_SRCS - settings/dolphin_generalsettings.kcfgc) + target_sources(kcm_dolphingeneral PRIVATE + settings/kcm/kcmdolphingeneral.cpp + settings/general/behaviorsettingspage.cpp + settings/general/previewssettingspage.cpp + settings/general/configurepreviewplugindialog.cpp + settings/general/confirmationssettingspage.cpp + settings/settingspagebase.cpp + settings/serviceitemdelegate.cpp + settings/servicemodel.cpp) -kconfig_add_kcfg_files(kcm_dolphingeneral_PART_SRCS - settings/dolphin_generalsettings.kcfgc) + kconfig_add_kcfg_files(kcm_dolphinviewmodes + settings/dolphin_compactmodesettings.kcfgc + settings/dolphin_directoryviewpropertysettings.kcfgc + settings/dolphin_detailsmodesettings.kcfgc + settings/dolphin_iconsmodesettings.kcfgc + settings/dolphin_generalsettings.kcfgc + settings/dolphin_versioncontrolsettings.kcfgc + ) + kconfig_add_kcfg_files(kcm_dolphinnavigation + settings/dolphin_generalsettings.kcfgc) -if(NOT WIN32) - # The settings are still accessible from the hamburger menu - add_library(kcm_dolphinviewmodes MODULE ${kcm_dolphinviewmodes_PART_SRCS}) - add_library(kcm_dolphinnavigation MODULE ${kcm_dolphinnavigation_PART_SRCS}) - add_library(kcm_dolphingeneral MODULE ${kcm_dolphingeneral_PART_SRCS}) + kconfig_add_kcfg_files(kcm_dolphingeneral + settings/dolphin_generalsettings.kcfgc) target_link_libraries(kcm_dolphinviewmodes dolphinprivate) target_link_libraries(kcm_dolphinnavigation dolphinprivate) diff --git a/src/dbusinterface.cpp b/src/dbusinterface.cpp index cf1ad53ad..7e453f72a 100644 --- a/src/dbusinterface.cpp +++ b/src/dbusinterface.cpp @@ -59,6 +59,18 @@ void DBusInterface::ShowItemProperties(const QStringList& uriList, const QString } } +void DBusInterface::SortOrderForUrl(const QString &url, QString &role, QString &order) +{ + QUrl qurl(url); + auto sort = Dolphin::sortOrderForUrl(qurl); + role = sort.first; + if (sort.second == Qt::AscendingOrder) { + order = QStringLiteral("ascending"); + } else { + order = QStringLiteral("descending"); + } +} + void DBusInterface::setAsDaemon() { m_isDaemon = true; diff --git a/src/dbusinterface.h b/src/dbusinterface.h index 9b183384d..66659e976 100644 --- a/src/dbusinterface.h +++ b/src/dbusinterface.h @@ -20,6 +20,8 @@ public: Q_SCRIPTABLE void ShowItems(const QStringList& uriList, const QString& startUpId); Q_SCRIPTABLE void ShowItemProperties(const QStringList& uriList, const QString& startUpId); + Q_SCRIPTABLE void SortOrderForUrl(const QString &url, QString &role, QString &order); + /** * Set whether this interface has been created by dolphin --daemon. */ diff --git a/src/dolphinbookmarkhandler.h b/src/dolphinbookmarkhandler.h index ac86f950c..a75090500 100644 --- a/src/dolphinbookmarkhandler.h +++ b/src/dolphinbookmarkhandler.h @@ -14,7 +14,6 @@ class DolphinMainWindow; class DolphinViewContainer; class KActionCollection; -class KBookmarkManager; class KBookmarkMenu; class QMenu; diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp index 2b216ce03..47f0cdd40 100644 --- a/src/dolphincontextmenu.cpp +++ b/src/dolphincontextmenu.cpp @@ -22,6 +22,7 @@ #include <KActionCollection> #include <KFileItemActions> #include <KFileItemListProperties> +#include <KHamburgerMenu> #include <KIO/EmptyTrashJob> #include <KIO/JobUiDelegate> #include <KIO/Paste> @@ -63,7 +64,10 @@ DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent, const DolphinView* view = m_mainWindow->activeViewContainer()->view(); m_selectedItems = view->selectedItems(); - QApplication::instance()->installEventFilter(this); + installEventFilter(this); + + static_cast<KHamburgerMenu *>(m_mainWindow->actionCollection()-> + action(QStringLiteral("hamburger_menu")))->addToMenu(this); } DolphinContextMenu::~DolphinContextMenu() @@ -144,8 +148,6 @@ void DolphinContextMenu::openTrashContextMenu() QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties")); addAction(propertiesAction); - addShowMenuBarAction(); - if (exec(m_pos) == emptyTrashAction) { Trash::empty(m_mainWindow); } @@ -204,7 +206,7 @@ void DolphinContextMenu::addDirectoryItemContextMenu(KFileItemActions &fileItemA QMenu* menu = newFileMenu->menu(); menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New")); - menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); + menu->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); addMenu(menu); addSeparator(); @@ -356,8 +358,6 @@ void DolphinContextMenu::openViewportContextMenu() QAction* propertiesAction = m_mainWindow->actionCollection()->action(QStringLiteral("properties")); addAction(propertiesAction); - addShowMenuBarAction(); - exec(m_pos); } @@ -418,16 +418,6 @@ void DolphinContextMenu::insertDefaultItemActions(const KFileItemListProperties& } } -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(); @@ -503,7 +493,7 @@ void DolphinContextMenu::addAdditionalActions(KFileItemActions &fileItemActions, addSeparator(); QList<QAction *> additionalActions; - if (props.isDirectory() && props.isLocal()) { + if (props.isDirectory() && props.isLocal() && ContextMenuSettings::showOpenTerminal()) { additionalActions << m_mainWindow->actionCollection()->action(QStringLiteral("open_terminal")); } fileItemActions.addActionsTo(this, KFileItemActions::MenuActionSource::All, additionalActions); diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 4297321fc..737856b23 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -24,7 +24,6 @@ #include "panels/folders/folderspanel.h" #include "panels/places/placesitemmodel.h" #include "panels/places/placespanel.h" -#include "panels/information/informationpanel.h" #include "panels/terminal/terminalpanel.h" #include "settings/dolphinsettingsdialog.h" #include "statusbar/dolphinstatusbar.h" @@ -64,12 +63,14 @@ #include <KUrlComboBox> #include <KUrlNavigator> #include <KWindowSystem> +#include <KXMLGUIFactory> #include <QApplication> #include <QClipboard> #include <QCloseEvent> #include <QDesktopServices> #include <QDialog> +#include <QDomDocument> #include <QFileInfo> #include <QLineEdit> #include <QMenuBar> @@ -83,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 @@ -177,15 +178,21 @@ DolphinMainWindow::DolphinMainWindow() : if (firstRun) { menuBar()->setVisible(false); - // Assure a proper default size if Dolphin runs the first time - resize(750, 500); } 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<KHamburgerMenu *>(actionCollection()->action( + KStandardAction::name(KStandardAction::HamburgerMenu))); + hamburgerMenu->setMenuBar(menuBar()); + hamburgerMenu->setShowMenuBarAction(showMenuBarAction); + connect(hamburgerMenu, &KHamburgerMenu::aboutToShowMenu, + this, &DolphinMainWindow::updateHamburgerMenu); + hamburgerMenu->hideActionsOf(toolBar()); + if (GeneralSettings::version() < 201 && !toolBar()->actions().contains(hamburgerMenu)) { + addHamburgerMenuToToolbar(); } updateAllowedToolbarAreas(); @@ -982,11 +989,6 @@ void DolphinMainWindow::toggleShowMenuBar() { const bool visible = menuBar()->isVisible(); menuBar()->setVisible(!visible); - if (visible) { - createControlButton(); - } else { - deleteControlButton(); - } } QPointer<QAction> DolphinMainWindow::preferredSearchTool() @@ -1153,87 +1155,91 @@ void DolphinMainWindow::openContextMenu(const QPoint& pos, } } -void DolphinMainWindow::updateControlMenu() +void DolphinMainWindow::updateHamburgerMenu() { - QMenu* menu = qobject_cast<QMenu*>(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(); - - 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->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); - - if (added) { - menu->addSeparator(); + auto hamburgerMenu = static_cast<KHamburgerMenu *>( + ac->action(KStandardAction::name(KStandardAction::HamburgerMenu))); + auto menu = hamburgerMenu->menu(); + 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(); - // 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); + 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(); } - 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); + // 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"))); - if (added) { - menu->addSeparator(); + 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. } - - // 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->addSeparator(); - // Add "Show Panels" menu - addActionToMenu(ac->action(QStringLiteral("panels")), menu); - - // 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); -} + // 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(); -void DolphinMainWindow::updateToolBar() -{ - if (!menuBar()->isVisible()) { - createControlButton(); + // 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("sort"))); + menu->addAction(ac->action(QStringLiteral("additional_info"))); + if (!GeneralSettings::showStatusBar() || !GeneralSettings::showZoomSlider()) { + menu->addAction(ac->action(QStringLiteral("zoom"))); + } + menu->addAction(ac->action(QStringLiteral("panels"))); -void DolphinMainWindow::slotControlButtonDeleted() -{ - m_controlButton = nullptr; - m_updateToolBarTimer->start(); + // 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) @@ -1245,7 +1251,9 @@ void DolphinMainWindow::slotPlaceActivated(const QUrl& url) // which had been unmounted earlier, see https://bugs.kde.org/show_bug.cgi?id=161385. reloadView(); } else { + view->disableUrlNavigatorSelectionRequests(); changeUrl(url); + view->enableUrlNavigatorSelectionRequests(); } } @@ -1269,6 +1277,7 @@ void DolphinMainWindow::activeViewChanged(DolphinViewContainer* viewContainer) // view and url navigator) and main window. oldViewContainer->disconnect(this); oldViewContainer->view()->disconnect(this); + oldViewContainer->urlNavigatorInternalWithHistory()->disconnect(this); auto navigators = static_cast<DolphinNavigatorsWidgetAction *> (actionCollection()->action(QStringLiteral("url_navigators"))); navigators->primaryUrlNavigator()->disconnect(this); @@ -1355,11 +1364,13 @@ 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(); menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New")); - menu->setIcon(QIcon::fromTheme(QStringLiteral("document-new"))); + menu->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); m_newFileMenu->setDelayed(false); connect(menu, &QMenu::aboutToShow, this, &DolphinMainWindow::updateNewMenu); @@ -1788,6 +1799,8 @@ void DolphinMainWindow::setupDockWidgets() infoPanel, &InformationPanel::setSelection); connect(this, &DolphinMainWindow::requestItemInfo, infoPanel, &InformationPanel::requestDelayedItemInfo); + connect(this, &DolphinMainWindow::fileItemsChanged, + infoPanel, &InformationPanel::slotFilesItemChanged); #endif // i18n: This is the last paragraph for the "What's This"-texts of all four panels. @@ -2076,65 +2089,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(); @@ -2173,6 +2127,8 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) this, &DolphinMainWindow::slotSelectionChanged); connect(view, &DolphinView::requestItemInfo, this, &DolphinMainWindow::requestItemInfo); + connect(view, &DolphinView::fileItemsChanged, + this, &DolphinMainWindow::fileItemsChanged); connect(view, &DolphinView::tabRequested, this, &DolphinMainWindow::openNewTab); connect(view, &DolphinView::requestContextMenu, @@ -2192,15 +2148,17 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) connect(view, &DolphinView::goUpRequested, this, &DolphinMainWindow::goUp); + connect(container->urlNavigatorInternalWithHistory(), &KUrlNavigator::urlChanged, + this, &DolphinMainWindow::changeUrl); + connect(container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged, + this, &DolphinMainWindow::updateHistory); + auto navigators = static_cast<DolphinNavigatorsWidgetAction *> (actionCollection()->action(QStringLiteral("url_navigators"))); - const KUrlNavigator *navigator = m_tabWidget->currentTabPage()->primaryViewActive() ? navigators->primaryUrlNavigator() : navigators->secondaryUrlNavigator(); - connect(navigator, &KUrlNavigator::urlChanged, - this, &DolphinMainWindow::changeUrl); QAction *editableLocactionAction = actionCollection()->action(QStringLiteral("editable_location")); editableLocactionAction->setChecked(navigator->isUrlEditable()); connect(navigator, &KUrlNavigator::editableStateChanged, @@ -2208,10 +2166,6 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) connect(navigator, &KUrlNavigator::tabRequested, this, &DolphinMainWindow::openNewTab); - disconnect(m_updateHistoryConnection); - m_updateHistoryConnection = connect( - container->urlNavigatorInternalWithHistory(), &KUrlNavigator::historyChanged, - this, &DolphinMainWindow::updateHistory); } void DolphinMainWindow::updateSplitAction() @@ -2434,6 +2388,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 <KXMLGUIFactory> and <QDomDocument> include + // whenever this method is removed (maybe in the year ~2026). +} + bool DolphinMainWindow::event(QEvent *event) { if (event->type() == QEvent::WhatsThisClicked) { @@ -2457,6 +2434,12 @@ bool DolphinMainWindow::eventFilter(QObject* obj, QEvent* event) return false; } +// Set a sane initial window size +QSize DolphinMainWindow::sizeHint() const +{ + return KXmlGuiWindow::sizeHint().expandedTo(QSize(760, 550)); +} + void DolphinMainWindow::saveNewToolbarConfig() { KXmlGuiWindow::saveNewToolbarConfig(); // Applies the new config. This has to be called first @@ -2468,6 +2451,8 @@ void DolphinMainWindow::saveNewToolbarConfig() m_tabWidget->currentTabPage()->insertNavigatorsWidget(navigators); } updateAllowedToolbarAreas(); + (static_cast<KHamburgerMenu *>(actionCollection()->action(KStandardAction::name( + KStandardAction::HamburgerMenu))))->hideActionsOf(toolBar()); } void DolphinMainWindow::focusTerminalPanel() diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 921f5a4c9..95e8bb564 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -15,6 +15,10 @@ #include <KSortableList> #include <kxmlguiwindow.h> +#ifdef HAVE_BALOO + #include "panels/information/informationpanel.h" +#endif + #include <QIcon> #include <QList> #include <QMenu> @@ -37,7 +41,6 @@ class KNewFileMenu; class KHelpMenu; class KToolBarPopupAction; class QToolButton; -class QIcon; class PlacesPanel; class TerminalPanel; @@ -194,6 +197,12 @@ Q_SIGNALS: void requestItemInfo(const KFileItem& item); /** + * It is emitted when in the current view, files are changed, + * or dirs have files/removed from them. + */ + void fileItemsChanged(const KFileItemList &changedFileItems); + + /** * Is emitted if the settings have been changed. */ void settingsChanged(); @@ -216,6 +225,9 @@ protected: /** Handles QWhatsThisClickedEvent and passes all others on. */ bool eventFilter(QObject*, QEvent*) override; + /** Sets a sane initial window size **/ + QSize sizeHint() const override; + protected Q_SLOTS: /** * Calls the base method KXmlGuiWindow::saveNewToolbarConfig(). @@ -459,9 +471,15 @@ private Q_SLOTS: const QUrl& url, const QList<QAction*>& customActions); - void updateControlMenu(); - void updateToolBar(); - void slotControlButtonDeleted(); + /** + * 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(); /** * Is called if the user clicked an item in the Places Panel. @@ -566,16 +584,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 @@ -616,6 +624,16 @@ private: /** Returns preferred search tool as configured in "More Search Tools" menu. */ QPointer<QAction> 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 @@ -653,11 +671,7 @@ private: KToolBarPopupAction* m_backAction; KToolBarPopupAction* m_forwardAction; - /** Makes sure that only one object is ever connected to the history. */ - QMetaObject::Connection m_updateHistoryConnection; - QMenu m_searchTools; - }; inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const diff --git a/src/dolphinnavigatorswidgetaction.cpp b/src/dolphinnavigatorswidgetaction.cpp index be88b61af..d66125af6 100644 --- a/src/dolphinnavigatorswidgetaction.cpp +++ b/src/dolphinnavigatorswidgetaction.cpp @@ -233,6 +233,8 @@ QPushButton *DolphinNavigatorsWidgetAction::newEmptyTrashButton(const DolphinUrl { auto emptyTrashButton = new QPushButton(QIcon::fromTheme(QStringLiteral("user-trash")), i18nc("@action:button", "Empty Trash"), parent); + emptyTrashButton->setToolTip(QLatin1String("Empties Trash to create free space")); + emptyTrashButton->setFlat(true); connect(emptyTrashButton, &QPushButton::clicked, this, [parent]() { Trash::empty(parent); }); diff --git a/src/dolphinpart.desktop.in b/src/dolphinpart.desktop.in index 71690ead9..848f847d5 100644 --- a/src/dolphinpart.desktop.in +++ b/src/dolphinpart.desktop.in @@ -43,6 +43,7 @@ Name[sr@ijekavian]=Делфинов приказ Name[sr@ijekavianlatin]=Dolphinov prikaz Name[sr@latin]=Dolphinov prikaz Name[sv]=Vy i Dolphin +Name[ta]=டால்பின் காட்சிமுறை Name[tr]=Dolphin Görünümü Name[uk]=Перегляд Dolphin Name[vi]=Khung xem Dolphin @@ -112,6 +113,7 @@ Name[sr@ijekavian]=Иконице Name[sr@ijekavianlatin]=Ikonice Name[sr@latin]=Ikonice Name[sv]=Ikoner +Name[ta]=சின்னங்கள் Name[tr]=Simgeler Name[uk]=Піктограми Name[vi]=Biểu tượng @@ -166,6 +168,7 @@ Name[sr@ijekavian]=Сажето Name[sr@ijekavianlatin]=Sažeto Name[sr@latin]=Sažeto Name[sv]=Kompakt +Name[ta]=சுருக்கமானது Name[tr]=Sıkışık Name[uk]=Компактний Name[vi]=Gọn @@ -220,6 +223,7 @@ Name[sr@ijekavian]=Детаљи Name[sr@ijekavianlatin]=Detalji Name[sr@latin]=Detalji Name[sv]=Detaljinformation +Name[ta]=விவரங்கள் Name[tr]=Ayrıntılar Name[uk]=Подробиці Name[vi]=Chi tiết diff --git a/src/dolphintabpage.cpp b/src/dolphintabpage.cpp index 36049fa97..33c77c42a 100644 --- a/src/dolphintabpage.cpp +++ b/src/dolphintabpage.cpp @@ -328,48 +328,6 @@ void DolphinTabPage::restoreState(const QByteArray& state) m_splitter->restoreState(splitterState); } -void DolphinTabPage::restoreStateV1(const QByteArray& state) -{ - if (state.isEmpty()) { - return; - } - - QByteArray sd = state; - QDataStream stream(&sd, QIODevice::ReadOnly); - - bool isSplitViewEnabled = false; - stream >> isSplitViewEnabled; - setSplitViewEnabled(isSplitViewEnabled, WithoutAnimation); - - QUrl primaryUrl; - stream >> primaryUrl; - m_primaryViewContainer->setUrl(primaryUrl); - bool primaryUrlEditable; - stream >> primaryUrlEditable; - m_primaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(primaryUrlEditable); - - if (isSplitViewEnabled) { - QUrl secondaryUrl; - stream >> secondaryUrl; - m_secondaryViewContainer->setUrl(secondaryUrl); - bool secondaryUrlEditable; - stream >> secondaryUrlEditable; - m_secondaryViewContainer->urlNavigatorInternalWithHistory()->setUrlEditable(secondaryUrlEditable); - } - - stream >> m_primaryViewActive; - if (m_primaryViewActive) { - m_primaryViewContainer->setActive(true); - } else { - Q_ASSERT(m_splitViewEnabled); - m_secondaryViewContainer->setActive(true); - } - - QByteArray splitterState; - stream >> splitterState; - m_splitter->restoreState(splitterState); -} - void DolphinTabPage::setActive(bool active) { if (active) { diff --git a/src/dolphintabpage.h b/src/dolphintabpage.h index a9b7f8133..57a0c3344 100644 --- a/src/dolphintabpage.h +++ b/src/dolphintabpage.h @@ -129,15 +129,6 @@ public: void restoreState(const QByteArray& state); /** - * Restores all tab related properties (urls, splitter layout, ...) from - * the given \a state. - * - * @deprecated The first tab state version has no version number, we keep - * this method to restore old states (<= Dolphin 4.14.x). - */ - Q_DECL_DEPRECATED void restoreStateV1(const QByteArray& state); - - /** * Set whether the tab page is active * */ diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index 0a024235b..cfb695e7d 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -87,15 +87,8 @@ void DolphinTabWidget::readProperties(const KConfigGroup& group) if (i >= count()) { openNewActivatedTab(); } - if (group.hasKey("Tab Data " % QString::number(i))) { - // Tab state created with Dolphin > 4.14.x - const QByteArray state = group.readEntry("Tab Data " % QString::number(i), QByteArray()); - tabPageAt(i)->restoreState(state); - } else { - // Tab state created with Dolphin <= 4.14.x - const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); - tabPageAt(i)->restoreStateV1(state); - } + const QByteArray state = group.readEntry("Tab Data " % QString::number(i), QByteArray()); + tabPageAt(i)->restoreState(state); } const int index = group.readEntry("Active Tab Index", 0); diff --git a/src/dolphinui.rc b/src/dolphinui.rc index e749abae0..1b7f2e8b1 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -1,6 +1,6 @@ <?xml version="1.0"?> <!DOCTYPE gui SYSTEM "kpartgui.dtd"> -<gui name="dolphin" version="33"> +<gui name="dolphin" version="35"> <MenuBar> <Menu name="file"> <Action name="new_menu" /> @@ -124,7 +124,7 @@ <Action name="split_view" /> <Action name="split_stash" /> <Action name="toggle_search" /> - <Action name="toggle_filter" /> + <Action name="hamburger_menu" /> </ToolBar> <ActionProperties scheme="Default"> <Action priority="0" name="go_back"/> diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 549b62b03..1a608669f 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -727,6 +727,18 @@ void DolphinViewContainer::slotUrlSelectionRequested(const QUrl& url) m_view->markUrlAsCurrent(url); // makes the item scroll into view } +void DolphinViewContainer::disableUrlNavigatorSelectionRequests() +{ + disconnect(m_urlNavigator.get(), &KUrlNavigator::urlSelectionRequested, + this, &DolphinViewContainer::slotUrlSelectionRequested); +} + +void DolphinViewContainer::enableUrlNavigatorSelectionRequests() +{ + connect(m_urlNavigator.get(), &KUrlNavigator::urlSelectionRequested, + this, &DolphinViewContainer::slotUrlSelectionRequested); +} + void DolphinViewContainer::redirect(const QUrl& oldUrl, const QUrl& newUrl) { Q_UNUSED(oldUrl) diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index eeb9204c1..1a92e1fa6 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -28,7 +28,6 @@ namespace KActivities { class FilterBar; class KMessageWidget; class QUrl; -class KUrlNavigator; class DolphinSearchBox; class DolphinStatusBar; @@ -175,6 +174,15 @@ public: */ QString caption() const; + /** + * Disable/enable the behavior of "select child when moving to parent folder" + * offered by KUrlNavigator. + * + * See KUrlNavigator::urlSelectionRequested + */ + void disableUrlNavigatorSelectionRequests(); + void enableUrlNavigatorSelectionRequests(); + public Q_SLOTS: /** * Sets the current active URL, where all actions are applied. The diff --git a/src/global.cpp b/src/global.cpp index 3d17a733b..197d6ec28 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -9,6 +9,7 @@ #include "dolphin_generalsettings.h" #include "dolphindebug.h" #include "dolphinmainwindowinterface.h" +#include "views/viewproperties.h" #include <KConfigWatcher> #include <KDialogJobUiDelegate> @@ -140,6 +141,12 @@ QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> Do return dolphinInterfaces; } +QPair<QString, Qt::SortOrder> Dolphin::sortOrderForUrl(QUrl &url) +{ + ViewProperties globalProps(url); + return QPair<QString, Qt::SortOrder>(globalProps.sortRole(), globalProps.sortOrder()); +} + double GlobalConfig::animationDurationFactor() { if (s_animationDurationFactor >= 0.0) { diff --git a/src/global.h b/src/global.h index 088e9c5b6..4f4eb890c 100644 --- a/src/global.h +++ b/src/global.h @@ -46,6 +46,8 @@ namespace Dolphin { */ QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> dolphinGuiInstances(const QString& preferredService); + QPair<QString, Qt::SortOrder> sortOrderForUrl(QUrl &url); + /** * TODO: Move this somewhere global to all KDE apps, not just Dolphin */ diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index da15ccbdd..a6c5e48ec 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -1015,6 +1015,8 @@ void KFileItemModel::slotItemsAdded(const QUrl &directoryUrl, const KFileItemLis // emitted during the maximum update interval. m_maximumUpdateIntervalTimer->start(); } + + Q_EMIT fileItemsChanged({KFileItem(directoryUrl)}); } void KFileItemModel::slotItemsDeleted(const KFileItemList& items) @@ -1023,6 +1025,7 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) QVector<int> indexesToRemove; indexesToRemove.reserve(items.count()); + KFileItemList dirsChanged; for (const KFileItem& item : items) { const int indexForItem = index(item); @@ -1036,6 +1039,11 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) m_filteredItems.erase(it); } } + + QUrl parentUrl = item.url().adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash); + if (dirsChanged.findByUrl(parentUrl).isNull()) { + dirsChanged << KFileItem(parentUrl); + } } std::sort(indexesToRemove.begin(), indexesToRemove.end()); @@ -1063,6 +1071,8 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) const KItemRangeList itemRanges = KItemRangeList::fromSortedContainer(indexesToRemove); removeFilteredChildren(itemRanges); removeItems(itemRanges, DeleteItemData); + + Q_EMIT fileItemsChanged(dirsChanged); } void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& items) @@ -1077,6 +1087,7 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& indexes.reserve(items.count()); QSet<QByteArray> changedRoles; + KFileItemList changedFiles; QListIterator<QPair<KFileItem, KFileItem> > it(items); while (it.hasNext()) { @@ -1102,6 +1113,7 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& m_items.remove(oldItem.url()); m_items.insert(newItem.url(), indexForItem); + changedFiles.append(newItem); indexes.append(indexForItem); } else { // Check if 'oldItem' is one of the filtered items. @@ -1130,6 +1142,8 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >& std::sort(indexes.begin(), indexes.end()); const KItemRangeList itemRangeList = KItemRangeList::fromSortedContainer(indexes); emitItemsChangedAndTriggerResorting(itemRangeList, changedRoles); + + Q_EMIT fileItemsChanged(changedFiles); } void KFileItemModel::slotClear() @@ -1719,6 +1733,15 @@ bool KFileItemModel::lessThan(const ItemData* a, const ItemData* b, const QColla } } + // Show hidden files and folders last + const bool isHiddenA = a->item.isHidden(); + const bool isHiddenB = b->item.isHidden(); + if (isHiddenA && !isHiddenB) { + return false; + } else if (!isHiddenA && isHiddenB) { + return true; + } + if (m_sortDirsFirst || (DetailsModeSettings::directorySizeCount() && m_sortRole == SizeRole)) { const bool isDirA = a->item.isDir(); const bool isDirB = b->item.isDir(); @@ -2090,7 +2113,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< if (daysDistance == 1) { const KLocalizedString format = ki18nc("@title:group Date: " "MMMM is full month name in current locale, and yyyy is " - "full year number", "'Yesterday' (MMMM, yyyy)"); + "full year number. You must keep the ' don't use any fancy \" or « or similar. The ' is not shown to the user, it's there to mark a part of the text that should not be formatted as a date", "'Yesterday' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); if (translatedFormat.count(QLatin1Char('\'')) == 2) { newGroupValue = fileTime.toString(translatedFormat); @@ -2105,7 +2128,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< } else if (daysDistance <= 7) { newGroupValue = fileTime.toString(i18nc("@title:group Date: " "The week day name: dddd, MMMM is full month name " - "in current locale, and yyyy is full year number", + "in current locale, and yyyy is full year number.", "dddd (MMMM, yyyy)")); newGroupValue = i18nc("Can be used to script translation of " "\"dddd (MMMM, yyyy)\" with context @title:group Date", @@ -2113,7 +2136,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< } else if (daysDistance <= 7 * 2) { const KLocalizedString format = ki18nc("@title:group Date: " "MMMM is full month name in current locale, and yyyy is " - "full year number", "'One Week Ago' (MMMM, yyyy)"); + "full year number. You must keep the ' don't use any fancy \" or « or similar. The ' is not shown to the user, it's there to mark a part of the text that should not be formatted as a date", "'One Week Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); if (translatedFormat.count(QLatin1Char('\'')) == 2) { newGroupValue = fileTime.toString(translatedFormat); @@ -2128,7 +2151,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< } else if (daysDistance <= 7 * 3) { const KLocalizedString format = ki18nc("@title:group Date: " "MMMM is full month name in current locale, and yyyy is " - "full year number", "'Two Weeks Ago' (MMMM, yyyy)"); + "full year number. You must keep the ' don't use any fancy \" or « or similar. The ' is not shown to the user, it's there to mark a part of the text that should not be formatted as a date", "'Two Weeks Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); if (translatedFormat.count(QLatin1Char('\'')) == 2) { newGroupValue = fileTime.toString(translatedFormat); @@ -2143,7 +2166,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< } else if (daysDistance <= 7 * 4) { const KLocalizedString format = ki18nc("@title:group Date: " "MMMM is full month name in current locale, and yyyy is " - "full year number", "'Three Weeks Ago' (MMMM, yyyy)"); + "full year number. You must keep the ' don't use any fancy \" or « or similar. The ' is not shown to the user, it's there to mark a part of the text that should not be formatted as a date", "'Three Weeks Ago' (MMMM, yyyy)"); const QString translatedFormat = format.toString(); if (translatedFormat.count(QLatin1Char('\'')) == 2) { newGroupValue = fileTime.toString(translatedFormat); @@ -2158,7 +2181,7 @@ QList<QPair<int, QVariant> > KFileItemModel::timeRoleGroups(const std::function< } else { const KLocalizedString format = ki18nc("@title:group Date: " "MMMM is full month name in current locale, and yyyy is " - "full year number", "'Earlier on' MMMM, yyyy"); + "full year number. You must keep the ' don't use any fancy \" or « or similar. The ' is not shown to the user, it's there to mark a part of the text that should not be formatted as a date", "'Earlier on' MMMM, yyyy"); const QString translatedFormat = format.toString(); if (translatedFormat.count(QLatin1Char('\'')) == 2) { newGroupValue = fileTime.toString(translatedFormat); diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index 886a1c6de..acf4b761c 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -245,6 +245,12 @@ Q_SIGNALS: */ void urlIsFileError(const QUrl& url); + /** + * It is emitted for files when they change and + * for dirs when files are added or removed. + */ + void fileItemsChanged(const KFileItemList &changedFileItems); + protected: void onGroupedSortingChanged(bool current) override; void onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems = true) override; diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp index f253cda53..10b9f1415 100644 --- a/src/kitemviews/kitemlistcontainer.cpp +++ b/src/kitemviews/kitemlistcontainer.cpp @@ -208,6 +208,8 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView* disconnect(previous, &KItemListView::maximumItemOffsetChanged, this, &KItemListContainer::updateItemOffsetScrollBar); disconnect(previous, &KItemListView::scrollTo, this, &KItemListContainer::scrollTo); + disconnect(m_horizontalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, previous, &KItemListView::scrollingStopped); + disconnect(m_verticalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, previous, &KItemListView::scrollingStopped); m_horizontalSmoothScroller->setTargetObject(nullptr); m_verticalSmoothScroller->setTargetObject(nullptr); } @@ -224,6 +226,9 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView* connect(current, &KItemListView::maximumItemOffsetChanged, this, &KItemListContainer::updateItemOffsetScrollBar); connect(current, &KItemListView::scrollTo, this, &KItemListContainer::scrollTo); + connect(m_horizontalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, current, &KItemListView::scrollingStopped); + connect(m_verticalSmoothScroller, &KItemListSmoothScroller::scrollingStopped, current, &KItemListView::scrollingStopped); + m_horizontalSmoothScroller->setTargetObject(current); m_verticalSmoothScroller->setTargetObject(current); updateSmoothScrollers(current->scrollOrientation()); diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 56cede2fd..5c8c712e8 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -526,8 +526,11 @@ void KItemListView::scrollToItem(int index) if (newOffset != scrollOffset()) { Q_EMIT scrollTo(newOffset); + return; } } + + Q_EMIT scrollingStopped(); } void KItemListView::beginTransaction() @@ -1602,16 +1605,16 @@ void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, c { disconnectRoleEditingSignals(index); - Q_EMIT roleEditingCanceled(index, role, value); m_editingRole = false; + Q_EMIT roleEditingCanceled(index, role, value); } void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value) { disconnectRoleEditingSignals(index); - Q_EMIT roleEditingFinished(index, role, value); m_editingRole = false; + Q_EMIT roleEditingFinished(index, role, value); } void KItemListView::setController(KItemListController* controller) @@ -1750,13 +1753,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const bool animate = (hint == Animation); for (int i = firstVisibleIndex; i <= lastVisibleIndex; ++i) { bool applyNewPos = true; - bool wasHidden = false; const QRectF itemBounds = m_layouter->itemRect(i); const QPointF newPos = itemBounds.topLeft(); KItemListWidget* widget = m_visibleItems.value(i); if (!widget) { - wasHidden = true; if (!reusableItems.isEmpty()) { // Reuse a KItemListWidget instance from an invisible item const int oldIndex = reusableItems.takeLast(); @@ -2551,7 +2552,7 @@ void KItemListView::updateGroupHeaderHeight() groupHeaderHeight += 2 * m_styleOption.horizontalMargin; groupHeaderMargin = m_styleOption.horizontalMargin; } else if (m_itemSize.isEmpty()){ - groupHeaderHeight += 2 * m_styleOption.padding; + groupHeaderHeight += 4 * m_styleOption.padding; groupHeaderMargin = m_styleOption.iconSize / 2; } else { groupHeaderHeight += 2 * m_styleOption.padding + m_styleOption.verticalMargin; diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index a84794335..5453d851f 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -307,6 +307,12 @@ Q_SIGNALS: void roleEditingCanceled(int index, const QByteArray& role, const QVariant& value); void roleEditingFinished(int index, const QByteArray& role, const QVariant& value); + /** + * Emitted once scrolling has finished, or immediately if no scrolling was necessary + * to get item in view in scrollToItem. + */ + void scrollingStopped(); + protected: QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; void setItemSize(const QSizeF& size); diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 73744b385..e58340fb8 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -764,6 +764,7 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const m_roleEditor = new KItemListRoleEditor(parent); m_roleEditor->setRole(current); + m_roleEditor->setAllowUpDownKeyChainEdit(m_layout != IconsLayout); m_roleEditor->setFont(styleOption().font); const QString text = data().value(current).toString(); diff --git a/src/kitemviews/private/kfileitemmodeldirlister.cpp b/src/kitemviews/private/kfileitemmodeldirlister.cpp index 90c970874..eb860a2b9 100644 --- a/src/kitemviews/private/kfileitemmodeldirlister.cpp +++ b/src/kitemviews/private/kfileitemmodeldirlister.cpp @@ -8,11 +8,16 @@ #include <KLocalizedString> #include <KIO/Job> +#include <kio_version.h> KFileItemModelDirLister::KFileItemModelDirLister(QObject* parent) : KDirLister(parent) { +#if KIO_VERSION < QT_VERSION_CHECK(5, 82, 0) setAutoErrorHandlingEnabled(false, nullptr); +#else + setAutoErrorHandlingEnabled(false); +#endif } KFileItemModelDirLister::~KFileItemModelDirLister() diff --git a/src/kitemviews/private/kitemlistroleeditor.cpp b/src/kitemviews/private/kitemlistroleeditor.cpp index df142a456..cc10bd58a 100644 --- a/src/kitemviews/private/kitemlistroleeditor.cpp +++ b/src/kitemviews/private/kitemlistroleeditor.cpp @@ -40,6 +40,11 @@ QByteArray KItemListRoleEditor::role() const return m_role; } +void KItemListRoleEditor::setAllowUpDownKeyChainEdit(bool allowChainEdit) +{ + m_allowUpDownKeyChainEdit = allowChainEdit; +} + bool KItemListRoleEditor::eventFilter(QObject* watched, QEvent* event) { if (watched == parentWidget() && event->type() == QEvent::Resize) { @@ -78,6 +83,20 @@ void KItemListRoleEditor::keyPressEvent(QKeyEvent* event) emitRoleEditingFinished(); event->accept(); return; + case Qt::Key_Tab: + case Qt::Key_Down: + if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Tab) { + emitRoleEditingFinished(EditNext); + event->accept(); + return; + } + case Qt::Key_Backtab: + case Qt::Key_Up: + if (m_allowUpDownKeyChainEdit || event->key() == Qt::Key_Backtab) { + emitRoleEditingFinished(EditPrevious); + event->accept(); + return; + } case Qt::Key_Left: case Qt::Key_Right: { QTextCursor cursor = textCursor(); @@ -143,10 +162,13 @@ void KItemListRoleEditor::autoAdjustSize() } } -void KItemListRoleEditor::emitRoleEditingFinished() +void KItemListRoleEditor::emitRoleEditingFinished(EditResultDirection direction) { + QVariant ret; + ret.setValue(EditResult {KIO::encodeFileName(toPlainText()), direction}); + if (!m_blockFinishedSignal) { - Q_EMIT roleEditingFinished(m_role, KIO::encodeFileName(toPlainText())); + Q_EMIT roleEditingFinished(m_role, ret); } } diff --git a/src/kitemviews/private/kitemlistroleeditor.h b/src/kitemviews/private/kitemlistroleeditor.h index 070cf5ce9..a0f55df51 100644 --- a/src/kitemviews/private/kitemlistroleeditor.h +++ b/src/kitemviews/private/kitemlistroleeditor.h @@ -11,12 +11,26 @@ #include <KTextEdit> +enum EditResultDirection{ + EditDone, + EditNext, + EditPrevious, +}; +Q_DECLARE_METATYPE(EditResultDirection) + +struct EditResult +{ + QString newName; + EditResultDirection direction; +}; +Q_DECLARE_METATYPE(EditResult) + /** * @brief Editor for renaming roles of a KItemListWidget. * * Provides signals when the editing got cancelled (e.g. by * pressing Escape or when losing the focus) or when the editing - * got finished (e.g. by pressing Enter or Return). + * got finished (e.g. by pressing Enter, Tab or Return). * * The size automatically gets increased if the text does not fit. */ @@ -31,6 +45,7 @@ public: void setRole(const QByteArray& role); QByteArray role() const; + void setAllowUpDownKeyChainEdit(bool allowChainEdit); bool eventFilter(QObject* watched, QEvent* event) override; Q_SIGNALS: @@ -53,11 +68,12 @@ private: * Emits the signal roleEditingFinished if m_blockFinishedSignal * is false. */ - void emitRoleEditingFinished(); + void emitRoleEditingFinished(EditResultDirection direction = EditDone); private: QByteArray m_role; bool m_blockFinishedSignal; + bool m_allowUpDownKeyChainEdit; }; #endif diff --git a/src/kitemviews/private/kitemlistsmoothscroller.cpp b/src/kitemviews/private/kitemlistsmoothscroller.cpp index 1465361ed..f77d3df58 100644 --- a/src/kitemviews/private/kitemlistsmoothscroller.cpp +++ b/src/kitemviews/private/kitemlistsmoothscroller.cpp @@ -175,6 +175,9 @@ void KItemListSmoothScroller::slotAnimationStateChanged(QAbstractAnimation::Stat if (newState == QAbstractAnimation::Stopped && m_smoothScrolling && !m_scrollBarPressed) { m_smoothScrolling = false; } + if (newState == QAbstractAnimation::Stopped) { + Q_EMIT scrollingStopped(); + } } void KItemListSmoothScroller::handleWheelEvent(QWheelEvent* event) diff --git a/src/kitemviews/private/kitemlistsmoothscroller.h b/src/kitemviews/private/kitemlistsmoothscroller.h index 55548219e..7b2839884 100644 --- a/src/kitemviews/private/kitemlistsmoothscroller.h +++ b/src/kitemviews/private/kitemlistsmoothscroller.h @@ -69,6 +69,11 @@ public: */ void handleWheelEvent(QWheelEvent* event); +Q_SIGNALS: + /** + * Emitted when the scrolling animation has finished + */ + void scrollingStopped(); protected: bool eventFilter(QObject* obj, QEvent* event) override; diff --git a/src/main.cpp b/src/main.cpp index ef2905d77..fba45f43c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -37,7 +37,7 @@ #endif #include <iostream> -extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv) +int main(int argc, char **argv) { #ifndef Q_OS_WIN // Prohibit using sudo or kdesu (but allow using the root user directly) diff --git a/src/org.kde.dolphin.appdata.xml b/src/org.kde.dolphin.appdata.xml index b1943fce6..2bb479cdd 100644 --- a/src/org.kde.dolphin.appdata.xml +++ b/src/org.kde.dolphin.appdata.xml @@ -46,6 +46,7 @@ <name xml:lang="sr-ijekavian">Делфин</name> <name xml:lang="sr-ijekavianlatin">Dolphin</name> <name xml:lang="sv">Dolphin</name> + <name xml:lang="ta">டால்பின்</name> <name xml:lang="tr">Dolphin</name> <name xml:lang="uk">Dolphin</name> <name xml:lang="vi">Dolphin</name> @@ -95,6 +96,7 @@ <summary xml:lang="sr-ijekavian">Менаџер фајлова</summary> <summary xml:lang="sr-ijekavianlatin">Menadžer fajlova</summary> <summary xml:lang="sv">Filhanterare</summary> + <summary xml:lang="ta">கோப்பு உலாவி</summary> <summary xml:lang="tr">Dosya Yöneticisi</summary> <summary xml:lang="uk">Програма для керування файлами</summary> <summary xml:lang="vi">Trình quản lí tệp</summary> @@ -126,6 +128,7 @@ <p xml:lang="sk">Dolphin je správca súborov KDE, ktorý vám umožní prechádzať a prehľadávať obsah vašich pevných diskov, USB kľúčov, SD kariet a ďalších. Vytváranie, presúvanie alebo mazanie súborov a priečinkov je jednoduché a rýchle.</p> <p xml:lang="sl">Dolphin je upravitelj datotek KDE, ki vam omogoča krmarjenje in brskanje po vsebini trdih diskov, USB ključkov, SD kartic in še več. Ustvarjanje, premikanje ali brisanje datotek in map je preprosto in hitro.</p> <p xml:lang="sv">Dolphin är KDE:s filhanterare som låter dig navigera och bläddra i innehållet på hårddiskar, USB-minnen, SD-kort, med mera. Skapa, flytta eller ta bort filer och kataloger är enkelt och går snabbt.</p> + <p xml:lang="ta">டால்பின் என்பது, உங்கள் வட்டுகள், USB சாதனங்கள், மற்றும் SD அட்டைகள் போன்றவற்றின் உள்ளடக்கத்தை பார்க்க உதவும் கே.டீ.யீ.யின் கோப்பு உலாவியாகும். கோப்புகள் மற்றும் அடைவுகளை எளிதாகவும் வேகமாகவும் உருவாக்க, நகர்த்த, மற்றும் நீக்க முடியும்.</p> <p xml:lang="tr">Dolphin, KDE'nin sabit disklerinizin, USB belleklerinizin, SD kartlarınızın ve daha fazlasının içeriğinde gezinmenizi ve bunlara göz atmanızı sağlayan dosya yöneticisidir. Dosya ve klasörlerin oluşturulması, taşınması veya silinmesi basit ve hızlıdır.</p> <p xml:lang="uk">Dolphin — програма для керування файлами KDE, за допомогою якої ви можете пересуватися та переглядати вміст дисків, флешок USB, SD-карток тощо. Створення, пересування або вилучення файлів та тек є простим і швидким завданням.</p> <p xml:lang="vi">Dolphin là trình quản lí tệp của KDE, nó cho phép bạn điều hướng và duyệt nội dung các ổ cứng, các thẻ USB, thẻ SD và các thiết bị khác của bạn. Việc tạo, chuyển, hay xoá tệp và thư mục đều đơn giản và nhanh chóng.</p> @@ -155,6 +158,7 @@ <p xml:lang="sk">Dolphin obsahuje množstvo funkcií produktivity, ktoré vám ušetria čas. Viaceré karty a funkcie rozdeleného zobrazenia umožňujú navigáciu vo viacerých priečinkoch súčasne. Medzi jednotlivými zobrazeniami môžete súbory jednoducho presúvať a presúvať alebo kopírovať. Ponuka pravým tlačidlom myši Dolphin ponúka mnoho rýchlych akcií, ktoré vám okrem iného umožňujú kompresiu, zdieľanie a duplikovanie súborov. Môžete tiež pridať svoje vlastné vlastné akcie.</p> <p xml:lang="sl">Dolphin vsebuje veliko produktivnih funkcij, s katerimi boste prihranili čas. Več zavihkov in funkcij razdeljenega pogleda omogočajo sočasno krmarjenje po več mapah, tako da lahko datoteke enostavno vlečete in spustite med pogledi, da jih premaknete ali kopirate. Dolphinov meni z desnim klikom nudi veliko hitrih dejanj, ki vam med drugim omogočajo stiskanje, skupno rabo in podvajanje datotek. Dodate lahko tudi svoja dejanja po meri.</p> <p xml:lang="sv">Dolphin innehåller mängder av produktivitetsfunktioner som sparar tid. Funktionerna för flera flikar och delad vy tillåter att flera kataloger navigeras samtidigt, och du kan enkelt dra och släppa filer mellan vyer för att flytta eller kopiera dem. Dolphins högerklicksmeny tillhandahåller många snabbåtgärder som låter dig bland annat komprimera, dela och duplicera filer. Du kan också lägga till egna åtgärder.</p> + <p xml:lang="ta">உங்கள் நேரத்தைச் சேமிக்கும் பல அமசங்களை டால்பின் கொண்டுள்ளது. பல கீற்றுகளையோ துண்டாக்கப்பட்ட காட்சிமுறையையோ கொண்டு ஒரே நேரத்தில் பல அடைவுகளில் உலாவலாம். மேலும், காட்சிகளுக்கிடையே கோப்புகளை இழுத்துப் போடலாம். டால்பினின் வலது-க்ளிக் பட்டியில் சுருக்குதல், பகிர்தல், மற்றும் நகலெடுத்தல் போன்ற பல செயல்கள் உள்ளன. மேலும், உங்களுக்கு விருப்பமான செயல்களை நீங்கள் வலது-க்ளிக் பட்டியில் சேர்க்கலாம்.</p> <p xml:lang="tr">Dolphin size zaman kazandıracak birçok üretkenlik özelliği içerir. Birden çok sekme ve bölünmüş görünüm özellikleri, aynı anda birden çok klasörde gezinmeye izin verir ve dosyaları taşımak veya kopyalamak için görünümler arasında kolayca sürükleyip bırakabilirsiniz. Dolphin'in sağ tıklama menüsü, diğer birçok şeyin yanı sıra dosyaları sıkıştırmanıza, paylaşmanıza ve çoğaltmanıza olanak tanıyan birçok hızlı işlem sağlar. Ayrıca kendi özel eylemlerinizi de ekleyebilirsiniz.</p> <p xml:lang="uk">У Dolphin передбачено багато можливостей, які роблять вашу роботу продуктивнішою та заощаджують час. За допомогою можливостей використання декількох вкладок та поділу панелей перегляду ви можете переглядати вміст декількох тек одночасно і без проблем перетягувати і скидати пункти файлів і тек між різними панелями з метою копіювання або пересування. У контекстному меню Dolphin, яке можна викликати клацанням правою кнопкою миші, серед іншого, передбачено багато пунктів для швидкого доступу до стискання, оприлюднення та дублювання файлів. Крім того, ви можете додавати туди власні нетипові пункти дій.</p> <p xml:lang="vi">Dolphin bao gồm nhiều tính năng năng suất sẽ giúp bạn tiết kiệm thời gian. Các tính năng đa thẻ và khung xem chia đôi cho phép điều hướng nhiều thư mục cùng lúc, và bạn có thể dễ dàng kéo thả tệp giữa các khung xem để chuyển hay chép chúng. Trình đơn bấm phải của Dolphin cung cấp nhiều hành động nhanh gọn cho phép bạn nén, chia sẻ, và tạo bản sao cho các tệp, cùng nhiều việc khác nữa. Bạn cũng có thể thêm các hành động tự chọn của mình.</p> @@ -184,6 +188,7 @@ <p xml:lang="sk">Delfín je veľmi ľahký, ale zároveň ho môžete prispôsobiť svojim konkrétnym potrebám. To znamená, že správu súborov môžete vykonávať presne tak, ako chcete. Dolphin podporuje tri rôzne režimy zobrazenia: klasické zobrazenie všetkých súborov v mriežke, podrobnejšie zobrazenie a stromové zobrazenie. Môžete tiež nakonfigurovať väčšinu správania Dolphin.</p> <p xml:lang="sl">Dolphin je zelo lahek, hkrati pa ga lahko prilagodite svojim posebnim potrebam. To pomeni, da lahko izvajate upravljanje datotek natanko tako, kot želite. Dolphin podpira tri različne načine pogleda: klasičen mrežni pogled vseh datotek, podrobnejši pogled in drevesni pogled. Večino vedenja Dolphina lahko tudi nastavljate.</p> <p xml:lang="sv">Dolphin är mycket lättviktigt, men samtidigt kan du anpassa det för dina specifika behov. Det betyder att du kan utföra filhantering precis på det sätt du vill. Dolphin stöder tre olika visningsmetoder: en klassisk rutnätsvy av alla filer, en mer detaljerad vy och en trädvy. Du kan också anpassa det mesta av Dolphins beteende.</p> + <p xml:lang="ta">டால்பின் மிகவும் சிக்கனமானது, ஆனால் அதே நேரத்தில், உங்கள் தேவைகளுக்கேற்ப அதை மாற்றி அமைக்கலாம். அதாவது, நீங்கள் விரும்பும் விதத்திலெயே உங்கள் கோப்புகளை நீங்கள் நிர்வகிக்கலாம். டால்பின் மூன்று காட்சிமுறைகளை ஆதரிக்கும்: சாதாரணமான காட்சிமுறை, அதைவிட விவரமான காட்சிமுறை, மற்றும் கிளைப்பட (tree) காட்சிமுறை. டால்பினின் நடத்தையின் பெரும்பாலான அம்சங்களை நீங்கள் மாற்றலாம்.</p> <p xml:lang="tr">Dolphin çok hafiftir, ancak aynı zamanda onu özel ihtiyaçlarınıza göre uyarlayabilirsiniz. Bu, dosya yönetiminizi tam olarak istediğiniz şekilde gerçekleştirebileceğiniz anlamına gelir. Dolphin üç farklı görünüm kipini destekler: tüm dosyaların klasik bir ızgara görünümü, daha ayrıntılı bir görünüm ve bir ağaç görünümü. Ayrıca, Dolphin'in davranışlarının çoğunu yapılandırabilirsiniz.</p> <p xml:lang="uk">Dolphin є дуже невибагливим до ресурсів. Втім, ви можете адаптувати програму до ваших потреб. Це означає, що ви можете здійснювати керування файлами саме так, як вам того хочеться. У Dolphin передбачено три різних режими перегляду: класичний перегляд таблицею усіх файлів, режим докладного перегляду та ієрархічний перегляд. Більшу частину характеристик роботи програми можна налаштувати Dolphin.</p> <p xml:lang="vi">Dolphin rất nhẹ, nhưng đồng thời bạn có thể điều chỉnh nó theo các nhu cầu cụ thể của mình. Điều này nghĩa là bạn có thể thực hiện việc quản lí tệp đúng như cách bạn muốn. Dolphin hỗ trợ ba chế độ xem khác nhau: một khung xem tất cả các tệp ở dạng lưới cổ điển, một khung xem chi tiết hơn, và một khung xem dạng cây. Bạn cũng có thể cấu hình hầu hết tất cả các ứng xử của Dolphin.</p> @@ -213,6 +218,7 @@ <p xml:lang="sk">Dolphin dokáže zobraziť súbory a priečinky z mnohých internetových cloudových služieb a iných vzdialených počítačov, akoby sa nachádzali priamo na vašej pracovnej ploche.</p> <p xml:lang="sl">Dolphin lahko prikazuje datoteke in mape iz številnih internetnih storitev v oblaku in druge oddaljene računalnike, kot da bi bili na namizju.</p> <p xml:lang="sv">Dolphin kan visa filer och kataloger från många molntjänster på Internet och från andra datorer, som om de fanns direkt på ditt eget skrivbord.</p> + <p xml:lang="ta">இணையத் தேக்கக (cloud storage) சேவைகளிலோ தொலைக் கணினிகளிலோ உள்ள கோப்புகளை, உங்கள் கணினியில் இருப்பது போல டால்பினால் காட்ட முடியும்.</p> <p xml:lang="tr">Dolphin, birçok İnternet bulut hizmetinden ve diğer uzak makinelerden dosya ve klasörleri sanki masaüstünüzdeymiş gibi görüntüleyebilir.</p> <p xml:lang="uk">Dolphin здатен показувати файли і теки із багатьох «хмарних» служб інтернету та віддалених комп'ютерів так, наче усі ці дані зберігаються на вашому робочому комп'ютері.</p> <p xml:lang="vi">Dolphin có thể hiển thị tệp và thư mục từ nhiều dịch vụ đám mây Liên Mạng và các máy ở xa khác như thể chúng ở ngay trên máy tính của bạn vậy.</p> @@ -242,6 +248,7 @@ <p xml:lang="sk">Dolphin tiež prichádza s integrovaným terminálom, ktorý umožňuje spúšťať príkazy v aktuálnom priečinku. Možnosti Dolphinu môžete ešte rozšíriť pomocou výkonných doplnkov, ktoré ho prispôsobia vášmu pracovnému toku. Integračný doplnok git môžete použiť na interakciu s úložiskami git, alebo doplnok Nextcloud na synchronizáciu súborov online a oveľa viac.</p> <p xml:lang="sl">Dolphin ima tudi integriran terminal, ki vam omogoča zagon ukazov v trenutni mapi. Zmogljivosti Dolphina lahko razširite še močnimi vtičniki, ki ga prilagodijo vašemu delovnemu toku. Lahko uporabite git integracijski vtičnik za interakcijo s skladišči git ali vtičnik Nextcloud za sinhronizacijo datotek v spletu in še veliko več.</p> <p xml:lang="sv">Dolphin levereras också med en integrerad terminal som låter dig köra kommandon i den aktuella katalogen. Du kan utöka Dolphins funktioner ytterligare med kraftfulla insticksprogram för att anpassa programmet till ditt arbetsflöde. Du kan använda insticksprogrammet git-integrering för att komma åt git-arkiv, eller insticksprogrammet Nextcloud för att synkronisera filer på nätet, med mera.</p> + <p xml:lang="ta">தற்போதைய அடைவில் நீங்கள் விரும்பும் கட்டளைகளை இயக்க உதவும் உள்ளமைந்த முனையத்தை டால்பின் கொண்டுள்ளது. பல ஆற்றல்மிக்க செருகுநிரல்களைக் கொண்டு நீங்கள் டால்பினின் இயலுமைகளை உங்கள் தேவைக்கேற்ப மேம்படுத்தலாம். உதாரணத்துக்கு git ஒருங்கிணைப்பு செருகுநிரலைக் கொண்டு git repo-களை நீங்கள் கையாளலாம், அல்லது Nextcloud செருகுநிரலைக் கொண்டு உங்கள் கோப்புகளை இணையத்தில் ஒத்திசைக்கலாம்.</p> <p xml:lang="tr">Dolphin ayrıca mevcut klasörde komutları çalıştırmanıza izin veren tümleşik bir uçbirim ile birlikte gelir. İş akışınıza uyarlamak için güçlü eklentilerle Dolphin'in yeteneklerini daha da genişletebilirsiniz. Git bütünleştirme eklentisini git depolarıyla etkileşime girmek veya Nextcloud eklentisini dosyalarınızı çevrimiçi olarak eşitlemek ve çok daha fazlasını kullanabilirsiniz.</p> <p xml:lang="uk">Також до Dolphin вбудовано термінал, за допомогою якого ви можете виконувати команди у поточній теці. Ви можете розширити можливості Dolphin за допомогою потужних додатків з метою пристосування програми до ваших робочих процедур. Ви можете скористатися додатком інтеграції із git для роботи зі сховищами git або додатком Nextcloud для синхронізації ваших файлів зі сховищами даних в інтернеті тощо.</p> <p xml:lang="vi">Dolphin còn đi kèm với một dòng lệnh tích hợp, cho phép bạn chạy lệnh ở thư mục hiện tại. Bạn thậm chí có thể mở rộng khả năng của Dolphin thêm nữa bằng các phần cài cắm mạnh mẽ để đáp ứng với cách làm việc của bạn. Bạn có thể dùng phần cài cắm tích hợp git để tương tác với các kho git, hay phần cài cắm Nextcloud để đồng bộ trực tuyến các tệp của bạn, và còn nhiều nữa.</p> @@ -289,13 +296,71 @@ <caption xml:lang="sk">Správa súborov v Dolphin</caption> <caption xml:lang="sl">Upravljanje datotek v Dolphinu</caption> <caption xml:lang="sv">Filhantering i Dolphin</caption> + <caption xml:lang="ta">டால்பினால் கோப்புகளை கையாளுதல்</caption> <caption xml:lang="tr">Dolphin'de dosya yönetimi</caption> <caption xml:lang="uk">Керування файлами у Dolphin</caption> <caption xml:lang="vi">Quản lí tệp trong Dolphin</caption> <caption xml:lang="x-test">xxFile management in Dolphinxx</caption> <caption xml:lang="zh-CN">用 Dolphin 进行文件管理</caption> <caption xml:lang="zh-TW">在 Dolphin 管理檔案</caption> - <image>https://kde.org/images/screenshots/dolphin.png</image> + <image>https://cdn.kde.org/screenshots/dolphin/dolphin.png</image> + </screenshot> + <screenshot type="default"> + <caption>Embedded Terminal in Dolphin</caption> + <caption xml:lang="az">Dolphin daxilinə yerləşdirilmiş Terminal</caption> + <caption xml:lang="ca">Terminal incrustat en el Dolphin</caption> + <caption xml:lang="cs">Zabudovaný terminál v Dolphinu</caption> + <caption xml:lang="de">Eingebettetes Terminal in Dolphin</caption> + <caption xml:lang="el">Ενσωματωμένο τερματικό στο Dolphin</caption> + <caption xml:lang="en-GB">Embedded Terminal in Dolphin</caption> + <caption xml:lang="es">Terminal integrado en Dolphin</caption> + <caption xml:lang="eu">Dolphinen txertatutako terminala</caption> + <caption xml:lang="fi">Upotettu pääte Dolphinissa</caption> + <caption xml:lang="fr">Terminal intégré dans Dolphin</caption> + <caption xml:lang="ia">Terminal incorporate in Dolphin</caption> + <caption xml:lang="it">Terminale integrato in Dolphin</caption> + <caption xml:lang="ko">Dolphin에 내장된 터미널</caption> + <caption xml:lang="nl">Ingebedde terminal in Dolphin</caption> + <caption xml:lang="pl">Osadzony terminal w Dolphinie</caption> + <caption xml:lang="pt">Terminal Incorporado no Dolphin</caption> + <caption xml:lang="pt-BR">Terminal incorporado no Dolphin</caption> + <caption xml:lang="ru">Встроенный терминал</caption> + <caption xml:lang="sk">Zabudovaný terminál v Dolphin</caption> + <caption xml:lang="sl">Vdelani teminal v Dolphinu</caption> + <caption xml:lang="sv">Inbäddad terminal i Dolphin</caption> + <caption xml:lang="uk">Вбудований термінал у Dolphin</caption> + <caption xml:lang="vi">Dòng lệnh nhúng trong Dolphin</caption> + <caption xml:lang="x-test">xxEmbedded Terminal in Dolphinxx</caption> + <caption xml:lang="zh-CN">Dolphin 的内嵌命令行终端</caption> + <image>https://cdn.kde.org/screenshots/dolphin/dolphin-terminal.png</image> + </screenshot> + <screenshot> + <caption>Dolphin lets you configure your file manager exactly how you want</caption> + <caption xml:lang="az">Dolphin, fayl bələdçisini tam istədiyiniz kimi tənzimləməyə imkan verir</caption> + <caption xml:lang="ca">El Dolphin permet configurar el gestor de fitxers exactament com es vol</caption> + <caption xml:lang="de">Mit Dolphin können Sie Ihre Dateiverwaltung genau so einrichten, wie Sie es wünschen</caption> + <caption xml:lang="el">Με το Dolphin διαμορφώνετε τον διαχειριστή αρχείων ακριβώς όπως τον θέλετε</caption> + <caption xml:lang="en-GB">Dolphin lets you configure your file manager exactly how you want</caption> + <caption xml:lang="es">Dolphin le permite configurar el gestor de archivos exactamente como lo desee</caption> + <caption xml:lang="eu">Dolphinek zure fitxategi-kudeatzailea nahi duzun eran konfiguratzen uzten dizu</caption> + <caption xml:lang="fi">Dolphinilla voit tehdä tiedostonhallintaa juuri kuten haluat</caption> + <caption xml:lang="fr">Dolphin vous permet de configurer votre gestionnaire de fichiers, exactement comme vous le souhaitez.</caption> + <caption xml:lang="ia">Dolphin te permitte configurar tu gerente de file exactemente como tu lo vole</caption> + <caption xml:lang="it">Dolphin ti consente di configurare il tuo gestore file esattamente come desideri</caption> + <caption xml:lang="ko">Dolphin은 사용하고 싶은 대로 설정할 수 있습니다</caption> + <caption xml:lang="nl">Dolphin laat u uw bestandsbeheerder exact configureren zoals u dat wilt</caption> + <caption xml:lang="pl">Dolphin umożliwia ustawienie zarządzania plikami dokładnie tak, jak tego chcesz</caption> + <caption xml:lang="pt">O Dolphin permite-lhe configurar o seu gestor de ficheiros exactamente como pretende</caption> + <caption xml:lang="pt-BR">O Dolphin permite a você configurar seu gerenciador de arquivos exatamente como você quer</caption> + <caption xml:lang="ru">Диспетчер файлов Dolphin позволяет настроить тонко настроить своё поведение</caption> + <caption xml:lang="sk">Dolphin vám umožňuje konfigurovať správcu súborov presne podľa vašich predstáv</caption> + <caption xml:lang="sl">Dolphin vam omogoča sestaviti upravljalnik datotek natančno tako kot želite</caption> + <caption xml:lang="sv">Dolphin låter dig anpassa din filhanterare exakt som du vill</caption> + <caption xml:lang="uk">Ви можете налаштувати вашу програму для керування файлами Dolphin так, щоб вона працювала саме так, як ви цього хочете</caption> + <caption xml:lang="vi">Dolphin cho phép bạn cấu hình trình quản lí tệp đúng như bạn muốn</caption> + <caption xml:lang="x-test">xxDolphin lets you configure your file manager exactly how you wantxx</caption> + <caption xml:lang="zh-CN">Dolphin 让您可以随心所欲地对文件管理器进行配置</caption> + <image>https://cdn.kde.org/screenshots/dolphin/dolphin-settings.png</image> </screenshot> </screenshots> <project_group>KDE</project_group> diff --git a/src/org.kde.dolphin.desktop b/src/org.kde.dolphin.desktop index 7020ef70a..63509b476 100755 --- a/src/org.kde.dolphin.desktop +++ b/src/org.kde.dolphin.desktop @@ -43,6 +43,7 @@ Name[sr@ijekavian]=Делфин Name[sr@ijekavianlatin]=Dolphin Name[sr@latin]=Dolphin Name[sv]=Dolphin +Name[ta]=டால்பின் Name[tr]=Dolphin Name[uk]=Dolphin Name[vi]=Dolphin @@ -98,6 +99,7 @@ GenericName[sr@ijekavian]=Менаџер фајлова GenericName[sr@ijekavianlatin]=Menadžer fajlova GenericName[sr@latin]=Menadžer fajlova GenericName[sv]=Filhanterare +GenericName[ta]=கோப்பு உலாவி GenericName[tr]=Dosya Yöneticisi GenericName[uk]=Менеджер файлів GenericName[vi]=Trình quản lí tệp diff --git a/src/panels/information/informationpanel.cpp b/src/panels/information/informationpanel.cpp index f843e7f46..9a6fc3708 100644 --- a/src/panels/information/informationpanel.cpp +++ b/src/panels/information/informationpanel.cpp @@ -242,6 +242,7 @@ void InformationPanel::showItemInfo() connect(m_folderStatJob, &KIO::Job::result, this, &InformationPanel::slotFolderStatFinished); } else { + m_shownUrl = item.url(); m_content->showItem(item); } } @@ -303,6 +304,15 @@ void InformationPanel::slotFilesAdded(const QString& directory) } } +void InformationPanel::slotFilesItemChanged(const KFileItemList &changedFileItems) +{ + const auto item = changedFileItems.findByUrl(m_shownUrl); + if (!item.isNull()) { + m_fileItem = item; + showItemInfo(); + } +} + void InformationPanel::slotFilesChanged(const QStringList& files) { for (const QString& fileName : files) { diff --git a/src/panels/information/informationpanel.h b/src/panels/information/informationpanel.h index debd88e46..d7f89bc9c 100644 --- a/src/panels/information/informationpanel.h +++ b/src/panels/information/informationpanel.h @@ -46,6 +46,8 @@ public Q_SLOTS: */ void requestDelayedItemInfo(const KFileItem& item); + void slotFilesItemChanged(const KFileItemList &changedFileItems); + protected: /** @see Panel::urlChanged() */ bool urlChanged() override; diff --git a/src/panels/places/dolphin_placespanelsettings.kcfg b/src/panels/places/dolphin_placespanelsettings.kcfg index b2ef8e574..db0ac9495 100644 --- a/src/panels/places/dolphin_placespanelsettings.kcfg +++ b/src/panels/places/dolphin_placespanelsettings.kcfg @@ -4,11 +4,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd"> + <include>kiconloader.h</include> <kcfgfile name="dolphinrc"/> <group name="PlacesPanel"> <entry name="IconSize" type="Int"> <label>Size of icons in the Places Panel (-1 means "use the style's small size")</label> - <default>-1</default> + <default code="true">KIconLoader::SizeSmallMedium</default> </entry> </group> </kcfg> diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index d49ad39ec..1f5f0260f 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -23,6 +23,7 @@ #include "placesview.h" #include "trash/dolphintrash.h" #include "views/draganddrophelper.h" +#include "settings/dolphinsettingsdialog.h" #include <KFilePlaceEditDialog> #include <KFilePlacesModel> @@ -181,6 +182,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) QMenu menu(this); QAction* emptyTrashAction = nullptr; + QAction* configureTrashAction = nullptr; QAction* editAction = nullptr; QAction* teardownAction = nullptr; QAction* ejectAction = nullptr; @@ -200,7 +202,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) if (item->url().isLocalFile()) { propertiesAction = menu.addAction(QIcon::fromTheme(QStringLiteral("document-properties")), i18nc("@action:inmenu", "Properties")); } - if (!isDevice && !isTrash) { + if (!isDevice) { menu.addSeparator(); } @@ -236,6 +238,10 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) } } + if (isTrash) { + configureTrashAction = menu.addAction(QIcon::fromTheme(QStringLiteral("configure")), i18nc("@action:inmenu", "Configure Trash...")); + } + if (!isDevice) { editAction = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-entry")), i18nc("@item:inmenu", "Edit...")); } @@ -255,6 +261,11 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) if (action) { if (action == emptyTrashAction) { Trash::empty(this); + } else if (action == configureTrashAction) { + DolphinSettingsDialog* settingsDialog = new DolphinSettingsDialog(item->url(), this); + settingsDialog->setCurrentPage(settingsDialog->trashSettings); + settingsDialog->setAttribute(Qt::WA_DeleteOnClose); + settingsDialog->show(); } else { // The index might have changed if devices were added/removed while // the context menu was open. diff --git a/src/panels/places/placesview.cpp b/src/panels/places/placesview.cpp index 5214f47dc..50446d44d 100644 --- a/src/panels/places/placesview.cpp +++ b/src/panels/places/placesview.cpp @@ -1,6 +1,5 @@ /* * SPDX-FileCopyrightText: 2012 Frank Reininghaus <[email protected]> - * SPDX-FileCopyrightText: 2021 Harald Sitter <[email protected]> * * SPDX-License-Identifier: GPL-2.0-or-later */ @@ -12,10 +11,6 @@ PlacesView::PlacesView(QGraphicsWidget* parent) : KStandardItemListView(parent) { - KItemListStyleOption option = styleOption(); - option.padding = 4; - setStyleOption(option); - const int iconSize = PlacesPanelSettings::iconSize(); if (iconSize >= 0) { setIconSize(iconSize); diff --git a/src/search/dolphinfacetswidget.cpp b/src/search/dolphinfacetswidget.cpp index e8a43101f..db53d595f 100644 --- a/src/search/dolphinfacetswidget.cpp +++ b/src/search/dolphinfacetswidget.cpp @@ -54,6 +54,12 @@ DolphinFacetsWidget::DolphinFacetsWidget(QWidget* parent) : m_ratingSelector->addItem(QIcon::fromTheme(QStringLiteral("starred-symbolic")), i18nc("@item:inlistbox", "Highest Rating"), 5); initComboBox(m_ratingSelector); + m_clearTagsAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-clear-all")), i18nc("@action:inmenu", "Clear Selection"), this); + connect(m_clearTagsAction, &QAction::triggered, this, [this]() { + resetSearchTags(); + Q_EMIT facetChanged(); + }); + m_tagsSelector = new QToolButton(this); m_tagsSelector->setIcon(QIcon::fromTheme(QStringLiteral("tag"))); m_tagsSelector->setMenu(new QMenu(this)); @@ -98,9 +104,7 @@ void DolphinFacetsWidget::resetSearchTerms() m_dateSelector->setCurrentIndex(0); m_ratingSelector->setCurrentIndex(0); - m_searchTags = QStringList(); - updateTagsSelector(); - updateTagsMenu(); + resetSearchTags(); } QStringList DolphinFacetsWidget::searchTerms() const @@ -219,6 +223,13 @@ void DolphinFacetsWidget::removeSearchTag(const QString& tag) updateTagsSelector(); } +void DolphinFacetsWidget::resetSearchTags() +{ + m_searchTags = QStringList(); + updateTagsSelector(); + updateTagsMenu(); +} + void DolphinFacetsWidget::initComboBox(QComboBox* combo) { combo->setFrame(false); @@ -241,6 +252,7 @@ void DolphinFacetsWidget::updateTagsSelector() } m_tagsSelector->setEnabled(isEnabled() && (hasListedTags || hasSelectedTags)); + m_clearTagsAction->setEnabled(hasSelectedTags); } void DolphinFacetsWidget::updateTagsMenu() @@ -253,7 +265,8 @@ void DolphinFacetsWidget::updateTagsMenu() void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& items) { - m_tagsSelector->menu()->clear(); + QMenu *tagsMenu = m_tagsSelector->menu(); + tagsMenu->clear(); QStringList allTags = QStringList(m_searchTags); for (const KFileItem &item: items) { @@ -265,7 +278,7 @@ void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& const bool onlyOneTag = allTags.count() == 1; for (const QString& tagName : qAsConst(allTags)) { - QAction* action = m_tagsSelector->menu()->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName); + QAction *action = tagsMenu->addAction(QIcon::fromTheme(QStringLiteral("tag")), tagName); action->setCheckable(true); action->setChecked(m_searchTags.contains(tagName)); @@ -283,5 +296,10 @@ void DolphinFacetsWidget::updateTagsMenuItems(const QUrl&, const KFileItemList& }); } + if (allTags.count() > 1) { + tagsMenu->addSeparator(); + tagsMenu->addAction(m_clearTagsAction); + } + updateTagsSelector(); } diff --git a/src/search/dolphinfacetswidget.h b/src/search/dolphinfacetswidget.h index 83345b344..3e3b0f264 100644 --- a/src/search/dolphinfacetswidget.h +++ b/src/search/dolphinfacetswidget.h @@ -63,6 +63,7 @@ private: void setTimespan(const QDate& date); void addSearchTag(const QString& tag); void removeSearchTag(const QString& tag); + void resetSearchTags(); void initComboBox(QComboBox* combo); void updateTagsSelector(); @@ -75,6 +76,7 @@ private: QStringList m_searchTags; KCoreDirLister m_tagsLister; + QAction *m_clearTagsAction; }; #endif diff --git a/src/settings/contextmenu/contextmenusettingspage.cpp b/src/settings/contextmenu/contextmenusettingspage.cpp index e04a7c65f..c92bad43e 100644 --- a/src/settings/contextmenu/contextmenusettingspage.cpp +++ b/src/settings/contextmenu/contextmenusettingspage.cpp @@ -21,6 +21,8 @@ #include <KServiceTypeTrader> #include <KDesktopFileActions> +#include <kio_version.h> + #include <QGridLayout> #include <QLabel> #include <QListWidget> @@ -120,6 +122,8 @@ bool ContextMenuSettingsPage::entryVisible(const QString& id) return ContextMenuSettings::showCopyLocation(); } else if (id == "duplicate") { return ContextMenuSettings::showDuplicateHere(); + } else if (id == "open_terminal") { + return ContextMenuSettings::showOpenTerminal(); } return false; } @@ -140,6 +144,8 @@ void ContextMenuSettingsPage::setEntryVisible(const QString& id, bool visible) ContextMenuSettings::setShowCopyLocation(visible); } else if (id == "duplicate") { ContextMenuSettings::setShowDuplicateHere(visible); + } else if (id == "open_terminal") { + ContextMenuSettings::setShowOpenTerminal(visible); } } @@ -274,7 +280,8 @@ void ContextMenuSettingsPage::loadServices() } } - // Load service plugins that implement the KFileItemActionPlugin interface + // Load service plugins, this is deprecated in KIO 5.82 +#if KIO_VERSION < QT_VERSION_CHECK(6, 0, 0) const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("KFileItemAction/Plugin")); for (const KService::Ptr &service : pluginServices) { const QString desktopEntryName = service->desktopEntryName(); @@ -283,11 +290,10 @@ void ContextMenuSettingsPage::loadServices() addRow(service->icon(), service->name(), desktopEntryName, checked); } } +#endif // Load JSON-based plugins that implement the KFileItemActionPlugin interface - const auto jsonPlugins = KPluginLoader::findPlugins(QStringLiteral("kf5/kfileitemaction"), [](const KPluginMetaData& metaData) { - return metaData.serviceTypes().contains(QLatin1String("KFileItemAction/Plugin")); - }); + const auto jsonPlugins = KPluginLoader::findPlugins(QStringLiteral("kf5/kfileitemaction")); for (const auto &jsonMetadata : jsonPlugins) { const QString desktopEntryName = jsonMetadata.pluginId(); @@ -306,9 +312,24 @@ void ContextMenuSettingsPage::loadVersionControlSystems() const QStringList enabledPlugins = VersionControlSettings::enabledPlugins(); // Create a checkbox for each available version control plugin + QSet<QString> loadedPlugins; + + const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("dolphin/vcs")); + for (const auto &plugin : plugins) { + const QString pluginName = plugin.name(); + addRow(QStringLiteral("code-class"), + pluginName, + VersionControlServicePrefix + pluginName, + enabledPlugins.contains(pluginName)); + loadedPlugins += pluginName; + } + const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin")); for (const auto &plugin : pluginServices) { const QString pluginName = plugin->name(); + if (loadedPlugins.contains(pluginName)) { + continue; + } addRow(QStringLiteral("code-class"), pluginName, VersionControlServicePrefix + pluginName, diff --git a/src/settings/dolphin_contextmenusettings.kcfg b/src/settings/dolphin_contextmenusettings.kcfg index 9e7056551..44fd83513 100644 --- a/src/settings/dolphin_contextmenusettings.kcfg +++ b/src/settings/dolphin_contextmenusettings.kcfg @@ -38,5 +38,9 @@ <label>Show 'Duplicate Here' in context menu.</label> <default>true</default> </entry> + <entry name="ShowOpenTerminal" type="Bool"> + <label>Show 'Open Terminal' in context menu.</label> + <default>true</default> + </entry> </group> </kcfg> diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index bc1cf72aa..728d11634 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -101,6 +101,10 @@ <label>Use auto-expanding folders for all view types</label> <default>false</default> </entry> + <entry name="ShowStatusBar" type="Bool"> + <label>Show the statusbar</label> + <default>true</default> + </entry> <entry name="ShowZoomSlider" type="Bool"> <label>Show zoom slider in the statusbar</label> <default>true</default> diff --git a/src/settings/dolphinsettingsdialog.cpp b/src/settings/dolphinsettingsdialog.cpp index 4d759c911..281cb7ba5 100644 --- a/src/settings/dolphinsettingsdialog.cpp +++ b/src/settings/dolphinsettingsdialog.cpp @@ -85,7 +85,8 @@ DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent, K QStringLiteral("open_in_new_tab"), QStringLiteral("open_in_new_window"), QStringLiteral("copy_location"), - QStringLiteral("duplicate") + QStringLiteral("duplicate"), + QStringLiteral("open_terminal"), }); KPageWidgetItem* contextMenuSettingsFrame = addPage(contextMenuSettingsPage, i18nc("@title:group", "Context Menu")); @@ -98,9 +99,9 @@ DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent, K trashSettingsPage = createTrashSettingsPage(this); #endif if (trashSettingsPage) { - KPageWidgetItem* trashSettingsFrame = addPage(trashSettingsPage, + trashSettings = addPage(trashSettingsPage, i18nc("@title:group", "Trash")); - trashSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("user-trash"))); + trashSettings->setIcon(QIcon::fromTheme(QStringLiteral("user-trash"))); connect(trashSettingsPage, &TrashSettingsPage::changed, this, &DolphinSettingsDialog::enableApply); } diff --git a/src/settings/dolphinsettingsdialog.h b/src/settings/dolphinsettingsdialog.h index 65ce95274..f9a5652ea 100644 --- a/src/settings/dolphinsettingsdialog.h +++ b/src/settings/dolphinsettingsdialog.h @@ -26,6 +26,8 @@ public: explicit DolphinSettingsDialog(const QUrl& url, QWidget* parent = nullptr, KActionCollection* actions = {}); ~DolphinSettingsDialog() override; + KPageWidgetItem* trashSettings; + Q_SIGNALS: void settingsChanged(); diff --git a/src/settings/general/statusbarsettingspage.cpp b/src/settings/general/statusbarsettingspage.cpp index ddefa1a40..9d90a64fd 100644 --- a/src/settings/general/statusbarsettingspage.cpp +++ b/src/settings/general/statusbarsettingspage.cpp @@ -15,19 +15,24 @@ StatusBarSettingsPage::StatusBarSettingsPage(QWidget* parent) : SettingsPageBase(parent), + m_showStatusBar(nullptr), m_showZoomSlider(nullptr), m_showSpaceInfo(nullptr) { + m_showStatusBar = new QCheckBox(i18nc("@option:check", "Show status bar"), this); m_showZoomSlider = new QCheckBox(i18nc("@option:check", "Show zoom slider"), this); m_showSpaceInfo = new QCheckBox(i18nc("@option:check", "Show space information"), this); QVBoxLayout* topLayout = new QVBoxLayout(this); + topLayout->addWidget(m_showStatusBar); topLayout->addWidget(m_showZoomSlider); topLayout->addWidget(m_showSpaceInfo); topLayout->addStretch(); loadSettings(); + connect(m_showStatusBar, &QCheckBox::toggled, this, &StatusBarSettingsPage::changed); + connect(m_showStatusBar, &QCheckBox::toggled, this, &StatusBarSettingsPage::onShowStatusBarToggled); connect(m_showZoomSlider, &QCheckBox::toggled, this, &StatusBarSettingsPage::changed); connect(m_showSpaceInfo, &QCheckBox::toggled, this, &StatusBarSettingsPage::changed); } @@ -36,9 +41,17 @@ StatusBarSettingsPage::~StatusBarSettingsPage() { } +void StatusBarSettingsPage::onShowStatusBarToggled() +{ + const bool checked = m_showStatusBar->isChecked(); + m_showZoomSlider->setEnabled(checked); + m_showSpaceInfo->setEnabled(checked); +} + void StatusBarSettingsPage::applySettings() { GeneralSettings* settings = GeneralSettings::self(); + settings->setShowStatusBar(m_showStatusBar->isChecked()); settings->setShowZoomSlider(m_showZoomSlider->isChecked()); settings->setShowSpaceInfo(m_showSpaceInfo->isChecked()); settings->save(); @@ -54,7 +67,10 @@ void StatusBarSettingsPage::restoreDefaults() void StatusBarSettingsPage::loadSettings() { + m_showStatusBar->setChecked(GeneralSettings::showStatusBar()); m_showZoomSlider->setChecked(GeneralSettings::showZoomSlider()); m_showSpaceInfo->setChecked(GeneralSettings::showSpaceInfo()); + + onShowStatusBarToggled(); } diff --git a/src/settings/general/statusbarsettingspage.h b/src/settings/general/statusbarsettingspage.h index 3c5e7c2ad..af8e06164 100644 --- a/src/settings/general/statusbarsettingspage.h +++ b/src/settings/general/statusbarsettingspage.h @@ -29,8 +29,10 @@ public: private: void loadSettings(); + void onShowStatusBarToggled(); private: + QCheckBox* m_showStatusBar; QCheckBox* m_showZoomSlider; QCheckBox* m_showSpaceInfo; }; diff --git a/src/settings/kcm/kcmdolphingeneral.desktop b/src/settings/kcm/kcmdolphingeneral.desktop index 172cdcab2..9753285fa 100644 --- a/src/settings/kcm/kcmdolphingeneral.desktop +++ b/src/settings/kcm/kcmdolphingeneral.desktop @@ -42,6 +42,7 @@ Name[sr@ijekavian]=Делфиново опште Name[sr@ijekavianlatin]=Dolphinovo opšte Name[sr@latin]=Dolphinovo opšte Name[sv]=Dolphin allmänt +Name[ta]=டால்பின் பொது அமைப்புகள் Name[tr]=Dolphin Genel Name[uk]=«Загальне» Dolphin Name[vi]=Chung cho Dolphin @@ -91,6 +92,7 @@ Comment[sr@ijekavian]=Овај сервис омогућава подешава� Comment[sr@ijekavianlatin]=Ovaj servis omogućava podešavanje opštih Dolphinovih postavki. Comment[sr@latin]=Ovaj servis omogućava podešavanje opštih Dolphinovih postavki. Comment[sv]=Den här tjänsten låter dig anpassa allmänna inställningar i Dolphin. +Comment[ta]=டால்பினின் பொது அமைப்புகளை அமைக்க இந்த சேவை உதவும். Comment[tr]=Bu servis genel Dolphin ayarlarını yapılandırmanızı sağlar. Comment[uk]=Ця служба надасть змогу налаштувати загальні параметри Dolphin. Comment[vi]=Dịch vụ này cho phép cấu hình các thiết lập chung của Dolphin. @@ -150,6 +152,7 @@ Name[sr@ijekavian]=Опште Name[sr@ijekavianlatin]=Opšte Name[sr@latin]=Opšte Name[sv]=Allmänt +Name[ta]=பொது Name[tr]=Genel Name[uk]=Загальне Name[vi]=Chung @@ -199,6 +202,7 @@ Comment[sr@ijekavian]=Подешавање општих поставки мен� Comment[sr@ijekavianlatin]=Podešavanje opštih postavki menadžera fajlova Comment[sr@latin]=Podešavanje opštih postavki menadžera fajlova Comment[sv]=Anpassa filhanterarens allmänna inställningar +Comment[ta]=பொதுவான கோப்பு மேலாளி அமைப்புகளை அமையுங்கள் Comment[tr]=Genel dosya yöneticisi ayarlarını yapılandır Comment[uk]=Налаштувати загальні параметри менеджера файлів Comment[vi]=Cấu hình các thiết lập chung cho trình quản lí tệp @@ -248,6 +252,7 @@ X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare +X-KDE-Keywords[ta]=file manager,கோப்பு மேலாளர், கோப்பு நிர்வாகி, கோப்பு உலாவி X-KDE-Keywords[tr]=dosya yöneticisi X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[vi]=file manager,trình quản lí tệp diff --git a/src/settings/kcm/kcmdolphinnavigation.desktop b/src/settings/kcm/kcmdolphinnavigation.desktop index ca9d5a799..0ff189a47 100644 --- a/src/settings/kcm/kcmdolphinnavigation.desktop +++ b/src/settings/kcm/kcmdolphinnavigation.desktop @@ -42,6 +42,7 @@ Name[sr@ijekavian]=Делфинова навигација Name[sr@ijekavianlatin]=Dolphinova navigacija Name[sr@latin]=Dolphinova navigacija Name[sv]=Dolphin navigering +Name[ta]=டால்பின் உலாவல் Name[tr]=Dolphin Gezintisi Name[uk]=«Навігація» Dolphin Name[vi]=Điều hướng Dolphin @@ -91,6 +92,7 @@ Comment[sr@ijekavian]=Овај сервис омогућава подешава� Comment[sr@ijekavianlatin]=Ovaj servis omogućava podešavanje navigacije u Dolphinu. Comment[sr@latin]=Ovaj servis omogućava podešavanje navigacije u Dolphinu. Comment[sv]=Den här tjänsten låter dig anpassa navigering i Dolphin. +Comment[ta]=டால்பினின் உலாவல் அமைப்புகளை அமைக்க இந்த சேவை உதவும். Comment[tr]=Bu servis Dolphin gezintisini yapılandırmanızı sağlar. Comment[uk]=Ця служба надасть змогу налаштувати навігацію у Dolphin. Comment[vi]=Dịch vụ này cho phép cấu hình điều hướng Dolphin. @@ -150,6 +152,7 @@ Name[sr@ijekavian]=Навигација Name[sr@ijekavianlatin]=Navigacija Name[sr@latin]=Navigacija Name[sv]=Navigering +Name[ta]=உலாவல் Name[tr]=Gezinti Name[uk]=Навігація Name[vi]=Điều hướng @@ -200,6 +203,7 @@ Comment[sr@ijekavian]=Подешавање навигације у менаџе� Comment[sr@ijekavianlatin]=Podešavanje navigacije u menadžeru fajlova Comment[sr@latin]=Podešavanje navigacije u menadžeru fajlova Comment[sv]=Anpassa filhanterarens navigering +Comment[ta]=கோப்பு உலாவியில் உலாவலை அமையுங்கள் Comment[tr]=Dosya yöneticisi gezintisini yapılandır Comment[uk]=Налаштувати навігацію у менеджері файлів Comment[vi]=Cấu hình điều hướng trình quản lí tệp @@ -249,6 +253,7 @@ X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare +X-KDE-Keywords[ta]=file manager,கோப்பு மேலாளர், கோப்பு நிர்வாகி, கோப்பு உலாவி X-KDE-Keywords[tr]=dosya yöneticisi X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[vi]=file manager,trình quản lí tệp diff --git a/src/settings/kcm/kcmdolphinviewmodes.desktop b/src/settings/kcm/kcmdolphinviewmodes.desktop index d035d6b30..f6b0a0a6c 100644 --- a/src/settings/kcm/kcmdolphinviewmodes.desktop +++ b/src/settings/kcm/kcmdolphinviewmodes.desktop @@ -41,6 +41,7 @@ Name[sr@ijekavian]=Делфинови режими приказа Name[sr@ijekavianlatin]=Dolphinovi režimi prikaza Name[sr@latin]=Dolphinovi režimi prikaza Name[sv]=Dolphin visningslägen +Name[ta]=டால்பின் காட்சிமுறைகள் Name[tr]=Dolphin Görünüm Kipleri Name[uk]=Режими перегляду Dolphin Name[vi]=Các chế độ xem Dolphin @@ -89,6 +90,7 @@ Comment[sr@ijekavian]=Овај сервис омогућава подешава� Comment[sr@ijekavianlatin]=Ovaj servis omogućava podešavanje Dolphinovih režima prikaza. Comment[sr@latin]=Ovaj servis omogućava podešavanje Dolphinovih režima prikaza. Comment[sv]=Den här tjänsten låter dig anpassa visningslägen i Dolphin. +Comment[ta]=டால்பினின் காட்சிமுறைகளை அமைக்க இந்த சேவை உதவும். Comment[tr]=Bu servis Dolphin görünüm kiplerini yapılandırmanızı sağlar. Comment[uk]=Ця служба надасть змогу налаштувати режими перегляду Dolphin. Comment[vi]=Dịch vụ này cho phép cấu hình các chế độ xem Dolphin. @@ -147,6 +149,7 @@ Name[sr@ijekavian]=Режими приказа Name[sr@ijekavianlatin]=Režimi prikaza Name[sr@latin]=Režimi prikaza Name[sv]=Visningslägen +Name[ta]=காட்சிமுறைகள் Name[tr]=Görünüm Kipleri Name[uk]=Режими перегляду Name[vi]=Các chế độ xem @@ -196,6 +199,7 @@ Comment[sr@ijekavian]=Подешавање режима приказа у мен Comment[sr@ijekavianlatin]=Podešavanje režima prikaza u menadžeru fajlova Comment[sr@latin]=Podešavanje režima prikaza u menadžeru fajlova Comment[sv]=Anpassa filhanterarens visningslägen +Comment[ta]=கோப்பு உலாவியின் காட்சிமுறைகளை அமையுங்கள் Comment[tr]=Dosya yöneticisi görünüm ayarlarını yapılandır Comment[uk]=Налаштувати режими перегляду менеджера файлів Comment[vi]=Cấu hình các chế độ xem trình quản lí tệp @@ -245,6 +249,7 @@ X-KDE-Keywords[sr@ijekavian]=file manager,менаџер фајлова X-KDE-Keywords[sr@ijekavianlatin]=file manager,menadžer fajlova X-KDE-Keywords[sr@latin]=file manager,menadžer fajlova X-KDE-Keywords[sv]=filhanterare +X-KDE-Keywords[ta]=file manager,கோப்பு மேலாளர், கோப்பு நிர்வாகி, கோப்பு உலாவி X-KDE-Keywords[tr]=dosya yöneticisi X-KDE-Keywords[uk]=менеджер,керування,файл,файли X-KDE-Keywords[vi]=file manager,trình quản lí tệp diff --git a/src/statusbar/dolphinstatusbar.cpp b/src/statusbar/dolphinstatusbar.cpp index 91c843366..8ac74e71f 100644 --- a/src/statusbar/dolphinstatusbar.cpp +++ b/src/statusbar/dolphinstatusbar.cpp @@ -321,12 +321,15 @@ void DolphinStatusBar::updateZoomSliderToolTip(int zoomLevel) void DolphinStatusBar::setExtensionsVisible(bool visible) { + bool showStatusBar = visible; bool showSpaceInfo = visible; bool showZoomSlider = visible; if (visible) { + showStatusBar = GeneralSettings::showStatusBar(); showSpaceInfo = GeneralSettings::showSpaceInfo(); showZoomSlider = GeneralSettings::showZoomSlider(); } + setVisible(showStatusBar); m_spaceInfo->setShown(showSpaceInfo); m_spaceInfo->setVisible(showSpaceInfo); m_zoomSlider->setVisible(showZoomSlider); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 692b7756f..e9a0e2dce 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -62,10 +62,7 @@ TEST_NAME viewpropertiestest LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test) # DolphinMainWindowTest -set(dolphinmainwindowtest_SRCS dolphinmainwindowtest.cpp) -qt5_add_resources(dolphinmainwindowtest_SRCS ${CMAKE_SOURCE_DIR}/src/dolphin.qrc) - -ecm_add_test(${dolphinmainwindowtest_SRCS} +ecm_add_test(dolphinmainwindowtest.cpp ${CMAKE_SOURCE_DIR}/src/dolphin.qrc TEST_NAME dolphinmainwindowtest LINK_LIBRARIES dolphinprivate dolphinstatic Qt5::Test) diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index 558a00ab5..f527fbc61 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -812,6 +812,19 @@ void KFileItemModelTest::testRemoveFilteredExpandedItems() void KFileItemModelTest::testSorting() { + // testDir structure is as follows + // ./ + // ├─ a + // ├─ b + // ├─ c/ + // │ ├─ c-2/ + // │ │ ├─ c-3 + // │ ├─ c-1 + // ├─ d + // ├─ e + // ├─ .f + // ├─ .g/ + QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSignalSpy itemsMovedSpy(m_model, &KFileItemModel::itemsMoved); QVERIFY(itemsMovedSpy.isValid()); @@ -836,17 +849,27 @@ void KFileItemModelTest::testSorting() m_testDir->createFile("d", "The largest file in this directory", now.addDays(-1)); m_testDir->createFile("e", "An even larger file", now.addDays(-4)); m_testDir->createFile(".f"); + m_testDir->createDir(".g"); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); + QCOMPARE(itemsInsertedSpy.count(), 1); + KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 5)); int index = m_model->index(QUrl(m_testDir->url().url() + "/c")); m_model->setExpanded(index, true); QVERIFY(itemsInsertedSpy.wait()); + QCOMPARE(itemsInsertedSpy.count(), 1); + itemRangeList = itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 2)); index = m_model->index(QUrl(m_testDir->url().url() + "/c/c-2")); m_model->setExpanded(index, true); QVERIFY(itemsInsertedSpy.wait()); + QCOMPARE(itemsInsertedSpy.count(), 1); + itemRangeList = itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(2, 1)); // Default: Sort by Name, ascending QCOMPARE(m_model->sortRole(), QByteArray("text")); @@ -942,7 +965,36 @@ void KFileItemModelTest::testSorting() QCOMPARE(itemsMovedSpy.first().at(0).value<KItemRange>(), KItemRange(4, 4)); QCOMPARE(itemsMovedSpy.takeFirst().at(1).value<QList<int> >(), QList<int>() << 7 << 6 << 5 << 4); - // TODO: Sort by other roles; show/hide hidden files + // 'Show Hidden Files' enabled + m_model->setShowHiddenFiles(true); + QVERIFY(m_model->showHiddenFiles()); + QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "d" << "e" << "b" << "a" << ".g" << ".f"); + QCOMPARE(itemsMovedSpy.count(), 0); + QCOMPARE(itemsInsertedSpy.count(), 1); + QCOMPARE(itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(), KItemRangeList() << KItemRange(8, 2)); + + // Sort by Name + m_model->setSortRole("text"); + QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a" << ".g" << ".f"); + QCOMPARE(itemsMovedSpy.count(), 1); + QCOMPARE(itemsMovedSpy.first().at(0).value<KItemRange>(), KItemRange(4, 2)); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value<QList<int> >(), QList<int>() << 5 << 4); + + // Sort ascending + m_model->setSortOrder(Qt::AscendingOrder); + QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "d" << "e" << ".g" << ".f"); + QCOMPARE(itemsMovedSpy.count(), 1); + QCOMPARE(itemsMovedSpy.first().at(0).value<KItemRange>(), KItemRange(4, 4)); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value<QList<int> >(), QList<int>() << 7 << 6 << 5 << 4); + + // 'Sort Folders First' disabled + m_model->setSortDirectoriesFirst(false); + QVERIFY(!m_model->sortDirectoriesFirst()); + QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e" << ".f" << ".g"); + QCOMPARE(itemsMovedSpy.count(), 1); + QCOMPARE(itemsMovedSpy.first().at(0).value<KItemRange>(), KItemRange(0, 10)); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value<QList<int> >(), QList<int>() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7 << 9 << 8); + } void KFileItemModelTest::testIndexForKeyboardSearch() @@ -1099,7 +1151,7 @@ void KFileItemModelTest::testRemoveHiddenItems() m_model->setShowHiddenFiles(true); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << ".a" << ".b" << "c" << "d" <<".f" << ".g" << "h" << "i"); + QCOMPARE(itemsInModel(), QStringList() << "c" << "d" << "h" << "i" << ".a" << ".b" <<".f" << ".g"); QCOMPARE(itemsInsertedSpy.count(), 1); QCOMPARE(itemsRemovedSpy.count(), 0); KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(); @@ -1110,14 +1162,14 @@ void KFileItemModelTest::testRemoveHiddenItems() QCOMPARE(itemsInsertedSpy.count(), 0); QCOMPARE(itemsRemovedSpy.count(), 1); itemRangeList = itemsRemovedSpy.takeFirst().at(0).value<KItemRangeList>(); - QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 2) << KItemRange(4, 2)); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(4, 4)); m_model->setShowHiddenFiles(true); - QCOMPARE(itemsInModel(), QStringList() << ".a" << ".b" << "c" << "d" <<".f" << ".g" << "h" << "i"); + QCOMPARE(itemsInModel(), QStringList() << "c" << "d" << "h" << "i" << ".a" << ".b" <<".f" << ".g"); QCOMPARE(itemsInsertedSpy.count(), 1); QCOMPARE(itemsRemovedSpy.count(), 0); itemRangeList = itemsInsertedSpy.takeFirst().at(0).value<KItemRangeList>(); - QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 2) << KItemRange(2, 2)); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(4, 4)); m_model->clear(); QCOMPARE(itemsInModel(), QStringList()); diff --git a/src/trash/dolphintrash.cpp b/src/trash/dolphintrash.cpp index bec266c3b..8684cda06 100644 --- a/src/trash/dolphintrash.cpp +++ b/src/trash/dolphintrash.cpp @@ -8,6 +8,7 @@ #include "dolphintrash.h" #include <KIO/JobUiDelegate> +#include <kio_version.h> #include <KJobWidgets> #include <QList> #include <KNotification> @@ -21,7 +22,11 @@ Trash::Trash() // The trash icon must always be updated dependent on whether // the trash is empty or not. We use a KDirLister that automatically // watches for changes if the number of items has been changed. +#if KIO_VERSION < QT_VERSION_CHECK(5, 82, 0) m_trashDirLister->setAutoErrorHandlingEnabled(false, nullptr); +#else + m_trashDirLister->setAutoErrorHandlingEnabled(false); +#endif m_trashDirLister->setDelayedMimeTypes(true); auto trashDirContentChanged = [this]() { bool isTrashEmpty = m_trashDirLister->items().isEmpty(); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index f0f67c9d0..ce77dd325 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -18,6 +18,7 @@ #include "kitemviews/kitemlistcontroller.h" #include "kitemviews/kitemlistheader.h" #include "kitemviews/kitemlistselectionmanager.h" +#include "kitemviews/private/kitemlistroleeditor.h" #include "versioncontrol/versioncontrolobserver.h" #include "viewproperties.h" #include "views/tooltips/tooltipmanager.h" @@ -178,6 +179,7 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) : connect(m_model, &KFileItemModel::errorMessage, this, &DolphinView::errorMessage); connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection); connect(m_model, &KFileItemModel::urlIsFileError, this, &DolphinView::urlIsFileError); + connect(m_model, &KFileItemModel::fileItemsChanged, this, &DolphinView::fileItemsChanged); connect(this, &DolphinView::itemCountChanged, this, &DolphinView::updatePlaceholderLabel); @@ -674,12 +676,21 @@ void DolphinView::renameSelectedItems() if (items.count() == 1 && GeneralSettings::renameInline()) { const int index = m_model->index(items.first()); - m_view->editRole(index, "text"); - hideToolTip(); + QMetaObject::Connection * const connection = new QMetaObject::Connection; + *connection = connect(m_view, &KItemListView::scrollingStopped, this, [=](){ + QObject::disconnect(*connection); + delete connection; + + m_view->editRole(index, "text"); + + hideToolTip(); + + connect(m_view, &DolphinItemListView::roleEditingFinished, + this, &DolphinView::slotRoleEditingFinished); + }); + m_view->scrollToItem(index); - connect(m_view, &DolphinItemListView::roleEditingFinished, - this, &DolphinView::slotRoleEditingFinished); } else { KIO::RenameFileDialog* dialog = new KIO::RenameFileDialog(items, this); connect(dialog, &KIO::RenameFileDialog::renamingFinished, @@ -1736,13 +1747,15 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con disconnect(m_view, &DolphinItemListView::roleEditingFinished, this, &DolphinView::slotRoleEditingFinished); - if (index < 0 || index >= m_model->count()) { + const KFileItemList items = selectedItems(); + if (items.count() != 1) { return; } if (role == "text") { - const KFileItem oldItem = m_model->fileItem(index); - const QString newName = value.toString(); + const KFileItem oldItem = items.first(); + const EditResult retVal = value.value<EditResult>(); + const QString newName = retVal.newName; if (!newName.isEmpty() && newName != oldItem.text() && newName != QLatin1Char('.') && newName != QLatin1String("..")) { const QUrl oldUrl = oldItem.url(); @@ -1773,14 +1786,14 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con #endif const bool newNameExistsAlready = (m_model->index(newUrl) >= 0); - if (!newNameExistsAlready) { + if (!newNameExistsAlready && m_model->index(oldUrl) == index) { // Only change the data in the model if no item with the new name // is in the model yet. If there is an item with the new name // already, calling KIO::CopyJob will open a dialog // asking for a new name, and KFileItemModel will update the // data when the dir lister signals that the file name has changed. QHash<QByteArray, QVariant> data; - data.insert(role, value); + data.insert(role, retVal.newName); m_model->setData(index, data); } @@ -1797,6 +1810,13 @@ void DolphinView::slotRoleEditingFinished(int index, const QByteArray& role, con connect(job, &KJob::result, this, &DolphinView::slotRenamingResult); } } + if (retVal.direction != EditDone) { + const short indexShift = retVal.direction == EditNext ? 1 : -1; + m_container->controller()->selectionManager()->setSelected(index, 1, KItemListSelectionManager::Deselect); + m_container->controller()->selectionManager()->setSelected(index + indexShift, 1, + KItemListSelectionManager::Select); + renameSelectedItems(); + } } } diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index be8263917..bb093774f 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -593,6 +593,8 @@ Q_SIGNALS: void goUpRequested(); + void fileItemsChanged(const KFileItemList &changedFileItems); + protected: /** Changes the zoom level if Control is pressed during a wheel event. */ void wheelEvent(QWheelEvent* event) override; diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index 236daed5f..4acc420b0 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -18,6 +18,7 @@ #endif #include <KActionCollection> #include <KActionMenu> +#include <KFileItemListProperties> #include <KLocalizedString> #include <KNewFileMenu> #include <KPropertiesDialog> @@ -68,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() @@ -155,6 +159,25 @@ void DolphinViewActionHandler::createActions() 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(); @@ -208,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")); @@ -709,3 +740,69 @@ 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 + 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"))); + } + } +} diff --git a/src/views/dolphinviewactionhandler.h b/src/views/dolphinviewactionhandler.h index 23b4e5f1a..3f73153ea 100644 --- a/src/views/dolphinviewactionhandler.h +++ b/src/views/dolphinviewactionhandler.h @@ -19,6 +19,7 @@ class QAction; class QActionGroup; class DolphinView; class KActionCollection; +class KFileItemList; /** * @short Handles all actions for DolphinView @@ -211,6 +212,13 @@ private Q_SLOTS: */ 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. diff --git a/src/views/versioncontrol/fileviewversioncontrolplugin.desktop b/src/views/versioncontrol/fileviewversioncontrolplugin.desktop index 4c33b3b2c..5cffe9aac 100644 --- a/src/views/versioncontrol/fileviewversioncontrolplugin.desktop +++ b/src/views/versioncontrol/fileviewversioncontrolplugin.desktop @@ -43,6 +43,7 @@ Comment[sr@ijekavian]=Прикључак управљања верзијама � Comment[sr@ijekavianlatin]=Priključak upravljanja verzijama za fajl prikaze Comment[sr@latin]=Priključak upravljanja verzijama za fajl prikaze Comment[sv]=Insticksprogram för versionskontroll i filvyer +Comment[ta]=கோப்புக் காட்சிகளுக்கான பதிப்புக் கட்டுப்பாட்டு (version control) செருகுநிரல் Comment[tr]=Dosya Görünümleri için Sürüm Kontrol Eklentisi Comment[uk]=Додаток керування версіями для панелей перегляду файлів Comment[vi]=Phần cài cắm "Quản lí phiên bản" cho khung xem tệp diff --git a/src/views/versioncontrol/kversioncontrolplugin.h b/src/views/versioncontrol/kversioncontrolplugin.h index aeac5ad29..c908be247 100644 --- a/src/views/versioncontrol/kversioncontrolplugin.h +++ b/src/views/versioncontrol/kversioncontrolplugin.h @@ -23,14 +23,15 @@ class KFileItem; * steps are required (in the example below it is assumed that a plugin for * Subversion will be written): * - * - Create a fileviewsvnplugin.desktop file with the following content: + * - Create a fileviewsvnplugin.json file with the following content: * <code> - * [Desktop Entry] - * Type=Service - * Name=Subversion - * X-KDE-ServiceTypes=FileViewVersionControlPlugin - * MimeType=text/plain; - * X-KDE-Library=fileviewsvnplugin + * { + * "KPlugin": { + * "Description": "The svn plugin", + * "Name": "Svn" + * } + * } + * </code> * * - Create a class FileViewSvnPlugin derived from KVersionControlPlugin and @@ -45,15 +46,13 @@ class KFileItem; * <code> * #include <KPluginFactory> * #include <KPluginLoader> - * K_PLUGIN_FACTORY(FileViewSvnPluginFactory, registerPlugin<FileViewSvnPlugin>();) - * K_EXPORT_PLUGIN(FileViewSvnPluginFactory("fileviewsvnplugin")) + * K_PLUGIN_CLASS_WITH_JSON(FileViewSvnPlugin, "fileviewsvnplugin.json") * </code> * * - Add the following lines to your CMakeLists.txt file: * <code> - * kde4_add_plugin(fileviewsvnplugin fileviewsvnplugin.cpp) - * target_link_libraries(fileviewsvnplugin konq) - * install(FILES fileviewsvnplugin.desktop DESTINATION ${SERVICES_INSTALL_DIR}) + * kcoreaddons_add_plugin(fileviewsvnplugin SOURCES fileviewsvnplugin.cpp INSTALL_NAMESPACE "dolphin/vcs") + * target_link_libraries(fileviewsvnplugin DolphinVcs) * </code> * * General implementation notes: diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp index cf5be3c91..9c18c6794 100644 --- a/src/views/versioncontrol/versioncontrolobserver.cpp +++ b/src/views/versioncontrol/versioncontrolobserver.cpp @@ -15,6 +15,8 @@ #include <KLocalizedString> #include <KService> #include <KServiceTypeTrader> +#include <KPluginLoader> +#include <KPluginMetaData> #include <QTimer> @@ -279,24 +281,33 @@ void VersionControlObserver::initPlugins() // all fileview version control plugins and remember them in 'plugins'. const QStringList enabledPlugins = VersionControlSettings::enabledPlugins(); - const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("FileViewVersionControlPlugin")); - for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { - if (enabledPlugins.contains((*it)->name())) { - KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>(this); - if (plugin) { - connect(plugin, &KVersionControlPlugin::itemVersionsChanged, - this, &VersionControlObserver::silentDirectoryVerification); - connect(plugin, &KVersionControlPlugin::infoMessage, - this, &VersionControlObserver::infoMessage); - connect(plugin, &KVersionControlPlugin::errorMessage, - this, &VersionControlObserver::errorMessage); - connect(plugin, &KVersionControlPlugin::operationCompletedMessage, - this, &VersionControlObserver::operationCompletedMessage); + const QVector<KPluginMetaData> plugins = KPluginLoader::findPlugins(QStringLiteral("dolphin/vcs")); + + QSet<QString> loadedPlugins; + for (const auto &p : plugins) { + if (enabledPlugins.contains(p.name())) { + KPluginLoader loader(p.fileName()); + KPluginFactory *factory = loader.factory(); + KVersionControlPlugin *plugin = factory->create<KVersionControlPlugin>(); + if (plugin) { m_plugins.append(plugin); + loadedPlugins += p.name(); } } } + + for (auto &plugin : qAsConst(m_plugins)) { + connect(plugin, &KVersionControlPlugin::itemVersionsChanged, + this, &VersionControlObserver::silentDirectoryVerification); + connect(plugin, &KVersionControlPlugin::infoMessage, + this, &VersionControlObserver::infoMessage); + connect(plugin, &KVersionControlPlugin::errorMessage, + this, &VersionControlObserver::errorMessage); + connect(plugin, &KVersionControlPlugin::operationCompletedMessage, + this, &VersionControlObserver::operationCompletedMessage); + } + m_pluginsInitialized = true; } } |
