diff --git a/krusader/Dialogs/krdialogs.h b/krusader/Dialogs/krdialogs.h --- a/krusader/Dialogs/krdialogs.h +++ b/krusader/Dialogs/krdialogs.h @@ -56,7 +56,8 @@ public: struct ChooseResult { QUrl url; - bool queue; + bool reverseQueueMode; + bool startPaused; bool preserveAttrs; // NOTE: field never read QUrl baseURL; // NOTE: field never read }; @@ -86,24 +87,31 @@ QUrl selectedURL() const; QUrl baseURL() const; bool preserveAttrs(); - bool enqueue() { return queueBox->isChecked(); } + bool isReverseQueueMode() { return reverseQueueMode; }; + bool isStartPaused() { return pauseBox->isChecked(); }; bool copyDirStructure(); void hidePreserveAttrs() { // preserveAttrsCB->hide(); } KUrlRequester *urlRequester(); +protected: + virtual void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; + + private slots: + void slotReverseQueueMode(); void slotTextChanged(const QString &); void slotDirStructCBChanged(); private: KUrlRequester *urlRequester_; QComboBox *baseUrlCombo; // QCheckBox *preserveAttrsCB; QCheckBox *copyDirStructureCB; - QCheckBox *queueBox; + QCheckBox *pauseBox; QPushButton *okButton; + bool reverseQueueMode = false; }; class KRGetDate : public QDialog diff --git a/krusader/Dialogs/krdialogs.cpp b/krusader/Dialogs/krdialogs.cpp --- a/krusader/Dialogs/krdialogs.cpp +++ b/krusader/Dialogs/krdialogs.cpp @@ -42,6 +42,7 @@ #include "../krglobal.h" #include "../VFS/vfs.h" #include "../defaults.h" +#include "../JobMan/jobman.h" QUrl KChooseDir::getFile(const QString &text, const QUrl& url, const QUrl& cwd) @@ -91,7 +92,8 @@ ChooseResult result; result.url = u; - result.queue = dlg->enqueue(); + result.reverseQueueMode = dlg->isReverseQueueMode(); + result.startPaused = dlg->isStartPaused(); result.preserveAttrs = dlg->preserveAttrs(); result.baseURL = dlg->copyDirStructure() ? dlg->baseURL() : QUrl(); return result; @@ -150,18 +152,40 @@ okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); - queueBox = new QCheckBox(i18n("Start &Paused"), this); - buttonBox->addButton(queueBox, QDialogButtonBox::ActionRole); + pauseBox = new QCheckBox(i18n("Start &Paused"), this); + buttonBox->addButton(pauseBox, QDialogButtonBox::ActionRole); + QPushButton *reverseQueueModeButton = new QPushButton(krJobMan->isQueueModeEnabled() ? i18n("F2 Run Immediately") : i18n("F2 Queue"), this); + reverseQueueModeButton->setToolTip(krJobMan->isQueueModeEnabled() ? i18n("Immediately start job even if there are running jobs in queue.") : i18n("Enqueue the job if queue is not empty. Otherwise start the job immediately.")); + buttonBox->addButton(reverseQueueModeButton, QDialogButtonBox::ActionRole); connect(buttonBox, SIGNAL(accepted()), SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(reverseQueueModeButton, SIGNAL(clicked()), SLOT(slotReverseQueueMode())); connect(urlRequester_, SIGNAL(textChanged(QString)), SLOT(slotTextChanged(QString))); urlRequester_->setFocus(); bool state = !urlName.isEmpty(); okButton->setEnabled(state); } +void KUrlRequesterDlgForCopy::keyPressEvent(QKeyEvent *e) +{ + switch (e->key()) { + case Qt::Key_F2: + slotReverseQueueMode(); + return; + default: + QDialog::keyPressEvent(e); + } +} + +void KUrlRequesterDlgForCopy::slotReverseQueueMode() +{ + reverseQueueMode = true; + accept(); +} + + bool KUrlRequesterDlgForCopy::preserveAttrs() { // return preserveAttrsCB->isChecked(); diff --git a/krusader/JobMan/jobman.h b/krusader/JobMan/jobman.h --- a/krusader/JobMan/jobman.h +++ b/krusader/JobMan/jobman.h @@ -78,11 +78,20 @@ */ bool waitForJobs(bool waitForUserInput); + /* Curent info about _queueMode state */ + bool isQueueModeEnabled() { return _queueMode; }; + public slots: /** Display, monitor and give user ability to control a job. - * If enqueued the job is not started. Otherwise this depends on the job manager mode. + * + * If reverseQueueMode is false, job is queued or run in parallel accordingly + * to job manager mode. When reverseQueueMode is true, opposite manager mode is chosen. + * + * When startPaused is true, job is never started immediately. Instead, it is waiting + * to be manually unpaused. Or in case of enabled queueMode it is started automatically + * when other jobs are finished. */ - void manageJob(KrJob *krJob, bool enqueue = false); + void manageJob(KrJob *krJob, bool reverseQueueMode = false, bool startPaused = false); protected slots: void slotKJobStarted(KJob *krJob); diff --git a/krusader/JobMan/jobman.cpp b/krusader/JobMan/jobman.cpp --- a/krusader/JobMan/jobman.cpp +++ b/krusader/JobMan/jobman.cpp @@ -251,7 +251,7 @@ return false; } -void JobMan::manageJob(KrJob *job, bool enqueue) +void JobMan::manageJob(KrJob *job, bool reverseQueueMode, bool startPaused) { JobMenuAction *menuAction = new JobMenuAction(job, _controlAction); @@ -262,7 +262,9 @@ connect(job, &KrJob::started, this, &JobMan::slotKJobStarted); connect(job, &KrJob::terminated, this, &JobMan::slotTerminated); - if (!enqueue && !(_queueMode && jobsAreRunning())) { + bool isQueueMode = _queueMode != reverseQueueMode; + + if (!startPaused && (!jobsAreRunning() || !isQueueMode)) { job->start(); } diff --git a/krusader/JobMan/krjob.h b/krusader/JobMan/krjob.h --- a/krusader/JobMan/krjob.h +++ b/krusader/JobMan/krjob.h @@ -41,7 +41,7 @@ /** Create a new copy, move, or link job. */ static KrJob *createCopyJob(KIO::CopyJob::CopyMode mode, const QList &src, - const QUrl &destination, KIO::JobFlags flags); + const QUrl &destination, KIO::JobFlags flags, bool startManually); /** Create a new trash or delete job. */ static KrJob *createDeleteJob(const QList &urls, bool moveToTrash); @@ -55,7 +55,7 @@ /** Return true if job was started and is not suspended(). */ bool isRunning() const { return _job && !_job->isSuspended(); } /** Return true if job was started and then paused by user. */ - bool isManuallyPaused() const { return _job && _job->isSuspended(); } + bool isManuallyPaused() const { return _initiallyPaused || (_job && _job->isSuspended()); } /** Return percent progress of job. */ int percent() const { return _job ? _job->percent() : 0; } @@ -72,13 +72,14 @@ private: KrJob(Type type, const QList &urls, const QUrl &dest, KIO::JobFlags flags, - const QString &description); + const QString &description, bool startManually = false); const Type _type; const QList _urls; const QUrl _dest; const KIO::JobFlags _flags; const QString _description; + bool _initiallyPaused; KIO::Job *_job; }; diff --git a/krusader/JobMan/krjob.cpp b/krusader/JobMan/krjob.cpp --- a/krusader/JobMan/krjob.cpp +++ b/krusader/JobMan/krjob.cpp @@ -23,7 +23,7 @@ #include KrJob *KrJob::createCopyJob(KIO::CopyJob::CopyMode mode, const QList &src, - const QUrl &destination, KIO::JobFlags flags) + const QUrl &destination, KIO::JobFlags flags, bool startManually) { Type type; QString description; @@ -42,7 +42,7 @@ break; } - return new KrJob(type, src, destination, flags, description); + return new KrJob(type, src, destination, flags, description, startManually); } KrJob *KrJob::createDeleteJob(const QList &urls, bool moveToTrash) @@ -59,8 +59,8 @@ } KrJob::KrJob(Type type, const QList &urls, const QUrl &dest, KIO::JobFlags flags, - const QString &description) - : _type(type), _urls(urls), _dest(dest), _flags(flags), _description(description), _job(0) + const QString &description, bool startManually) + : _type(type), _urls(urls), _dest(dest), _flags(flags), _description(description), _initiallyPaused(startManually), _job(0) { } @@ -72,6 +72,8 @@ return; } + _initiallyPaused = false; + switch (_type) { case Copy: { KIO::CopyJob *job = KIO::copy(_urls, _dest, _flags); diff --git a/krusader/Panel/panelfunc.h b/krusader/Panel/panelfunc.h --- a/krusader/Panel/panelfunc.h +++ b/krusader/Panel/panelfunc.h @@ -76,10 +76,10 @@ void viewDlg(); void edit(); void editNew(); // create a new textfile and edit it - void moveFilesByQueue() { moveFiles(true); } - void copyFilesByQueue() { copyFiles(true); } - void moveFiles(bool enqueue = false) { copyFiles(enqueue, true); } - void copyFiles(bool enqueue = false, bool move = false); + void moveFilesByQueue(); // start in queue regardless of _queueMode state + void copyFilesByQueue(); // start in queue regardless of _queueMode state + void moveFiles(bool reverseQueueMode = false) { copyFiles(reverseQueueMode, true); } + void copyFiles(bool reverseQueueMode = false, bool move = false); /*! * asks the user the new directory name diff --git a/krusader/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp --- a/krusader/Panel/panelfunc.cpp +++ b/krusader/Panel/panelfunc.cpp @@ -87,6 +87,7 @@ #include "../KViewer/krviewer.h" #include "../GUI/syncbrowsebutton.h" #include "../MountMan/kmountman.h" +#include "../JobMan/jobman.h" QPointer ListPanelFunc::copyToClipboardOrigin; @@ -572,14 +573,25 @@ fileToCreate = QUrl(); } -void ListPanelFunc::copyFiles(bool enqueue, bool move) +void ListPanelFunc::moveFilesByQueue() +{ + moveFiles(!krJobMan->isQueueModeEnabled()); +} + +void ListPanelFunc::copyFilesByQueue() +{ + copyFiles(!krJobMan->isQueueModeEnabled()); +} + +void ListPanelFunc::copyFiles(bool reverseQueueMode, bool move) { QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety QUrl destination = panel->otherPanel()->virtualPath(); + bool startPaused = false; KConfigGroup group(krConfig, "Advanced"); @@ -603,7 +615,8 @@ if (destination.isEmpty()) return ; // the user canceled - enqueue = result.queue; + reverseQueueMode = result.reverseQueueMode; + startPaused = result.startPaused; } const QList fileUrls = files()->getUrls(fileNames); @@ -619,7 +632,7 @@ } KIO::CopyJob::CopyMode mode = move ? KIO::CopyJob::Move : KIO::CopyJob::Copy; - KrVfsHandler::instance().startCopyFiles(fileUrls, destination, mode, true, enqueue); + KrVfsHandler::instance().startCopyFiles(fileUrls, destination, mode, true, reverseQueueMode, startPaused); if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { panel->view->saveSelection(); diff --git a/krusader/VFS/default_vfs.h b/krusader/VFS/default_vfs.h --- a/krusader/VFS/default_vfs.h +++ b/krusader/VFS/default_vfs.h @@ -59,7 +59,7 @@ virtual void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, - bool showProgressInfo = true, bool enqueue = false) Q_DECL_OVERRIDE; + bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) Q_DECL_OVERRIDE; virtual void dropFiles(const QUrl &destination, QDropEvent *event) Q_DECL_OVERRIDE; virtual void addFiles(const QList &fileUrls, KIO::CopyJob::CopyMode mode, diff --git a/krusader/VFS/default_vfs.cpp b/krusader/VFS/default_vfs.cpp --- a/krusader/VFS/default_vfs.cpp +++ b/krusader/VFS/default_vfs.cpp @@ -56,20 +56,22 @@ } void default_vfs::copyFiles(const QList &urls, const QUrl &destination, - KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool enqueue) + KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool reverseQueueMode, bool startPaused) { // resolve relative path before resolving symlinks const QUrl dest = resolveRelativePath(destination); KIO::JobFlags flags = showProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo; - KrJob *krJob = KrJob::createCopyJob(mode, urls, destination, flags); + // allow job to be started only manually when startPaused=true AND queueMode=false + bool queueMode = krJobMan->isQueueModeEnabled() != reverseQueueMode; + KrJob *krJob = KrJob::createCopyJob(mode, urls, destination, flags, startPaused && !queueMode); connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectJob(job, dest); }); if (mode == KIO::CopyJob::Move) { // notify source about removed files connect(krJob, &KrJob::started, [=](KIO::Job *job) { connectSourceVFS(job, urls); }); } - krJobMan->manageJob(krJob, enqueue); + krJobMan->manageJob(krJob, reverseQueueMode, startPaused); } void default_vfs::dropFiles(const QUrl &destination, QDropEvent *event) diff --git a/krusader/VFS/krvfshandler.h b/krusader/VFS/krvfshandler.h --- a/krusader/VFS/krvfshandler.h +++ b/krusader/VFS/krvfshandler.h @@ -52,7 +52,7 @@ */ void startCopyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, - bool showProgressInfo = true, bool enqueue = false); + bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false); static KrVfsHandler &instance(); static vfs::VFS_TYPE getVfsType(const QUrl &url); diff --git a/krusader/VFS/krvfshandler.cpp b/krusader/VFS/krvfshandler.cpp --- a/krusader/VFS/krvfshandler.cpp +++ b/krusader/VFS/krvfshandler.cpp @@ -49,10 +49,10 @@ } void KrVfsHandler::startCopyFiles(const QList &urls, const QUrl &destination, - KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool enqueue) + KIO::CopyJob::CopyMode mode, bool showProgressInfo, bool reverseQueueMode, bool startPaused) { vfs *vfs = getVfs(destination); // implementation depends on filesystem of destination - vfs->copyFiles(urls, destination, mode, showProgressInfo, enqueue); + vfs->copyFiles(urls, destination, mode, showProgressInfo, reverseQueueMode, startPaused); } void KrVfsHandler::refreshVfs(const QUrl &directory) diff --git a/krusader/VFS/vfs.h b/krusader/VFS/vfs.h --- a/krusader/VFS/vfs.h +++ b/krusader/VFS/vfs.h @@ -87,7 +87,7 @@ /// Destination is absolute URL. May implemented async. virtual void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, - bool showProgressInfo = true, bool enqueue = false) = 0; + bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) = 0; /// Handle file dropping in this VFS. Destination is absolute URL. May implemented async. virtual void dropFiles(const QUrl &destination, QDropEvent *event) = 0; diff --git a/krusader/VFS/virt_vfs.h b/krusader/VFS/virt_vfs.h --- a/krusader/VFS/virt_vfs.h +++ b/krusader/VFS/virt_vfs.h @@ -48,7 +48,7 @@ /// Create virtual files in this VFS. Copy mode and showProgressInfo are ignored. void copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode mode = KIO::CopyJob::Copy, - bool showProgressInfo = true, bool enqueue = false) Q_DECL_OVERRIDE; + bool showProgressInfo = true, bool reverseQueueMode = false, bool startPaused = false) Q_DECL_OVERRIDE; /// Handle file dropping in this VFS: Always creates virtual files. void dropFiles(const QUrl &destination, QDropEvent *event) Q_DECL_OVERRIDE; diff --git a/krusader/VFS/virt_vfs.cpp b/krusader/VFS/virt_vfs.cpp --- a/krusader/VFS/virt_vfs.cpp +++ b/krusader/VFS/virt_vfs.cpp @@ -56,7 +56,7 @@ void virt_vfs::copyFiles(const QList &urls, const QUrl &destination, KIO::CopyJob::CopyMode /*mode*/, bool /*showProgressInfo*/, - bool /*enqueue*/) + bool /*reverseQueueMode*/, bool /*startPaused*/) { const QString dir = QDir(destination.path()).absolutePath().remove('/');