]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Merge branch 'master' into kf6
authorNicolas Fella <nicolas.fella@gmx.de>
Tue, 24 Oct 2023 21:12:22 +0000 (23:12 +0200)
committerNicolas Fella <nicolas.fella@gmx.de>
Tue, 24 Oct 2023 21:14:25 +0000 (23:14 +0200)
1  2 
src/dolphinmainwindow.cpp
src/kitemviews/kitemlistview.cpp
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/kstandarditemlistwidget.h
src/settings/contextmenu/contextmenusettingspage.cpp
src/views/dolphinview.cpp
src/views/dolphinviewactionhandler.cpp

index e5fb4efa994924112839d8d8fbe8e5f12d70c322,ca0038586951c2ea5a9a111401d6ce8106157278..27e4d238115ec82935e9826130ec85bd5b412178
@@@ -54,6 -54,7 +54,6 @@@
  #include <KShell>
  #include <KShortcutsDialog>
  #include <KStandardAction>
 -#include <KStartupInfo>
  #include <KSycoca>
  #include <KTerminalLauncherJob>
  #include <KToggleAction>
@@@ -63,8 -64,7 +63,8 @@@
  #include <KUrlNavigator>
  #include <KWindowSystem>
  #include <KXMLGUIFactory>
 -#include <kio_version.h>
 +
 +#include <kwidgetsaddons_version.h>
  
  #include <QApplication>
  #include <QClipboard>
  
  #include <algorithm>
  
 +#if HAVE_X11
 +#include <KStartupInfo>
 +#endif
 +
  namespace
  {
  // Used for GeneralSettings::version() to determine whether
@@@ -162,9 -158,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);
  
@@@ -283,10 -276,8 +283,10 @@@ void DolphinMainWindow::activateWindow(
  
      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());
@@@ -537,7 -528,7 +537,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);
@@@ -844,11 -835,10 +844,11 @@@ void DolphinMainWindow::slotAboutToShow
  {
      const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
      int entries = 0;
 -    m_backAction->menu()->clear();
 +    QMenu *menu = m_backAction->popupMenu();
 +    menu->clear();
      for (int i = urlNavigator->historyIndex() + 1; i < urlNavigator->historySize() && entries < MaxNumberOfNavigationentries; ++i, ++entries) {
 -        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_backAction->menu());
 -        m_backAction->menu()->addAction(action);
 +        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, menu);
 +        menu->addAction(action);
      }
  }
  
@@@ -873,10 -863,10 +873,10 @@@ void DolphinMainWindow::slotAboutToShow
  {
      const KUrlNavigator *urlNavigator = m_activeViewContainer->urlNavigatorInternalWithHistory();
      int entries = 0;
 -    m_forwardAction->menu()->clear();
 +    QMenu *menu = m_forwardAction->popupMenu();
      for (int i = urlNavigator->historyIndex() - 1; i >= 0 && entries < MaxNumberOfNavigationentries; --i, ++entries) {
 -        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, m_forwardAction->menu());
 -        m_forwardAction->menu()->addAction(action);
 +        QAction *action = urlNavigatorHistoryAction(urlNavigator, i, menu);
 +        menu->addAction(action);
      }
  }
  
@@@ -1549,8 -1539,7 +1549,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")));
                                  "<emphasis>Tab</emphasis> with the current location and view.<nl/>"
                                  "A tab is an additional view within this window. "
                                  "You can drag and drop items between tabs."));
 -    actionCollection()->setDefaultShortcuts(newTab, {Qt::CTRL | Qt::Key_T, Qt::CTRL | Qt::SHIFT | Qt::Key_N});
 +    actionCollection()->setDefaultShortcut(newTab, Qt::CTRL | Qt::Key_T);
      connect(newTab, &QAction::triggered, this, &DolphinMainWindow::openNewActivatedTab);
  
      QAction *addToPlaces = actionCollection()->addAction(QStringLiteral("add_to_places"));
      toggleSelectionModeToolBarAction->setWhatsThis(toggleSelectionModeAction->whatsThis());
      actionCollection()->addAction(QStringLiteral("toggle_selection_mode_tool_bar"), toggleSelectionModeToolBarAction);
      toggleSelectionModeToolBarAction->setCheckable(true);
 -    toggleSelectionModeToolBarAction->setPopupMode(QToolButton::DelayedPopup);
 +    toggleSelectionModeToolBarAction->setPopupMode(KToolBarPopupAction::DelayedPopup);
      connect(toggleSelectionModeToolBarAction, &QAction::triggered, toggleSelectionModeAction, &QAction::trigger);
      connect(toggleSelectionModeAction, &QAction::toggled, toggleSelectionModeToolBarAction, &QAction::setChecked);
  
          m_backAction->setObjectName(backAction->objectName());
          m_backAction->setShortcuts(backAction->shortcuts());
      }
 -    m_backAction->setPopupMode(QToolButton::DelayedPopup);
 +    m_backAction->setPopupMode(KToolBarPopupAction::DelayedPopup);
      connect(m_backAction, &QAction::triggered, this, &DolphinMainWindow::goBack);
 -    connect(m_backAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
 -    connect(m_backAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
 +    connect(m_backAction->popupMenu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowBackPopupMenu);
 +    connect(m_backAction->popupMenu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoBack);
      actionCollection()->addAction(m_backAction->objectName(), m_backAction);
  
      auto backShortcuts = m_backAction->shortcuts();
          m_forwardAction->setObjectName(forwardAction->objectName());
          m_forwardAction->setShortcuts(forwardAction->shortcuts());
      }
 -    m_forwardAction->setPopupMode(QToolButton::DelayedPopup);
 +    m_forwardAction->setPopupMode(KToolBarPopupAction::DelayedPopup);
      connect(m_forwardAction, &QAction::triggered, this, &DolphinMainWindow::goForward);
 -    connect(m_forwardAction->menu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
 -    connect(m_forwardAction->menu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
 +    connect(m_forwardAction->popupMenu(), &QMenu::aboutToShow, this, &DolphinMainWindow::slotAboutToShowForwardPopupMenu);
 +    connect(m_forwardAction->popupMenu(), &QMenu::triggered, this, &DolphinMainWindow::slotGoForward);
      actionCollection()->addAction(m_forwardAction->objectName(), m_forwardAction);
      actionCollection()->setDefaultShortcuts(m_forwardAction, m_forwardAction->shortcuts());
  
      // enable middle-click to open in a new tab
      auto *middleClickEventFilter = new MiddleClickActionEventFilter(this);
      connect(middleClickEventFilter, &MiddleClickActionEventFilter::actionMiddleClicked, this, &DolphinMainWindow::slotBackForwardActionMiddleClicked);
 -    m_backAction->menu()->installEventFilter(middleClickEventFilter);
 -    m_forwardAction->menu()->installEventFilter(middleClickEventFilter);
 +    m_backAction->popupMenu()->installEventFilter(middleClickEventFilter);
 +    m_forwardAction->popupMenu()->installEventFilter(middleClickEventFilter);
      KStandardAction::up(this, &DolphinMainWindow::goUp, actionCollection());
      QAction *homeAction = KStandardAction::home(this, &DolphinMainWindow::goHome, actionCollection());
      homeAction->setWhatsThis(xi18nc("@info:whatsthis",
@@@ -2398,6 -2387,7 +2398,7 @@@ void DolphinMainWindow::connectViewSign
  {
      connect(container, &DolphinViewContainer::showFilterBarChanged, this, &DolphinMainWindow::updateFilterBarAction);
      connect(container, &DolphinViewContainer::writeStateChanged, this, &DolphinMainWindow::slotWriteStateChanged);
+     slotWriteStateChanged(container->view()->isFolderWritable());
      connect(container, &DolphinViewContainer::searchModeEnabledChanged, this, &DolphinMainWindow::updateSearchAction);
      connect(container, &DolphinViewContainer::captionChanged, this, &DolphinMainWindow::updateWindowTitle);
      connect(container, &DolphinViewContainer::tabRequested, this, &DolphinMainWindow::openNewTab);
@@@ -2497,7 -2487,6 +2498,7 @@@ void DolphinMainWindow::createPanelActi
      panelAction->setText(dockAction->text());
      panelAction->setIcon(icon);
      dockAction->setIcon(icon);
 +    dockAction->setEnabled(true);
      actionCollection()->setDefaultShortcut(panelAction, shortcut);
  
      connect(panelAction, &QAction::triggered, dockAction, &QAction::trigger);
index 659e59f0f40e7fb9794aebd1f491f042110f0e2c,be22b91cce91a4af301520c8d79359135f1dabed..cf14836592ffe680a7cccb640a361f769eefa5c0
@@@ -236,7 -236,7 +236,7 @@@ void KItemListView::setVisibleRoles(con
          if (!m_headerWidget->automaticColumnResizing()) {
              // The column-width of new roles are still 0. Apply the preferred
              // column-width as default with.
 -            for (const QByteArray &role : qAsConst(m_visibleRoles)) {
 +            for (const QByteArray &role : std::as_const(m_visibleRoles)) {
                  if (m_headerWidget->columnWidth(role) == 0) {
                      const qreal width = m_headerWidget->preferredColumnWidth(role);
                      m_headerWidget->setColumnWidth(role, width);
@@@ -537,7 -537,7 +537,7 @@@ bool KItemListView::isElided(int index
      return m_sizeHintResolver->isElided(index);
  }
  
- void KItemListView::scrollToItem(int index)
+ void KItemListView::scrollToItem(int index, ViewItemPosition viewItemPosition)
  {
      QRectF viewGeometry = geometry();
      if (m_headerWidget->isVisible()) {
      }
      QRectF currentRect = itemRect(index);
  
-     // Fix for Bug 311099 - View the underscore when using Ctrl + PagDown
+     // Fix for Bug 311099 - View the underscore when using Ctrl + PageDown
      currentRect.adjust(-m_styleOption.horizontalMargin, -m_styleOption.verticalMargin, m_styleOption.horizontalMargin, m_styleOption.verticalMargin);
  
-     if (!viewGeometry.contains(currentRect)) {
-         qreal newOffset = scrollOffset();
-         if (scrollOrientation() == Qt::Vertical) {
+     qreal newOffset = scrollOffset();
+     if (scrollOrientation() == Qt::Vertical && (currentRect.top() < viewGeometry.top() || currentRect.bottom() > viewGeometry.bottom())) {
+         switch (viewItemPosition) {
+         case Beginning:
+             newOffset += currentRect.top() - viewGeometry.top();
+             break;
+         case Middle:
+             newOffset += 0.5 * (currentRect.top() + currentRect.bottom() - (viewGeometry.top() + viewGeometry.bottom()));
+             break;
+         case End:
+             newOffset += currentRect.bottom() - viewGeometry.bottom();
+             break;
+         case Nearest:
              if (currentRect.top() < viewGeometry.top()) {
                  newOffset += currentRect.top() - viewGeometry.top();
-             } else if (currentRect.bottom() > viewGeometry.bottom()) {
+             } else {
                  newOffset += currentRect.bottom() - viewGeometry.bottom();
              }
-         } else {
+             break;
+         default:
+             Q_UNREACHABLE();
+         }
+     } else if (scrollOrientation() == Qt::Horizontal && (currentRect.left() < viewGeometry.left() || currentRect.right() > viewGeometry.right())) {
+         switch (viewItemPosition) {
+         case Beginning:
+             if (layoutDirection() == Qt::RightToLeft) {
+                 newOffset += currentRect.right() - viewGeometry.right();
+             } else {
+                 newOffset += currentRect.left() - viewGeometry.left();
+             }
+             break;
+         case Middle:
+             newOffset += 0.5 * (currentRect.left() + currentRect.right() - (viewGeometry.left() + viewGeometry.right()));
+             break;
+         case End:
+             if (layoutDirection() == Qt::RightToLeft) {
+                 newOffset += currentRect.left() - viewGeometry.left();
+             } else {
+                 newOffset += currentRect.right() - viewGeometry.right();
+             }
+             break;
+         case Nearest:
              if (currentRect.left() < viewGeometry.left()) {
                  newOffset += currentRect.left() - viewGeometry.left();
-             } else if (currentRect.right() > viewGeometry.right()) {
+             } else {
                  newOffset += currentRect.right() - viewGeometry.right();
              }
+             break;
+         default:
+             Q_UNREACHABLE();
          }
+     }
  
-         if (newOffset != scrollOffset()) {
-             Q_EMIT scrollTo(newOffset);
-             return;
-         }
+     if (newOffset != scrollOffset()) {
+         Q_EMIT scrollTo(newOffset);
+         return;
      }
  
      Q_EMIT scrollingStopped();
@@@ -687,7 -723,7 +723,7 @@@ void KItemListView::paint(QPainter *pai
  {
      QGraphicsWidget::paint(painter, option, widget);
  
 -    for (auto animation : qAsConst(m_rubberBandAnimations)) {
 +    for (auto animation : std::as_const(m_rubberBandAnimations)) {
          QRectF rubberBandRect = animation->property(RubberPropertyName).toRectF();
  
          const QPointF topLeft = rubberBandRect.topLeft();
@@@ -1064,9 -1100,12 +1100,9 @@@ void KItemListView::updateFont(
  
  void KItemListView::updatePalette()
  {
 -    if (scene() && !scene()->views().isEmpty()) {
 -        KItemListStyleOption option = styleOption();
 -        option.palette = scene()->views().first()->palette();
 -
 -        setStyleOption(option);
 -    }
 +    KItemListStyleOption option = styleOption();
 +    option.palette = palette();
 +    setStyleOption(option);
  }
  
  void KItemListView::slotItemsInserted(const KItemRangeList &itemRanges)
@@@ -1250,7 -1289,7 +1286,7 @@@ void KItemListView::slotItemsRemoved(co
          // after the deleted items. It is important to update them in ascending
          // order to prevent overlaps when setting the new index.
          std::sort(itemsToMove.begin(), itemsToMove.end());
 -        for (int i : qAsConst(itemsToMove)) {
 +        for (int i : std::as_const(itemsToMove)) {
              KItemListWidget *widget = m_visibleItems.value(i);
              Q_ASSERT(widget);
              const int newIndex = i - count;
@@@ -1876,7 -1915,7 +1912,7 @@@ void KItemListView::doLayout(LayoutAnim
      }
  
      // Delete invisible KItemListWidget instances that have not been reused
 -    for (int index : qAsConst(reusableItems)) {
 +    for (int index : std::as_const(reusableItems)) {
          recycleWidget(m_visibleItems.value(index));
      }
  
@@@ -2252,7 -2291,7 +2288,7 @@@ QHash<QByteArray, qreal> KItemListView:
      const QFontMetricsF fontMetrics(m_headerWidget->font());
      const int gripMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderGripMargin);
      const int headerMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderMargin);
 -    for (const QByteArray &visibleRole : qAsConst(m_visibleRoles)) {
 +    for (const QByteArray &visibleRole : std::as_const(m_visibleRoles)) {
          const QString headerText = m_model->roleDescription(visibleRole);
          const qreal headerWidth = fontMetrics.horizontalAdvance(headerText) + gripMargin + headerMargin * 2;
          widths.insert(visibleRole, headerWidth);
          const int endIndex = startIndex + itemRange.count - 1;
  
          for (int i = startIndex; i <= endIndex; ++i) {
 -            for (const QByteArray &visibleRole : qAsConst(m_visibleRoles)) {
 +            for (const QByteArray &visibleRole : std::as_const(m_visibleRoles)) {
                  qreal maxWidth = widths.value(visibleRole, 0);
                  const qreal width = creator->preferredRoleColumnWidth(visibleRole, i, this);
                  maxWidth = qMax(width, maxWidth);
@@@ -2309,7 -2348,7 +2345,7 @@@ void KItemListView::applyColumnWidthsFr
  
  void KItemListView::updateWidgetColumnWidths(KItemListWidget *widget)
  {
 -    for (const QByteArray &role : qAsConst(m_visibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_visibleRoles)) {
          widget->setColumnWidth(role, m_headerWidget->columnWidth(role));
      }
      widget->setSidePadding(m_headerWidget->sidePadding());
@@@ -2326,7 -2365,7 +2362,7 @@@ void KItemListView::updatePreferredColu
  
      if (itemCount == rangesItemCount) {
          const QHash<QByteArray, qreal> preferredWidths = preferredColumnWidths(itemRanges);
 -        for (const QByteArray &role : qAsConst(m_visibleRoles)) {
 +        for (const QByteArray &role : std::as_const(m_visibleRoles)) {
              m_headerWidget->setPreferredColumnWidth(role, preferredWidths.value(role));
          }
      } else {
@@@ -2381,7 -2420,7 +2417,7 @@@ void KItemListView::applyAutomaticColum
      // size does not use the available view-size the size of the
      // first role will get stretched.
  
 -    for (const QByteArray &role : qAsConst(m_visibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_visibleRoles)) {
          const qreal preferredWidth = m_headerWidget->preferredColumnWidth(role);
          m_headerWidget->setColumnWidth(role, preferredWidth);
      }
  qreal KItemListView::columnWidthsSum() const
  {
      qreal widthsSum = 0;
 -    for (const QByteArray &role : qAsConst(m_visibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_visibleRoles)) {
          widthsSum += m_headerWidget->columnWidth(role);
      }
      return widthsSum;
index 52df17ad32ca6b3e495140f5574ee93bc51cdf39,0088e4116b34e2ab732e95d588de393b3b001a52..e37013f95fe88562313c8c42e1bd7cd72c165b9d
@@@ -1205,6 -1205,16 +1205,16 @@@ QString KStandardItemListWidget::elideR
      return m_customizedFontMetrics.elidedText(text, Qt::ElideRight, elidingWidth);
  }
  
+ QString KStandardItemListWidget::escapeString(const QString &text) const
+ {
+     QString escaped(text);
+     const QChar returnSymbol(0x21b5);
+     escaped.replace('\n', returnSymbol);
+     return escaped;
+ }
  void KStandardItemListWidget::updateIconsLayoutTextCache()
  {
      //      +------+
      // Initialize properties for the "text" role. It will be used as anchor
      // for initializing the position of the other roles.
      TextInfo *nameTextInfo = m_textInfo.value("text");
-     const QString nameText = KStringHandler::preProcessWrap(values["text"].toString());
+     const QString nameText = KStringHandler::preProcessWrap(escapeString(values["text"].toString()));
      nameTextInfo->staticText.setText(nameText);
  
      // Calculate the number of lines required for the name and the required width
  
      // Calculate the position for each additional information
      qreal y = nameTextInfo->pos.y() + nameHeight;
 -    for (const QByteArray &role : qAsConst(m_sortedVisibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_sortedVisibleRoles)) {
          if (role == "text") {
              continue;
          }
@@@ -1347,8 -1357,8 +1357,8 @@@ void KStandardItemListWidget::updateCom
      const qreal x = option.padding * 3 + iconSize();
      qreal y = qRound((widgetHeight - textLinesHeight) / 2);
      const qreal maxWidth = size().width() - x - option.padding;
 -    for (const QByteArray &role : qAsConst(m_sortedVisibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_sortedVisibleRoles)) {
-         const QString text = roleText(role, values);
+         const QString text = escapeString(roleText(role, values));
          TextInfo *textInfo = m_textInfo.value(role);
          textInfo->staticText.setText(text);
  
@@@ -1397,7 -1407,7 +1407,7 @@@ void KStandardItemListWidget::updateDet
      qreal x = firstColumnInc;
      const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
  
 -    for (const QByteArray &role : qAsConst(m_sortedVisibleRoles)) {
 +    for (const QByteArray &role : std::as_const(m_sortedVisibleRoles)) {
          QString text = roleText(role, values);
  
          // Elide the text in case it does not fit into the available column-width
  
          const bool isTextRole = (role == "text");
          if (isTextRole) {
+             text = escapeString(text);
              availableTextWidth -= firstColumnInc - sidePadding();
          }
  
@@@ -1544,18 -1555,13 +1555,18 @@@ void KStandardItemListWidget::closeRole
      m_roleEditor = nullptr;
  }
  
 -QPixmap KStandardItemListWidget::pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode)
 +QPixmap KStandardItemListWidget::pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode) const
  {
      static const QIcon fallbackIcon = QIcon::fromTheme(QStringLiteral("unknown"));
 +    qreal dpr = qApp->devicePixelRatio();
 +    if (scene() && !scene()->views().isEmpty()) {
 +        dpr = scene()->views().constFirst()->devicePixelRatioF();
 +    }
  
 -    size *= qApp->devicePixelRatio();
 +    size *= dpr;
  
 -    const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QLatin1Char(':')) % ":" % QString::number(size) % ":" % QString::number(mode);
 +    const QString key = "KStandardItemListWidget:" % name % ":" % overlays.join(QLatin1Char(':')) % ":" % QString::number(size) % "@" % QString::number(dpr)
 +        % ":" % QString::number(mode);
      QPixmap pixmap;
  
      if (!QPixmapCache::find(key, &pixmap)) {
          if (icon.isNull()) {
              icon = QIcon(name);
          }
 -        if (icon.isNull() || icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode).isNull()) {
 +        if (icon.isNull() || icon.pixmap(size / dpr, size / dpr, mode).isNull()) {
              icon = fallbackIcon;
          }
  
 -        pixmap = icon.pixmap(size / qApp->devicePixelRatio(), size / qApp->devicePixelRatio(), mode);
 +        pixmap = icon.pixmap(QSize(size / dpr, size / dpr), dpr, mode);
          if (pixmap.width() != size || pixmap.height() != size) {
              KPixmapModifier::scale(pixmap, QSize(size, size));
          }
  
          QPixmapCache::insert(key, pixmap);
      }
 -    pixmap.setDevicePixelRatio(qApp->devicePixelRatio());
 +    pixmap.setDevicePixelRatio(dpr);
  
      return pixmap;
  }
index 1313179c96703b52fdb13e63ebcacd5153781155,52cde1423851b16bba9682a39715cff163f53aca..a09f0c7a83090ae384f8d36dcff20c37a0c2fd03
@@@ -208,13 -208,20 +208,20 @@@ private
  
      QString elideRightKeepExtension(const QString &text, int elidingWidth) const;
  
+     /**
+      * Escapes text for display purposes.
+      *
+      * Replaces '\n' with Unicode line break (U+21B5).
+      */
+     QString escapeString(const QString &text) const;
      /**
       * Closes the role editor and returns the focus back
       * to the KItemListContainer.
       */
      void closeRoleEditor();
  
 -    static QPixmap pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode);
 +    QPixmap pixmapForIcon(const QString &name, const QStringList &overlays, int size, QIcon::Mode mode) const;
  
      /**
       * @return Preferred size of the rating-image based on the given
index 68073a16e36ac05178c3fd717b8b111b2e73c961,c81078095c1574e3023faf5a7c80bd41e196afc8..a1fada2adc8c4dde1a6e2d6b29163be2ab18c95f
@@@ -9,14 -9,18 +9,14 @@@
  #include "dolphin_contextmenusettings.h"
  #include "dolphin_versioncontrolsettings.h"
  #include "global.h"
 -#include "settings/serviceitemdelegate.h"
  #include "settings/servicemodel.h"
  
  #include <KDesktopFile>
 -#include <KDesktopFileActions>
  #include <KFileUtils>
  #include <KLocalizedString>
  #include <KMessageBox>
  #include <KPluginMetaData>
  #include <KService>
 -#include <KServiceTypeTrader>
 -#include <kio_version.h>
  #include <kiocore_export.h>
  #include <kservice_export.h>
  #include <kwidgetsaddons_version.h>
@@@ -69,6 -73,7 +69,6 @@@ ContextMenuSettingsPage::ContextMenuSet
      m_listView = new QListView(this);
      QScroller::grabGesture(m_listView->viewport(), QScroller::TouchGesture);
  
 -    auto *delegate = new ServiceItemDelegate(m_listView, m_listView);
      m_serviceModel = new ServiceModel(this);
      m_sortModel = new QSortFilterProxyModel(this);
      m_sortModel->setSourceModel(m_serviceModel);
@@@ -77,6 -82,7 +77,6 @@@
      m_sortModel->setFilterRole(Qt::DisplayRole);
      m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
      m_listView->setModel(m_sortModel);
 -    m_listView->setItemDelegate(delegate);
      m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
      connect(m_listView, &QListView::clicked, this, &ContextMenuSettingsPage::changed);
  
@@@ -170,15 -176,14 +170,14 @@@ void ContextMenuSettingsPage::applySett
  
      QStringList enabledPlugins;
  
-     const QAbstractItemModel *model = m_listView->model();
-     for (int i = 0; i < model->rowCount(); ++i) {
-         const QModelIndex index = model->index(i, 0);
-         const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
-         const bool checked = model->data(index, Qt::CheckStateRole).value<Qt::CheckState>() == Qt::Checked;
+     for (int i = 0; i < m_serviceModel->rowCount(); ++i) {
+         const QModelIndex index = m_serviceModel->index(i, 0);
+         const QString service = m_serviceModel->data(index, ServiceModel::DesktopEntryNameRole).toString();
 -        const bool checked = m_serviceModel->data(index, Qt::CheckStateRole).toBool();
++        const bool checked = m_serviceModel->data(index, Qt::CheckStateRole).value<Qt::CheckState>() == Qt::Checked;
  
          if (service.startsWith(VersionControlServicePrefix)) {
              if (checked) {
-                 enabledPlugins.append(model->data(index, Qt::DisplayRole).toString());
+                 enabledPlugins.append(m_serviceModel->data(index, Qt::DisplayRole).toString());
              }
          } else if (service == QLatin1String(DeleteService)) {
              KSharedConfig::Ptr globalConfig = KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::NoGlobals);
  
  void ContextMenuSettingsPage::restoreDefaults()
  {
-     QAbstractItemModel *model = m_listView->model();
-     for (int i = 0; i < model->rowCount(); ++i) {
-         const QModelIndex index = model->index(i, 0);
-         const QString service = model->data(index, ServiceModel::DesktopEntryNameRole).toString();
+     for (int i = 0; i < m_serviceModel->rowCount(); ++i) {
+         const QModelIndex index = m_serviceModel->index(i, 0);
+         const QString service = m_serviceModel->data(index, ServiceModel::DesktopEntryNameRole).toString();
  
          const bool checked =
              !service.startsWith(VersionControlServicePrefix) && service != QLatin1String(DeleteService) && service != QLatin1String(CopyToMoveToService);
-         model->setData(index, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
 -        m_serviceModel->setData(index, checked, Qt::CheckStateRole);
++        m_serviceModel->setData(index, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
      }
  }
  
@@@ -257,7 -261,7 +255,7 @@@ void ContextMenuSettingsPage::showEvent
              for (const QString &id : m_actionIds) {
                  const QAction *action = m_actions->action(id);
                  if (action) {
 -                    addRow(action->icon().name(), action->text(), id, entryVisible(id));
 +                    addRow(action->icon().name(), KLocalizedString::removeAcceleratorMarker(action->text()), id, entryVisible(id));
                  }
              }
          }
@@@ -278,8 -282,15 +276,8 @@@ void ContextMenuSettingsPage::loadServi
      const auto locations = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("kio/servicemenus"), QStandardPaths::LocateDirectory);
      QStringList files = KFileUtils::findAllUniqueFiles(locations);
  
 -#if KIOWIDGETS_BUILD_DEPRECATED_SINCE(5, 90)
 -    const KService::List services = KServiceTypeTrader::self()->query(QStringLiteral("KonqPopupMenu/Plugin"));
 -    for (const KService::Ptr &service : services) {
 -        files << QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kservices5/" % service->entryPath());
 -    }
 -#endif
 -
 -    for (const auto &file : qAsConst(files)) {
 -        const QList<KServiceAction> serviceActions = KDesktopFileActions::userDefinedServices(KService(file), true);
 +    for (const auto &file : std::as_const(files)) {
 +        const QList<KServiceAction> serviceActions = KService(file).actions();
  
          const KDesktopFile desktopFile(file);
          const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu");
          }
      }
  
 -    // Load service plugins, this is deprecated in KIO 5.82
 -#if KIOCORE_BUILD_DEPRECATED_SINCE(5, 82)
 -    const KService::List pluginServices = KServiceTypeTrader::self()->query(QStringLiteral("KFileItemAction/Plugin"));
 -    for (const KService::Ptr &service : pluginServices) {
 -        const QString desktopEntryName = service->desktopEntryName();
 -        if (!isInServicesList(desktopEntryName)) {
 -            const bool checked = showGroup.readEntry(desktopEntryName, true);
 -            addRow(service->icon(), service->name(), desktopEntryName, checked);
 -        }
 -    }
 -#endif
 -
      // Load JSON-based plugins that implement the KFileItemActionPlugin interface
 -    const auto jsonPlugins = KPluginMetaData::findPlugins(QStringLiteral("kf" QT_STRINGIFY(QT_VERSION_MAJOR)) + QStringLiteral("/kfileitemaction"));
 +    const auto jsonPlugins = KPluginMetaData::findPlugins(QStringLiteral("kf6/kfileitemaction"));
  
      for (const auto &jsonMetadata : jsonPlugins) {
          const QString desktopEntryName = jsonMetadata.pluginId();
@@@ -347,7 -370,7 +345,7 @@@ void ContextMenuSettingsPage::addRow(co
      m_serviceModel->setData(index, icon, Qt::DecorationRole);
      m_serviceModel->setData(index, text, Qt::DisplayRole);
      m_serviceModel->setData(index, value, ServiceModel::DesktopEntryNameRole);
 -    m_serviceModel->setData(index, checked, Qt::CheckStateRole);
 +    m_serviceModel->setData(index, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
  }
  
  #include "moc_contextmenusettingspage.cpp"
index 5bdc9e15f93ea9856a46218233670b4fef6d7b65,0a1d70bf11e334fc3d644861f4209c5546f95fc1..0bb73e6234c24ae35e021694771cf8c81e64861a
@@@ -35,7 -35,7 +35,7 @@@
  #include <KFileItemListProperties>
  #include <KFormat>
  #include <KIO/CopyJob>
 -#include <KIO/DeleteJob>
 +#include <KIO/DeleteOrTrashJob>
  #include <KIO/DropJob>
  #include <KIO/JobUiDelegate>
  #include <KIO/Paste>
@@@ -49,6 -49,9 +49,6 @@@
  
  #include <kwidgetsaddons_version.h>
  
 -#include <KIO/DeleteOrTrashJob>
 -#include <kio_version.h>
 -
  #include <QAbstractItemView>
  #include <QActionGroup>
  #include <QApplication>
@@@ -267,7 -270,6 +267,6 @@@ void DolphinView::setActive(bool active
      if (active) {
          m_container->setFocus();
          Q_EMIT activated();
-         Q_EMIT writeStateChanged(m_isFolderWritable);
      }
  }
  
@@@ -626,7 -628,7 +625,7 @@@ void DolphinView::requestStatusBarText(
              return;
          }
  
 -        m_statJobForStatusBarText = KIO::statDetails(m_model->rootItem().url(), KIO::StatJob::SourceSide, KIO::StatRecursiveSize, KIO::HideProgressInfo);
 +        m_statJobForStatusBarText = KIO::stat(m_model->rootItem().url(), KIO::StatJob::SourceSide, KIO::StatRecursiveSize, KIO::HideProgressInfo);
          connect(m_statJobForStatusBarText, &KJob::result, this, &DolphinView::slotStatJobResult);
          m_statJobForStatusBarText->start();
      }
@@@ -1759,7 -1761,7 +1758,7 @@@ void DolphinView::updateViewState(
  
                  // scroll to current item and reset the state
                  if (m_scrollToCurrentItem) {
-                     m_view->scrollToItem(currentIndex);
+                     m_view->scrollToItem(currentIndex, KItemListView::ViewItemPosition::Middle);
                      m_scrollToCurrentItem = false;
                  }
                  m_currentItemUrl = QUrl();
@@@ -2243,6 -2245,11 +2242,11 @@@ void DolphinView::updateWritableState(
      }
  }
  
+ bool DolphinView::isFolderWritable() const
+ {
+     return m_isFolderWritable;
+ }
  QUrl DolphinView::viewPropertiesUrl() const
  {
      if (m_viewPropertiesContext.isEmpty()) {
index 397ff5d5e5770d08f767ff3a6715b32869e441b2,f73c613e0a57dc774fd62665ce4755788ffa9205..98cbbdf80092c2612638800a3b0c1eb6c52ea365
@@@ -60,6 -60,7 +60,7 @@@ void DolphinViewActionHandler::setCurre
      connect(view, &DolphinView::sortRoleChanged, this, &DolphinViewActionHandler::slotSortRoleChanged);
      connect(view, &DolphinView::zoomLevelChanged, this, &DolphinViewActionHandler::slotZoomLevelChanged);
      connect(view, &DolphinView::writeStateChanged, this, &DolphinViewActionHandler::slotWriteStateChanged);
+     slotWriteStateChanged(view->isFolderWritable());
      connect(view, &DolphinView::selectionModeChangeRequested, this, [this](bool enabled) {
          Q_EMIT selectionModeChangeTriggered(enabled);
      });
@@@ -215,7 -216,7 +216,7 @@@ void DolphinViewActionHandler::createAc
      viewModeActions->addAction(compactAction);
      viewModeActions->addAction(detailsAction);
      viewModeActions->setToolBarMode(KSelectAction::MenuMode);
 -    connect(viewModeActions, &KSelectAction::triggered, this, &DolphinViewActionHandler::slotViewModeActionTriggered);
 +    connect(viewModeActions, &KSelectAction::actionTriggered, this, &DolphinViewActionHandler::slotViewModeActionTriggered);
  
      QAction *zoomInAction = KStandardAction::zoomIn(this, &DolphinViewActionHandler::zoomIn, m_actionCollection);
      zoomInAction->setWhatsThis(i18nc("@info:whatsthis zoom in", "This increases the icon size."));
@@@ -714,7 -715,7 +715,7 @@@ void DolphinViewActionHandler::slotSort
      // actions and the sub-menu-actions. If an action gets checked, it must
      // be assured that all other actions get unchecked, except the ascending/
      // descending actions
 -    for (QAction *groupAction : qAsConst(m_sortByActions)) {
 +    for (QAction *groupAction : std::as_const(m_sortByActions)) {
          KActionMenu *actionMenu = qobject_cast<KActionMenu *>(groupAction);
          if (actionMenu) {
              const auto actions = actionMenu->menu()->actions();