]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Merge remote-tracking branch 'origin/master' into kf6
authorMéven Car <meven@kde.org>
Sun, 10 Sep 2023 13:24:39 +0000 (15:24 +0200)
committerMéven Car <meven@kde.org>
Sun, 10 Sep 2023 13:24:39 +0000 (15:24 +0200)
1  2 
src/dolphincontextmenu.cpp
src/dolphinmainwindow.cpp
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kitemlistview.cpp
src/kitemviews/kstandarditemlistwidget.cpp
src/kitemviews/kstandarditemlistwidget.h
src/kitemviews/private/kitemlistheaderwidget.cpp
src/panels/places/placespanel.cpp
src/settings/contextmenu/contextmenusettingspage.cpp
src/settings/dolphinsettingsdialog.cpp
src/views/dolphinview.cpp

index f209633479ca0bb8b3a69ad17b4aaefed423b3b9,4dc54946f6f869586de4f9cb3f6ae9fdb2257b0c..34d2102ef0e83df6e5a90fb3fc09cf105c11436b
@@@ -7,7 -7,6 +7,6 @@@
  #include "dolphincontextmenu.h"
  
  #include "dolphin_contextmenusettings.h"
- #include "dolphin_generalsettings.h"
  #include "dolphinmainwindow.h"
  #include "dolphinnewfilemenu.h"
  #include "dolphinplacesmodelsingleton.h"
@@@ -16,7 -15,6 +15,6 @@@
  #include "global.h"
  #include "trash/dolphintrash.h"
  #include "views/dolphinview.h"
- #include "views/viewmodecontroller.h"
  
  #include <KActionCollection>
  #include <KFileItemListProperties>
@@@ -29,6 -27,7 +27,6 @@@
  #include <KLocalizedString>
  #include <KNewFileMenu>
  #include <KStandardAction>
 -#include <kio_version.h>
  
  #include <QApplication>
  #include <QClipboard>
@@@ -76,6 -75,8 +74,8 @@@ void DolphinContextMenu::addAllActions(
          m_context |= SearchContext;
      } else if (scheme.contains(QLatin1String("timeline"))) {
          m_context |= TimelineContext;
+     } else if (scheme == QStringLiteral("recentlyused")) {
+         m_context |= RecentlyUsedContext;
      }
  
      if (!m_fileInfo.isNull() && !m_selectedItems.isEmpty()) {
@@@ -137,7 -138,7 +137,7 @@@ void DolphinContextMenu::addTrashItemCo
      addAction(QIcon::fromTheme("restoration"), i18nc("@action:inmenu", "Restore"), [this]() {
          QList<QUrl> selectedUrls;
          selectedUrls.reserve(m_selectedItems.count());
 -        for (const KFileItem &item : qAsConst(m_selectedItems)) {
 +        for (const KFileItem &item : std::as_const(m_selectedItems)) {
              selectedUrls.append(item.url());
          }
  
@@@ -164,11 -165,15 +164,15 @@@ void DolphinContextMenu::addDirectoryIt
          addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_new_window")));
      }
  
+     if (ContextMenuSettings::showOpenInSplitView()) {
+         addAction(m_mainWindow->actionCollection()->action(QStringLiteral("open_in_split_view")));
+     }
      // Insert 'Open With' entries
      addOpenWithActions();
  
      // set up 'Create New' menu
 -    DolphinNewFileMenu *newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection(), m_mainWindow);
 +    DolphinNewFileMenu *newFileMenu = new DolphinNewFileMenu(m_mainWindow->actionCollection()->action(QStringLiteral("create_dir")), m_mainWindow);
      newFileMenu->checkUpToDate();
      newFileMenu->setWorkingDirectory(m_fileInfo.url());
      newFileMenu->setEnabled(selectedItemsProps.supportsWriting());
      addSeparator();
  }
  
+ void DolphinContextMenu::addOpenParentFolderActions()
+ {
+     addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18nc("@action:inmenu", "Open Path"), [this]() {
+         const QUrl url = m_fileInfo.targetUrl();
+         const QUrl parentUrl = KIO::upUrl(url);
+         m_mainWindow->changeUrl(parentUrl);
+         m_mainWindow->activeViewContainer()->view()->markUrlsAsSelected({url});
+         m_mainWindow->activeViewContainer()->view()->markUrlAsCurrent(url);
+     });
+     addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "Open Path in New Tab"), [this]() {
+         m_mainWindow->openNewTab(KIO::upUrl(m_fileInfo.targetUrl()));
+     });
+     addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@action:inmenu", "Open Path in New Window"), [this]() {
+         Dolphin::openNewWindow({m_fileInfo.targetUrl()}, m_mainWindow, Dolphin::OpenNewWindowFlag::Select);
+     });
+ }
  void DolphinContextMenu::addItemContextMenu()
  {
      Q_ASSERT(!m_fileInfo.isNull());
          // single files
          if (m_fileInfo.isDir()) {
              addDirectoryItemContextMenu();
-         } else if (m_context & TimelineContext || m_context & SearchContext) {
+         } else if (m_context & TimelineContext || m_context & SearchContext || m_context & RecentlyUsedContext) {
              addOpenWithActions();
  
-             addAction(QIcon::fromTheme(QStringLiteral("document-open-folder")), i18nc("@action:inmenu", "Open Path"), [this]() {
-                 m_mainWindow->changeUrl(KIO::upUrl(m_fileInfo.url()));
-                 m_mainWindow->activeViewContainer()->view()->markUrlsAsSelected({m_fileInfo.url()});
-                 m_mainWindow->activeViewContainer()->view()->markUrlAsCurrent(m_fileInfo.url());
-             });
-             addAction(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "Open Path in New Tab"), [this]() {
-                 m_mainWindow->openNewTab(KIO::upUrl(m_fileInfo.url()));
-             });
-             addAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("@action:inmenu", "Open Path in New Window"), [this]() {
-                 Dolphin::openNewWindow({m_fileInfo.url()}, m_mainWindow, Dolphin::OpenNewWindowFlag::Select);
-             });
+             addOpenParentFolderActions();
  
              addSeparator();
          } else {
      } else {
          // multiple files
          bool selectionHasOnlyDirs = true;
 -        for (const auto &item : qAsConst(m_selectedItems)) {
 +        for (const auto &item : std::as_const(m_selectedItems)) {
              const QUrl &url = DolphinView::openItemAsFolderUrl(item);
              if (url.isEmpty()) {
                  selectionHasOnlyDirs = false;
index 7064c63c93b22a25ba317a47b829fab8897ec46b,744ad8f0aa980d6ea00ef5a09421efdff0194aa5..a88e1a594af3207580f73134d71e32692b66bdba
@@@ -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());
@@@ -506,12 -497,38 +506,38 @@@ void DolphinMainWindow::openInNewWindow
      }
  }
  
+ void DolphinMainWindow::openInSplitView(const QUrl &url)
+ {
+     QUrl newSplitViewUrl = url;
+     if (newSplitViewUrl.isEmpty()) {
+         const KFileItemList list = m_activeViewContainer->view()->selectedItems();
+         if (list.count() == 1) {
+             const KFileItem &item = list.first();
+             newSplitViewUrl = DolphinView::openItemAsFolderUrl(item);
+         }
+     }
+     if (newSplitViewUrl.isEmpty()) {
+         return;
+     }
+     DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
+     if (tabPage->splitViewEnabled()) {
+         tabPage->switchActiveView();
+         tabPage->activeViewContainer()->setUrl(newSplitViewUrl);
+     } else {
+         tabPage->setSplitViewEnabled(true, WithAnimation, newSplitViewUrl);
+         updateViewActions();
+     }
+ }
  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);
@@@ -818,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);
      }
  }
  
@@@ -847,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);
      }
  }
  
@@@ -895,7 -911,6 +921,6 @@@ void DolphinMainWindow::toggleSplitView
  {
      DolphinTabPage *tabPage = m_tabWidget->currentTabPage();
      tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled(), WithAnimation);
      updateViewActions();
  }
  
@@@ -1154,7 -1169,8 +1179,8 @@@ void DolphinMainWindow::openTerminalHer
  {
      QList<QUrl> urls = {};
  
-     for (const KFileItem &item : m_activeViewContainer->view()->selectedItems()) {
+     const auto selectedItems = m_activeViewContainer->view()->selectedItems();
+     for (const KFileItem &item : selectedItems) {
          QUrl url = item.targetUrl();
          if (item.isFile()) {
              url.setPath(QFileInfo(url.path()).absolutePath());
  
      if (urls.count() > 5) {
          QString question = i18np("Are you sure you want to open 1 terminal window?", "Are you sure you want to open %1 terminal windows?", urls.count());
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
-         const int answer = KMessageBox::warningTwoActions(
-             this,
-             question,
-             {},
- #else
-         const int answer = KMessageBox::warningYesNo(
+         const int answer = KMessageBox::warningContinueCancel(
              this,
              question,
              {},
- #endif
              KGuiItem(i18ncp("@action:button", "Open %1 Terminal", "Open %1 Terminals", urls.count()), QStringLiteral("utilities-terminal")),
-             KStandardGuiItem::cancel());
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
-         if (answer != KMessageBox::PrimaryAction) {
- #else
-         if (answer != KMessageBox::Yes) {
- #endif
+             KStandardGuiItem::cancel(),
+             QStringLiteral("ConfirmOpenManyTerminals"));
+         if (answer != KMessageBox::PrimaryAction && answer != KMessageBox::Continue) {
              return;
          }
      }
  
-     for (const QUrl &url : urls) {
+     for (const QUrl &url : std::as_const(urls)) {
          openTerminalJob(url);
      }
  }
@@@ -1533,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")));
      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",
      openInNewWindow->setText(i18nc("@action:inmenu", "Open in New Window"));
      openInNewWindow->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
      connect(openInNewWindow, &QAction::triggered, this, &DolphinMainWindow::openInNewWindow);
+     QAction *openInSplitViewAction = actionCollection()->addAction(QStringLiteral("open_in_split_view"));
+     openInSplitViewAction->setText(i18nc("@action:inmenu", "Open in Split View"));
+     openInSplitViewAction->setIcon(QIcon::fromTheme(QStringLiteral("view-right-new")));
+     connect(openInSplitViewAction, &QAction::triggered, this, [this]() {
+         openInSplitView(QUrl());
+     });
  }
  
  void DolphinMainWindow::setupDockWidgets()
      connect(m_placesPanel, &PlacesPanel::newWindowRequested, this, [this](const QUrl &url) {
          Dolphin::openNewWindow({url}, this);
      });
+     connect(m_placesPanel, &PlacesPanel::openInSplitViewRequested, this, &DolphinMainWindow::openInSplitView);
      connect(m_placesPanel, &PlacesPanel::errorMessage, this, &DolphinMainWindow::showErrorMessage);
      connect(this, &DolphinMainWindow::urlChanged, m_placesPanel, &PlacesPanel::setUrl);
      connect(placesDock, &DolphinDockWidget::visibilityChanged, &DolphinUrlNavigatorsController::slotPlacesPanelVisibilityChanged);
@@@ -2473,7 -2486,6 +2497,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 a175e0bfe0e65076c3711f263708157da079c87d,f42f2c193877d34183fff9cc82e74f766c39425f..77d5a319ca5670c585a6cfaed78fbf0db7c50ec5
@@@ -17,6 -17,7 +17,6 @@@
  #include <KIO/Job>
  #include <KLocalizedString>
  #include <KUrlMimeData>
 -#include <kio_version.h>
  
  #include <QElapsedTimer>
  #include <QIcon>
@@@ -981,7 -982,7 +981,7 @@@ void KFileItemModel::resortAllItems(
      // been moved because of the resorting.
      QList<QUrl> oldUrls;
      oldUrls.reserve(itemCount);
 -    for (const ItemData *itemData : qAsConst(m_itemData)) {
 +    for (const ItemData *itemData : std::as_const(m_itemData)) {
          oldUrls.append(itemData->item.url());
      }
  
@@@ -1196,7 -1197,12 +1196,12 @@@ void KFileItemModel::slotItemsDeleted(c
  
      for (const KFileItem &item : items) {
          if (item.url() == currentDir) {
-             Q_EMIT currentDirectoryRemoved();
+             // #473377: Delay emitting currentDirectoryRemoved() to avoid modifying KCoreDirLister
+             // before KCoreDirListerCache::deleteDir() returns.
+             QTimer::singleShot(0, this, [this] {
+                 Q_EMIT currentDirectoryRemoved();
+             });
              return;
          }
  
          indexesToRemoveWithChildren.reserve(m_itemData.count());
  
          const int itemCount = m_itemData.count();
 -        for (int index : qAsConst(indexesToRemove)) {
 +        for (int index : std::as_const(indexesToRemove)) {
              indexesToRemoveWithChildren.append(index);
  
              const int parentLevel = expandedParentsCount(index);
@@@ -1644,7 -1650,7 +1649,7 @@@ void KFileItemModel::prepareItemsForSor
      case DeletionTimeRole:
          // These roles can be determined with retrieveData, and they have to be stored
          // in the QHash "values" for the sorting.
 -        for (ItemData *itemData : qAsConst(itemDataList)) {
 +        for (ItemData *itemData : std::as_const(itemDataList)) {
              if (itemData->values.isEmpty()) {
                  itemData->values = retrieveData(itemData->item, itemData->parent);
              }
  
      case TypeRole:
          // At least store the data including the file type for items with known MIME type.
 -        for (ItemData *itemData : qAsConst(itemDataList)) {
 +        for (ItemData *itemData : std::as_const(itemDataList)) {
              if (itemData->values.isEmpty()) {
                  const KFileItem item = itemData->item;
                  if (item.isDir() || item.isMimeTypeKnown()) {
@@@ -2593,7 -2599,7 +2598,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 33a341081a7978de7dbda9bdcfcf24f34b298356,38d21ff5e73b23df49c732027680a9b5cc4e83af..d43438c30026409a6cdb817c253c360c35a359ea
@@@ -231,7 -231,7 +231,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);
@@@ -361,7 -361,7 +361,7 @@@ void KItemListView::setGeometry(const Q
          if (m_headerWidget->automaticColumnResizing()) {
              applyAutomaticColumnWidths();
          } else {
-             const qreal requiredWidth = columnWidthsSum();
+             const qreal requiredWidth = columnWidthsSum() + 2 * m_headerWidget->sidePadding();
              const QSizeF dynamicItemSize(qMax(newSize.width(), requiredWidth), m_itemSize.height());
              m_layouter->setItemSize(dynamicItemSize);
          }
@@@ -669,7 -669,7 +669,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();
@@@ -961,6 -961,18 +961,18 @@@ bool KItemListView::event(QEvent *event
          updateFont();
          break;
  
+     case QEvent::FocusIn:
+         focusInEvent(static_cast<QFocusEvent *>(event));
+         event->accept();
+         return true;
+         break;
+     case QEvent::FocusOut:
+         focusOutEvent(static_cast<QFocusEvent *>(event));
+         event->accept();
+         return true;
+         break;
      default:
          // Forward all other events to the controller and handle them there
          if (!m_editingRole && m_controller && m_controller->processEvent(event, transform())) {
@@@ -1034,9 -1046,12 +1046,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)
@@@ -1220,7 -1235,7 +1232,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;
@@@ -1846,7 -1861,7 +1858,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));
      }
  
@@@ -2222,7 -2237,7 +2234,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);
  void KItemListView::applyColumnWidthsFromHeader()
  {
      // Apply the new size to the layouter
-     const qreal requiredWidth = columnWidthsSum() + m_headerWidget->sidePadding();
+     const qreal requiredWidth = columnWidthsSum() + 2 * m_headerWidget->sidePadding();
      const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth), m_itemSize.height());
      m_layouter->setItemSize(dynamicItemSize);
  
  
  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());
@@@ -2296,7 -2311,7 +2308,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 {
@@@ -2351,7 -2366,7 +2363,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 firstColumnWidth = m_headerWidget->columnWidth(firstRole);
      QSizeF dynamicItemSize = m_itemSize;
  
-     qreal requiredWidth = columnWidthsSum() + m_headerWidget->sidePadding()
-         + m_headerWidget->sidePadding(); // Adding the padding a second time so we have the same padding symmetrically on both sides of the view.
-     // This improves UX, looks better and increases the chances of users figuring out that the padding area can be used for deselecting and dropping files.
+     qreal requiredWidth = columnWidthsSum() + 2 * m_headerWidget->sidePadding(); // Adding the padding a second time so we have the same padding
+     // symmetrically on both sides of the view. This improves UX, looks better and increases the chances of users figuring out that the padding
+     // area can be used for deselecting and dropping files.
      const qreal availableWidth = size().width();
      if (requiredWidth < availableWidth) {
          // Stretch the first column to use the whole remaining width
  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 499a5041643ca714ac3dac48706aedce88d39dc7,01b135038d3d1707f3a6f1f9c896f832c0cc6be4..52df17ad32ca6b3e495140f5574ee93bc51cdf39
@@@ -386,7 -386,7 +386,7 @@@ void KStandardItemListWidget::paint(QPa
      }
  
      painter->setFont(m_customizedFont);
-     painter->setPen(textColor());
+     painter->setPen(textColor(*widget));
      const TextInfo *textInfo = m_textInfo.value("text");
  
      if (!textInfo) {
@@@ -645,7 -645,7 +645,7 @@@ void KStandardItemListWidget::setTextCo
      }
  }
  
- QColor KStandardItemListWidget::textColor() const
+ QColor KStandardItemListWidget::textColor(const QWidget &widget) const
  {
      if (!isSelected()) {
          if (m_isHidden) {
          }
      }
  
-     const QPalette::ColorGroup group = isActiveWindow() ? QPalette::Active : QPalette::Inactive;
+     const QPalette::ColorGroup group = isActiveWindow() && widget.hasFocus() ? QPalette::Active : QPalette::Inactive;
      const QPalette::ColorRole role = isSelected() ? QPalette::HighlightedText : normalTextColorRole();
      return styleOption().palette.color(group, role);
  }
@@@ -1015,8 -1015,11 +1015,11 @@@ void KStandardItemListWidget::updatePix
                  iconName = QStringLiteral("unknown");
              }
              const QStringList overlays = values["iconOverlays"].toStringList();
-             m_pixmap =
-                 pixmapForIcon(iconName, overlays, maxIconHeight, m_layout != IconsLayout && isActiveWindow() && isSelected() ? QIcon::Selected : QIcon::Normal);
+             const bool hasFocus = scene()->views()[0]->parentWidget()->hasFocus();
+             m_pixmap = pixmapForIcon(iconName,
+                                      overlays,
+                                      maxIconHeight,
+                                      m_layout != IconsLayout && isActiveWindow() && isSelected() && hasFocus ? QIcon::Selected : QIcon::Normal);
  
          } else if (m_pixmap.width() / m_pixmap.devicePixelRatio() != maxIconWidth || m_pixmap.height() / m_pixmap.devicePixelRatio() != maxIconHeight) {
              // A custom pixmap has been applied. Assure that the pixmap
@@@ -1278,7 -1281,7 +1281,7 @@@ void KStandardItemListWidget::updateIco
  
      // 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;
          }
@@@ -1344,7 -1347,7 +1347,7 @@@ 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);
          TextInfo *textInfo = m_textInfo.value(role);
          textInfo->staticText.setText(text);
@@@ -1394,7 -1397,7 +1397,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
  void KStandardItemListWidget::updateAdditionalInfoTextColor()
  {
      QColor c1;
+     const bool hasFocus = scene()->views()[0]->parentWidget()->hasFocus();
      if (m_customTextColor.isValid()) {
          c1 = m_customTextColor;
-     } else if (isSelected() && (m_layout != DetailsLayout || m_highlightEntireRow)) {
+     } else if (isSelected() && hasFocus && (m_layout != DetailsLayout || m_highlightEntireRow)) {
          // The detail text colour needs to match the main text (HighlightedText) for the same level
          // of readability. We short circuit early here to avoid interpolating with another colour.
          m_additionalInfoTextColor = styleOption().palette.color(QPalette::HighlightedText);
@@@ -1540,18 -1544,13 +1544,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 73bc393f4ad0ec2db60ce88d6f7e0f3f87c685c8,c4f80af1ddbdc1b35f1211d87c24e748254128f4..1313179c96703b52fdb13e63ebcacd5153781155
@@@ -139,7 -139,7 +139,7 @@@ protected
      virtual QPalette::ColorRole normalTextColorRole() const;
  
      void setTextColor(const QColor &color);
-     QColor textColor() const;
+     QColor textColor(const QWidget &widget) const;
  
      void setOverlay(const QPixmap &overlay);
      QPixmap overlay() const;
          QPointF pos;
          QStaticText staticText;
      };
+     void updateAdditionalInfoTextColor();
  
  public Q_SLOTS:
      void finishRoleEditing();
@@@ -200,8 -201,6 +201,6 @@@ private
      void updateCompactLayoutTextCache();
      void updateDetailsLayoutTextCache();
  
-     void updateAdditionalInfoTextColor();
      void drawPixmap(QPainter *painter, const QPixmap &pixmap);
      void drawSiblingsInformation(QPainter *painter);
  
       */
      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 3e12325615fbade7c6a7c4b079301e400407720b,82e5dde97754535b6d9e5e2d7e33e7bca72f7dc4..02a4f939d13b2e26f0b3e43ed301799a6a57e739
@@@ -136,7 -136,7 +136,7 @@@ void KItemListHeaderWidget::setSidePadd
  {
      if (m_sidePadding != width) {
          m_sidePadding = width;
-         sidePaddingChanged(width);
+         Q_EMIT sidePaddingChanged(width);
          update();
      }
  }
@@@ -167,7 -167,7 +167,7 @@@ void KItemListHeaderWidget::paint(QPain
  
      qreal x = -m_offset + m_sidePadding;
      int orderIndex = 0;
 -    for (const QByteArray &role : qAsConst(m_columns)) {
 +    for (const QByteArray &role : std::as_const(m_columns)) {
          const qreal roleWidth = m_columnWidths.value(role);
          const QRectF rect(x, 0, roleWidth, size().height());
          paintRole(painter, role, rect, orderIndex, widget);
@@@ -507,7 -507,7 +507,7 @@@ int KItemListHeaderWidget::roleIndexAt(
      int index = -1;
  
      qreal x = -m_offset + m_sidePadding;
 -    for (const QByteArray &role : qAsConst(m_columns)) {
 +    for (const QByteArray &role : std::as_const(m_columns)) {
          ++index;
          x += m_columnWidths.value(role);
          if (pos.x() <= x) {
@@@ -540,7 -540,7 +540,7 @@@ bool KItemListHeaderWidget::isAbovePadd
          return pos.x() >= (lx - grip) && pos.x() <= lx;
      case Trailing: {
          qreal rx = lx;
 -        for (const QByteArray &role : qAsConst(m_columns)) {
 +        for (const QByteArray &role : std::as_const(m_columns)) {
              rx += m_columnWidths.value(role);
          }
          return pos.x() >= (rx - grip) && pos.x() <= rx;
@@@ -604,7 -604,7 +604,7 @@@ int KItemListHeaderWidget::targetOfMovi
  qreal KItemListHeaderWidget::roleXPosition(const QByteArray &role) const
  {
      qreal x = -m_offset + m_sidePadding;
 -    for (const QByteArray &visibleRole : qAsConst(m_columns)) {
 +    for (const QByteArray &visibleRole : std::as_const(m_columns)) {
          if (visibleRole == role) {
              return x;
          }
index 8b245f0e72a2c16ab5caa8fa6e75fa2b1de90af4,e3d133ff0555b083c70ecad2b56c09d052b48b1a..8bdb18ba224681d1cece10e21f1dff5dd1004baa
@@@ -47,6 -47,15 +47,15 @@@ PlacesPanel::PlacesPanel(QWidget *paren
      connect(m_configureTrashAction, &QAction::triggered, this, &PlacesPanel::slotConfigureTrash);
      addAction(m_configureTrashAction);
  
+     m_openInSplitView = new QAction(QIcon::fromTheme(QStringLiteral("view-right-new")), i18nc("@action:inmenu", "Open in Split View"));
+     m_openInSplitView->setPriority(QAction::HighPriority);
+     connect(m_openInSplitView, &QAction::triggered, this, [this]() {
+         const QUrl url = currentIndex().data(KFilePlacesModel::UrlRole).toUrl();
+         Q_EMIT openInSplitViewRequested(url);
+     });
+     addAction(m_openInSplitView);
      connect(this, &PlacesPanel::contextMenuAboutToShow, this, &PlacesPanel::slotContextMenuAboutToShow);
  
      connect(this, &PlacesPanel::iconSizeChanged, this, [](const QSize &newSize) {
@@@ -141,7 -150,7 +150,7 @@@ static bool isInternalDrag(const QMimeD
  
  void PlacesPanel::dragMoveEvent(QDragMoveEvent *event)
  {
 -    const QModelIndex index = indexAt(event->pos());
 +    const QModelIndex index = indexAt(event->position().toPoint());
      if (index.isValid()) {
          auto *placesModel = static_cast<KFilePlacesModel *>(model());
  
@@@ -188,6 -197,7 +197,7 @@@ void PlacesPanel::slotContextMenuAboutT
      const Solid::Device device = placesModel->deviceForIndex(index);
  
      m_configureTrashAction->setVisible(url.scheme() == QLatin1String("trash"));
+     m_openInSplitView->setVisible(url.isValid());
  
      // show customContextMenuActions only on the view's context menu
      if (!url.isValid() && !device.isValid()) {
index 5e755d249d97cd39fade45a25c308d7cb6756a4c,23ddfba31deed43f865162294b397e845266879c..1c83e477ea43305d559b85fd805705c6a8752182
@@@ -7,9 -7,9 +7,8 @@@
  #include "contextmenusettingspage.h"
  
  #include "dolphin_contextmenusettings.h"
- #include "dolphin_generalsettings.h"
  #include "dolphin_versioncontrolsettings.h"
  #include "global.h"
 -#include "settings/serviceitemdelegate.h"
  #include "settings/servicemodel.h"
  
  #include <KDesktopFile>
@@@ -19,6 -19,8 +18,6 @@@
  #include <KMessageBox>
  #include <KPluginMetaData>
  #include <KService>
 -#include <KServiceTypeTrader>
 -#include <kio_version.h>
  #include <kiocore_export.h>
  #include <kservice_export.h>
  #include <kwidgetsaddons_version.h>
@@@ -71,6 -73,7 +70,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);
@@@ -79,6 -82,7 +78,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);
  
@@@ -118,6 -122,8 +117,8 @@@ bool ContextMenuSettingsPage::entryVisi
          return ContextMenuSettings::showOpenInNewTab();
      } else if (id == "open_in_new_window") {
          return ContextMenuSettings::showOpenInNewWindow();
+     } else if (id == "open_in_split_view") {
+         return ContextMenuSettings::showOpenInSplitView();
      } else if (id == "copy_location") {
          return ContextMenuSettings::showCopyLocation();
      } else if (id == "duplicate") {
@@@ -144,6 -150,8 +145,8 @@@ void ContextMenuSettingsPage::setEntryV
          ContextMenuSettings::setShowOpenInNewTab(visible);
      } else if (id == "open_in_new_window") {
          ContextMenuSettings::setShowOpenInNewWindow(visible);
+     } else if (id == "open_in_split_view") {
+         return ContextMenuSettings::setShowOpenInSplitView(visible);
      } else if (id == "copy_location") {
          ContextMenuSettings::setShowCopyLocation(visible);
      } else if (id == "duplicate") {
@@@ -172,7 -180,7 +175,7 @@@ void ContextMenuSettingsPage::applySett
      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).toBool();
 +        const bool checked = model->data(index, Qt::CheckStateRole).value<Qt::CheckState>() == Qt::Checked;
  
          if (service.startsWith(VersionControlServicePrefix)) {
              if (checked) {
          VersionControlSettings::self()->save();
  
          if (!laterSelected) {
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
              KMessageBox::ButtonCode promptRestart =
                  KMessageBox::questionTwoActions(window(),
- #else
-             KMessageBox::ButtonCode promptRestart =
-                 KMessageBox::questionYesNo(window(),
- #endif
                                                  i18nc("@info",
                                                        "Dolphin must be restarted to apply the "
                                                        "updated version control system settings."),
                                                  i18nc("@info", "Restart now?"),
                                                  KGuiItem(QApplication::translate("KStandardGuiItem", "&Restart"), QStringLiteral("dialog-restart")),
                                                  KGuiItem(QApplication::translate("KStandardGuiItem", "&Later"), QStringLiteral("dialog-later")));
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
              if (promptRestart == KMessageBox::ButtonCode::PrimaryAction) {
- #else
-             if (promptRestart == KMessageBox::ButtonCode::Yes) {
- #endif
                  Dolphin::openNewWindow();
                  qApp->quit();
              } else {
@@@ -237,7 -236,7 +231,7 @@@ void ContextMenuSettingsPage::restoreDe
  
          const bool checked =
              !service.startsWith(VersionControlServicePrefix) && service != QLatin1String(DeleteService) && service != QLatin1String(CopyToMoveToService);
 -        model->setData(index, checked, Qt::CheckStateRole);
 +        model->setData(index, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
      }
  }
  
@@@ -264,7 -263,7 +258,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));
                  }
              }
          }
@@@ -285,7 -284,14 +279,7 @@@ 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)) {
 +    for (const auto &file : std::as_const(files)) {
          const QList<KServiceAction> serviceActions = KDesktopFileActions::userDefinedServices(KService(file), true);
  
          const KDesktopFile desktopFile(file);
          }
      }
  
 -    // 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();
@@@ -354,7 -372,7 +348,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 0d2c76e3c8b841d142bba10a5bea70aa9cd14083,d05d5a81414ec37a5f20444da313a6970b20bf36..8c41794e93b593d9b11a9ffeda3b6208c44c7dd3
@@@ -68,6 -68,7 +68,7 @@@ DolphinSettingsDialog::DolphinSettingsD
                                                                  QStringLiteral("view_mode"),
                                                                  QStringLiteral("open_in_new_tab"),
                                                                  QStringLiteral("open_in_new_window"),
+                                                                 QStringLiteral("open_in_split_view"),
                                                                  QStringLiteral("copy_location"),
                                                                  QStringLiteral("duplicate"),
                                                                  QStringLiteral("open_terminal_here"),
@@@ -129,7 -130,7 +130,7 @@@ void DolphinSettingsDialog::enableApply
  
  void DolphinSettingsDialog::applySettings()
  {
 -    for (SettingsPageBase *page : qAsConst(m_pages)) {
 +    for (SettingsPageBase *page : std::as_const(m_pages)) {
          page->applySettings();
      }
  
  
  void DolphinSettingsDialog::restoreDefaults()
  {
 -    for (SettingsPageBase *page : qAsConst(m_pages)) {
 +    for (SettingsPageBase *page : std::as_const(m_pages)) {
          page->restoreDefaults();
      }
  }
@@@ -160,29 -161,17 +161,17 @@@ void DolphinSettingsDialog::closeEvent(
          return;
      }
  
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
      const auto response = KMessageBox::warningTwoActionsCancel(this,
- #else
-     const auto response = KMessageBox::warningYesNoCancel(this,
- #endif
                                                                 i18n("You have unsaved changes. Do you want to apply the changes or discard them?"),
                                                                 i18n("Warning"),
                                                                 KStandardGuiItem::save(),
                                                                 KStandardGuiItem::discard(),
                                                                 KStandardGuiItem::cancel());
      switch (response) {
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
      case KMessageBox::PrimaryAction:
- #else
-     case KMessageBox::Yes:
- #endif
          applySettings();
          Q_FALLTHROUGH();
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
      case KMessageBox::SecondaryAction:
- #else
-     case KMessageBox::No:
- #endif
          event->accept();
          break;
      case KMessageBox::Cancel:
index 3beb246a1abd84b53755c80b878aa1c8d474947e,21e23d5acae65b838c86c9c198ece771904dc8c8..e27f423f6b79c2a2f863f79f921696b30b2d6218
@@@ -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>
@@@ -276,6 -279,10 +276,10 @@@ bool DolphinView::isActive() cons
  void DolphinView::setViewMode(Mode mode)
  {
      if (mode != m_mode) {
+         // Reset scrollbars before changing the view mode.
+         m_container->horizontalScrollBar()->setValue(0);
+         m_container->verticalScrollBar()->setValue(0);
          ViewProperties props(viewPropertiesUrl());
          props.setViewMode(mode);
  
@@@ -619,7 -626,7 +623,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();
      }
@@@ -1055,24 -1062,14 +1059,14 @@@ void DolphinView::slotItemsActivated(co
  
      if (indexes.count() > 5) {
          QString question = i18np("Are you sure you want to open 1 item?", "Are you sure you want to open %1 items?", indexes.count());
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
-         const int answer = KMessageBox::warningTwoActions(
+         const int answer = KMessageBox::warningContinueCancel(
              this,
              question,
              {},
- #else
-         const int answer =
-             KMessageBox::warningYesNo(this,
-                                       question,
-                                       {},
- #endif
              KGuiItem(i18ncp("@action:button", "Open %1 Item", "Open %1 Items", indexes.count()), QStringLiteral("document-open")),
-             KStandardGuiItem::cancel());
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
-         if (answer != KMessageBox::PrimaryAction) {
- #else
-         if (answer != KMessageBox::Yes) {
- #endif
+             KStandardGuiItem::cancel(),
+             QStringLiteral("ConfirmOpenManyFolders"));
+         if (answer != KMessageBox::PrimaryAction && answer != KMessageBox::Continue) {
              return;
          }
      }
@@@ -1426,6 -1423,14 +1420,14 @@@ void DolphinView::slotItemCreated(cons
      }
  }
  
+ void DolphinView::onDirectoryLoadingCompleted()
+ {
+     // the model should now contain all the items created by the job
+     updateSelectionState();
+     m_selectJobCreatedItems = false;
+     m_selectedUrls.clear();
+ }
  void DolphinView::slotJobResult(KJob *job)
  {
      if (job->error() && job->error() != KIO::ERR_USER_CANCELED) {
          updateSelectionState();
          if (!m_selectedUrls.isEmpty()) {
              // not all urls were found, the model may not be up to date
-             // TODO KF6 replace with Qt::singleShotConnection
-             QMetaObject::Connection *const connection = new QMetaObject::Connection;
-             *connection = connect(
-                 m_model,
-                 &KFileItemModel::directoryLoadingCompleted,
-                 this,
-                 [this, connection]() {
-                     // the model should now contain all the items created by the job
-                     updateSelectionState();
-                     m_selectJobCreatedItems = false;
-                     m_selectedUrls.clear();
-                     QObject::disconnect(*connection);
-                     delete connection;
-                 },
-                 Qt::UniqueConnection);
+             connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::onDirectoryLoadingCompleted, Qt::UniqueConnection);
          } else {
              m_selectJobCreatedItems = false;
              m_selectedUrls.clear();
@@@ -1998,13 -1989,8 +1986,8 @@@ void DolphinView::slotRoleEditingFinish
              if (!hiddenFilesShown() && newName.startsWith(QLatin1Char('.')) && !oldItem.name().startsWith(QLatin1Char('.'))) {
                  KGuiItem yesGuiItem(i18nc("@action:button", "Rename and Hide"), QStringLiteral("view-hidden"));
  
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
                  const auto code =
                      KMessageBox::questionTwoActions(this,
- #else
-                 const auto code =
-                     KMessageBox::questionYesNo(this,
- #endif
                                                      oldItem.isFile() ? i18n("Adding a dot to the beginning of this file's name will hide it from view.\n"
                                                                              "Do you still want to rename it?")
                                                                       : i18n("Adding a dot to the beginning of this folder's name will hide it from view.\n"
                                                      KStandardGuiItem::cancel(),
                                                      QStringLiteral("ConfirmHide"));
  
- #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
                  if (code == KMessageBox::SecondaryAction) {
- #else
-                 if (code == KMessageBox::No) {
- #endif
                      return;
                  }
              }
@@@ -2301,7 -2283,7 +2280,7 @@@ void DolphinView::copyPathToClipboard(
      if (clipboard == nullptr) {
          return;
      }
-     clipboard->setText(path);
+     clipboard->setText(QDir::toNativeSeparators(path));
  }
  
  void DolphinView::slotIncreaseZoom()