File indexing completed on 2024-04-28 05:47:34
0001 /* 0002 SPDX-FileCopyrightText: 2016 Elvis Angelaccio <elvis.angelaccio@kde.org> 0003 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "compressfileitemaction.h" 0009 0010 #include <QDir> 0011 #include <QMenu> 0012 #include <QMimeDatabase> 0013 0014 #include <KFileItem> 0015 #include <KIO/ApplicationLauncherJob> 0016 #include <KLocalizedString> 0017 #include <KPluginFactory> 0018 0019 #include <KIO/OpenFileManagerWindowJob> 0020 #include <algorithm> 0021 0022 #include "addtoarchive.h" 0023 #include "pluginmanager.h" 0024 0025 K_PLUGIN_CLASS_WITH_JSON(CompressFileItemAction, "compressfileitemaction.json") 0026 0027 using namespace Kerfuffle; 0028 0029 CompressFileItemAction::CompressFileItemAction(QObject *parent, const QVariantList &) 0030 : KAbstractFileItemActionPlugin(parent) 0031 , m_pluginManager(new PluginManager(this)) 0032 { 0033 } 0034 0035 QList<QAction *> CompressFileItemAction::actions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget) 0036 { 0037 // #268163: don't offer compression on already compressed archives, unless the user selected 2 or more of them. 0038 if (fileItemInfos.items().count() == 1 && m_pluginManager->supportedMimeTypes().contains(fileItemInfos.mimeType())) { 0039 return {}; 0040 } 0041 0042 // KFileItemListProperties::isLocal() doesn't check target URL (e.g. files on the desktop) 0043 const auto urlList = fileItemInfos.urlList(); 0044 const bool hasLocalUrl = std::any_of(urlList.begin(), urlList.end(), [](const QUrl &url) { 0045 return url.isLocalFile(); 0046 }); 0047 0048 if (!hasLocalUrl) { 0049 return {}; 0050 } 0051 0052 QList<QAction *> actions; 0053 const QIcon icon = QIcon::fromTheme(QStringLiteral("archive-insert")); 0054 0055 QMenu *compressMenu = new QMenu(parentWidget); 0056 0057 compressMenu->addAction(createAction(icon, parentWidget, urlList, QStringLiteral("tar.gz"))); 0058 0059 const QMimeType zipMime = QMimeDatabase().mimeTypeForName(QStringLiteral("application/zip")); 0060 // Don't offer zip compression if no zip plugin is available. 0061 if (!m_pluginManager->preferredWritePluginsFor(zipMime).isEmpty()) { 0062 compressMenu->addAction(createAction(icon, parentWidget, urlList, QStringLiteral("zip"))); 0063 } 0064 0065 compressMenu->addAction(createAction(icon, parentWidget, urlList, QString())); 0066 0067 QAction *compressMenuAction = new QAction(i18nc("@action:inmenu Compress submenu in Dolphin context menu", "Compress"), parentWidget); 0068 compressMenuAction->setMenu(compressMenu); 0069 compressMenuAction->setEnabled(fileItemInfos.isLocal() && fileItemInfos.supportsWriting() && !m_pluginManager->availableWritePlugins().isEmpty()); 0070 compressMenuAction->setIcon(icon); 0071 0072 actions << compressMenuAction; 0073 return actions; 0074 } 0075 0076 QAction *CompressFileItemAction::createAction(const QIcon &icon, QWidget *parent, const QList<QUrl> &urls, const QString &fileExtension) 0077 { 0078 QString name; 0079 if (fileExtension.isEmpty()) { 0080 name = i18nc("@action:inmenu Part of Compress submenu in Dolphin context menu", "Compress to..."); 0081 } else { 0082 QString fileName = AddToArchive::getFileNameForUrls(urls, fileExtension).section(QDir::separator(), -1); 0083 if (fileName.length() > 21) { 0084 fileName = fileName.left(10) + QStringLiteral("…") + fileName.right(10); 0085 } 0086 0087 name = i18nc("@action:inmenu Part of Compress submenu in Dolphin context menu, %1 filename", "Here as \"%1\"", fileName); 0088 } 0089 0090 QAction *action = new QAction(icon, name, parent); 0091 0092 connect(action, &QAction::triggered, this, [fileExtension, urls, parent, this]() { 0093 // Don't pass a parent to the job, otherwise it will be killed if dolphin gets closed. 0094 auto *addToArchiveJob = new AddToArchive(nullptr); 0095 addToArchiveJob->setImmediateProgressReporting(true); 0096 addToArchiveJob->setChangeToFirstPath(true); 0097 for (const QUrl &url : urls) { 0098 addToArchiveJob->addInput(url); 0099 } 0100 if (!fileExtension.isEmpty()) { 0101 addToArchiveJob->setAutoFilenameSuffix(fileExtension); 0102 } else { 0103 if (!addToArchiveJob->showAddDialog(parent)) { 0104 delete addToArchiveJob; 0105 return; 0106 } 0107 } 0108 addToArchiveJob->start(); 0109 connect(addToArchiveJob, &KJob::finished, this, [this, addToArchiveJob]() { 0110 if (addToArchiveJob->error() == 0) { 0111 KIO::highlightInFileManager({QUrl::fromLocalFile(addToArchiveJob->fileName())}); 0112 } else if (!addToArchiveJob->errorString().isEmpty()) { 0113 Q_EMIT error(addToArchiveJob->errorString()); 0114 } 0115 addToArchiveJob->deleteLater(); 0116 }); 0117 }); 0118 0119 return action; 0120 } 0121 0122 #include "compressfileitemaction.moc" 0123 #include "moc_compressfileitemaction.cpp"