]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Merge branch 'master' into kf6
authorMéven Car <meven@kde.org>
Wed, 28 Jun 2023 07:49:46 +0000 (09:49 +0200)
committerMéven Car <meven@kde.org>
Wed, 28 Jun 2023 07:49:46 +0000 (09:49 +0200)
1  2 
src/CMakeLists.txt
src/dolphinmainwindow.cpp
src/dolphinnavigatorswidgetaction.cpp
src/dolphintabbar.cpp
src/dolphinviewcontainer.cpp
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodelrolesupdater.cpp
src/tests/CMakeLists.txt

diff --combined src/CMakeLists.txt
index 56637ff6ce4c857b47b6314b78016dccde097a98,62c70ba79abd3f8d1d5f280af003a74490a86969..9cd4e2932c5ce92f7409745746b7b4a246654ffa
@@@ -39,7 -39,6 +39,7 @@@ ecm_generate_headers(dolphinvcs_LIB_HEA
      RELATIVE "views/versioncontrol"
      REQUIRED_HEADERS dolphinvcs_LIB_HEADERS
  )
 +target_include_directories(dolphinvcs INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}>")
  
  install(TARGETS dolphinvcs EXPORT DolphinVcsTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
  
@@@ -184,6 -183,7 +184,7 @@@ kconfig_add_kcfg_files(dolphinprivat
      settings/dolphin_directoryviewpropertysettings.kcfgc
      settings/dolphin_detailsmodesettings.kcfgc
      settings/dolphin_iconsmodesettings.kcfgc
+     settings/dolphin_contentdisplaysettings.kcfgc
      settings/dolphin_generalsettings.kcfgc
      settings/dolphin_contextmenusettings.kcfgc
      settings/dolphin_versioncontrolsettings.kcfgc
@@@ -196,30 -196,28 +197,30 @@@ target_link_libraries
      dolphinvcs
      Qt${QT_MAJOR_VERSION}::Concurrent
      Qt${QT_MAJOR_VERSION}::Gui
 -    KF5::I18n
 -    KF5::IconThemes
 -    KF5::KIOCore
 -    KF5::KIOWidgets
 -    KF5::KIOFileWidgets
 -    KF5::Completion
 -    KF5::TextWidgets
 -    KF5::ConfigCore
 -    KF5::NewStuff
 -    KF5::NewStuffWidgets    # KNSWidgets::Button
 -    KF5::Parts
 -    KF5::WindowSystem
 -    KF5::WidgetsAddons
 -    KF5::Codecs
 +    KF6::I18n
 +    KF6::IconThemes
 +    KF6::KIOCore
 +    KF6::KIOWidgets
 +    KF6::KIOFileWidgets
 +    KF6::Completion
 +    KF6::TextWidgets
 +    KF6::ConfigCore
 +    KF6::NewStuffWidgets    # KNSWidgets::Button
 +    KF6::Parts
 +    KF6::WindowSystem
 +    KF6::WidgetsAddons
 +    KF6::Codecs
 +    KF6::KCMUtils
 +
 +    KF6::MoreTools
  )
  
  if(HAVE_BALOO)
      target_link_libraries(
          dolphinprivate PUBLIC
 -        KF5::FileMetaData
 -        KF5::Baloo
 -        KF5::BalooWidgets
 +        KF6::FileMetaData
 +        KF6::Baloo
 +        KF6::BalooWidgets
      )
  endif()
  
@@@ -291,6 -289,7 +292,6 @@@ target_sources(dolphinstatic PRIVAT
      selectionmode/bottombarcontentscontainer.cpp
      selectionmode/topbar.cpp
      settings/general/behaviorsettingspage.cpp
 -    settings/general/configurepreviewplugindialog.cpp
      settings/general/confirmationssettingspage.cpp
      settings/general/generalsettingspage.cpp
      settings/general/previewssettingspage.cpp
      settings/viewmodes/viewsettingspage.cpp
      settings/viewmodes/viewmodesettings.cpp
      settings/viewmodes/viewsettingstab.cpp
+     settings/viewmodes/contentdisplaytab.cpp
      statusbar/dolphinstatusbar.cpp
      statusbar/mountpointobserver.cpp
      statusbar/mountpointobservercache.cpp
      selectionmode/bottombarcontentscontainer.h
      selectionmode/topbar.h
      settings/general/behaviorsettingspage.h
 -    settings/general/configurepreviewplugindialog.h
      settings/general/confirmationssettingspage.h
      settings/general/generalsettingspage.h
      settings/general/previewssettingspage.h
      settings/viewmodes/viewsettingspage.h
      settings/viewmodes/viewmodesettings.h
      settings/viewmodes/viewsettingstab.h
+     settings/viewmodes/contentdisplaytab.h
      statusbar/dolphinstatusbar.h
      statusbar/mountpointobserver.h
      statusbar/mountpointobservercache.h
@@@ -409,6 -411,7 +412,7 @@@ kconfig_add_kcfg_files(dolphinstati
      settings/dolphin_detailsmodesettings.kcfgc
      settings/dolphin_contextmenusettings.kcfgc
      settings/dolphin_iconsmodesettings.kcfgc
+     settings/dolphin_contentdisplaysettings.kcfgc
      search/dolphin_searchsettings.kcfgc
      settings/dolphin_versioncontrolsettings.kcfgc
  )
@@@ -428,25 -431,25 +432,25 @@@ target_sources(dolphinstatic PRIVAT
  target_include_directories(dolphinstatic SYSTEM PRIVATE ${PHONON_INCLUDES})
  target_link_libraries(dolphinstatic
      dolphinprivate
 -    KF5::CoreAddons
 -    KF5::KCMUtils
 -    KF5::DBusAddons
 -    KF5::Notifications
 +    KF6::CoreAddons
 +    KF6::KCMUtils
 +    KF6::DBusAddons
 +    KF6::Notifications
      Phonon::phonon4qt${QT_MAJOR_VERSION}
  )
  
  if (HAVE_KACTIVITIES)
      target_link_libraries(
          dolphinstatic
 -        KF5::Activities
 +        KF6::Activities
      )
  endif()
  
  if (HAVE_KUSERFEEDBACK)
      target_link_libraries(
          dolphinstatic
 -        KUserFeedbackCore
 -        KUserFeedbackWidgets
 +        KUserFeedbackCoreQt6
 +        KUserFeedbackWidgetsQt6
      )
  endif()
  
@@@ -470,12 -473,12 +474,12 @@@ target_link_libraries(dolphi
      PRIVATE
      dolphinprivate
      dolphinstatic
 -    KF5::Crash
 +    KF6::Crash
  )
  
  if (HAVE_X11)
      if (QT_MAJOR_VERSION STREQUAL "5")
 -        target_link_libraries(dolphin PRIVATE Qt5::X11Extras)
 +        target_link_libraries(dolphin PRIVATE Qt{QT_MAJOR_VERSION}::X11Extras)
      else()
          target_link_libraries(dolphin PRIVATE Qt::GuiPrivate)
      endif()
@@@ -525,6 -528,7 +529,6 @@@ if(NOT WIN32
          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/kcm/kcmdolphingeneral.h
          settings/general/behaviorsettingspage.h
          settings/general/previewssettingspage.h
 -        settings/general/configurepreviewplugindialog.h
          settings/general/confirmationssettingspage.h
          settings/settingspagebase.h
          settings/serviceitemdelegate.h
          settings/dolphin_directoryviewpropertysettings.kcfgc
          settings/dolphin_detailsmodesettings.kcfgc
          settings/dolphin_iconsmodesettings.kcfgc
+         settings/dolphin_contentdisplaysettings.kcfgc
          settings/dolphin_generalsettings.kcfgc
          settings/dolphin_versioncontrolsettings.kcfgc
      )
@@@ -585,6 -591,7 +590,7 @@@ install( FILES settings/dolphin_directo
                 settings/dolphin_compactmodesettings.kcfg
                 settings/dolphin_iconsmodesettings.kcfg
                 settings/dolphin_detailsmodesettings.kcfg
+                settings/dolphin_contentdisplaysettings.kcfg
                 settings/dolphin_versioncontrolsettings.kcfg
           DESTINATION ${KDE_INSTALL_KCFGDIR} )
  
index a03655f5ae6b25da7ceac886f4ecf16e0d57e3ed,219c9eb56f16c398d46a3d7cc4cf3c61fe354456..480e91727b64bac8813c0e77c4602cab796400ea
  #include <KDualAction>
  #include <KFileItemListProperties>
  #include <KIO/CommandLauncherJob>
 -#include <kio_version.h>
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0)
  #include <KIO/JobUiDelegateFactory>
 -#else
 -#include <KIO/JobUiDelegate>
 -#endif
  #include <KIO/OpenFileManagerWindowJob>
  #include <KIO/OpenUrlJob>
  #include <KJobWidgets>
@@@ -54,6 -59,7 +54,6 @@@
  #include <KShell>
  #include <KShortcutsDialog>
  #include <KStandardAction>
 -#include <KStartupInfo>
  #include <KSycoca>
  #include <KTerminalLauncherJob>
  #include <KToggleAction>
@@@ -64,6 -70,7 +64,6 @@@
  #include <KWindowSystem>
  #include <KXMLGUIFactory>
  
 -#include <kio_version.h>
  #include <kwidgetsaddons_version.h>
  
  #include <QApplication>
  
  #include <algorithm>
  
 +#if HAVE_X11
 +#include <KStartupInfo>
 +#endif
 +
  namespace
  {
  // Used for GeneralSettings::version() to determine whether
@@@ -162,9 -165,6 +162,9 @@@ DolphinMainWindow::DolphinMainWindow(
      connect(m_actionHandler, &DolphinViewActionHandler::createDirectoryTriggered, this, &DolphinMainWindow::createDirectory);
      connect(m_actionHandler, &DolphinViewActionHandler::selectionModeChangeTriggered, this, &DolphinMainWindow::slotSetSelectionMode);
  
 +    Q_CHECK_PTR(actionCollection()->action(QStringLiteral("create_dir")));
 +    m_newFileMenu->setNewFolderShortcutAction(actionCollection()->action(QStringLiteral("create_dir")));
 +
      m_remoteEncoding = new DolphinRemoteEncoding(this, m_actionHandler);
      connect(this, &DolphinMainWindow::urlChanged, m_remoteEncoding, &DolphinRemoteEncoding::slotAboutToOpenUrl);
  
@@@ -277,41 -277,14 +277,16 @@@ void DolphinMainWindow::openFiles(cons
      openFiles(QUrl::fromStringList(files), splitView);
  }
  
- bool DolphinMainWindow::isOnCurrentDesktop() const
- {
- #if HAVE_X11
-     if (KWindowSystem::isPlatformX11()) {
-         const NET::Properties properties = NET::WMDesktop;
-         KWindowInfo info(this->winId(), properties);
-         return info.isOnCurrentDesktop();
-     }
- #endif
-     return true;
- }
- bool DolphinMainWindow::isOnActivity(const QString &activityId) const
- {
- #if HAVE_X11 && HAVE_KACTIVITIES
-     if (KWindowSystem::isPlatformX11()) {
-         const NET::Properties properties = NET::Supported;
-         const NET::Properties2 properties2 = NET::WM2Activities;
-         KWindowInfo info(this->winId(), properties, properties2);
-         return info.activities().contains(activityId);
-     }
- #endif
-     return true;
- }
  void DolphinMainWindow::activateWindow(const QString &activationToken)
  {
      window()->setAttribute(Qt::WA_NativeWindow, true);
  
      if (KWindowSystem::isPlatformWayland()) {
          KWindowSystem::setCurrentXdgActivationToken(activationToken);
 -    } else {
 +    } else if (KWindowSystem::isPlatformX11()) {
 +#if HAVE_X11
          KStartupInfo::setNewStartupId(window()->windowHandle(), activationToken.toUtf8());
 +#endif
      }
  
      KWindowSystem::activateWindow(window()->windowHandle());
@@@ -536,7 -509,7 +511,7 @@@ void DolphinMainWindow::showTarget(
      const KFileItem link = m_activeViewContainer->view()->selectedItems().at(0);
      const QUrl destinationUrl = link.url().resolved(QUrl(link.linkDest()));
  
 -    auto job = KIO::statDetails(destinationUrl, KIO::StatJob::SourceSide, KIO::StatNoDetails);
 +    auto job = KIO::stat(destinationUrl, KIO::StatJob::SourceSide, KIO::StatNoDetails);
  
      connect(job, &KJob::finished, this, [this, destinationUrl](KJob *job) {
          KIO::StatJob *statJob = static_cast<KIO::StatJob *>(job);
@@@ -703,12 -676,20 +678,12 @@@ void DolphinMainWindow::readProperties(
  void DolphinMainWindow::updateNewMenu()
  {
      m_newFileMenu->checkUpToDate();
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 97, 0)
      m_newFileMenu->setWorkingDirectory(activeViewContainer()->url());
 -#else
 -    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
 -#endif
  }
  
  void DolphinMainWindow::createDirectory()
  {
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 97, 0)
      m_newFileMenu->setWorkingDirectory(activeViewContainer()->url());
 -#else
 -    m_newFileMenu->setPopupFiles(QList<QUrl>() << activeViewContainer()->url());
 -#endif
      m_newFileMenu->createDirectory();
  }
  
@@@ -1283,7 -1264,11 +1258,7 @@@ void DolphinMainWindow::handleUrl(cons
          activeViewContainer()->setUrl(url);
      } else {
          m_lastHandleUrlOpenJob = new KIO::OpenUrlJob(url);
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0)
          m_lastHandleUrlOpenJob->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
 -#else
 -        m_lastHandleUrlOpenJob->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
 -#endif
          m_lastHandleUrlOpenJob->setShowOpenOrExecuteDialog(true);
  
          connect(m_lastHandleUrlOpenJob, &KIO::OpenUrlJob::mimeTypeFound, this, [this, url](const QString &mimetype) {
@@@ -1557,8 -1542,7 +1532,8 @@@ void DolphinMainWindow::setupActions(
      auto hamburgerMenuAction = KStandardAction::hamburgerMenu(nullptr, nullptr, actionCollection());
  
      // setup 'File' menu
 -    m_newFileMenu = new DolphinNewFileMenu(actionCollection(), this);
 +    m_newFileMenu = new DolphinNewFileMenu(nullptr, this);
 +    actionCollection()->addAction(QStringLiteral("new_menu"), m_newFileMenu);
      QMenu *menu = m_newFileMenu->menu();
      menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
      menu->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
      stashSplit->setVisible(sessionInterface && sessionInterface->isServiceRegistered(QStringLiteral("org.kde.kio.StashNotifier")));
      connect(stashSplit, &QAction::triggered, this, &DolphinMainWindow::toggleSplitStash);
  
-     KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
+     QAction *redisplay = KStandardAction::redisplay(this, &DolphinMainWindow::reloadView, actionCollection());
+     redisplay->setToolTip(i18nc("@info:tooltip", "Refresh view"));
+     redisplay->setWhatsThis(xi18nc("@info:whatsthis refresh",
+                                    "<para>This refreshes "
+                                    "the folder view.</para>"
+                                    "<para>If the contents of this folder have changed, refreshing will re-scan this folder "
+                                    "and show you a newly-updated view of the files and folders contained here.</para>"
+                                    "<para>If the view is split, this refreshes the one that is currently in focus.</para>"));
  
      QAction *stop = actionCollection()->addAction(QStringLiteral("stop"));
      stop->setText(i18nc("@action:inmenu View", "Stop"));
index cb2e4bc002862cb47bc8b748fb9f623681ab6d60,a36836a37e50a17cd21b3bf161e33d23f491b396..a68118395111f0984b2daa1f177a7aba0ff89e18
@@@ -1,6 -1,6 +1,6 @@@
  /*
      This file is part of the KDE project
-     SPDX-FileCopyrightText: 2020 Felix Ernst <fe.a.ernst@gmail.com>
+     SPDX-FileCopyrightText: 2020 Felix Ernst <felixernst@kde.org>
  
      SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
  */
@@@ -42,7 -42,7 +42,7 @@@ DolphinNavigatorsWidgetAction::DolphinN
  
  void DolphinNavigatorsWidgetAction::adjustSpacing()
  {
 -    m_previousWindowWidth = parentWidget()->window()->width();
 +    m_previousWindowWidth = qobject_cast<QWidget *>(parent())->window()->width();
      auto viewGeometries = m_viewGeometriesHelper.viewGeometries();
      const int widthOfSplitterPrimary = viewGeometries.globalXOfPrimary + viewGeometries.widthOfPrimary - viewGeometries.globalXOfNavigatorsWidget;
      const QList<int> splitterSizes = {widthOfSplitterPrimary, m_splitter->width() - widthOfSplitterPrimary};
@@@ -298,7 -298,7 +298,7 @@@ DolphinNavigatorsWidgetAction::ViewGeom
  bool DolphinNavigatorsWidgetAction::ViewGeometriesHelper::eventFilter(QObject *watched, QEvent *event)
  {
      if (event->type() == QEvent::Resize) {
 -        if (m_navigatorsWidgetAction->parentWidget()->window()->width() != m_navigatorsWidgetAction->m_previousWindowWidth) {
 +        if (qobject_cast<QWidget*>(m_navigatorsWidgetAction->parent())->window()->width() != m_navigatorsWidgetAction->m_previousWindowWidth) {
              // The window is being resized which means not all widgets have gotten their new sizes yet.
              // Let's wait a bit so the sizes of the navigatorsWidget and the viewContainers have all
              // had a chance to be updated.
diff --combined src/dolphintabbar.cpp
index aa74e17ae6dea5949d4ce0d5edf678301e3cbd2d,c04b349546fff16329be88eef8c97c56d93e084a..ac9f1f734a097d75552d403f7e50bd87db3b31aa
@@@ -32,7 -32,7 +32,7 @@@ DolphinTabBar::DolphinTabBar(QWidget *p
  void DolphinTabBar::dragEnterEvent(QDragEnterEvent *event)
  {
      const QMimeData *mimeData = event->mimeData();
 -    const int index = tabAt(event->pos());
 +    const int index = tabAt(event->position().toPoint());
  
      if (mimeData->hasUrls()) {
          event->acceptProposedAction();
@@@ -52,7 -52,7 +52,7 @@@ void DolphinTabBar::dragLeaveEvent(QDra
  void DolphinTabBar::dragMoveEvent(QDragMoveEvent *event)
  {
      const QMimeData *mimeData = event->mimeData();
 -    const int index = tabAt(event->pos());
 +    const int index = tabAt(event->position().toPoint());
  
      if (mimeData->hasUrls()) {
          updateAutoActivationTimer(index);
@@@ -67,7 -67,7 +67,7 @@@ void DolphinTabBar::dropEvent(QDropEven
      updateAutoActivationTimer(-1);
  
      const QMimeData *mimeData = event->mimeData();
 -    const int index = tabAt(event->pos());
 +    const int index = tabAt(event->position().toPoint());
  
      if (mimeData->hasUrls()) {
          Q_EMIT tabDropEvent(index, event);
@@@ -103,14 -103,15 +103,15 @@@ void DolphinTabBar::mouseReleaseEvent(Q
  
  void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent *event)
  {
-     const int index = tabAt(event->pos());
+     int index = tabAt(event->pos());
  
      if (index < 0) {
-         // Double click on the empty tabbar area opens a new activated tab
-         // with the url from the current tab.
-         Q_EMIT openNewActivatedTab(currentIndex());
-         return;
+         // empty tabbar area case
+         index = currentIndex();
      }
+     // Double click on the tabbar opens a new activated tab
+     // with the url from the doubleclicked tab or currentTab otherwise.
+     Q_EMIT openNewActivatedTab(index);
  
      QTabBar::mouseDoubleClickEvent(event);
  }
index 57b443eb4650c18646edb4036a7ade9e8ed24337,8627891c053d92f40e1eda0765532efa38a17c22..12108b7294940594be81b6d60a349f40bfd47918
@@@ -6,8 -6,11 +6,11 @@@
  
  #include "dolphinviewcontainer.h"
  
+ #include "dolphin_compactmodesettings.h"
+ #include "dolphin_contentdisplaysettings.h"
  #include "dolphin_detailsmodesettings.h"
  #include "dolphin_generalsettings.h"
+ #include "dolphin_iconsmodesettings.h"
  #include "dolphindebug.h"
  #include "dolphinplacesmodelsingleton.h"
  #include "filterbar/filterbar.h"
  #endif
  #include <KFileItemActions>
  #include <KFilePlacesModel>
 -#include <kio_version.h>
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0)
  #include <KIO/JobUiDelegateFactory>
 -#else
 -#include <KIO/JobUiDelegate>
 -#endif
  #include <KIO/OpenUrlJob>
  #include <KLocalizedString>
  #include <KMessageWidget>
@@@ -171,11 -179,9 +174,9 @@@ DolphinViewContainer::DolphinViewContai
  
      setSearchModeEnabled(isSearchUrl(url));
  
-     connect(DetailsModeSettings::self(), &KCoreConfigSkeleton::configChanged, this, [=]() {
-         if (view()->viewMode() == DolphinView::Mode::DetailsView) {
-             view()->reload();
-         }
-     });
+     // Update view as the ContentDisplaySettings change
+     // this happens here and not in DolphinView as DolphinviewContainer and DolphinView are not in the same build target ATM
+     connect(ContentDisplaySettings::self(), &KCoreConfigSkeleton::configChanged, m_view, &DolphinView::reload);
  
      KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
      connect(placesModel, &KFilePlacesModel::dataChanged, this, &DolphinViewContainer::slotPlacesModelChanged);
@@@ -719,7 -725,11 +720,7 @@@ void DolphinViewContainer::slotItemActi
      }
  
      KIO::OpenUrlJob *job = new KIO::OpenUrlJob(item.targetUrl(), item.mimetype());
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 98, 0)
      job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
 -#else
 -    job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
 -#endif
      job->setShowOpenOrExecuteDialog(true);
      connect(job, &KIO::OpenUrlJob::finished, this, &DolphinViewContainer::slotOpenUrlFinished);
      job->start();
index 4b06525f5156108e02bf49196fc871365497449e,629332703685f561b75dd18261fcf95ab19f5570..28e0876b9ed4d5c21a024b1d6f7fbf053a589bb1
@@@ -8,7 -8,7 +8,7 @@@
  
  #include "kfileitemmodel.h"
  
- #include "dolphin_detailsmodesettings.h"
+ #include "dolphin_contentdisplaysettings.h"
  #include "dolphin_generalsettings.h"
  #include "dolphindebug.h"
  #include "private/kfileitemmodelsortalgorithm.h"
@@@ -17,6 -17,7 +17,6 @@@
  #include <KIO/Job>
  #include <KLocalizedString>
  #include <KUrlMimeData>
 -#include <kio_version.h>
  
  #include <QElapsedTimer>
  #include <QIcon>
@@@ -104,6 -105,8 +104,8 @@@ KFileItemModel::KFileItemModel(QObject 
      connect(m_resortAllItemsTimer, &QTimer::timeout, this, &KFileItemModel::resortAllItems);
  
      connect(GeneralSettings::self(), &GeneralSettings::sortingChoiceChanged, this, &KFileItemModel::slotSortingChoiceChanged);
+     setShowTrashMime(m_dirLister->showHiddenFiles());
  }
  
  KFileItemModel::~KFileItemModel()
@@@ -128,6 -131,8 +130,8 @@@ void KFileItemModel::refreshDirectory(c
      }
  
      m_dirLister->openUrl(url, KDirLister::Reload);
+     Q_EMIT directoryRefreshing();
  }
  
  QUrl KFileItemModel::directory() const
@@@ -235,9 -240,35 +239,31 @@@ bool KFileItemModel::sortHiddenLast() c
      return m_sortHiddenLast;
  }
  
+ void KFileItemModel::setShowTrashMime(bool show)
+ {
+     const auto trashMime = QStringLiteral("application/x-trash");
+     QStringList excludeFilter = m_filter.excludeMimeTypes();
+     bool wasShown = !excludeFilter.contains(trashMime);
+     if (show) {
+         if (!wasShown) {
+             excludeFilter.removeAll(trashMime);
+         }
+     } else {
+         if (wasShown) {
+             excludeFilter.append(trashMime);
+         }
+     }
+     if (wasShown != show) {
+         setExcludeMimeTypeFilter(excludeFilter);
+     }
+ }
  void KFileItemModel::setShowHiddenFiles(bool show)
  {
 -#if KIO_VERSION < QT_VERSION_CHECK(5, 100, 0)
 -    m_dirLister->setShowingDotFiles(show);
 -#else
      m_dirLister->setShowHiddenFiles(show);
 -#endif
+     setShowTrashMime(show);
      m_dirLister->emitChanges();
      if (show) {
          dispatchPendingItemsToInsert();
  
  bool KFileItemModel::showHiddenFiles() const
  {
 -#if KIO_VERSION < QT_VERSION_CHECK(5, 100, 0)
 -    return m_dirLister->showingDotFiles();
 -#else
      return m_dirLister->showHiddenFiles();
 -#endif
  }
  
  void KFileItemModel::setShowDirectoriesOnly(bool enabled)
@@@ -589,7 -624,9 +615,7 @@@ bool KFileItemModel::setExpanded(int in
  
          m_expandedDirs.remove(targetUrl);
          m_dirLister->stop(url);
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 92, 0)
          m_dirLister->forgetDirs(url);
 -#endif
  
          const int parentLevel = expandedParentsCount(index);
          const int itemCount = m_itemData.count();
                  const QUrl url = itemData->item.url();
                  m_expandedDirs.remove(targetUrl);
                  m_dirLister->stop(url); // TODO: try to unit-test this, see https://bugs.kde.org/show_bug.cgi?id=332102#c11
 -#if KIO_VERSION >= QT_VERSION_CHECK(5, 92, 0)
                  m_dirLister->forgetDirs(url);
 -#endif
                  expandedChildren.append(targetUrl);
              }
              ++childIndex;
@@@ -725,6 -764,20 +751,20 @@@ QStringList KFileItemModel::mimeTypeFil
      return m_filter.mimeTypes();
  }
  
+ void KFileItemModel::setExcludeMimeTypeFilter(const QStringList &filters)
+ {
+     if (m_filter.excludeMimeTypes() != filters) {
+         dispatchPendingItemsToInsert();
+         m_filter.setExcludeMimeTypes(filters);
+         applyFilters();
+     }
+ }
+ QStringList KFileItemModel::excludeMimeTypeFilter() const
+ {
+     return m_filter.excludeMimeTypes();
+ }
  void KFileItemModel::applyFilters()
  {
      // ===STEP 1===
@@@ -1808,7 -1861,7 +1848,7 @@@ QHash<QByteArray, QVariant> KFileItemMo
      }
  
      if (m_requestRole[IsHiddenRole]) {
-         data.insert(sharedValue("isHidden"), item.isHidden());
+         data.insert(sharedValue("isHidden"), item.isHidden() || item.mimetype() == QStringLiteral("application/x-trash"));
      }
  
      if (m_requestRole[NameRole]) {
      }
  
      if (m_requestRole[ExtensionRole] && !isDir) {
+         // TODO KF6 use KFileItem::suffix 464722
          data.insert(sharedValue("extension"), QFileInfo(item.name()).suffix());
      }
  
@@@ -1975,7 -2029,7 +2016,7 @@@ bool KFileItemModel::lessThan(const Ite
          }
      }
  
-     if (m_sortDirsFirst || (DetailsModeSettings::directorySizeCount() && m_sortRole == SizeRole)) {
+     if (m_sortDirsFirst || (ContentDisplaySettings::directorySizeCount() && m_sortRole == SizeRole)) {
          const bool isDirA = a->item.isDir();
          const bool isDirB = b->item.isDir();
          if (isDirA && !isDirB) {
@@@ -2027,7 -2081,7 +2068,7 @@@ int KFileItemModel::sortRoleCompare(con
          break;
  
      case SizeRole: {
-         if (DetailsModeSettings::directorySizeCount() && itemA.isDir()) {
+         if (ContentDisplaySettings::directorySizeCount() && itemA.isDir()) {
              // folders first then
              // items A and B are folders thanks to lessThan checks
              auto valueA = a->values.value("count");
@@@ -2287,7 -2341,7 +2328,7 @@@ QList<QPair<int, QVariant>> KFileItemMo
          KIO::filesize_t fileSize = !item.isNull() ? item.size() : ~0U;
          QString newGroupValue;
          if (!item.isNull() && item.isDir()) {
-             if (DetailsModeSettings::directorySizeCount() || m_sortDirsFirst) {
+             if (ContentDisplaySettings::directorySizeCount() || m_sortDirsFirst) {
                  newGroupValue = i18nc("@title:group Size", "Folders");
              } else {
                  fileSize = m_itemData.at(i)->values.value("size").toULongLong();
@@@ -2552,7 -2606,7 +2593,7 @@@ QList<QPair<int, QVariant>> KFileItemMo
          if (info.permission(QFile::ExeUser)) {
              user += i18nc("@item:intext Access permission, concatenated", "Execute, ");
          }
 -        user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.count() - 2);
 +        user = user.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : user.mid(0, user.length() - 2);
  
          // Set group string
          QString group;
          if (info.permission(QFile::ExeGroup)) {
              group += i18nc("@item:intext Access permission, concatenated", "Execute, ");
          }
 -        group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.count() - 2);
 +        group = group.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : group.mid(0, group.length() - 2);
  
          // Set others string
          QString others;
          if (info.permission(QFile::ExeOther)) {
              others += i18nc("@item:intext Access permission, concatenated", "Execute, ");
          }
 -        others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.count() - 2);
 +        others = others.isEmpty() ? i18nc("@item:intext Access permission, concatenated", "Forbidden") : others.mid(0, others.length() - 2);
  
          const QString newGroupValue = i18nc("@title:group Files and folders by permissions", "User: %1 | Group: %2 | Others: %3", user, group, others);
          if (newGroupValue != groupValue) {
index 8d5656dafb146cd9df5d8799eb2f2d8a896b0f45,9d8ae55dad98cdee6bbc4d22f8644f00cedf3174..09dd2eba1f9a84fd1837e34ee5866bc2608f3825
@@@ -20,6 -20,8 +20,8 @@@
  #include <KPluginMetaData>
  #include <KSharedConfig>
  
+ #include "dolphin_contentdisplaysettings.h"
  #if HAVE_BALOO
  #include "private/kbaloorolesprovider.h"
  #include <Baloo/File>
@@@ -72,7 -74,6 +74,6 @@@ KFileItemModelRolesUpdater::KFileItemMo
      , m_resolvableRoles()
      , m_enabledPlugins()
      , m_localFileSizePreviewLimit(0)
-     , m_scanDirectories(true)
      , m_pendingSortRoleItems()
      , m_pendingIndexes()
      , m_pendingPreviewItems()
      m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this);
      connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result, this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived);
  
 -    const QString pluginNamespace = QStringLiteral("kf" QT_STRINGIFY(QT_VERSION_MAJOR)) + QStringLiteral("/overlayicon");
 +    const QString pluginNamespace = QStringLiteral("kf" QT_STRINGIFY(QT_MAJOR_VERSION)) + QStringLiteral("/overlayicon");
      const auto plugins = KPluginMetaData::findPlugins(pluginNamespace, {}, KPluginMetaData::AllowEmptyMetaData);
      for (const KPluginMetaData &data : plugins) {
          auto instance = QPluginLoader(data.fileName()).instance();
@@@ -321,16 -322,6 +322,6 @@@ qlonglong KFileItemModelRolesUpdater::l
      return m_localFileSizePreviewLimit;
  }
  
- void KFileItemModelRolesUpdater::setScanDirectories(bool enabled)
- {
-     m_scanDirectories = enabled;
- }
- bool KFileItemModelRolesUpdater::scanDirectories() const
- {
-     return m_scanDirectories;
- }
  void KFileItemModelRolesUpdater::setHoverSequenceState(const QUrl &itemUrl, int seqIdx)
  {
      const KFileItem item = m_model->fileItem(itemUrl);
@@@ -423,8 -414,7 +414,7 @@@ void KFileItemModelRolesUpdater::slotIt
          m_hoverSequenceLoadedItems.clear();
  
          killPreviewJob();
-         if (m_scanDirectories) {
+         if (!m_model->showDirectoriesOnly()) {
              m_directoryContentsCounter->stopWorker();
          }
      } else {
@@@ -856,10 -846,10 +846,10 @@@ void KFileItemModelRolesUpdater::applyC
  #endif
  }
  
- void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString &path, int count, long size)
+ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString &path, int count, long long size)
  {
-     const bool getSizeRole = m_roles.contains("size");
      const bool getIsExpandableRole = m_roles.contains("isExpandable");
+     const bool getSizeRole = m_roles.contains("size");
  
      if (getSizeRole || getIsExpandableRole) {
          const int index = m_model->index(QUrl::fromLocalFile(path));
@@@ -1278,18 -1268,71 +1268,71 @@@ bool KFileItemModelRolesUpdater::applyR
  
  void KFileItemModelRolesUpdater::startDirectorySizeCounting(const KFileItem &item, int index)
  {
-     if (item.isSlow()) {
+     if (ContentDisplaySettings::directorySizeCount() || item.isSlow() || !item.isLocalFile()) {
+         // fastpath no recursion necessary
+         auto data = m_model->data(index);
+         if (data.value("size") == -2) {
+             // means job already started
+             return;
+         }
+         auto url = item.url();
+         if (!item.localPath().isEmpty()) {
+             // optimization for desktop:/, trash:/
+             url = QUrl::fromLocalFile(item.localPath());
+         }
+         data.insert("isExpandable", false);
+         data.insert("count", 0);
+         data.insert("size", -2); // invalid size, -1 means size unknown
+         disconnect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+         m_model->setData(index, data);
+         connect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+         auto listJob = KIO::listDir(url);
+         QObject::connect(listJob, &KIO::ListJob::entries, this, [this, index](const KJob * /*job*/, const KIO::UDSEntryList &list) {
+             auto data = m_model->data(index);
+             int origCount = data.value("count").toInt();
+             int entryCount = origCount;
+             for (const KIO::UDSEntry &entry : list) {
+                 const auto name = entry.stringValue(KIO::UDSEntry::UDS_NAME);
+                 if (name == QStringLiteral("..") || name == QStringLiteral(".")) {
+                     continue;
+                 }
+                 if (!m_model->showHiddenFiles() && name.startsWith(QLatin1Char('.'))) {
+                     continue;
+                 }
+                 if (m_model->showDirectoriesOnly() && !entry.isDir()) {
+                     continue;
+                 }
+                 ++entryCount;
+             }
+             // count has changed
+             if (origCount < entryCount) {
+                 QHash<QByteArray, QVariant> data;
+                 data.insert("isExpandable", entryCount > 0);
+                 data.insert("count", entryCount);
+                 disconnect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+                 m_model->setData(index, data);
+                 connect(m_model, &KFileItemModel::itemsChanged, this, &KFileItemModelRolesUpdater::slotItemsChanged);
+             }
+         });
          return;
      }
  
      // Tell m_directoryContentsCounter that we want to count the items
      // inside the directory. The result will be received in slotDirectoryContentsCountReceived.
-     if (m_scanDirectories && item.isLocalFile()) {
-         const QString path = item.localPath();
-         const auto priority = index >= m_firstVisibleIndex && index <= m_lastVisibleIndex ? KDirectoryContentsCounter::PathCountPriority::High
-                                                                                           : KDirectoryContentsCounter::PathCountPriority::Normal;
-         m_directoryContentsCounter->scanDirectory(path, priority);
-     }
+     const QString path = item.localPath();
+     const auto priority = index >= m_firstVisibleIndex && index <= m_lastVisibleIndex ? KDirectoryContentsCounter::PathCountPriority::High
+                                                                                       : KDirectoryContentsCounter::PathCountPriority::Normal;
+     m_directoryContentsCounter->scanDirectory(path, priority);
  }
  
  QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileItem &item, int index)
      }
  
      if (m_roles.contains("extension")) {
+         // TODO KF6 use KFileItem::suffix 464722
          data.insert("extension", QFileInfo(item.name()).suffix());
      }
  
diff --combined src/tests/CMakeLists.txt
index 2495a3a595bc7404827f82cdfb63fb30e50b1cc7,8e0c6f11909a688d5df44b25590be5ccce4cf811..6431ff3fa9190b6f4c2b3feca040c6fd791e5c57
@@@ -20,6 -20,11 +20,11 @@@ ecm_add_test(kitemlistcontrollertest.cp
  TEST_NAME kitemlistcontrollertest
  LINK_LIBRARIES dolphinprivate Qt${QT_MAJOR_VERSION}::Test)
  
+ # KItemListControllerExpandTest
+ ecm_add_test(kitemlistcontrollerexpandtest.cpp testdir.cpp
+ TEST_NAME kitemlistcontrollerexpandtest
+ LINK_LIBRARIES dolphinprivate Qt${QT_MAJOR_VERSION}::Test)
  # KFileItemListViewTest
  ecm_add_test(kfileitemlistviewtest.cpp testdir.cpp
  TEST_NAME kfileitemlistviewtest
@@@ -38,14 -43,14 +43,14 @@@ target_link_libraries(kfileitemmodelben
  ecm_add_test(kitemlistkeyboardsearchmanagertest.cpp LINK_LIBRARIES dolphinprivate Qt${QT_MAJOR_VERSION}::Test)
  
  # DolphinSearchBox
 -if (KF5Baloo_FOUND)
 +if (KF6Baloo_FOUND)
      ecm_add_test(dolphinsearchboxtest.cpp
      TEST_NAME dolphinsearchboxtest
      LINK_LIBRARIES dolphinprivate dolphinstatic Qt${QT_MAJOR_VERSION}::Test)
  endif()
  
  # DolphinQuery
 -if (KF5Baloo_FOUND)
 +if (KF6Baloo_FOUND)
      ecm_add_test(dolphinquerytest.cpp
      TEST_NAME dolphinquerytest
      LINK_LIBRARIES dolphinprivate dolphinstatic Qt${QT_MAJOR_VERSION}::Test)