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 | |