Skip to content

Commit

Permalink
feat: Support Ctrl+Y recovery undo (Ctrl+Z) operation to prevent file…
Browse files Browse the repository at this point in the history
…s from being deleted

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

Log: Support Ctrl+Y recovery undo (Ctrl+Z) operation to prevent files from being deleted
Task: https://pms.uniontech.com/task-view-341623.html
  • Loading branch information
liyigang1 committed May 27, 2024
1 parent 0033285 commit 6cbd5a4
Show file tree
Hide file tree
Showing 36 changed files with 843 additions and 255 deletions.
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 @@ -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 @@ -88,6 +88,7 @@ class AbstractWorker : public QObject

void requestShowTipsDialog(DFMBASE_NAMESPACE::AbstractJobHandler::ShowDialogType type, const QList<QUrl> list);

Check warning on line 89 in src/plugins/common/core/dfmplugin-fileoperations/fileoperations/fileoperationutils/abstractworker.h

View workflow job for this annotation

GitHub Actions / cppcheck

Parameter 'list' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.
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

0 comments on commit 6cbd5a4

Please sign in to comment.