| 1 | /* |
| 2 | This file is part of the KDE project |
| 3 | SPDX-FileCopyrightText: 2025 Méven Car <meven@kde.org> |
| 4 | |
| 5 | SPDX-License-Identifier: GPL-2.0-or-later |
| 6 | */ |
| 7 | |
| 8 | #include "dropintonewfolderPlugin.h" |
| 9 | #include "copyjob.h" |
| 10 | #include "openfilemanagerwindowjob.h" |
| 11 | #include <KIO/FileUndoManager> |
| 12 | #include <KIO/OpenFileManagerWindowJob> |
| 13 | #include <KIO/StatJob> |
| 14 | #include <kfileitem.h> |
| 15 | #include <knewfilemenu.h> |
| 16 | |
| 17 | #include <QAction> |
| 18 | |
| 19 | #include <KFileItemListProperties> |
| 20 | #include <KLocalizedString> |
| 21 | #include <KPluginFactory> |
| 22 | |
| 23 | K_PLUGIN_CLASS_WITH_JSON(DropIntoNewFolderPlugin, "dropintonewfolderPlugin.json" ) |
| 24 | |
| 25 | DropIntoNewFolderPlugin::DropIntoNewFolderPlugin(QObject *parent, const QVariantList &) |
| 26 | : KIO::DndPopupMenuPlugin(parent) |
| 27 | { |
| 28 | } |
| 29 | |
| 30 | QList<QAction *> DropIntoNewFolderPlugin::setup(const KFileItemListProperties &fileItemProps, const QUrl &destination) |
| 31 | { |
| 32 | QList<QAction *> actionList; |
| 33 | |
| 34 | if (!destination.isLocalFile()) { |
| 35 | return actionList; |
| 36 | } |
| 37 | // need to check write acccess to dest and m_urls |
| 38 | bool allowed = fileItemProps.supportsMoving(); |
| 39 | |
| 40 | if (allowed) { |
| 41 | auto statJob = KIO::stat(url: destination, side: KIO::StatJob::StatSide::SourceSide, details: KIO::StatDetail::StatBasic); |
| 42 | |
| 43 | if (!statJob->exec()) { |
| 44 | qWarning() << "Could not stat destination" << destination; |
| 45 | allowed = false; |
| 46 | } else { |
| 47 | KFileItem item(statJob->statResult(), destination); |
| 48 | |
| 49 | allowed = item.isWritable(); |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | const QString dropIntoNewFolderMessage = i18nc("@action:inmenu Context menu shown when files are dragged" , "Move Into New Folder" ); |
| 54 | |
| 55 | QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("folder-new" )), dropIntoNewFolderMessage, this); |
| 56 | connect(sender: action, signal: &QAction::triggered, context: this, slot: &DropIntoNewFolderPlugin::slotTriggered); |
| 57 | action->setEnabled(allowed); |
| 58 | |
| 59 | actionList.append(t: action); |
| 60 | m_dest = destination; |
| 61 | m_urls = fileItemProps.urlList(); |
| 62 | |
| 63 | return actionList; |
| 64 | } |
| 65 | |
| 66 | void DropIntoNewFolderPlugin::slotTriggered() |
| 67 | { |
| 68 | auto = new KNewFileMenu(this); |
| 69 | menu->setWorkingDirectory(m_dest); |
| 70 | menu->setWindowTitle(i18nc("@title:window" , "Create New Folder for These Items" )); |
| 71 | |
| 72 | connect(sender: menu, signal: &KNewFileMenu::directoryCreated, context: this, slot: [this](const QUrl &newFolder) { |
| 73 | auto job = KIO::move(src: m_urls, dest: newFolder); |
| 74 | KIO::FileUndoManager::self()->recordCopyJob(copyJob: job); |
| 75 | connect(sender: job, signal: &KJob::result, context: this, slot: [newFolder, this](KJob *job) { |
| 76 | if (job->error() != KJob::NoError) { |
| 77 | return; |
| 78 | } |
| 79 | auto openFileManagerJob = new KIO::OpenFileManagerWindowJob{this}; |
| 80 | openFileManagerJob->setHighlightUrls({newFolder}); |
| 81 | openFileManagerJob->start(); |
| 82 | }); |
| 83 | job->start(); |
| 84 | }); |
| 85 | |
| 86 | menu->createDirectory(); |
| 87 | } |
| 88 | |
| 89 | #include "dropintonewfolderPlugin.moc" |
| 90 | #include "moc_dropintonewfolderPlugin.cpp" |
| 91 | |