┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/dbusinterface.h4
-rw-r--r--src/dolphinbookmarkhandler.cpp7
-rw-r--r--src/dolphinmainwindow.cpp17
-rw-r--r--src/dolphinpart.cpp8
-rw-r--r--src/dolphintabwidget.cpp7
-rw-r--r--src/dolphinviewcontainer.cpp29
-rw-r--r--src/dolphinviewcontainer.h7
-rw-r--r--src/global.cpp82
-rw-r--r--src/global.h7
-rw-r--r--src/kitemviews/kfileitemlistwidget.cpp20
-rw-r--r--src/kitemviews/kfileitemmodel.cpp18
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.cpp20
-rw-r--r--src/kitemviews/kfileitemmodelrolesupdater.h2
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp2
-rw-r--r--src/kitemviews/private/kdirectorycontentscounter.cpp71
-rw-r--r--src/kitemviews/private/kdirectorycontentscounter.h21
-rw-r--r--src/kitemviews/private/kdirectorycontentscounterworker.cpp98
-rw-r--r--src/kitemviews/private/kdirectorycontentscounterworker.h14
-rw-r--r--src/main.cpp31
-rw-r--r--src/org.kde.dolphin.appdata.xml1
-rw-r--r--src/panels/information/informationpanel.cpp2
-rw-r--r--src/panels/information/informationpanelcontent.cpp39
-rw-r--r--src/panels/terminal/org.kde.KIOFuse.VFS.xml13
-rw-r--r--src/panels/terminal/terminalpanel.cpp45
-rw-r--r--src/panels/terminal/terminalpanel.h2
-rw-r--r--src/search/dolphinsearchbox.cpp17
-rw-r--r--src/search/dolphinsearchbox.h5
-rw-r--r--src/settings/dolphin_detailsmodesettings.kcfg8
-rw-r--r--src/settings/dolphin_generalsettings.kcfg4
-rw-r--r--src/settings/kcm/kcmdolphingeneral.cpp22
-rw-r--r--src/settings/kcm/kcmdolphingeneral.h2
-rw-r--r--src/settings/kcm/kcmdolphinnavigation.cpp10
-rw-r--r--src/settings/kcm/kcmdolphinnavigation.h4
-rw-r--r--src/settings/kcm/kcmdolphinservices.cpp8
-rw-r--r--src/settings/kcm/kcmdolphinservices.h2
-rw-r--r--src/settings/kcm/kcmdolphinviewmodes.cpp16
-rw-r--r--src/settings/kcm/kcmdolphinviewmodes.h2
-rw-r--r--src/settings/services/servicemenuinstaller/CMakeLists.txt1
-rw-r--r--src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp32
-rw-r--r--src/settings/services/servicessettingspage.cpp10
-rw-r--r--src/settings/services/servicessettingspage.h2
-rw-r--r--src/settings/startup/startupsettingspage.cpp90
-rw-r--r--src/settings/startup/startupsettingspage.h8
-rw-r--r--src/settings/viewmodes/viewsettingstab.cpp50
-rw-r--r--src/settings/viewmodes/viewsettingstab.h5
-rw-r--r--src/views/dolphinview.cpp18
-rw-r--r--src/views/dolphinviewactionhandler.cpp2
-rw-r--r--src/views/versioncontrol/kversioncontrolplugin.h17
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.cpp14
-rw-r--r--src/views/versioncontrol/versioncontrolobserver.h2
51 files changed, 638 insertions, 281 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 02a43a209..fc7b33cbd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -272,6 +272,7 @@ qt5_add_resources(dolphinstatic_SRCS dolphin.qrc)
qt5_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/dolphinmainwindow.h org.kde.DolphinMainWindow.xml)
qt5_add_dbus_adaptor(dolphinstatic_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindow.h DolphinMainWindow)
qt5_add_dbus_interface(dolphinstatic_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.DolphinMainWindow.xml dolphinmainwindowinterface)
+qt5_add_dbus_interface(dolphinstatic_SRCS panels/terminal/org.kde.KIOFuse.VFS.xml kiofuse_interface)
add_library(dolphinstatic STATIC ${dolphinstatic_SRCS})
diff --git a/src/dbusinterface.h b/src/dbusinterface.h
index 391916d62..c1029ea23 100644
--- a/src/dbusinterface.h
+++ b/src/dbusinterface.h
@@ -34,12 +34,12 @@ public:
Q_SCRIPTABLE void ShowItemProperties(const QStringList& uriList, const QString& startUpId);
/**
- * Set whether this interface has been created by dolphin --deamon.
+ * Set whether this interface has been created by dolphin --daemon.
*/
void setAsDaemon();
/**
- * @return Whether this interface has been created by dolphin --deamon.
+ * @return Whether this interface has been created by dolphin --daemon.
*/
bool isDaemon() const;
diff --git a/src/dolphinbookmarkhandler.cpp b/src/dolphinbookmarkhandler.cpp
index ded83d6bb..0d31b8984 100644
--- a/src/dolphinbookmarkhandler.cpp
+++ b/src/dolphinbookmarkhandler.cpp
@@ -21,6 +21,7 @@
#include "dolphinmainwindow.h"
#include "dolphinviewcontainer.h"
#include "global.h"
+#include <KActionCollection>
#include <KBookmarkMenu>
#include <KIO/Global>
#include <QDebug>
@@ -47,7 +48,11 @@ DolphinBookmarkHandler::DolphinBookmarkHandler(DolphinMainWindow *mainWindow,
}
m_bookmarkManager = KBookmarkManager::managerForFile(bookmarksFile, QStringLiteral("dolphin"));
m_bookmarkManager->setUpdate(true);
- m_bookmarkMenu.reset(new KBookmarkMenu(m_bookmarkManager, this, menu, collection));
+ m_bookmarkMenu.reset(new KBookmarkMenu(m_bookmarkManager, this, menu));
+
+ collection->addAction(QStringLiteral("add_bookmark"), m_bookmarkMenu->addBookmarkAction());
+ collection->addAction(QStringLiteral("edit_bookmarks"), m_bookmarkMenu->editBookmarksAction());
+ collection->addAction(QStringLiteral("add_bookmarks_list"), m_bookmarkMenu->bookmarkTabsAsFolderAction());
}
DolphinBookmarkHandler::~DolphinBookmarkHandler()
diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp
index f88bc3f44..3ac3ab1c1 100644
--- a/src/dolphinmainwindow.cpp
+++ b/src/dolphinmainwindow.cpp
@@ -50,9 +50,11 @@
#include <KActionMenu>
#include <KAuthorized>
#include <KConfig>
+#include <KConfigGui>
#include <KDualAction>
#include <KFileItemListProperties>
#include <KHelpMenu>
+#include <KIO/CommandLauncherJob>
#include <KIO/JobUiDelegate>
#include <KIO/OpenFileManagerWindowJob>
#include <KJobWidgets>
@@ -579,6 +581,14 @@ void DolphinMainWindow::closeEvent(QCloseEvent* event)
}
}
+ if (GeneralSettings::rememberOpenedTabs()) {
+ KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin"));
+ KConfig *config = KConfigGui::sessionConfig();
+ saveGlobalProperties(config);
+ savePropertiesInternal(config, 1);
+ config->sync();
+ }
+
GeneralSettings::setVersion(CurrentDolphinVersion);
GeneralSettings::self()->save();
@@ -926,7 +936,10 @@ void DolphinMainWindow::compareFiles()
command.append("\" \"");
command.append(urlB.toDisplayString(QUrl::PreferLocalFile));
command.append('\"');
- KRun::runCommand(command, QStringLiteral("Kompare"), QStringLiteral("kompare"), this);
+
+ KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(command, this);
+ job->setDesktopName(QStringLiteral("org.kde.kompare"));
+ job->start();
}
void DolphinMainWindow::toggleShowMenuBar()
@@ -1265,7 +1278,7 @@ void DolphinMainWindow::tabCountChanged(int count)
void DolphinMainWindow::updateWindowTitle()
{
- const QString newTitle = m_activeViewContainer->caption();
+ const QString newTitle = m_activeViewContainer->captionWindowTitle();
if (windowTitle() != newTitle) {
setWindowTitle(newTitle);
}
diff --git a/src/dolphinpart.cpp b/src/dolphinpart.cpp
index 7e7425121..0c41b2bec 100644
--- a/src/dolphinpart.cpp
+++ b/src/dolphinpart.cpp
@@ -34,6 +34,7 @@
#include <KActionCollection>
#include <KAuthorized>
#include <KConfigGroup>
+#include <KDialogJobUiDelegate>
#include <KFileItemListProperties>
#include <KIconLoader>
#include <KJobWidgets>
@@ -42,7 +43,7 @@
#include <KMimeTypeEditor>
#include <KNS3/KMoreToolsMenuFactory>
#include <KPluginFactory>
-#include <KRun>
+#include <KIO/CommandLauncherJob>
#include <KSharedConfig>
#include <KToolInvocation>
@@ -546,7 +547,10 @@ void DolphinPart::slotFindFile()
if (!(actions.isEmpty())) {
actions.first()->trigger();
} else {
- KRun::run(QStringLiteral("kfind"), {url()}, widget());
+ KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob(QStringLiteral("kfind"), {url().toString()}, this);
+ job->setDesktopName(QStringLiteral("org.kde.kfind"));
+ job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, widget()));
+ job->start();
}
}
diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp
index 89c54baf5..fba6fe084 100644
--- a/src/dolphintabwidget.cpp
+++ b/src/dolphintabwidget.cpp
@@ -25,9 +25,9 @@
#include "dolphinviewcontainer.h"
#include <KConfigGroup>
-#include <KRun>
#include <KShell>
#include <kio/global.h>
+#include <KIO/CommandLauncherJob>
#include <KAcceleratorManager>
#include <QApplication>
@@ -334,8 +334,9 @@ void DolphinTabWidget::detachTab(int index)
}
args << QStringLiteral("--new-window");
- const QString command = QStringLiteral("dolphin %1").arg(KShell::joinArgs(args));
- KRun::runCommand(command, this);
+ KIO::CommandLauncherJob *job = new KIO::CommandLauncherJob("dolphin", args, this);
+ job->setDesktopName(QStringLiteral("org.kde.dolphin"));
+ job->start();
closeTab(index);
}
diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp
index 3a17805ab..4ab34a06a 100644
--- a/src/dolphinviewcontainer.cpp
+++ b/src/dolphinviewcontainer.cpp
@@ -29,6 +29,8 @@
#include "trash/dolphintrash.h"
#include "views/viewmodecontroller.h"
#include "views/viewproperties.h"
+#include "dolphin_detailsmodesettings.h"
+#include "views/dolphinview.h"
#ifdef HAVE_KACTIVITIES
#include <KActivities/ResourceInstance>
@@ -119,7 +121,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
connect(m_searchBox, &DolphinSearchBox::activated, this, &DolphinViewContainer::activate);
connect(m_searchBox, &DolphinSearchBox::closeRequest, this, &DolphinViewContainer::closeSearchBox);
connect(m_searchBox, &DolphinSearchBox::searchRequest, this, &DolphinViewContainer::startSearching);
- connect(m_searchBox, &DolphinSearchBox::returnPressed, this, &DolphinViewContainer::requestFocus);
+ connect(m_searchBox, &DolphinSearchBox::focusViewRequest, this, &DolphinViewContainer::requestFocus);
m_searchBox->setWhatsThis(xi18nc("@info:whatsthis findbar",
"<para>This helps you find files and folders. Enter a <emphasis>"
"search term</emphasis> and specify search settings with the "
@@ -249,6 +251,12 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
setSearchModeEnabled(isSearchUrl(url));
+ connect(DetailsModeSettings::self(), &KCoreConfigSkeleton::configChanged, this, [=]() {
+ if (view()->mode() == DolphinView::Mode::DetailsView) {
+ view()->reload();
+ }
+ });
+
// Initialize kactivities resource instance
#ifdef HAVE_KACTIVITIES
@@ -449,6 +457,18 @@ void DolphinViewContainer::reload()
m_messageWidget->hide();
}
+QString DolphinViewContainer::captionWindowTitle() const
+{
+ if (GeneralSettings::showFullPathInTitlebar() && !isSearchModeEnabled()) {
+ if (!url().isLocalFile()) {
+ return url().adjusted(QUrl::StripTrailingSlash).toString();
+ }
+ return url().adjusted(QUrl::StripTrailingSlash).path();
+ } else {
+ return DolphinViewContainer::caption();
+ }
+}
+
QString DolphinViewContainer::caption() const
{
if (isSearchModeEnabled()) {
@@ -459,13 +479,6 @@ QString DolphinViewContainer::caption() const
}
}
- if (GeneralSettings::showFullPathInTitlebar()) {
- if (!url().isLocalFile()) {
- return url().adjusted(QUrl::StripTrailingSlash).toString();
- }
- return url().adjusted(QUrl::StripTrailingSlash).path();
- }
-
KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
const auto& matchedPlaces = placesModel->match(placesModel->index(0,0), KFilePlacesModel::UrlRole, QUrl(url().adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/?")), 1, Qt::MatchRegExp);
diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h
index 5207d2d35..52e63cbe0 100644
--- a/src/dolphinviewcontainer.h
+++ b/src/dolphinviewcontainer.h
@@ -134,6 +134,13 @@ public:
void reload();
/**
+ * @return Returns a Caption suitable for display in the window title.
+ * It is calculated depending on GeneralSettings::showFullPathInTitlebar().
+ * If it's false, it calls caption().
+ */
+ QString captionWindowTitle() const;
+
+ /**
* @return Returns a Caption suitable for display to the user. It is
* calculated depending on settings, if a search is active and other
* factors.
diff --git a/src/global.cpp b/src/global.cpp
index 5236fa4d1..32a2d4ebb 100644
--- a/src/global.cpp
+++ b/src/global.cpp
@@ -23,7 +23,9 @@
#include "dolphindebug.h"
#include "dolphinmainwindowinterface.h"
-#include <KRun>
+#include <KDialogJobUiDelegate>
+#include <KIO/ApplicationLauncherJob>
+#include <KService>
#include <KWindowSystem>
#include <QApplication>
@@ -60,13 +62,11 @@ void Dolphin::openNewWindow(const QList<QUrl> &urls, QWidget *window, const Open
if (!urls.isEmpty()) {
command.append(QLatin1String(" %U"));
}
- KRun::run(
- command,
- urls,
- window,
- QApplication::applicationDisplayName(),
- QApplication::windowIcon().name()
- );
+ KService::Ptr service(new KService(QApplication::applicationDisplayName(), command, QApplication::windowIcon().name()));
+ auto *job = new KIO::ApplicationLauncherJob(service, window);
+ job->setUrls(urls);
+ job->setUiDelegate(new KDialogJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, window));
+ job->start();
}
bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFiles, bool splitView, const QString& preferredService)
@@ -78,36 +78,7 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
return false;
}
- QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> dolphinInterfaces;
- if (!preferredService.isEmpty()) {
- QSharedPointer<OrgKdeDolphinMainWindowInterface> preferredInterface(
- new OrgKdeDolphinMainWindowInterface(preferredService,
- QStringLiteral("/dolphin/Dolphin_1"),
- QDBusConnection::sessionBus()));
- if (preferredInterface->isValid() && !preferredInterface->lastError().isValid()) {
- dolphinInterfaces.append(qMakePair(preferredInterface, QStringList()));
- }
- }
-
- // Look for dolphin instances among all available dbus services.
- const QStringList dbusServices = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
- // Don't match the service without trailing "-" (unique instance)
- const QString pattern = QStringLiteral("org.kde.dolphin-");
- // Don't match the pid without leading "-"
- const QString myPid = QLatin1Char('-') + QString::number(QCoreApplication::applicationPid());
- for (const QString& service : dbusServices) {
- if (service.startsWith(pattern) && !service.endsWith(myPid)) {
- // Check if instance can handle our URLs
- QSharedPointer<OrgKdeDolphinMainWindowInterface> interface(
- new OrgKdeDolphinMainWindowInterface(service,
- QStringLiteral("/dolphin/Dolphin_1"),
- QDBusConnection::sessionBus()));
- if (interface->isValid() && !interface->lastError().isValid()) {
- dolphinInterfaces.append(qMakePair(interface, QStringList()));
- }
- }
- }
-
+ auto dolphinInterfaces = dolphinGuiInstances(preferredService);
if (dolphinInterfaces.isEmpty()) {
return false;
}
@@ -145,3 +116,38 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
}
return attached;
}
+
+QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> Dolphin::dolphinGuiInstances(const QString& preferredService)
+{
+ QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> dolphinInterfaces;
+ if (!preferredService.isEmpty()) {
+ QSharedPointer<OrgKdeDolphinMainWindowInterface> preferredInterface(
+ new OrgKdeDolphinMainWindowInterface(preferredService,
+ QStringLiteral("/dolphin/Dolphin_1"),
+ QDBusConnection::sessionBus()));
+ if (preferredInterface->isValid() && !preferredInterface->lastError().isValid()) {
+ dolphinInterfaces.append(qMakePair(preferredInterface, QStringList()));
+ }
+ }
+
+ // Look for dolphin instances among all available dbus services.
+ const QStringList dbusServices = QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
+ // Don't match the service without trailing "-" (unique instance)
+ const QString pattern = QStringLiteral("org.kde.dolphin-");
+ // Don't match the pid without leading "-"
+ const QString myPid = QLatin1Char('-') + QString::number(QCoreApplication::applicationPid());
+ for (const QString& service : dbusServices) {
+ if (service.startsWith(pattern) && !service.endsWith(myPid)) {
+ // Check if instance can handle our URLs
+ QSharedPointer<OrgKdeDolphinMainWindowInterface> interface(
+ new OrgKdeDolphinMainWindowInterface(service,
+ QStringLiteral("/dolphin/Dolphin_1"),
+ QDBusConnection::sessionBus()));
+ if (interface->isValid() && !interface->lastError().isValid()) {
+ dolphinInterfaces.append(qMakePair(interface, QStringList()));
+ }
+ }
+ }
+
+ return dolphinInterfaces;
+}
diff --git a/src/global.h b/src/global.h
index 7ee564581..daf86134e 100644
--- a/src/global.h
+++ b/src/global.h
@@ -24,6 +24,8 @@
#include <QUrl>
#include <QWidget>
+class OrgKdeDolphinMainWindowInterface;
+
namespace Dolphin {
QList<QUrl> validateUris(const QStringList& uriList);
@@ -52,6 +54,11 @@ namespace Dolphin {
bool attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFiles, bool splitView, const QString& preferredService = QString());
/**
+ * Returns a QVector with all GUI-capable Dolphin instances
+ */
+ QVector<QPair<QSharedPointer<OrgKdeDolphinMainWindowInterface>, QStringList>> dolphinGuiInstances(const QString& preferredService);
+
+ /**
* TODO: Move this somewhere global to all KDE apps, not just Dolphin
*/
const int VERTICAL_SPACER_HEIGHT = 18;
diff --git a/src/kitemviews/kfileitemlistwidget.cpp b/src/kitemviews/kfileitemlistwidget.cpp
index 40b8ccf37..a495a4c2f 100644
--- a/src/kitemviews/kfileitemlistwidget.cpp
+++ b/src/kitemviews/kfileitemlistwidget.cpp
@@ -21,6 +21,8 @@
#include "kfileitemmodel.h"
#include "kitemlistview.h"
+#include "dolphin_detailsmodesettings.h"
+
#include <KFormat>
#include <KLocalizedString>
@@ -64,14 +66,24 @@ QString KFileItemListWidgetInformant::roleText(const QByteArray& role,
if (role == "size") {
if (values.value("isDir").toBool()) {
- // The item represents a directory. Show the number of sub directories
- // instead of the file size of the directory.
+ // The item represents a directory.
if (!roleValue.isNull()) {
- const int count = roleValue.toInt();
+ const int count = values.value("count").toInt();
if (count < 0) {
text = i18nc("@item:intable", "Unknown");
} else {
- text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+ if (DetailsModeSettings::directorySizeCount()) {
+ // Show the number of sub directories instead of the file size of the directory.
+ text = i18ncp("@item:intable", "%1 item", "%1 items", count);
+ } else {
+ // if we have directory size available
+ if (roleValue == -1) {
+ text = i18nc("@item:intable", "Unknown");
+ } else {
+ const KIO::filesize_t size = roleValue.value<KIO::filesize_t>();
+ text = KFormat().formatByteSize(size);
+ }
+ }
}
}
} else {
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp
index e4dca2734..5e9603ba1 100644
--- a/src/kitemviews/kfileitemmodel.cpp
+++ b/src/kitemviews/kfileitemmodel.cpp
@@ -22,6 +22,7 @@
#include "kfileitemmodel.h"
#include "dolphin_generalsettings.h"
+#include "dolphin_detailsmodesettings.h"
#include "dolphindebug.h"
#include "private/kfileitemmodeldirlister.h"
#include "private/kfileitemmodelsortalgorithm.h"
@@ -1767,8 +1768,15 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
// See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
Q_ASSERT(itemB.isDir());
- const QVariant valueA = a->values.value("size");
- const QVariant valueB = b->values.value("size");
+ QVariant valueA, valueB;
+ if (DetailsModeSettings::directorySizeCount()) {
+ // use dir size then
+ valueA = a->values.value("size");
+ valueB = b->values.value("size");
+ } else {
+ valueA = a->values.value("count");
+ valueB = b->values.value("count");
+ }
if (valueA.isNull() && valueB.isNull()) {
result = 0;
} else if (valueA.isNull()) {
@@ -1776,7 +1784,11 @@ int KFileItemModel::sortRoleCompare(const ItemData* a, const ItemData* b, const
} else if (valueB.isNull()) {
result = +1;
} else {
- result = valueA.toInt() - valueB.toInt();
+ if (valueA < valueB) {
+ return -1;
+ } else {
+ return +1;
+ }
}
} else {
// See "if (m_sortFoldersFirst || m_sortRole == SizeRole)" in KFileItemModel::lessThan():
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp
index bf2c84c40..c28e240a5 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.cpp
+++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp
@@ -44,7 +44,6 @@
#include <QElapsedTimer>
#include <QTimer>
-
// #define KFILEITEMMODELROLESUPDATER_DEBUG
namespace {
@@ -108,9 +107,9 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO
this, &KFileItemModelRolesUpdater::slotSortRoleChanged);
// Use a timer to prevent that each call of slotItemsChanged() results in a synchronous
- // resolving of the roles. Postpone the resolving until no update has been done for 1 second.
+ // resolving of the roles. Postpone the resolving until no update has been done for 100 ms.
m_recentlyChangedItemsTimer = new QTimer(this);
- m_recentlyChangedItemsTimer->setInterval(1000);
+ m_recentlyChangedItemsTimer->setInterval(100);
m_recentlyChangedItemsTimer->setSingleShot(true);
connect(m_recentlyChangedItemsTimer, &QTimer::timeout, this, &KFileItemModelRolesUpdater::resolveRecentlyChangedItems);
@@ -750,7 +749,7 @@ void KFileItemModelRolesUpdater::applyChangedBalooRolesForItem(const KFileItem &
#endif
}
-void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString& path, int count)
+void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString& path, int count, long size)
{
const bool getSizeRole = m_roles.contains("size");
const bool getIsExpandableRole = m_roles.contains("isExpandable");
@@ -761,17 +760,16 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin
QHash<QByteArray, QVariant> data;
if (getSizeRole) {
- data.insert("size", count);
+ data.insert("count", count);
+ if (size != -1) {
+ data.insert("size", QVariant::fromValue(size));
+ }
}
if (getIsExpandableRole) {
data.insert("isExpandable", count > 0);
}
- disconnect(m_model, &KFileItemModel::itemsChanged,
- this, &KFileItemModelRolesUpdater::slotItemsChanged);
m_model->setData(index, data);
- connect(m_model, &KFileItemModel::itemsChanged,
- this, &KFileItemModelRolesUpdater::slotItemsChanged);
}
}
}
@@ -997,7 +995,7 @@ void KFileItemModelRolesUpdater::applySortRole(int index)
data.insert("type", item.mimeComment());
} else if (m_model->sortRole() == "size" && item.isLocalFile() && item.isDir()) {
const QString path = item.localPath();
- data.insert("size", m_directoryContentsCounter->countDirectoryContentsSynchronously(path));
+ m_directoryContentsCounter->scanDirectory(path);
} else {
// Probably the sort role is a baloo role - just determine all roles.
data = rolesData(item);
@@ -1070,7 +1068,7 @@ QHash<QByteArray, QVariant> KFileItemModelRolesUpdater::rolesData(const KFileIte
// Tell m_directoryContentsCounter that we want to count the items
// inside the directory. The result will be received in slotDirectoryContentsCountReceived.
const QString path = item.localPath();
- m_directoryContentsCounter->addDirectory(path);
+ m_directoryContentsCounter->scanDirectory(path);
} else if (getSizeRole) {
data.insert("size", -1); // -1 indicates an unknown number of items
}
diff --git a/src/kitemviews/kfileitemmodelrolesupdater.h b/src/kitemviews/kfileitemmodelrolesupdater.h
index 9078c8e0d..e21cd30df 100644
--- a/src/kitemviews/kfileitemmodelrolesupdater.h
+++ b/src/kitemviews/kfileitemmodelrolesupdater.h
@@ -212,7 +212,7 @@ private slots:
void applyChangedBalooRoles(const QString& file);
void applyChangedBalooRolesForItem(const KFileItem& file);
- void slotDirectoryContentsCountReceived(const QString& path, int count);
+ void slotDirectoryContentsCountReceived(const QString& path, int count, long size);
private:
/**
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index 5ddf52e5f..0c25ebb8b 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -1219,7 +1219,7 @@ void KItemListController::startDragging()
const QPoint hotSpot((pixmap.width() / pixmap.devicePixelRatio()) / 2, 0);
drag->setHotSpot(hotSpot);
- drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction);
+ drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::MoveAction);
QAccessibleEvent accessibilityEvent(view(), QAccessible::DragDropStart);
QAccessible::updateAccessibility(&accessibilityEvent);
diff --git a/src/kitemviews/private/kdirectorycontentscounter.cpp b/src/kitemviews/private/kdirectorycontentscounter.cpp
index bd204fe8e..a19bce8b3 100644
--- a/src/kitemviews/private/kdirectorycontentscounter.cpp
+++ b/src/kitemviews/private/kdirectorycontentscounter.cpp
@@ -24,8 +24,14 @@
#include <KDirWatch>
#include <QFileInfo>
+#include <QDir>
#include <QThread>
+namespace {
+ /// cache of directory counting result
+ static QHash<QString, QPair<int, long>> *s_cache;
+}
+
KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObject* parent) :
QObject(parent),
m_model(model),
@@ -43,9 +49,12 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj
m_workerThread->start();
}
+ if (s_cache == nullptr) {
+ s_cache = new QHash<QString, QPair<int, long>>();
+ }
+
m_worker = new KDirectoryContentsCounterWorker();
m_worker->moveToThread(m_workerThread);
- ++m_workersCount;
connect(this, &KDirectoryContentsCounter::requestDirectoryContentsCount,
m_worker, &KDirectoryContentsCounterWorker::countDirectoryContents);
@@ -58,9 +67,7 @@ KDirectoryContentsCounter::KDirectoryContentsCounter(KFileItemModel* model, QObj
KDirectoryContentsCounter::~KDirectoryContentsCounter()
{
- --m_workersCount;
-
- if (m_workersCount > 0) {
+ if (m_workerThread->isRunning()) {
// The worker thread will continue running. It could even be running
// a method of m_worker at the moment, so we delete it using
// deleteLater() to prevent a crash.
@@ -79,38 +86,17 @@ KDirectoryContentsCounter::~KDirectoryContentsCounter()
}
}
-void KDirectoryContentsCounter::addDirectory(const QString& path)
+void KDirectoryContentsCounter::scanDirectory(const QString& path)
{
startWorker(path);
}
-int KDirectoryContentsCounter::countDirectoryContentsSynchronously(const QString& path)
-{
- const QString resolvedPath = QFileInfo(path).canonicalFilePath();
-
- if (!m_dirWatcher->contains(resolvedPath)) {
- m_dirWatcher->addDir(resolvedPath);
- m_watchedDirs.insert(resolvedPath);
- }
-
- KDirectoryContentsCounterWorker::Options options;
-
- if (m_model->showHiddenFiles()) {
- options |= KDirectoryContentsCounterWorker::CountHiddenFiles;
- }
-
- if (m_model->showDirectoriesOnly()) {
- options |= KDirectoryContentsCounterWorker::CountDirectoriesOnly;
- }
-
- return KDirectoryContentsCounterWorker::subItemsCount(path, options);
-}
-
-void KDirectoryContentsCounter::slotResult(const QString& path, int count)
+void KDirectoryContentsCounter::slotResult(const QString& path, int count, long size)
{
m_workerIsBusy = false;
- const QString resolvedPath = QFileInfo(path).canonicalFilePath();
+ const QFileInfo info = QFileInfo(path);
+ const QString resolvedPath = info.canonicalFilePath();
if (!m_dirWatcher->contains(resolvedPath)) {
m_dirWatcher->addDir(resolvedPath);
@@ -121,7 +107,22 @@ void KDirectoryContentsCounter::slotResult(const QString& path, int count)
startWorker(m_queue.dequeue());
}
- emit result(path, count);
+ if (s_cache->contains(resolvedPath)) {
+ const auto pair = s_cache->value(resolvedPath);
+ if (pair.first == count && pair.second == size) {
+ // no change no need to send another result event
+ return;
+ }
+ }
+
+ if (info.dir().path() == m_model->rootItem().url().path()) {
+ // update cache or overwrite value
+ // when path is a direct children of the current model root
+ s_cache->insert(resolvedPath, QPair<int, long>(count, size));
+ }
+
+ // sends the results
+ emit result(resolvedPath, count, size);
}
void KDirectoryContentsCounter::slotDirWatchDirty(const QString& path)
@@ -146,7 +147,7 @@ void KDirectoryContentsCounter::slotItemsRemoved()
if (!m_watchedDirs.isEmpty()) {
// Don't let KDirWatch watch for removed items
if (allItemsRemoved) {
- foreach (const QString& path, m_watchedDirs) {
+ for (const QString& path : qAsConst(m_watchedDirs)) {
m_dirWatcher->removeDir(path);
}
m_watchedDirs.clear();
@@ -166,6 +167,13 @@ void KDirectoryContentsCounter::slotItemsRemoved()
void KDirectoryContentsCounter::startWorker(const QString& path)
{
+ if (s_cache->contains(path)) {
+ // fast path when in cache
+ // will be updated later if result has changed
+ const auto pair = s_cache->value(path);
+ emit result(path, pair.first, pair.second);
+ }
+
if (m_workerIsBusy) {
m_queue.enqueue(path);
} else {
@@ -185,4 +193,3 @@ void KDirectoryContentsCounter::startWorker(const QString& path)
}
QThread* KDirectoryContentsCounter::m_workerThread = nullptr;
-int KDirectoryContentsCounter::m_workersCount = 0;
diff --git a/src/kitemviews/private/kdirectorycontentscounter.h b/src/kitemviews/private/kdirectorycontentscounter.h
index 349860757..0c900ec64 100644
--- a/src/kitemviews/private/kdirectorycontentscounter.h
+++ b/src/kitemviews/private/kdirectorycontentscounter.h
@@ -25,6 +25,7 @@
#include <QQueue>
#include <QSet>
+#include <QHash>
class KDirWatch;
class KFileItemModel;
@@ -45,28 +46,23 @@ public:
*
* The directory \a path is watched for changes, and the signal is emitted
* again if a change occurs.
- */
- void addDirectory(const QString& path);
-
- /**
- * In contrast to \a addDirectory, this function counts the items inside
- * the directory \a path synchronously and returns the result.
*
- * The directory is watched for changes, and the signal \a result is
- * emitted if a change occurs.
+ * Uses a cache internally to speed up first result,
+ * but emit again result when the cache was updated
*/
- int countDirectoryContentsSynchronously(const QString& path);
+ void scanDirectory(const QString& path);
signals:
/**
- * Signals that the directory \a path contains \a count items.
+ * Signals that the directory \a path contains \a count items of size \a
+ * Size calculation depends on parameter DetailsModeSettings::recursiveDirectorySizeLimit
*/
- void result(const QString& path, int count);
+ void result(const QString& path, int count, long size);
void requestDirectoryContentsCount(const QString& path, KDirectoryContentsCounterWorker::Options options);
private slots:
- void slotResult(const QString& path, int count);
+ void slotResult(const QString& path, int count, long size);
void slotDirWatchDirty(const QString& path);
void slotItemsRemoved();
@@ -79,7 +75,6 @@ private:
QQueue<QString> m_queue;
static QThread* m_workerThread;
- static int m_workersCount;
KDirectoryContentsCounterWorker* m_worker;
bool m_workerIsBusy;
diff --git a/src/kitemviews/private/kdirectorycontentscounterworker.cpp b/src/kitemviews/private/kdirectorycontentscounterworker.cpp
index e9c954ed9..3117d07aa 100644
--- a/src/kitemviews/private/kdirectorycontentscounterworker.cpp
+++ b/src/kitemviews/private/kdirectorycontentscounterworker.cpp
@@ -22,44 +22,33 @@
// Required includes for subItemsCount():
#ifdef Q_OS_WIN
- #include <QDir>
+#include <QDir>
#else
- #include <QFile>
- #include <qplatformdefs.h>
+#include <QFile>
+#include <qplatformdefs.h>
#endif
+#include "dolphin_detailsmodesettings.h"
+
KDirectoryContentsCounterWorker::KDirectoryContentsCounterWorker(QObject* parent) :
QObject(parent)
{
qRegisterMetaType<KDirectoryContentsCounterWorker::Options>();
}
-int KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options)
+KDirectoryContentsCounterWorker::CountResult walkDir(const QString &dirPath,
+ const bool countHiddenFiles,
+ const bool countDirectoriesOnly,
+ QT_DIRENT *dirEntry,
+ const uint allowedRecursiveLevel)
{
- const bool countHiddenFiles = options & CountHiddenFiles;
- const bool countDirectoriesOnly = options & CountDirectoriesOnly;
-
-#ifdef Q_OS_WIN
- QDir dir(path);
- QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System;
- if (countHiddenFiles) {
- filters |= QDir::Hidden;
- }
- if (countDirectoriesOnly) {
- filters |= QDir::Dirs;
- } else {
- filters |= QDir::AllEntries;
- }
- return dir.entryList(filters).count();
-#else
- // Taken from kio/src/widgets/kdirmodel.cpp
- // Copyright (C) 2006 David Faure <[email protected]>
-
int count = -1;
- auto dir = QT_OPENDIR(QFile::encodeName(path));
+ long size = -1;
+ auto dir = QT_OPENDIR(QFile::encodeName(dirPath));
if (dir) {
count = 0;
- QT_DIRENT *dirEntry = nullptr;
+ QT_STATBUF buf;
+
while ((dirEntry = QT_READDIR(dir))) {
if (dirEntry->d_name[0] == '.') {
if (dirEntry->d_name[1] == '\0' || !countHiddenFiles) {
@@ -76,20 +65,69 @@ int KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options
// as directory instead of trying to do an expensive stat()
// (see bugs 292642 and 299997).
const bool countEntry = !countDirectoriesOnly ||
- dirEntry->d_type == DT_DIR ||
- dirEntry->d_type == DT_LNK ||
- dirEntry->d_type == DT_UNKNOWN;
+ dirEntry->d_type == DT_DIR ||
+ dirEntry->d_type == DT_LNK ||
+ dirEntry->d_type == DT_UNKNOWN;
if (countEntry) {
++count;
}
+
+ if (allowedRecursiveLevel > 0) {
+
+ bool linkFound = false;
+ QString nameBuf = QStringLiteral("%1/%2").arg(dirPath, dirEntry->d_name);
+
+ if (dirEntry->d_type == DT_REG || dirEntry->d_type == DT_LNK) {
+ if (QT_STAT(nameBuf.toLocal8Bit(), &buf) == 0) {
+ if (S_ISDIR(buf.st_mode)) {
+ // was a dir link, recurse
+ linkFound = true;
+ }
+ size += buf.st_size;
+ }
+ }
+ if (dirEntry->d_type == DT_DIR || linkFound) {
+ // recursion for dirs and dir links
+ size += walkDir(nameBuf, countHiddenFiles, countDirectoriesOnly, dirEntry, allowedRecursiveLevel - 1).size;
+ }
+ }
}
QT_CLOSEDIR(dir);
}
- return count;
+ return KDirectoryContentsCounterWorker::CountResult{count, size};
+}
+
+KDirectoryContentsCounterWorker::CountResult KDirectoryContentsCounterWorker::subItemsCount(const QString& path, Options options)
+{
+ const bool countHiddenFiles = options & CountHiddenFiles;
+ const bool countDirectoriesOnly = options & CountDirectoriesOnly;
+
+#ifdef Q_OS_WIN
+ QDir dir(path);
+ QDir::Filters filters = QDir::NoDotAndDotDot | QDir::System;
+ if (countHiddenFiles) {
+ filters |= QDir::Hidden;
+ }
+ if (countDirectoriesOnly) {
+ filters |= QDir::Dirs;
+ } else {
+ filters |= QDir::AllEntries;
+ }
+ return {dir.entryList(filters).count(), 0};
+#else
+
+ const uint maxRecursiveLevel = DetailsModeSettings::directorySizeCount() ? 1 : DetailsModeSettings::recursiveDirectorySizeLimit();
+
+ QT_DIRENT *dirEntry = nullptr;
+
+ auto res = walkDir(QFile::encodeName(path), countHiddenFiles, countDirectoriesOnly, dirEntry, maxRecursiveLevel);
+
+ return res;
#endif
}
void KDirectoryContentsCounterWorker::countDirectoryContents(const QString& path, Options options)
{
- emit result(path, subItemsCount(path, options));
+ auto res = subItemsCount(path, options);
+ emit result(path, res.count, res.size);
}
diff --git a/src/kitemviews/private/kdirectorycontentscounterworker.h b/src/kitemviews/private/kdirectorycontentscounterworker.h
index b40da6e87..fac9978d5 100644
--- a/src/kitemviews/private/kdirectorycontentscounterworker.h
+++ b/src/kitemviews/private/kdirectorycontentscounterworker.h
@@ -37,6 +37,14 @@ public:
};
Q_DECLARE_FLAGS(Options, Option)
+ struct CountResult {
+ /// number of elements in the directory
+ int count;
+ /// Recursive sum of the size of the directory content files and folders
+ /// Calculation depends on DetailsModeSettings::recursiveDirectorySizeLimit
+ long size;
+ };
+
explicit KDirectoryContentsCounterWorker(QObject* parent = nullptr);
/**
@@ -45,13 +53,13 @@ public:
*
* @return The number of items.
*/
- static int subItemsCount(const QString& path, Options options);
+ static CountResult subItemsCount(const QString& path, Options options);
signals:
/**
- * Signals that the directory \a path contains \a count items.
+ * Signals that the directory \a path contains \a count items and optionally the size of its content.
*/
- void result(const QString& path, int count);
+ void result(const QString& path, int count, long size);
public slots:
/**
diff --git a/src/main.cpp b/src/main.cpp
index 5932df5ce..802e64d25 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -31,6 +31,7 @@
#include <KDBusService>
#include <KLocalizedString>
#include <Kdelibs4ConfigMigrator>
+#include <KConfigGui>
#include <QApplication>
#include <QCommandLineParser>
@@ -139,6 +140,9 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
const bool openFiles = parser.isSet(QStringLiteral("select"));
const QStringList args = parser.positionalArguments();
QList<QUrl> urls = Dolphin::validateUris(args);
+ // We later mutate urls, so we need to store if it was empty originally
+ const bool startedWithURLs = !urls.isEmpty();
+
if (parser.isSet(QStringLiteral("daemon"))) {
KDBusService dolphinDBusService;
@@ -154,7 +158,7 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
}
}
- if (urls.isEmpty()) {
+ if (!startedWithURLs) {
// We need at least one URL to open Dolphin
urls.append(Dolphin::homeUrl());
}
@@ -174,12 +178,25 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
mainWindow->show();
- if (app.isSessionRestored()) {
- const QString className = KXmlGuiWindow::classNameOfToplevel(1);
- if (className == QLatin1String("DolphinMainWindow")) {
- mainWindow->restore(1);
- } else {
- qCWarning(DolphinDebug) << "Unknown class " << className << " in session saved data!";
+ if (!app.isSessionRestored()) {
+ KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin"));
+ }
+
+ // Only restore session if:
+ // 1. Dolphin was not started with command line args
+ // 2. The "remember state" setting is enabled or session restoration after
+ // reboot is in use
+ // 3. There is a session available to restore
+ if (!startedWithURLs && (app.isSessionRestored() || GeneralSettings::rememberOpenedTabs()) ) {
+ // Get saved state data for the last-closed Dolphin instance
+ const QString serviceName = QStringLiteral("org.kde.dolphin-%1").arg(QCoreApplication::applicationPid());
+ if (Dolphin::dolphinGuiInstances(serviceName).size() > 0) {
+ const QString className = KXmlGuiWindow::classNameOfToplevel(1);
+ if (className == QLatin1String("DolphinMainWindow")) {
+ mainWindow->restore(1);
+ } else {
+ qCWarning(DolphinDebug) << "Unknown class " << className << " in session saved data!";
+ }
}
}
diff --git a/src/org.kde.dolphin.appdata.xml b/src/org.kde.dolphin.appdata.xml
index c3d2c7fc0..05228bdbb 100644
--- a/src/org.kde.dolphin.appdata.xml
+++ b/src/org.kde.dolphin.appdata.xml
@@ -576,6 +576,7 @@
<caption xml:lang="pt-BR">Gerenciamento de arquivos no Dolphin</caption>
<caption xml:lang="ru">Управление файлами</caption>
<caption xml:lang="sk">Správa súborov v Dolphin</caption>
+ <caption xml:lang="sl">Upravljanje datotek v Dolphinu</caption>
<caption xml:lang="sv">Filhantering i Dolphin</caption>
<caption xml:lang="uk">Керування файлами у Dolphin</caption>
<caption xml:lang="x-test">xxFile management in Dolphinxx</caption>
diff --git a/src/panels/information/informationpanel.cpp b/src/panels/information/informationpanel.cpp
index 23e7f1922..4f0e4e5eb 100644
--- a/src/panels/information/informationpanel.cpp
+++ b/src/panels/information/informationpanel.cpp
@@ -248,7 +248,7 @@ void InformationPanel::showItemInfo()
if (item.isNull()) {
// No item is hovered and no selection has been done: provide
// an item for the currently shown directory.
- m_folderStatJob = KIO::stat(url(), KIO::HideProgressInfo);
+ m_folderStatJob = KIO::statDetails(url(), KIO::StatJob::SourceSide, KIO::StatDefaultDetails | KIO::StatRecursiveSize, KIO::HideProgressInfo);
if (m_folderStatJob->uiDelegate()) {
KJobWidgets::setWindow(m_folderStatJob, this);
}
diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp
index 5c7c7c3f1..a0c872560 100644
--- a/src/panels/information/informationpanelcontent.cpp
+++ b/src/panels/information/informationpanelcontent.cpp
@@ -78,7 +78,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
// delay. This prevents flickering if the new preview can be generated
// within a very small timeframe.
m_outdatedPreviewTimer = new QTimer(this);
- m_outdatedPreviewTimer->setInterval(300);
+ m_outdatedPreviewTimer->setInterval(100);
m_outdatedPreviewTimer->setSingleShot(true);
connect(m_outdatedPreviewTimer, &QTimer::timeout,
this, &InformationPanelContent::markOutdatedPreview);
@@ -189,12 +189,8 @@ void InformationPanelContent::refreshPixmapView()
// Mark the currently shown preview as outdated. This is done
// with a small delay to prevent a flickering when the next preview
- // can be shown within a short timeframe. This timer is not started
- // for directories, as directory previews might fail and return the
- // same icon.
- if (!m_item.isDir()) {
- m_outdatedPreviewTimer->start();
- }
+ // can be shown within a short timeframe.
+ m_outdatedPreviewTimer->start();
QStringList plugins = KIO::PreviewJob::availablePlugins();
m_previewJob = new KIO::PreviewJob(KFileItemList() << m_item,
@@ -221,7 +217,6 @@ void InformationPanelContent::refreshPreview()
}
m_preview->setCursor(Qt::ArrowCursor);
- bool usePhonon = false;
setNameLabelText(m_item.text());
if (InformationPanelSettings::previewsShown()) {
@@ -229,11 +224,12 @@ void InformationPanelContent::refreshPreview()
const bool isSearchUrl = itemUrl.scheme().contains(QLatin1String("search")) && m_item.localPath().isEmpty();
if (isSearchUrl) {
m_preview->show();
+ m_phononWidget->hide();
// in the case of a search-URL the URL is not readable for humans
// (at least not useful to show in the Information Panel)
m_preview->setPixmap(
- QIcon::fromTheme(QStringLiteral("baloo")).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous)
+ QIcon::fromTheme(QStringLiteral("baloo")).pixmap(m_preview->height(), m_preview->width())
);
} else {
@@ -242,12 +238,13 @@ void InformationPanelContent::refreshPreview()
const QString mimeType = m_item.mimetype();
const bool isAnimatedImage = m_preview->isAnimatedImage(itemUrl.toLocalFile());
m_isVideo = !isAnimatedImage && mimeType.startsWith(QLatin1String("video/"));
- usePhonon = m_isVideo || mimeType.startsWith(QLatin1String("audio/"));
+ bool usePhonon = m_isVideo || mimeType.startsWith(QLatin1String("audio/"));
if (usePhonon) {
// change the cursor of the preview
m_preview->setCursor(Qt::PointingHandCursor);
m_preview->installEventFilter(m_phononWidget);
+ m_phononWidget->show();
// if the video is playing, has been paused or stopped
// we don't need to update the preview/phonon widget states
@@ -267,7 +264,6 @@ void InformationPanelContent::refreshPreview()
m_preview->show();
}
- m_phononWidget->show();
m_phononWidget->setUrl(m_item.targetUrl(), m_isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio);
adjustWidgetSizes(parentWidget()->width());
}
@@ -314,7 +310,7 @@ void InformationPanelContent::showItems(const KFileItemList& items)
m_preview->stopAnimatedImage();
m_preview->setPixmap(
- QIcon::fromTheme(QStringLiteral("dialog-information")).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous)
+ QIcon::fromTheme(QStringLiteral("dialog-information")).pixmap(m_preview->height(), m_preview->width())
);
setNameLabelText(i18ncp("@label", "%1 item selected", "%1 items selected", items.count()));
@@ -358,7 +354,7 @@ bool InformationPanelContent::eventFilter(QObject* obj, QEvent* event)
void InformationPanelContent::showIcon(const KFileItem& item)
{
m_outdatedPreviewTimer->stop();
- QPixmap pixmap = QIcon::fromTheme(item.iconName()).pixmap(KIconLoader::SizeEnormous, KIconLoader::SizeEnormous);
+ QPixmap pixmap = QIcon::fromTheme(item.iconName()).pixmap(m_preview->height(), m_preview->width());
KIconLoader::global()->drawOverlays(item.overlays(), pixmap, KIconLoader::Desktop);
m_preview->setPixmap(pixmap);
}
@@ -411,11 +407,18 @@ void InformationPanelContent::showPreview(const KFileItem& item,
void InformationPanelContent::markOutdatedPreview()
{
- KIconEffect *iconEffect = KIconLoader::global()->iconEffect();
- QPixmap disabledPixmap = iconEffect->apply(m_preview->pixmap(),
- KIconLoader::Desktop,
- KIconLoader::DisabledState);
- m_preview->setPixmap(disabledPixmap);
+ if (m_item.isDir()) {
+ // directory preview can be long
+ // but since we always have icons to display
+ // use it until the preview is done
+ showIcon(m_item);
+ } else {
+ KIconEffect *iconEffect = KIconLoader::global()->iconEffect();
+ QPixmap disabledPixmap = iconEffect->apply(m_preview->pixmap(),
+ KIconLoader::Desktop,
+ KIconLoader::DisabledState);
+ m_preview->setPixmap(disabledPixmap);
+ }
}
KFileItemList InformationPanelContent::items()
diff --git a/src/panels/terminal/org.kde.KIOFuse.VFS.xml b/src/panels/terminal/org.kde.KIOFuse.VFS.xml
new file mode 100644
index 000000000..56f753e41
--- /dev/null
+++ b/src/panels/terminal/org.kde.KIOFuse.VFS.xml
@@ -0,0 +1,13 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.kde.KIOFuse.VFS">
+ <method name="mountUrl">
+ <arg name="remoteUrl" type="s" direction="in"/>
+ <arg type="s" direction="out"/>
+ </method>
+ <method name="remoteUrl">
+ <arg name="localUrl" type="s" direction="in"/>
+ <arg type="s" direction="out"/>
+ </method>
+ </interface>
+</node>
diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp
index 59b2694fb..ac0bcd0fe 100644
--- a/src/panels/terminal/terminalpanel.cpp
+++ b/src/panels/terminal/terminalpanel.cpp
@@ -18,6 +18,7 @@
***************************************************************************/
#include "terminalpanel.h"
+#include "kiofuse_interface.h"
#include <KIO/DesktopExecParser>
#include <KIO/Job>
@@ -25,6 +26,7 @@
#include <KJobWidgets>
#include <KLocalizedString>
#include <KMessageWidget>
+#include <KMountPoint>
#include <KParts/ReadOnlyPart>
#include <KPluginFactory>
#include <KPluginLoader>
@@ -50,7 +52,10 @@ TerminalPanel::TerminalPanel(QWidget* parent) :
m_konsolePartMissingMessage(nullptr),
m_konsolePart(nullptr),
m_konsolePartCurrentDirectory(),
- m_sendCdToTerminalHistory()
+ m_sendCdToTerminalHistory(),
+ m_kiofuseInterface(QStringLiteral("org.kde.KIOFuse"),
+ QStringLiteral("/org/kde/KIOFuse"),
+ QDBusConnection::sessionBus())
{
m_layout = new QVBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
@@ -244,6 +249,19 @@ void TerminalPanel::slotMostLocalUrlResult(KJob* job)
const QUrl url = statJob->mostLocalUrl();
if (url.isLocalFile()) {
sendCdToTerminal(url.toLocalFile());
+ } else {
+ // URL isn't local, only hope for the terminal to be in sync with the
+ // DolphinView is to mount the remote URL in KIOFuse and point to it.
+ // If we can't do that for any reason, silently fail.
+ auto reply = m_kiofuseInterface.mountUrl(url.toString());
+ QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(reply, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher* watcher) {
+ watcher->deleteLater();
+ if (!reply.isError()) {
+ // Successfully mounted, point to the KIOFuse equivalent path.
+ sendCdToTerminal(reply.value());
+ }
+ });
}
m_mostLocalUrlJob = nullptr;
@@ -261,8 +279,31 @@ void TerminalPanel::slotKonsolePartCurrentDirectoryChanged(const QString& dir)
}
}
+ // User may potentially be browsing inside a KIOFuse mount.
+ // If so lets try and change the DolphinView to point to the remote URL equivalent.
+ // instead of into the KIOFuse mount itself (which can cause performance issues!)
const QUrl url(QUrl::fromLocalFile(dir));
- emit changeUrl(url);
+
+ KMountPoint::Ptr mountPoint = KMountPoint::currentMountPoints().findByPath(m_konsolePartCurrentDirectory);
+ if (mountPoint && mountPoint->mountType() != QStringLiteral("fuse.kio-fuse")) {
+ // Not in KIOFUse mount, so just switch to the corresponding URL.
+ emit changeUrl(url);
+ return;
+ }
+
+ auto reply = m_kiofuseInterface.remoteUrl(m_konsolePartCurrentDirectory);
+ QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(reply, this);
+ QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [=] (QDBusPendingCallWatcher* watcher) {
+ watcher->deleteLater();
+ if (reply.isError()) {
+ // KIOFuse errored out... just show the normal URL
+ emit changeUrl(url);
+ } else {
+ // Our location happens to be in a KIOFuse mount and is mounted.
+ // Let's change the DolphinView to point to the remote URL equivalent.
+ emit changeUrl(QUrl::fromUserInput(reply.value()));
+ }
+ });
}
bool TerminalPanel::terminalHasFocus() const
diff --git a/src/panels/terminal/terminalpanel.h b/src/panels/terminal/terminalpanel.h
index 6ab205fe3..661fee4d4 100644
--- a/src/panels/terminal/terminalpanel.h
+++ b/src/panels/terminal/terminalpanel.h
@@ -21,6 +21,7 @@
#define TERMINALPANEL_H
#include "panels/panel.h"
+#include "kiofuse_interface.h"
#include <QQueue>
@@ -101,6 +102,7 @@ private:
KParts::ReadOnlyPart* m_konsolePart;
QString m_konsolePartCurrentDirectory;
QQueue<QString> m_sendCdToTerminalHistory;
+ org::kde::KIOFuse::VFS m_kiofuseInterface;
};
#endif // TERMINALPANEL_H
diff --git a/src/search/dolphinsearchbox.cpp b/src/search/dolphinsearchbox.cpp
index 23f520de1..cdc0718df 100644
--- a/src/search/dolphinsearchbox.cpp
+++ b/src/search/dolphinsearchbox.cpp
@@ -136,6 +136,7 @@ QUrl DolphinSearchBox::urlForSearching() const
}
query.addQueryItem(QStringLiteral("url"), searchPath().url());
+ query.addQueryItem(QStringLiteral("title"), queryTitle(m_searchInput->text()));
url.setQuery(query);
}
@@ -219,6 +220,9 @@ void DolphinSearchBox::keyReleaseEvent(QKeyEvent* event)
m_searchInput->clear();
}
}
+ else if (event->key() == Qt::Key_Down) {
+ emit focusViewRequest();
+ }
}
bool DolphinSearchBox::eventFilter(QObject* obj, QEvent* event)
@@ -283,7 +287,7 @@ void DolphinSearchBox::slotSearchTextChanged(const QString& text)
void DolphinSearchBox::slotReturnPressed()
{
emitSearchRequest();
- emit returnPressed();
+ emit focusViewRequest();
}
void DolphinSearchBox::slotFacetChanged()
@@ -469,6 +473,12 @@ void DolphinSearchBox::init()
connect(m_startSearchTimer, &QTimer::timeout, this, &DolphinSearchBox::emitSearchRequest);
}
+QString DolphinSearchBox::queryTitle(const QString& text) const
+{
+ return i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.",
+ "Query Results from '%1'", text);
+}
+
QUrl DolphinSearchBox::balooUrlForSearching() const
{
#ifdef HAVE_BALOO
@@ -491,8 +501,7 @@ QUrl DolphinSearchBox::balooUrlForSearching() const
query.setSearchString(queryStrings.join(QLatin1Char(' ')));
- return query.toSearchUrl(i18nc("@title UDS_DISPLAY_NAME for a KIO directory listing. %1 is the query the user entered.",
- "Query Results from '%1'", text));
+ return query.toSearchUrl(queryTitle(text));
#else
return QUrl();
#endif
@@ -541,7 +550,7 @@ bool DolphinSearchBox::isIndexingEnabled() const
{
#ifdef HAVE_BALOO
const Baloo::IndexerConfig searchInfo;
- return searchInfo.fileIndexingEnabled() && searchInfo.shouldBeIndexed(searchPath().toLocalFile());
+ return searchInfo.fileIndexingEnabled() && !searchPath().isEmpty() && searchInfo.shouldBeIndexed(searchPath().toLocalFile());
#else
return false;
#endif
diff --git a/src/search/dolphinsearchbox.h b/src/search/dolphinsearchbox.h
index 5fef4ec5a..4afd752bc 100644
--- a/src/search/dolphinsearchbox.h
+++ b/src/search/dolphinsearchbox.h
@@ -118,8 +118,6 @@ signals:
*/
void searchTextChanged(const QString& text);
- void returnPressed();
-
/**
* Emitted as soon as the search box should get closed.
*/
@@ -131,6 +129,7 @@ signals:
* @see DolphinSearchBox::setActive()
*/
void activated();
+ void focusViewRequest();
private slots:
void emitSearchRequest();
@@ -162,6 +161,8 @@ private:
bool isIndexingEnabled() const;
private:
+ QString queryTitle(const QString& text) const;
+
bool m_startedSearching;
bool m_active;
diff --git a/src/settings/dolphin_detailsmodesettings.kcfg b/src/settings/dolphin_detailsmodesettings.kcfg
index e9a8fb28d..6ef344ac4 100644
--- a/src/settings/dolphin_detailsmodesettings.kcfg
+++ b/src/settings/dolphin_detailsmodesettings.kcfg
@@ -44,5 +44,13 @@
<label>Expandable folders</label>
<default>true</default>
</entry>
+ <entry name="DirectorySizeCount" type="Bool">
+ <label>Whether or not content count is use as directory size</label>
+ <default>true</default>
+ </entry>
+ <entry name="RecursiveDirectorySizeLimit" type="UInt">
+ <label>Recursive directory size limit</label>
+ <default>10</default>
+ </entry>
</group>
</kcfg>
diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg
index fca70656d..c397b2945 100644
--- a/src/settings/dolphin_generalsettings.kcfg
+++ b/src/settings/dolphin_generalsettings.kcfg
@@ -42,6 +42,10 @@
<label>Home URL</label>
<default code="true">QUrl::fromLocalFile(QDir::homePath()).toDisplayString(QUrl::PreferLocalFile)</default>
</entry>
+ <entry name="RememberOpenedTabs" type="Bool">
+ <label>Remember open folders and tabs</label>
+ <default>true</default>
+ </entry>
<entry name="SplitView" type="Bool">
<label>Split the view into two panes</label>
<default>false</default>
diff --git a/src/settings/kcm/kcmdolphingeneral.cpp b/src/settings/kcm/kcmdolphingeneral.cpp
index a82cb3858..39eccff76 100644
--- a/src/settings/kcm/kcmdolphingeneral.cpp
+++ b/src/settings/kcm/kcmdolphingeneral.cpp
@@ -33,12 +33,10 @@
K_PLUGIN_FACTORY(KCMDolphinGeneralConfigFactory, registerPlugin<DolphinGeneralConfigModule>(QStringLiteral("dolphingeneral"));)
-DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget* parent, const QVariantList& args) :
- KCModule(parent),
+DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget *parent, const QVariantList &args) :
+ KCModule(parent, args),
m_pages()
{
- Q_UNUSED(args)
-
setButtons(KCModule::Default | KCModule::Help);
QVBoxLayout* topLayout = new QVBoxLayout(this);
@@ -49,29 +47,17 @@ DolphinGeneralConfigModule::DolphinGeneralConfigModule(QWidget* parent, const QV
// initialize 'Behavior' tab
BehaviorSettingsPage* behaviorPage = new BehaviorSettingsPage(QUrl::fromLocalFile(QDir::homePath()), tabWidget);
tabWidget->addTab(behaviorPage, i18nc("@title:tab Behavior settings", "Behavior"));
-#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
- connect(behaviorPage, &BehaviorSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
-#else
connect(behaviorPage, &BehaviorSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
-#endif
// initialize 'Previews' tab
PreviewsSettingsPage* previewsPage = new PreviewsSettingsPage(tabWidget);
tabWidget->addTab(previewsPage, i18nc("@title:tab Previews settings", "Previews"));
-#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
- connect(previewsPage, &PreviewsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
-#else
connect(previewsPage, &PreviewsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
-#endif
// initialize 'Confirmations' tab
ConfirmationsSettingsPage* confirmationsPage = new ConfirmationsSettingsPage(tabWidget);
tabWidget->addTab(confirmationsPage, i18nc("@title:tab Confirmations settings", "Confirmations"));
-#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
- connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, QOverload<>::of(&DolphinGeneralConfigModule::changed));
-#else
connect(confirmationsPage, &ConfirmationsSettingsPage::changed, this, &DolphinGeneralConfigModule::markAsChanged);
-#endif
m_pages.append(behaviorPage);
m_pages.append(previewsPage);
m_pages.append(confirmationsPage);
@@ -85,14 +71,14 @@ DolphinGeneralConfigModule::~DolphinGeneralConfigModule()
void DolphinGeneralConfigModule::save()
{
- foreach (SettingsPageBase* page, m_pages) {
+ for (SettingsPageBase* page : qAsConst(m_pages)) {
page->applySettings();
}
}
void DolphinGeneralConfigModule::defaults()
{
- foreach (SettingsPageBase* page, m_pages) {
+ for (SettingsPageBase* page : qAsConst(m_pages)) {
page->applySettings();
}
}
diff --git a/src/settings/kcm/kcmdolphingeneral.h b/src/settings/kcm/kcmdolphingeneral.h
index c542c0139..2b60c7591 100644
--- a/src/settings/kcm/kcmdolphingeneral.h
+++ b/src/settings/kcm/kcmdolphingeneral.h
@@ -34,7 +34,7 @@ class DolphinGeneralConfigModule : public KCModule
Q_OBJECT
public:
- DolphinGeneralConfigModule(QWidget* parent, const QVariantList& args);
+ DolphinGeneralConfigModule(QWidget *parent, const QVariantList &args);
~DolphinGeneralConfigModule() override;
void save() override;
diff --git a/src/settings/kcm/kcmdolphinnavigation.cpp b/src/settings/kcm/kcmdolphinnavigation.cpp
index 2cdabdeee..f8de4eed2 100644
--- a/src/settings/kcm/kcmdolphinnavigation.cpp
+++ b/src/settings/kcm/kcmdolphinnavigation.cpp
@@ -29,23 +29,17 @@
K_PLUGIN_FACTORY(KCMDolphinNavigationConfigFactory, registerPlugin<DolphinNavigationConfigModule>(QStringLiteral("dolphinnavigation"));)
-DolphinNavigationConfigModule::DolphinNavigationConfigModule(QWidget* parent, const QVariantList& args) :
- KCModule(parent),
+DolphinNavigationConfigModule::DolphinNavigationConfigModule(QWidget *parent, const QVariantList &args) :
+ KCModule(parent, args),
m_navigation(nullptr)
{
- Q_UNUSED(args)
-
setButtons(KCModule::Default | KCModule::Help);
QVBoxLayout* topLayout = new QVBoxLayout(this);
topLayout->setContentsMargins(0, 0, 0, 0);
m_navigation = new NavigationSettingsPage(this);
-#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
- connect(m_navigation, &NavigationSettingsPage::changed, this, QOverload<>::of(&DolphinNavigationConfigModule::changed));
-#else
connect(m_navigation, &NavigationSettingsPage::changed, this, &DolphinNavigationConfigModule::markAsChanged);
-#endif
topLayout->addWidget(m_navigation, 0, {});
}
diff --git a/src/settings/kcm/kcmdolphinnavigation.h b/src/settings/kcm/kcmdolphinnavigation.h
index 2bcc7abab..7eb6b26e7 100644
--- a/src/settings/kcm/kcmdolphinnavigation.h
+++ b/src/settings/kcm/kcmdolphinnavigation.h
@@ -32,14 +32,14 @@ class DolphinNavigationConfigModule : public KCModule
Q_OBJECT
public:
- DolphinNavigationConfigModule(QWidget* parent, const QVariantList& args);
+ DolphinNavigationConfigModule(QWidget *parent, const QVariantList &args);
~DolphinNavigationConfigModule() override;
void save() override;
void defaults() override;
private:
- NavigationSettingsPage* m_navigation;
+ NavigationSettingsPage *m_navigation;
};
#endif
diff --git a/src/settings/kcm/kcmdolphinservices.cpp b/src/settings/kcm/kcmdolphinservices.cpp
index e6a8867d7..92e71bae0 100644
--- a/src/settings/kcm/kcmdolphinservices.cpp
+++ b/src/settings/kcm/kcmdolphinservices.cpp
@@ -30,22 +30,16 @@
K_PLUGIN_FACTORY(KCMDolphinServicesConfigFactory, registerPlugin<DolphinServicesConfigModule>(QStringLiteral("dolphinservices"));)
DolphinServicesConfigModule::DolphinServicesConfigModule(QWidget* parent, const QVariantList& args) :
- KCModule(parent),
+ KCModule(parent, args),
m_services(nullptr)
{
- Q_UNUSED(args)
-
setButtons(KCModule::Default | KCModule::Help);
QVBoxLayout* topLayout = new QVBoxLayout(this);
topLayout->setContentsMargins(0, 0, 0, 0);
m_services = new ServicesSettingsPage(this);
-#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0)
- connect(m_services, &ServicesSettingsPage::changed, this, QOverload<>::of(&DolphinServicesConfigModule::changed));
-#else
connect(m_services, &ServicesSettingsPage::changed, this, &DolphinServicesConfigModule::markAsChanged);
-#endif
topLayout->addWidget(m_services, 0, {});
}
diff --git a/src/settings/kcm/kcmdolphinservices.h b/src/settings/kcm/kcmdolphinservices.h
index 6c6af6728..a567450ca 100644
--- a/src/settings/kcm/kcmdolphinservices.h
+++ b/src/settings/kcm/kcmdolphinservices.h
@@ -39,7 +39,7 @@ public:
void defaults() override;
private:
- ServicesSettingsPage* m_services;
+ ServicesSettingsPage *m_services;
};
#endif
diff --git a/src/settings/kcm/kcmdolphinviewmodes.cpp b/src/settings/kcm/kcmdolphinviewmodes.cpp
index 4fac11600..91abe5cd4 100644
--- a/src/settings/kcm/kcmdolphinviewmodes.cpp
+++ b/src/settings/kcm/kcmdolphinviewmodes.cpp
@@ -33,12 +33,10 @@
K_PLUGIN_FACTORY(KCMDolphinViewModesConfigFactory, registerPlugin<DolphinViewModesConfigModule>(QStringLiteral("dolphinviewmodes"));)
-DolphinViewModesConfigModule::DolphinViewModesConfigModule(QWidget* parent, const QVariantList& args) :
- KCModule(parent),
+DolphinViewModesConfigModule::DolphinViewModesConfigModule(QWidget *parent, const QVariantList &args) :
+ KCModule(parent, args),
m_tabs()
{
- Q_UNUSED(args)
-
setButtons(KCModule::Default | KCModule::Help);
QVBoxLayout* topLayout = new QVBoxLayout(this);
@@ -74,7 +72,7 @@ DolphinViewModesConfigModule::~DolphinViewModesConfigModule()
void DolphinViewModesConfigModule::save()
{
- foreach (ViewSettingsTab* tab, m_tabs) {
+ for (ViewSettingsTab *tab : qAsConst(m_tabs)) {
tab->applySettings();
}
reparseConfiguration();
@@ -82,7 +80,7 @@ void DolphinViewModesConfigModule::save()
void DolphinViewModesConfigModule::defaults()
{
- foreach (ViewSettingsTab* tab, m_tabs) {
+ for (ViewSettingsTab *tab : qAsConst(m_tabs)) {
tab->restoreDefaultSettings();
}
reparseConfiguration();
@@ -90,13 +88,15 @@ void DolphinViewModesConfigModule::defaults()
void DolphinViewModesConfigModule::reparseConfiguration()
{
- QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration"));
+ QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"),
+ QStringLiteral("org.kde.Konqueror.Main"),
+ QStringLiteral("reparseConfiguration"));
QDBusConnection::sessionBus().send(message);
}
void DolphinViewModesConfigModule::viewModeChanged()
{
- emit changed(true);
+ emit markAsChanged();
}
#include "kcmdolphinviewmodes.moc"
diff --git a/src/settings/kcm/kcmdolphinviewmodes.h b/src/settings/kcm/kcmdolphinviewmodes.h
index c3775adff..40965b0e6 100644
--- a/src/settings/kcm/kcmdolphinviewmodes.h
+++ b/src/settings/kcm/kcmdolphinviewmodes.h
@@ -32,7 +32,7 @@ class DolphinViewModesConfigModule : public KCModule
Q_OBJECT
public:
- DolphinViewModesConfigModule(QWidget* parent, const QVariantList& args);
+ DolphinViewModesConfigModule(QWidget *parent, const QVariantList &args);
~DolphinViewModesConfigModule() override;
void save() override;
diff --git a/src/settings/services/servicemenuinstaller/CMakeLists.txt b/src/settings/services/servicemenuinstaller/CMakeLists.txt
index 988899936..deb08421b 100644
--- a/src/settings/services/servicemenuinstaller/CMakeLists.txt
+++ b/src/settings/services/servicemenuinstaller/CMakeLists.txt
@@ -6,5 +6,6 @@ target_link_libraries(servicemenuinstaller PRIVATE
Qt5::Core
Qt5::Gui
KF5::I18n
+ KF5::CoreAddons
)
install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp
index 06f34c6b9..60621921a 100644
--- a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp
+++ b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp
@@ -30,6 +30,7 @@
#include <QGuiApplication>
#include <KLocalizedString>
+#include <KShell>
// @param msg Error that gets logged to CLI
Q_NORETURN void fail(const QString &str)
@@ -59,6 +60,11 @@ struct UncompressCommand
QStringList args2;
};
+enum ScriptExecution{
+ Process,
+ Konsole
+};
+
void runUncompress(const QString &inputPath, const QString &outputPath)
{
QVector<QPair<QStringList, UncompressCommand>> mimeTypeToCommand;
@@ -126,12 +132,24 @@ QString findRecursive(const QString &dir, const QString &basename)
return QString();
}
-bool runScriptOnce(const QString &path, const QStringList &args)
+bool runScriptOnce(const QString &path, const QStringList &args, ScriptExecution execution)
{
QProcess process;
process.setWorkingDirectory(QFileInfo(path).absolutePath());
- process.start(path, args, QIODevice::NotOpen);
+ const static bool konsoleAvailable = !QStandardPaths::findExecutable("konsole").isEmpty();
+ if (konsoleAvailable && execution == ScriptExecution::Konsole) {
+ QString bashCommand = KShell::quoteArg(path) + ' ';
+ if (!args.isEmpty()) {
+ bashCommand.append(args.join(' '));
+ }
+ bashCommand.append("|| $SHELL");
+ // If the install script fails a shell opens and the user can fix the problem
+ // without an error konsole closes
+ process.start("konsole", QStringList() << "-e" << "bash" << "-c" << bashCommand, QIODevice::NotOpen);
+ } else {
+ process.start(path, args, QIODevice::NotOpen);
+ }
if (!process.waitForStarted()) {
fail(i18n("Failed to run installer script %1", path));
}
@@ -163,11 +181,11 @@ bool runScriptVariants(const QString &path, bool hasArgVariants, const QStringLi
qInfo() << "[servicemenuinstaller]: Trying to run installer/uninstaller" << path;
if (hasArgVariants) {
for (const auto &arg : argVariants) {
- if (runScriptOnce(path, {arg})) {
+ if (runScriptOnce(path, {arg}, ScriptExecution::Process)) {
return true;
}
}
- } else if (runScriptOnce(path, {})) {
+ } else if (runScriptOnce(path, {}, ScriptExecution::Konsole)) {
return true;
}
@@ -247,7 +265,11 @@ bool cmdInstall(const QString &archive, QString &errorText)
}
if (!installerPath.isEmpty()) {
- return runScriptVariants(installerPath, true, {"--local", "--local-install", "--install"}, errorText);
+ // Try to run script without variants first
+ if (!runScriptVariants(installerPath, false, {}, errorText)) {
+ return runScriptVariants(installerPath, true, {"--local", "--local-install", "--install"}, errorText);
+ }
+ return true;
}
fail(i18n("Failed to find an installation script in %1", dir));
diff --git a/src/settings/services/servicessettingspage.cpp b/src/settings/services/servicessettingspage.cpp
index fe900bc5c..ba6c48f80 100644
--- a/src/settings/services/servicessettingspage.cpp
+++ b/src/settings/services/servicessettingspage.cpp
@@ -38,6 +38,7 @@
#include <QListWidget>
#include <QShowEvent>
#include <QSortFilterProxyModel>
+#include <QLineEdit>
namespace
{
@@ -61,6 +62,11 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
"Select which services should "
"be shown in the context menu:"), this);
label->setWordWrap(true);
+ m_searchLineEdit = new QLineEdit(this);
+ m_searchLineEdit->setPlaceholderText(i18nc("@label:textbox", "Search..."));
+ connect(m_searchLineEdit, &QLineEdit::textChanged, this, [=](const QString &filter){
+ m_sortModel->setFilterFixedString(filter);
+ });
m_listView = new QListView(this);
ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView);
@@ -69,6 +75,8 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
m_sortModel->setSourceModel(m_serviceModel);
m_sortModel->setSortRole(Qt::DisplayRole);
m_sortModel->setSortLocaleAware(true);
+ m_sortModel->setFilterRole(Qt::DisplayRole);
+ m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_listView->setModel(m_sortModel);
m_listView->setItemDelegate(delegate);
m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
@@ -80,6 +88,7 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
connect(downloadButton, &KNS3::Button::dialogFinished, this, &ServicesSettingsPage::loadServices);
topLayout->addWidget(label);
+ topLayout->addWidget(m_searchLineEdit);
topLayout->addWidget(m_listView);
topLayout->addWidget(downloadButton);
@@ -236,6 +245,7 @@ void ServicesSettingsPage::loadServices()
}
m_sortModel->sort(Qt::DisplayRole);
+ m_searchLineEdit->setFocus(Qt::OtherFocusReason);
}
void ServicesSettingsPage::loadVersionControlSystems()
diff --git a/src/settings/services/servicessettingspage.h b/src/settings/services/servicessettingspage.h
index cd4cbe52f..dd53cf5dd 100644
--- a/src/settings/services/servicessettingspage.h
+++ b/src/settings/services/servicessettingspage.h
@@ -26,6 +26,7 @@
class QListView;
class QSortFilterProxyModel;
class ServiceModel;
+class QLineEdit;
/**
* @brief Page for the 'Services' settings of the Dolphin settings dialog.
@@ -74,6 +75,7 @@ private:
ServiceModel* m_serviceModel;
QSortFilterProxyModel* m_sortModel;
QListView* m_listView;
+ QLineEdit *m_searchLineEdit;
QStringList m_enabledVcsPlugins;
};
diff --git a/src/settings/startup/startupsettingspage.cpp b/src/settings/startup/startupsettingspage.cpp
index d7d5fba4c..eb1495746 100644
--- a/src/settings/startup/startupsettingspage.cpp
+++ b/src/settings/startup/startupsettingspage.cpp
@@ -27,18 +27,24 @@
#include <KLocalizedString>
#include <KMessageBox>
+#include <QButtonGroup>
#include <QCheckBox>
#include <QFileDialog>
#include <QLineEdit>
#include <QPushButton>
+#include <QRadioButton>
#include <QFormLayout>
+#include <QGridLayout>
#include <QHBoxLayout>
-#include <QVBoxLayout>
StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) :
SettingsPageBase(parent),
m_url(url),
m_homeUrl(nullptr),
+ m_homeUrlBoxLayoutContainer(nullptr),
+ m_buttonBoxLayoutContainer(nullptr),
+ m_rememberOpenedTabsRadioButton(nullptr),
+ m_homeUrlRadioButton(nullptr),
m_splitView(nullptr),
m_editableUrl(nullptr),
m_showFullPath(nullptr),
@@ -48,9 +54,19 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) :
{
QFormLayout* topLayout = new QFormLayout(this);
+ m_rememberOpenedTabsRadioButton = new QRadioButton(i18nc("@option:radio Startup Settings", "Folders, tabs, and window state from last time"));
+ m_homeUrlRadioButton = new QRadioButton();
+ // HACK: otherwise the radio button has too much spacing in a grid layout
+ m_homeUrlRadioButton->setMaximumWidth(24);
+
+ QButtonGroup* initialViewGroup = new QButtonGroup(this);
+ initialViewGroup->addButton(m_rememberOpenedTabsRadioButton);
+ initialViewGroup->addButton(m_homeUrlRadioButton);
+
// create 'Home URL' editor
- QHBoxLayout* homeUrlBoxLayout = new QHBoxLayout();
+ m_homeUrlBoxLayoutContainer = new QWidget(this);
+ QHBoxLayout* homeUrlBoxLayout = new QHBoxLayout(m_homeUrlBoxLayoutContainer);
homeUrlBoxLayout->setContentsMargins(0, 0, 0, 0);
m_homeUrl = new QLineEdit();
@@ -67,7 +83,8 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) :
connect(selectHomeUrlButton, &QPushButton::clicked,
this, &StartupSettingsPage::selectHomeUrl);
- QHBoxLayout* buttonBoxLayout = new QHBoxLayout();
+ m_buttonBoxLayoutContainer = new QWidget(this);
+ QHBoxLayout* buttonBoxLayout = new QHBoxLayout(m_buttonBoxLayoutContainer);
buttonBoxLayout->setContentsMargins(0, 0, 0, 0);
QPushButton* useCurrentButton = new QPushButton(i18nc("@action:button", "Use Current Location"));
@@ -79,41 +96,50 @@ StartupSettingsPage::StartupSettingsPage(const QUrl& url, QWidget* parent) :
connect(useDefaultButton, &QPushButton::clicked,
this, &StartupSettingsPage::useDefaultLocation);
- QVBoxLayout* homeBoxLayout = new QVBoxLayout();
- homeBoxLayout->setContentsMargins(0, 0, 0, 0);
- homeBoxLayout->addLayout(homeUrlBoxLayout);
- homeBoxLayout->addLayout(buttonBoxLayout);
+ QGridLayout* startInLocationLayout = new QGridLayout();
+ startInLocationLayout->setHorizontalSpacing(0);
+ startInLocationLayout->setContentsMargins(0, 0, 0, 0);
+ startInLocationLayout->addWidget(m_homeUrlRadioButton, 0, 0);
+ startInLocationLayout->addWidget(m_homeUrlBoxLayoutContainer, 0, 1);
+ startInLocationLayout->addWidget(m_buttonBoxLayoutContainer, 1, 1);
- topLayout->addRow(i18nc("@label:textbox", "Start in:"), homeBoxLayout);
+ topLayout->addRow(i18nc("@label:textbox", "Show on startup:"), m_rememberOpenedTabsRadioButton);
+ topLayout->addRow(QString(), startInLocationLayout);
topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
-
- // create 'Split view', 'Show full path', 'Editable location' and 'Filter bar' checkboxes
- m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Split view mode"));
- topLayout->addRow(i18nc("@label:checkbox", "Window options:"), m_splitView);
- m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Editable location bar"));
+ m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Begin in split view mode"));
+ topLayout->addRow(i18n("New windows:"), m_splitView);
+ m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"));
+ topLayout->addRow(QString(), m_filterBar);
+ m_editableUrl = new QCheckBox(i18nc("@option:check Startup Settings", "Make location bar editable"));
topLayout->addRow(QString(), m_editableUrl);
+
+ topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
+
+ m_openExternallyCalledFolderInNewTab = new QCheckBox(i18nc("@option:check Startup Settings", "Open new folders in tabs"));
+ topLayout->addRow(i18nc("@label:checkbox", "General:"), m_openExternallyCalledFolderInNewTab);
m_showFullPath = new QCheckBox(i18nc("@option:check Startup Settings", "Show full path inside location bar"));
topLayout->addRow(QString(), m_showFullPath);
- m_filterBar = new QCheckBox(i18nc("@option:check Startup Settings", "Show filter bar"));
- topLayout->addRow(QString(), m_filterBar);
m_showFullPathInTitlebar = new QCheckBox(i18nc("@option:check Startup Settings", "Show full path in title bar"));
topLayout->addRow(QString(), m_showFullPathInTitlebar);
- m_openExternallyCalledFolderInNewTab = new QCheckBox(i18nc("@option:check Startup Settings", "Open new folders in tabs"));
- topLayout->addRow(QString(), m_openExternallyCalledFolderInNewTab);
-
loadSettings();
+ updateInitialViewOptions();
+
connect(m_homeUrl, &QLineEdit::textChanged, this, &StartupSettingsPage::slotSettingsChanged);
+ connect(m_rememberOpenedTabsRadioButton, &QRadioButton::toggled, this, &StartupSettingsPage::slotSettingsChanged);
+ connect(m_homeUrlRadioButton, &QRadioButton::toggled, this, &StartupSettingsPage::slotSettingsChanged);
+
connect(m_splitView, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
connect(m_editableUrl, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
- connect(m_showFullPath, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
connect(m_filterBar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
- connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
+
connect(m_openExternallyCalledFolderInNewTab, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
+ connect(m_showFullPath, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
+ connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &StartupSettingsPage::slotSettingsChanged);
}
StartupSettingsPage::~StartupSettingsPage()
@@ -132,12 +158,21 @@ void StartupSettingsPage::applySettings()
KMessageBox::error(this, i18nc("@info", "The location for the home folder is invalid or does not exist, it will not be applied."));
}
+ // Remove saved state if "remember open tabs" has been turned off
+ if (!m_rememberOpenedTabsRadioButton->isChecked()) {
+ KConfigGroup windowState{KSharedConfig::openConfig(QStringLiteral("dolphinrc")), "WindowState"};
+ if (windowState.exists()) {
+ windowState.deleteGroup();
+ }
+ }
+
+ settings->setRememberOpenedTabs(m_rememberOpenedTabsRadioButton->isChecked());
settings->setSplitView(m_splitView->isChecked());
settings->setEditableUrl(m_editableUrl->isChecked());
- settings->setShowFullPath(m_showFullPath->isChecked());
settings->setFilterBar(m_filterBar->isChecked());
- settings->setShowFullPathInTitlebar(m_showFullPathInTitlebar->isChecked());
settings->setOpenExternallyCalledFolderInNewTab(m_openExternallyCalledFolderInNewTab->isChecked());
+ settings->setShowFullPath(m_showFullPath->isChecked());
+ settings->setShowFullPathInTitlebar(m_showFullPathInTitlebar->isChecked());
settings->save();
}
@@ -155,9 +190,18 @@ void StartupSettingsPage::slotSettingsChanged()
// to apply the startup settings only if they have been explicitly changed by the user
// (see bug #254947).
GeneralSettings::setModifiedStartupSettings(true);
+
+ // Enable and disable home URL controls appropriately
+ updateInitialViewOptions();
emit changed();
}
+void StartupSettingsPage::updateInitialViewOptions()
+{
+ m_homeUrlBoxLayoutContainer->setEnabled(m_homeUrlRadioButton->isChecked());
+ m_buttonBoxLayoutContainer->setEnabled(m_homeUrlRadioButton->isChecked());
+}
+
void StartupSettingsPage::selectHomeUrl()
{
const QUrl homeUrl(QUrl::fromUserInput(m_homeUrl->text(), QString(), QUrl::AssumeLocalFile));
@@ -182,6 +226,8 @@ void StartupSettingsPage::loadSettings()
{
const QUrl url(Dolphin::homeUrl());
m_homeUrl->setText(url.toDisplayString(QUrl::PreferLocalFile));
+ m_rememberOpenedTabsRadioButton->setChecked(GeneralSettings::rememberOpenedTabs());
+ m_homeUrlRadioButton->setChecked(!GeneralSettings::rememberOpenedTabs());
m_splitView->setChecked(GeneralSettings::splitView());
m_editableUrl->setChecked(GeneralSettings::editableUrl());
m_showFullPath->setChecked(GeneralSettings::showFullPath());
diff --git a/src/settings/startup/startupsettingspage.h b/src/settings/startup/startupsettingspage.h
index a5e0b236f..d1c937f1f 100644
--- a/src/settings/startup/startupsettingspage.h
+++ b/src/settings/startup/startupsettingspage.h
@@ -23,8 +23,9 @@
#include <QUrl>
-class QLineEdit;
class QCheckBox;
+class QLineEdit;
+class QRadioButton;
/**
* @brief Page for the 'Startup' settings of the Dolphin settings dialog.
@@ -48,6 +49,7 @@ public:
private slots:
void slotSettingsChanged();
+ void updateInitialViewOptions();
void selectHomeUrl();
void useCurrentLocation();
void useDefaultLocation();
@@ -58,6 +60,10 @@ private:
private:
QUrl m_url;
QLineEdit* m_homeUrl;
+ QWidget* m_homeUrlBoxLayoutContainer;
+ QWidget* m_buttonBoxLayoutContainer;
+ QRadioButton* m_rememberOpenedTabsRadioButton;
+ QRadioButton* m_homeUrlRadioButton;
QCheckBox* m_splitView;
QCheckBox* m_editableUrl;
diff --git a/src/settings/viewmodes/viewsettingstab.cpp b/src/settings/viewmodes/viewsettingstab.cpp
index 06b0b8cf5..fa891133b 100644
--- a/src/settings/viewmodes/viewsettingstab.cpp
+++ b/src/settings/viewmodes/viewsettingstab.cpp
@@ -33,6 +33,10 @@
#include <QComboBox>
#include <QHelpEvent>
#include <QFormLayout>
+#include <QSpinBox>
+#include <QRadioButton>
+#include <QButtonGroup>
+#include <QLabel>
ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
QWidget(parent),
@@ -42,11 +46,11 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
m_fontRequester(nullptr),
m_widthBox(nullptr),
m_maxLinesBox(nullptr),
- m_expandableFolders(nullptr)
+ m_expandableFolders(nullptr),
+ m_recursiveDirectorySizeLimit(nullptr)
{
QFormLayout* topLayout = new QFormLayout(this);
-
// Create "Icon Size" section
const int minRange = ZoomLevelInfo::minimumLevel();
const int maxRange = ZoomLevelInfo::maximumLevel();
@@ -75,7 +79,6 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
m_fontRequester = new DolphinFontRequester(this);
topLayout->addRow(i18nc("@label:listbox", "Label font:"), m_fontRequester);
-
switch (m_mode) {
case IconsMode: {
m_widthBox = new QComboBox();
@@ -107,8 +110,30 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
case DetailsMode:
m_expandableFolders = new QCheckBox(i18nc("@option:check", "Expandable"));
topLayout->addRow(i18nc("@label:checkbox", "Folders:"), m_expandableFolders);
- break;
- default:
+
+#ifndef Q_OS_WIN
+ // Sorting properties
+ m_numberOfItems = new QRadioButton(i18nc("option:radio", "Number of items"));
+ m_sizeOfContents = new QRadioButton(i18nc("option:radio", "Size of contents, up to "));
+
+ QButtonGroup* sortingModeGroup = new QButtonGroup(this);
+ sortingModeGroup->addButton(m_numberOfItems);
+ sortingModeGroup->addButton(m_sizeOfContents);
+
+ m_recursiveDirectorySizeLimit = new QSpinBox();
+ connect(m_recursiveDirectorySizeLimit, QOverload<int>::of(&QSpinBox::valueChanged), this, [this](int value) {
+ m_recursiveDirectorySizeLimit->setSuffix(i18np(" level deep", " levels deep", value));
+ });
+ m_recursiveDirectorySizeLimit->setRange(1, 20);
+ m_recursiveDirectorySizeLimit->setSingleStep(1);
+
+ QHBoxLayout *contentsSizeLayout = new QHBoxLayout();
+ contentsSizeLayout->addWidget(m_sizeOfContents);
+ contentsSizeLayout->addWidget(m_recursiveDirectorySizeLimit);
+
+ topLayout->addRow(i18nc("@title:group", "Folder size displays:"), m_numberOfItems);
+ topLayout->addRow(QString(), contentsSizeLayout);
+#endif
break;
}
@@ -128,6 +153,11 @@ ViewSettingsTab::ViewSettingsTab(Mode mode, QWidget* parent) :
break;
case DetailsMode:
connect(m_expandableFolders, &QCheckBox::toggled, this, &ViewSettingsTab::changed);
+ connect(m_recursiveDirectorySizeLimit, QOverload<int>::of(&QSpinBox::valueChanged), this, &ViewSettingsTab::changed);
+ connect(m_numberOfItems, &QRadioButton::toggled, this, &ViewSettingsTab::changed);
+ connect(m_sizeOfContents, &QRadioButton::toggled, this, [=]() {
+ m_recursiveDirectorySizeLimit->setEnabled(m_sizeOfContents->isChecked());
+ });
break;
default:
break;
@@ -153,6 +183,8 @@ void ViewSettingsTab::applySettings()
break;
case DetailsMode:
DetailsModeSettings::setExpandableFolders(m_expandableFolders->isChecked());
+ DetailsModeSettings::setDirectorySizeCount(m_numberOfItems->isChecked());
+ DetailsModeSettings::setRecursiveDirectorySizeLimit(m_recursiveDirectorySizeLimit->value());
break;
default:
break;
@@ -201,6 +233,14 @@ void ViewSettingsTab::loadSettings()
break;
case DetailsMode:
m_expandableFolders->setChecked(DetailsModeSettings::expandableFolders());
+ if (DetailsModeSettings::directorySizeCount()) {
+ m_numberOfItems->setChecked(true);
+ m_recursiveDirectorySizeLimit->setEnabled(false);
+ } else {
+ m_sizeOfContents->setChecked(true);
+ m_recursiveDirectorySizeLimit->setEnabled(true);
+ }
+ m_recursiveDirectorySizeLimit->setValue(DetailsModeSettings::recursiveDirectorySizeLimit());
break;
default:
break;
diff --git a/src/settings/viewmodes/viewsettingstab.h b/src/settings/viewmodes/viewsettingstab.h
index fff882e5e..4d459fca2 100644
--- a/src/settings/viewmodes/viewsettingstab.h
+++ b/src/settings/viewmodes/viewsettingstab.h
@@ -28,6 +28,8 @@ class DolphinFontRequester;
class QComboBox;
class QCheckBox;
class QSlider;
+class QSpinBox;
+class QRadioButton;
/**
* @brief Represents one tab of the view-settings page.
@@ -72,6 +74,9 @@ private:
QComboBox* m_widthBox;
QComboBox* m_maxLinesBox;
QCheckBox* m_expandableFolders;
+ QRadioButton* m_numberOfItems;
+ QRadioButton* m_sizeOfContents;
+ QSpinBox* m_recursiveDirectorySizeLimit;
};
#endif
diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp
index d8f2aab93..f0dc17837 100644
--- a/src/views/dolphinview.cpp
+++ b/src/views/dolphinview.cpp
@@ -1200,7 +1200,7 @@ void DolphinView::slotPasteJobResult(KJob *job)
emit errorMessage(job->errorString());
}
if (!m_selectedUrls.isEmpty()) {
- m_selectedUrls << KDirModel::simplifiedUrlList(m_selectedUrls);
+ m_selectedUrls = KDirModel::simplifiedUrlList(m_selectedUrls);
}
}
@@ -1493,13 +1493,27 @@ void DolphinView::calculateItemCount(int& fileCount,
KIO::filesize_t& totalFileSize) const
{
const int itemCount = m_model->count();
+
+ bool countFileSize = true;
+
+ // In case we have a precomputed value
+ const auto job = KIO::statDetails(m_model->rootItem().url(), KIO::StatJob::SourceSide, KIO::StatRecursiveSize);
+ job->exec();
+ const auto entry = job->statResult();
+ if (entry.contains(KIO::UDSEntry::UDS_RECURSIVE_SIZE)) {
+ totalFileSize = static_cast<KIO::filesize_t>(entry.numberValue(KIO::UDSEntry::UDS_RECURSIVE_SIZE));
+ countFileSize = false;
+ }
+
for (int i = 0; i < itemCount; ++i) {
const KFileItem item = m_model->fileItem(i);
if (item.isDir()) {
++folderCount;
} else {
++fileCount;
- totalFileSize += item.size();
+ if (countFileSize) {
+ totalFileSize += item.size();
+ }
}
}
}
diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp
index c61e1aaa9..e89e2e62c 100644
--- a/src/views/dolphinviewactionhandler.cpp
+++ b/src/views/dolphinviewactionhandler.cpp
@@ -283,7 +283,7 @@ void DolphinViewActionHandler::createActions()
"<para>Hidden items only differ from other ones in that their "
"name starts with a \".\". In general there is no need for "
"users to access them which is why they are hidden.</para>"));
- m_actionCollection->setDefaultShortcuts(showHiddenFiles, {Qt::ALT + Qt::Key_Period, Qt::CTRL + Qt::Key_H, Qt::Key_F8});
+ m_actionCollection->setDefaultShortcuts(showHiddenFiles, KStandardShortcut::showHideHiddenFiles());
connect(showHiddenFiles, &KToggleAction::triggered, this, &DolphinViewActionHandler::toggleShowHiddenFiles);
QAction* adjustViewProps = m_actionCollection->addAction(QStringLiteral("view_properties"));
diff --git a/src/views/versioncontrol/kversioncontrolplugin.h b/src/views/versioncontrol/kversioncontrolplugin.h
index 287974534..0d94a3fc8 100644
--- a/src/views/versioncontrol/kversioncontrolplugin.h
+++ b/src/views/versioncontrol/kversioncontrolplugin.h
@@ -180,14 +180,17 @@ public:
virtual ItemVersion itemVersion(const KFileItem& item) const = 0;
/**
- * @return List of actions that are available for the items \p items.
- * It is recommended to keep the number of returned actions small
- * in case if an item is an unversioned directory that is not
- * inside the hierarchy tree of the version control system. This
- * prevents having a cluttered context menu for directories
- * outside the version control system.
+ * @return List of actions that are available for the \p items in a version controlled
+ * path.
*/
- virtual QList<QAction*> actions(const KFileItemList& items) const = 0;
+ virtual QList<QAction*> versionControlActions(const KFileItemList& items) const = 0;
+
+ /**
+ * @return List of actions that are available for the out of version control
+ * items \p items. It's opposed to the \p versionedActions. Common usage
+ * is for clone/checkout actions.
+ */
+ virtual QList<QAction*> outOfVersionControlActions(const KFileItemList& items) const = 0;
Q_SIGNALS:
/**
diff --git a/src/views/versioncontrol/versioncontrolobserver.cpp b/src/views/versioncontrol/versioncontrolobserver.cpp
index 2d801686e..f6c74fb5f 100644
--- a/src/views/versioncontrol/versioncontrolobserver.cpp
+++ b/src/views/versioncontrol/versioncontrolobserver.cpp
@@ -118,11 +118,19 @@ QList<QAction*> VersionControlObserver::actions(const KFileItemList& items) cons
}
}
- if (!m_model || hasNullItems || !isVersioned()) {
+ if (!m_model || hasNullItems) {
return {};
}
- return m_plugin->actions(items);
+ if (isVersionControlled()) {
+ return m_plugin->versionControlActions(items);
+ } else {
+ QList<QAction*> actions;
+ for (const auto &plugin : qAsConst(m_plugins)) {
+ actions << plugin.first->outOfVersionControlActions(items);
+ }
+ return actions;
+ }
}
void VersionControlObserver::delayedDirectoryVerification()
@@ -360,7 +368,7 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const QUrl& director
return bestPlugin;
}
-bool VersionControlObserver::isVersioned() const
+bool VersionControlObserver::isVersionControlled() const
{
return m_versionedDirectory && m_plugin;
}
diff --git a/src/views/versioncontrol/versioncontrolobserver.h b/src/views/versioncontrol/versioncontrolobserver.h
index 66f992963..648c9d6fd 100644
--- a/src/views/versioncontrol/versioncontrolobserver.h
+++ b/src/views/versioncontrol/versioncontrolobserver.h
@@ -143,7 +143,7 @@ private:
/**
* Returns true, if the directory contains a version control information.
*/
- bool isVersioned() const;
+ bool isVersionControlled() const;
private:
bool m_pendingItemStatesUpdate;