Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support Ctrl+Y recovery undo (Ctrl+Z) operation to prevent files from being deleted #1992

Merged
merged 1 commit into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,16 @@
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>
<method name="SaveRedoOperations">
<arg name="values" type="a{sv}" direction="in"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
</method>
<method name="RevocationRedoOperations">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>
<method name="CleanOperationsByUrl">
<arg name="urls" type="as" direction="in"/>
</method>
</interface>
</node>
3 changes: 3 additions & 0 deletions include/dfm-base/dfm_event_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ enum GlobalEventType {
kLoadPlugins,
kHeadlessStarted,
kShowSettingDialog,
kSaveRedoOperator, // save Ctrl+Z operator
kCleanSaveOperatorByUrls, // if file delete,clear all ops which contains url
kRedo, // Ctrl+Y

// request file operations
kOpenFiles = 200,
Expand Down
2 changes: 2 additions & 0 deletions include/dfm-base/interfaces/abstractjobhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class AbstractJobHandler : public QObject
kDontFormatFileName = 0x100, // 拷贝时不处理文件名称
kRevocation = 0x200, // 拷贝时不处理文件名称
kCopyRemote = 0x400, // 深信服远程拷贝
kRedo = 0x800, // 重新执行(ctrl + Y)
kCountProgressCustomize = 0x800, // 强制使用自己统计进度
};
Q_ENUM(JobFlag)
Expand Down Expand Up @@ -244,6 +245,7 @@ class AbstractJobHandler : public QObject
void requestShowTipsDialog(DFMBASE_NAMESPACE::AbstractJobHandler::ShowDialogType type, const QList<QUrl> list);
void workerFinish();
void requestRemoveTaskWidget();
void requestSaveRedoOperation(const QString &token, const bool moreThanZero);
Q_SIGNALS: // 发送给任务使用的信号
/*!
* \brief userAction 用户当前动作
Expand Down
5 changes: 4 additions & 1 deletion src/dfm-base/shortcut/shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ Shortcut::Shortcut(QObject *parent)
<< ShortcutItem(tr("Cut"), "Ctrl + X ")
<< ShortcutItem(tr("Paste"), "Ctrl + V ")
<< ShortcutItem(tr("Rename"), "F2 ")
<< ShortcutItem(tr("Open in terminal"), "Shift + T ");
<< ShortcutItem(tr("Open in terminal"), "Shift + T ")
<< ShortcutItem(tr("Undo"), "Ctrl + Z ")
<< ShortcutItem(tr("Redo"), "Ctrl + Y ");

group2.groupName = tr("New/Search");
group2.groupItems << ShortcutItem(tr("New window"), "Ctrl + N ")
<< ShortcutItem(tr("New folder"), "Ctrl + Shift + N ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ void FileOperations::initEventHandle()
DFMBASE_NAMESPACE::AbstractJobHandler::OperatorHandleCallback)>(&TrashFileEventReceiver::handleOperationRestoreFromTrash));
dpfSignalDispatcher->subscribe(GlobalEventType::kCopyFromTrash,
TrashFileEventReceiver::instance(),
static_cast<void (TrashFileEventReceiver::*)(const quint64, const QList<QUrl>, const QUrl,
static_cast<void (TrashFileEventReceiver::*)(const quint64, const QList<QUrl>&, const QUrl&,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags,
DFMBASE_NAMESPACE::AbstractJobHandler::OperatorHandleCallback)>(&TrashFileEventReceiver::handleOperationCopyFromTrash));
dpfSignalDispatcher->subscribe(GlobalEventType::kCopyFromTrash,
TrashFileEventReceiver::instance(),
static_cast<void (TrashFileEventReceiver::*)(const quint64, const QList<QUrl>, const QUrl,
static_cast<void (TrashFileEventReceiver::*)(const quint64, const QList<QUrl>&, const QUrl&,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags,
DFMBASE_NAMESPACE::AbstractJobHandler::OperatorHandleCallback, const QVariant,
AbstractJobHandler::OperatorCallback)>(&TrashFileEventReceiver::handleOperationCopyFromTrash));
Expand Down Expand Up @@ -282,6 +282,15 @@ void FileOperations::initEventHandle()
const QList<QUrl>,
const QVariant,
AbstractJobHandler::OperatorCallback)>(&FileOperationsEventReceiver::handleOperationHideFiles));
dpfSignalDispatcher->subscribe(GlobalEventType::kSaveRedoOperator,
FileOperationsEventReceiver::instance(),
&FileOperationsEventReceiver::handleOperationSaveRedoOperations);
dpfSignalDispatcher->subscribe(GlobalEventType::kCleanSaveOperatorByUrls,
FileOperationsEventReceiver::instance(),
&FileOperationsEventReceiver::handleOperationCleanByUrls);
dpfSignalDispatcher->subscribe(GlobalEventType::kRedo,
FileOperationsEventReceiver::instance(),
&FileOperationsEventReceiver::handleRecoveryOperationRedoRecovery);
}

void FileOperations::followEvents()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,18 @@ bool DoDeleteFilesWorker::deleteAllFiles()
*/
bool DoDeleteFilesWorker::deleteFilesOnCanNotRemoveDevice()
{
if (allFilesList.count() == 1) {
auto info = InfoFactory::create<FileInfo>(allFilesList.first(), Global::CreateFileInfoType::kCreateFileInfoSync);
if (info && info->isAttributes(OptInfoType::kIsFile) && info->size() > 0)
moreThanZero = true;
}

AbstractJobHandler::SupportAction action { AbstractJobHandler::SupportAction::kNoAction };
for (QList<QUrl>::iterator it = --allFilesList.end(); it != --allFilesList.begin(); --it) {
if (!stateCheck())
return false;
const QUrl &url = *it;
auto info = InfoFactory::create<FileInfo>(url, Global::CreateFileInfoType::kCreateFileInfoSync);
emitCurrentTaskNotify(url, QUrl());
do {
action = AbstractJobHandler::SupportAction::kNoAction;
Expand All @@ -78,8 +85,10 @@ bool DoDeleteFilesWorker::deleteFilesOnCanNotRemoveDevice()
} while (!isStopped() && action == AbstractJobHandler::SupportAction::kRetryAction);

if (sourceUrls.contains(url)) {
if (action == AbstractJobHandler::SupportAction::kNoAction)
if (action == AbstractJobHandler::SupportAction::kNoAction) {
completeSourceFiles.append(url);
completeTargetFiles.append(url);
}
}

deleteFilesCount++;
Expand All @@ -99,6 +108,11 @@ bool DoDeleteFilesWorker::deleteFilesOnCanNotRemoveDevice()
bool DoDeleteFilesWorker::deleteFilesOnOtherDevice()
{
bool ok = true;
if (sourceUrls.count() == 1) {
auto info = InfoFactory::create<FileInfo>(sourceUrls.first(), Global::CreateFileInfoType::kCreateFileInfoSync);
if (info && info->isAttributes(OptInfoType::kIsFile) && info->size() > 0)
moreThanZero = true;
}
for (auto &url : sourceUrls) {
const auto &info = InfoFactory::create<FileInfo>(url, Global::CreateFileInfoType::kCreateFileInfoSync);
if (!info) {
Expand All @@ -116,7 +130,7 @@ bool DoDeleteFilesWorker::deleteFilesOnOtherDevice()

if (!ok)
return false;

completeTargetFiles.append(url);
completeSourceFiles.append(url);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,16 @@ JobHandlePointer FileCopyMoveJob::copyFromTrash(const QList<QUrl> &sources, cons
* \return JobHandlePointer 任务控制器
*/
JobHandlePointer FileCopyMoveJob::moveToTrash(const QList<QUrl> &sources,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags)
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags, const bool isInit)
{
if (!getOperationsAndDialogService()) {
fmCritical() << "get service fialed !!!!!!!!!!!!!!!!!!!";
return nullptr;
}

JobHandlePointer jobHandle = operationsService->moveToTrash(sources, flags);
initArguments(jobHandle);
if (isInit)
initArguments(jobHandle);

return jobHandle;
}
Expand All @@ -148,15 +149,16 @@ JobHandlePointer FileCopyMoveJob::moveToTrash(const QList<QUrl> &sources,
* \return JobHandlePointer 任务控制器
*/
JobHandlePointer FileCopyMoveJob::restoreFromTrash(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags)
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags, const bool isInit)
{
if (!getOperationsAndDialogService()) {
fmCritical() << "get service fialed !!!!!!!!!!!!!!!!!!!";
return nullptr;
}

JobHandlePointer jobHandle = operationsService->restoreFromTrash(sources, target, flags);
initArguments(jobHandle);
if (isInit)
initArguments(jobHandle);

return jobHandle;
}
Expand All @@ -167,15 +169,17 @@ JobHandlePointer FileCopyMoveJob::restoreFromTrash(const QList<QUrl> &sources, c
* \return JobHandlePointer 任务控制器
*/
JobHandlePointer FileCopyMoveJob::deletes(const QList<QUrl> &sources,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags)
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags, const bool isInit)
{
if (!getOperationsAndDialogService()) {
fmCritical() << "get service fialed !!!!!!!!!!!!!!!!!!!";
return nullptr;
}

JobHandlePointer jobHandle = operationsService->deletes(sources, flags);
initArguments(jobHandle);

if (isInit)
initArguments(jobHandle);

return jobHandle;
}
Expand All @@ -188,15 +192,17 @@ JobHandlePointer FileCopyMoveJob::deletes(const QList<QUrl> &sources,
* \return JobHandlePointer 任务控制器
*/
JobHandlePointer FileCopyMoveJob::cut(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags)
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags,
const bool isInit)
{
if (!getOperationsAndDialogService()) {
fmCritical() << "get service fialed !!!!!!!!!!!!!!!!!!!";
return nullptr;
}

JobHandlePointer jobHandle = operationsService->cut(sources, target, flags);
initArguments(jobHandle);
if (isInit)
initArguments(jobHandle);

return jobHandle;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,26 @@ class FileCopyMoveJob : public QObject
JobHandlePointer copyFromTrash(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
JobHandlePointer moveToTrash(const QList<QUrl> &sources,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags
= DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint,
const bool isInit = true);
JobHandlePointer restoreFromTrash(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint,
const bool isInit = true);
JobHandlePointer deletes(const QList<QUrl> &sources,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags
&flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint,
const bool isInit = true);
JobHandlePointer cut(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags
= DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint,
const bool isInit = true);
JobHandlePointer cleanTrash(const QList<QUrl> &sources);
void initArguments(const JobHandlePointer handler);

private:
bool getOperationsAndDialogService();
void initArguments(const JobHandlePointer handler);

private slots:
void onHandleAddTask();
void onHandleAddTaskWithArgs(const JobInfoPointer info);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "dfmplugin_fileoperations_global.h"
#include <dfm-base/interfaces/abstractjobhandler.h>
#include <dfm-base/dfm_event_defines.h>

#include <dfm-framework/dpf.h>

Expand All @@ -31,7 +32,8 @@ class FileOperationsService : public QObject
JobHandlePointer restoreFromTrash(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
JobHandlePointer deletes(const QList<QUrl> &sources,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags
&flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
JobHandlePointer cut(const QList<QUrl> &sources, const QUrl &target,
const DFMBASE_NAMESPACE::AbstractJobHandler::JobFlags &flags = DFMBASE_NAMESPACE::AbstractJobHandler::JobFlag::kNoHint);
JobHandlePointer cleanTrash(const QList<QUrl> &sources);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void AbstractJob::setJobArgs(const JobHandlePointer handle, const QList<QUrl> &s
connect(doWorker.data(), &AbstractWorker::errorNotify, this, &AbstractJob::handleError, Qt::QueuedConnection);
connect(this, &AbstractJob::errorNotify, handle.get(), &AbstractJobHandler::onError);
connect(doWorker.data(), &AbstractWorker::workerFinish, handle.get(), &AbstractJobHandler::workerFinish, Qt::QueuedConnection);
connect(doWorker.data(), &AbstractWorker::requestSaveRedoOperation, handle.get(), &AbstractJobHandler::requestSaveRedoOperation, Qt::QueuedConnection);
doWorker->setWorkArgs(handle, sources, target, flags);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define ABSTRACTJOB_H

#include "dfmplugin_fileoperations_global.h"
#include <dfm-base/dfm_event_defines.h>
#include <dfm-base/interfaces/abstractjobhandler.h>

#include <QObject>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,38 +542,51 @@ void AbstractWorker::saveOperations()
|| jobType == AbstractJobHandler::JobType::kCutType
|| jobType == AbstractJobHandler::JobType::kMoveToTrashType
|| jobType == AbstractJobHandler::JobType::kRestoreType) {
GlobalEventType operatorType = GlobalEventType::kDeleteFiles;
QList<QUrl> targetUrls;
GlobalEventType operatorType = GlobalEventType::kDeleteFiles, redoType = GlobalEventType::kUnknowType;
QList<QUrl> targetUrls, redoSources, redoTargets;
redoSources = completeSourceFiles;
redoTargets.append(targetUrl);
switch (jobType) {
case AbstractJobHandler::JobType::kCopyType:
operatorType = GlobalEventType::kDeleteFiles;
targetUrls.append(UrlRoute::urlParent(completeSourceFiles.first()));
redoType = GlobalEventType::kCopy;
break;
case AbstractJobHandler::JobType::kCutType:
operatorType = GlobalEventType::kCutFile;
if (!sourceUrls.isEmpty() && FileUtils::isTrashFile(sourceUrls.first()))
if (!sourceUrls.isEmpty() && FileUtils::isTrashFile(sourceUrls.first())) {
operatorType = GlobalEventType::kMoveToTrash;
for (auto url : completeSourceFiles)
targetUrls.append(UrlRoute::urlParent(url));
} else {
targetUrls.append(UrlRoute::urlParent(completeSourceFiles.first()));
}
redoType = GlobalEventType::kCutFile;
break;
case AbstractJobHandler::JobType::kMoveToTrashType:
operatorType = GlobalEventType::kRestoreFromTrash;
redoType = GlobalEventType::kMoveToTrash;
break;
case AbstractJobHandler::JobType::kRestoreType:
operatorType = GlobalEventType::kMoveToTrash;
redoType = GlobalEventType::kRestoreFromTrash;
break;
default:
operatorType = GlobalEventType::kDeleteFiles;
operatorType = GlobalEventType::kUnknowType;
break;
}
QVariantMap values;
values.insert("event", QVariant::fromValue(static_cast<uint16_t>(operatorType)));
values.insert("sources", QUrl::toStringList(completeTargetFiles));
values.insert("targets", QUrl::toStringList(targetUrls));
if (jobType != AbstractJobHandler::JobType::kDeleteType)
dpfSignalDispatcher->publish(GlobalEventType::kSaveOperator, values);
values.insert("undoevent", QVariant::fromValue(static_cast<uint16_t>(operatorType)));
values.insert("undosources", QUrl::toStringList(completeTargetFiles));
values.insert("undotargets", QUrl::toStringList(targetUrls));
values.insert("redoevent", QVariant::fromValue(static_cast<uint16_t>(redoType)));
values.insert("redosources", QUrl::toStringList(completeSourceFiles));
values.insert("redotargets", QUrl::toStringList(redoTargets));
dpfSignalDispatcher->publish(GlobalEventType::kSaveOperator, values);
}
}

if (handle && isConvert && !completeSourceFiles.isEmpty()) {
emit requestSaveRedoOperation(QString::number(quintptr(handle.data()),16), moreThanZero);
}
}

AbstractWorker::~AbstractWorker()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ class AbstractWorker : public QObject

void removeTaskWidget();

void requestShowTipsDialog(DFMBASE_NAMESPACE::AbstractJobHandler::ShowDialogType type, const QList<QUrl> list);
void requestShowTipsDialog(DFMBASE_NAMESPACE::AbstractJobHandler::ShowDialogType type, const QList<QUrl> &list);
void workerFinish();
void requestSaveRedoOperation(const QString &token, const bool moreThanZero);
signals: // update proccess timer use
void startUpdateProgressTimer();
void startWork();
Expand Down Expand Up @@ -184,6 +185,7 @@ protected slots:
QSharedPointer<QThreadPool> threadPool { nullptr };
static std::atomic_bool bigFileCopy;
QAtomicInteger<qint64> bigFileSize { 0 }; // bigger than this is big file
std::atomic_bool moreThanZero{ false };
};
DPFILEOPERATIONS_END_NAMESPACE

Expand Down
Loading
Loading