diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/itemactions/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | src/itemactions/hidefileitemaction.cpp | 173 | ||||
| -rw-r--r-- | src/itemactions/hidefileitemaction.h | 26 | ||||
| -rw-r--r-- | src/itemactions/hidefileitemaction.json | 10 | ||||
| -rw-r--r-- | src/settings/contextmenu/contextmenusettingspage.cpp | 5 |
5 files changed, 224 insertions, 1 deletions
diff --git a/src/itemactions/CMakeLists.txt b/src/itemactions/CMakeLists.txt index 6610b0e4a..cd196eb36 100644 --- a/src/itemactions/CMakeLists.txt +++ b/src/itemactions/CMakeLists.txt @@ -11,6 +11,16 @@ target_link_libraries(movetonewfolderitemaction KF6::KIOWidgets KF6::KIOFileWidgets) +#hidefileitemaction plugin +kcoreaddons_add_plugin(hidefileitemaction + SOURCES hidefileitemaction.cpp hidefileitemaction.h + INSTALL_NAMESPACE "kf6/kfileitemaction") + +target_link_libraries(hidefileitemaction + KF6::CoreAddons + KF6::I18n + KF6::KIOCore + KF6::KIOWidgets) if(NOT WIN32) # setfoldericon plugin @@ -24,3 +34,4 @@ if(NOT WIN32) KF6::KIOCore KF6::KIOWidgets) endif() + diff --git a/src/itemactions/hidefileitemaction.cpp b/src/itemactions/hidefileitemaction.cpp new file mode 100644 index 000000000..b01117838 --- /dev/null +++ b/src/itemactions/hidefileitemaction.cpp @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: 2025 Kostiantyn Korchuhanov <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "hidefileitemaction.h" +#include "../dolphindebug.h" + +#ifdef QT_DBUS_LIB +#include <KDirNotify> +#endif +#include <KConfigGroup> +#include <KFileItem> +#include <KFileItemListProperties> +#include <KLocalizedString> +#include <KPluginFactory> +#include <KSharedConfig> + +#include <QAction> +#include <QDir> +#include <QFile> +#include <QFileInfo> +#include <QTextStream> +#include <QUrl> + +K_PLUGIN_CLASS_WITH_JSON(HideFileItemAction, "hidefileitemaction.json"); + +HideFileItemAction::HideFileItemAction(QObject *parent) + : KAbstractFileItemActionPlugin(parent) +{ +} + +static bool pluginIsEnabled() +{ + KConfigGroup showGroup(KSharedConfig::openConfig(QStringLiteral("kservicemenurc")), QStringLiteral("Show")); + return showGroup.readEntry(QStringLiteral("hidefileitemaction"), false); +} + +static QStringList readHiddenFileEntries(const QString &hiddenPath) +{ + QStringList entriesNames; + QFile readHiddenFile(hiddenPath); + if (readHiddenFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&readHiddenFile); + while (!in.atEnd()) { + entriesNames.append(in.readLine()); + } + } + return entriesNames; +} + +static bool fileAlreadyHidden(const KFileItem &item) +{ + QString fileName = item.name(); + QString parentPath = QFileInfo(item.localPath()).absolutePath(); + QString hiddenPath = QDir(parentPath).filePath(".hidden"); + + QStringList entriesNames = readHiddenFileEntries(hiddenPath); + + return entriesNames.contains(fileName); +} + +static void writeHiddenFileEntries(const QString &hiddenPath, const QStringList &entriesNames) +{ + QFile writeHiddenFile(hiddenPath); + if (writeHiddenFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + QTextStream out(&writeHiddenFile); + out << entriesNames.join("\n"); + } +} + +static void writeFileToHidden(const QString &hiddenPath, const QString &fileName) +{ + QStringList entriesNames = readHiddenFileEntries(hiddenPath); + if (!entriesNames.contains(fileName)) { + entriesNames.append(fileName); + writeHiddenFileEntries(hiddenPath, entriesNames); + } +} + +static void deleteFileFromHidden(const QString &hiddenPath, const QString &fileName) +{ + QStringList entriesNames = readHiddenFileEntries(hiddenPath); + entriesNames.removeAll(fileName); + writeHiddenFileEntries(hiddenPath, entriesNames); +} + +QList<QAction *> HideFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) +{ + if (!pluginIsEnabled()) { + return {}; + } + const KFileItemList selectedItems = fileItemInfos.items(); + if (selectedItems.isEmpty()) { + return {}; + } + + const QUrl parentFileUrl = selectedItems.first().url().adjusted(QUrl::RemoveFilename); + const QString parentFilePath = parentFileUrl.toLocalFile(); + const QString hiddenFilePath = QDir(parentFilePath).filePath(".hidden"); + + for (const KFileItem &item : selectedItems) { + if (item.url().adjusted(QUrl::RemoveFilename).toLocalFile() != parentFilePath) { + return {}; + } + } + + QFileInfo parentFileInfo(parentFilePath); + QFileInfo hiddenFileInfo(hiddenFilePath); + const bool canWrite = parentFileInfo.isWritable() && (!hiddenFileInfo.exists() || hiddenFileInfo.isWritable()); + + QAction *hideFolder = new QAction(i18nc("@action:inmenu", "Hide"), parentWidget); + hideFolder->setIcon(QIcon::fromTheme("hide_table_row")); + hideFolder->setEnabled(canWrite); + + connect(hideFolder, &QAction::triggered, this, [selectedItems, hiddenFilePath, parentFilePath]() { + for (const KFileItem &item : selectedItems) { + if (item.name() == ".hidden") { + continue; + } + + QString fileName = item.name(); + writeFileToHidden(hiddenFilePath, fileName); + +#ifdef QT_DBUS_LIB + org::kde::KDirNotify::emitFilesChanged({QUrl::fromLocalFile(parentFilePath)}); +#endif + } + }); + + QAction *unhideFolder = new QAction(i18nc("@action:inmenu", "Unhide"), parentWidget); + unhideFolder->setIcon(QIcon::fromTheme("view-visible")); + unhideFolder->setEnabled(canWrite); + + connect(unhideFolder, &QAction::triggered, this, [selectedItems, hiddenFilePath, parentFilePath]() { + for (const KFileItem &item : selectedItems) { + if (item.name() == ".hidden") { + continue; + } + + QString fileName = item.name(); + deleteFileFromHidden(hiddenFilePath, fileName); + +#ifdef QT_DBUS_LIB + org::kde::KDirNotify::emitFilesChanged({QUrl::fromLocalFile(parentFilePath)}); +#endif + } + }); + + bool anyFileHidden = false; + bool anyFileVisible = false; + for (const KFileItem &item : selectedItems) { + if (fileAlreadyHidden(item)) { + anyFileHidden = true; + } else { + anyFileVisible = true; + } + if (anyFileHidden && anyFileVisible) { + break; + } + } + if (anyFileHidden && anyFileVisible) { + return {hideFolder, unhideFolder}; + } + if (anyFileVisible) { + return {hideFolder}; + } + return {unhideFolder}; +} + +#include "hidefileitemaction.moc" +#include "moc_hidefileitemaction.cpp" diff --git a/src/itemactions/hidefileitemaction.h b/src/itemactions/hidefileitemaction.h new file mode 100644 index 000000000..565f0d563 --- /dev/null +++ b/src/itemactions/hidefileitemaction.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2025 Kostiantyn Korchuhanov <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HIDEFILEITEMACTION_H +#define HIDEFILEITEMACTION_H + +#include <KAbstractFileItemActionPlugin> +#include <KFileItemListProperties> +#include <QAction> +#include <QList> +#include <QWidget> + +class HideFileItemAction : public KAbstractFileItemActionPlugin +{ + Q_OBJECT + +public: + HideFileItemAction(QObject *parent); + + QList<QAction *> actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) override; +}; + +#endif // HIDEFILEITEMACTION_H diff --git a/src/itemactions/hidefileitemaction.json b/src/itemactions/hidefileitemaction.json new file mode 100644 index 000000000..7b4627254 --- /dev/null +++ b/src/itemactions/hidefileitemaction.json @@ -0,0 +1,10 @@ +{ + "KPlugin": { + "Icon": "hide_table_row", + "MimeTypes": [ + "application/octet-stream" + ], + "Name": "Hide" + }, + "X-KDE-Show-In-Submenu": true +} diff --git a/src/settings/contextmenu/contextmenusettingspage.cpp b/src/settings/contextmenu/contextmenusettingspage.cpp index b3585e3fa..ae3b58033 100644 --- a/src/settings/contextmenu/contextmenusettingspage.cpp +++ b/src/settings/contextmenu/contextmenusettingspage.cpp @@ -300,7 +300,10 @@ void ContextMenuSettingsPage::loadServices() for (const auto &jsonMetadata : jsonPlugins) { const QString desktopEntryName = jsonMetadata.pluginId(); if (!isInServicesList(desktopEntryName)) { - const bool checked = showGroup.readEntry(desktopEntryName, true); + bool checked = showGroup.readEntry(desktopEntryName, true); + if (!showGroup.hasKey(desktopEntryName) && desktopEntryName == QStringLiteral("hidefileitemaction")) { + checked = false; + } addRow(jsonMetadata.iconName(), jsonMetadata.name(), desktopEntryName, checked); } } |
