1 // case - file manager for N900
2 // Copyright (C) 2010 Lukas Hrazky <lukkash@email.cz>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "fileoperator.h"
22 #include <QMessageBox>
23 #include <QHBoxLayout>
33 #define BLOCK_SIZE 524288
38 emit operationPaused(this); \
43 #define SHOW_ERROR_PROMPT(promptString, fileName) \
44 response = FileOperator::NONE; \
45 if (ignoreAll[errno]) { \
46 response = FileOperator::IGNORE; \
49 char *realBuf = buf; \
51 strcpy(buf, tr("File is sequential").toStdString().c_str()); \
53 realBuf = strerror_r(errno, buf, 255); \
55 emit showErrorPrompt(this, promptString + " " + realBuf + ".", fileName, errno); \
60 #define ERROR_PROMPT(operation, promptString, fileName) \
62 response = FileOperator::NONE; \
63 while (!abort && operation) { \
64 SHOW_ERROR_PROMPT(promptString, fileName) \
65 if (response == FileOperator::IGNORE) { \
73 #define SPECIAL_COPY_ERROR_PROMPT(operation, promptString, fileName) \
75 ERROR_PROMPT(operation, promptString, fileName) \
76 if (abort || response == FileOperator::IGNORE) { \
78 updateProgress(fileSizeMap[path]); \
79 removeExcludeFiles.insert(path); \
86 #define OVERWRITE_PROMPT(file, newFile) \
88 response = FileOperator::NONE; \
90 while (!abort && response == FileOperator::NONE && newFile.exists()) { \
91 if (overwriteAll != FileOperator::NONE) { \
92 response = overwriteAll; \
94 emit showOverwritePrompt(this, newFile.absoluteFilePath(), \
95 newFile.isDir() && file.isDir()); \
99 else if (response == FileOperator::NONE) { \
100 emit showInputFilenamePrompt(this, newFile, file.isDir()); \
102 if (newNameFromDialog.size()) { \
103 newFile.setFile(newNameFromDialog); \
108 if (response == FileOperator::ASK) response = FileOperator::NONE; \
112 FileOperator::FileOperator(QWidget *parent) : QWidget(parent) {
113 QHBoxLayout *layout = new QHBoxLayout;
114 layout->setContentsMargins(0, 0, 0, 0);
115 layout->setSpacing(0);
117 qRegisterMetaType<QFileInfo>("QFileInfo");
121 QString FileOperator::shortenPath(const QString &path) {
122 QString homePath = QFSFileEngine::homePath();
124 if (path.indexOf(homePath, 0) == 0) {
125 QString result = path;
127 result.replace(0, homePath.size(), "~");
135 QString FileOperator::unwindPath(const QString &path) {
136 QString result = path;
137 // if ~ is the first character and / or nothing follows it, replace with home dir
138 if (path == "~" || path.indexOf("~/", 0) == 0) {
139 QString homePath = QFSFileEngine::homePath();
140 result.replace(0, 1, homePath);
141 // in case someone wants to enter a dir called ~ in the current dir, he can escape it with \~
142 } else if (path == "\\~" || path.indexOf("\\~/", 0) == 0) {
143 result.replace(0, 2, "~");
150 void FileOperator::deleteFiles(const QFileInfoList &files) {
152 if (files.size() == 1) {
153 title = tr("Delete file");
154 desc = tr("Are you sure you want to delete %1?")
155 .arg(FileOperator::shortenPath(files[0].absoluteFilePath()));
157 title = tr("Delete files");
158 desc = tr("You are about to delete %1 files. Are you sure you want to continue?").arg(files.size());
161 int confirm = QMessageBox::warning(
169 if(confirm == QMessageBox::Yes) {
170 caterNewThread(new DeleteThread(files));
175 void FileOperator::copyFiles(const QFileInfoList &files, QDir &destination) {
177 if (files.size() == 1) {
178 title = tr("Copy file");
179 desc = tr("Are you sure you want to copy %1 to %2?")
180 .arg(FileOperator::shortenPath(files[0].absoluteFilePath()))
181 .arg(FileOperator::shortenPath(destination.absolutePath()));
183 title = tr("Copy files");
184 desc = tr("You are about to copy %1 files to %2. Are you sure you want to continue?")
185 .arg(files.size()).arg(FileOperator::shortenPath(destination.absolutePath()));
188 int confirm = QMessageBox::warning(
196 if(confirm == QMessageBox::Yes) {
197 caterNewThread(new CopyThread(files, destination));
202 void FileOperator::moveFiles(const QFileInfoList &files, QDir &destination) {
203 // for move we don't wanna move to the same dir
204 if (files[0].absolutePath() == destination.absolutePath()) return;
207 if (files.size() == 1) {
208 title = tr("Move file");
209 desc = tr("Are you sure you want to move %1 to %2?")
210 .arg(FileOperator::shortenPath(files[0].absoluteFilePath()))
211 .arg(FileOperator::shortenPath(destination.absolutePath()));
213 title = tr("Move files");
214 desc = tr("You are about to move %1 files to %2. Are you sure you want to continue?")
215 .arg(files.size()).arg(FileOperator::shortenPath(destination.absolutePath()));
218 int confirm = QMessageBox::warning(
226 if(confirm == QMessageBox::Yes) {
227 caterNewThread(new MoveThread(files, destination));
232 void FileOperator::showErrorPrompt(FileManipulatorThread* manipulator,
233 const QString &message,
234 const QString &fileName,
238 QAbstractButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
239 QAbstractButton *abortButton = msgBox.addButton(tr("Abort"), QMessageBox::DestructiveRole);
240 QAbstractButton *retryButton = msgBox.addButton(QMessageBox::Retry);
241 QAbstractButton *ignoreButton = msgBox.addButton(QMessageBox::Ignore);
242 QAbstractButton *ignoreAllButton = msgBox.addButton(tr("Ignore All"), QMessageBox::AcceptRole);
243 msgBox.setText(message.arg(FileOperator::shortenPath(fileName)));
247 if (msgBox.clickedButton() == cancelButton) {
248 manipulator->pause = true;
249 manipulator->setResponse(RETRY);
250 } else if (msgBox.clickedButton() == abortButton) {
251 manipulator->setResponse(ABORT);
252 } else if (msgBox.clickedButton() == retryButton) {
253 manipulator->setResponse(RETRY);
254 } else if (msgBox.clickedButton() == ignoreButton) {
255 manipulator->setResponse(IGNORE);
256 } else if (msgBox.clickedButton() == ignoreAllButton) {
257 manipulator->setResponse(IGNORE, true, err);
262 void FileOperator::showOverwritePrompt(
263 FileManipulatorThread* manipulator,
264 const QString &fileName,
265 const bool dirOverDir)
268 QAbstractButton *yesButton = msgBox.addButtonFirst(QDialogButtonBox::Yes);
269 QAbstractButton *yesToAllButton = msgBox.addButtonFirst(QDialogButtonBox::YesToAll);
270 QAbstractButton *noButton = msgBox.addButtonSecond(QDialogButtonBox::No);
271 QAbstractButton *noToAllButton = msgBox.addButtonSecond(QDialogButtonBox::NoToAll);
272 QAbstractButton *abortButton = msgBox.addButtonSecond(tr("Abort"), QDialogButtonBox::DestructiveRole);
273 QAbstractButton *newNameButton = msgBox.addButtonFirst(tr("New Name"), QDialogButtonBox::AcceptRole);
274 QAbstractButton *askButton = 0;
275 QAbstractButton *skipDirButton = 0;
278 msgBox.setText(tr("Directory %1 already exists. Overwrite the files inside?")
279 .arg(FileOperator::shortenPath(fileName)));
280 askButton = msgBox.addButtonFirst(tr("Ask"), QDialogButtonBox::AcceptRole);
281 skipDirButton = msgBox.addButtonSecond(tr("Skip"), QDialogButtonBox::NoRole);
283 msgBox.setText(tr("File %1 already exists. Overwrite?").arg(FileOperator::shortenPath(fileName)));
288 if (msgBox.clickedButton == 0) {
289 manipulator->pause = true;
290 manipulator->setResponse(NONE);
291 } else if (msgBox.clickedButton == abortButton) {
292 manipulator->setResponse(ABORT);
293 } else if (msgBox.clickedButton == yesButton) {
294 manipulator->setResponse(OVERWRITE);
295 } else if (msgBox.clickedButton == yesToAllButton) {
296 manipulator->setResponse(OVERWRITE, true);
297 } else if (msgBox.clickedButton == noButton) {
298 manipulator->setResponse(KEEP);
299 } else if (msgBox.clickedButton == noToAllButton) {
300 manipulator->setResponse(KEEP, true);
301 } else if (msgBox.clickedButton == askButton) {
302 manipulator->setResponse(ASK);
303 } else if (msgBox.clickedButton == newNameButton) {
304 manipulator->setResponse(NONE);
305 } else if (msgBox.clickedButton == skipDirButton) {
306 manipulator->setResponse(SKIP_DIR);
311 void FileOperator::showInputFilenamePrompt(FileManipulatorThread* manipulator,
312 const QFileInfo &file,
316 QString prompt, error;
319 prompt = tr("Enter the new directory name.");
321 prompt = tr("Enter the new file name.");
324 manipulator->mutex.lock();
326 manipulator->newNameFromDialog = "";
327 QString text = file.fileName();
330 text = QInputDialog::getText(this, QString(), prompt + error, QLineEdit::Normal, text, &ok);
335 if (text.contains(QRegExp("[\"*/:<>?\\\\|]"))) {
336 error = "<small><br/><font color = 'red'>" + tr("The name cannot contain any of the following characters: ") +
337 "\"*/:<>?\\|</font></small>";
338 } else if (ok && !text.isEmpty()) {
339 QFileInfo info(file.path() + "/" + text);
340 manipulator->newNameFromDialog = info.absoluteFilePath();
345 manipulator->mutex.unlock();
350 void FileOperator::remove(FileManipulatorThread* manipulator) {
352 layout()->removeWidget(manipulator->progressBar);
353 manipulatorList.removeAll(manipulator);
358 void FileOperator::setBarSize(FileManipulatorThread* manipulator, unsigned int size) {
359 manipulator->progressBar->setMinimum(0);
360 manipulator->progressBar->setMaximum(size);
364 void FileOperator::updateProgress(FileManipulatorThread* manipulator, int value) {
365 manipulator->setText(value);
369 void FileOperator::showPaused(FileManipulatorThread* manipulator) {
370 manipulator->setText(0);
374 void FileOperator::togglePauseOperation(FileManipulatorThread* manipulator) {
375 if (manipulator->pause) {
376 manipulator->pause = false;
379 manipulator->pause = true;
384 void FileOperator::abortOperation(FileManipulatorThread* manipulator) {
385 int confirm = QMessageBox::warning(
387 tr("Abort operation"),
388 tr("Are you sure you want to abort the operation?"),
393 if(confirm == QMessageBox::Yes) {
394 manipulator->abort = true;
395 manipulator->pause = false;
396 manipulator->setText(0);
402 void FileOperator::caterNewThread(FileManipulatorThread *thread) {
403 manipulatorList.append(thread);
405 connect(thread, SIGNAL(showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int)),
406 this, SLOT(showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int)));
407 connect(thread, SIGNAL(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)),
408 this, SLOT(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)));
409 connect(thread, SIGNAL(showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, bool)),
410 this, SLOT(showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, bool)));
411 connect(thread, SIGNAL(finished(FileManipulatorThread*)),
412 this, SLOT(remove(FileManipulatorThread*)));
413 connect(thread, SIGNAL(setBarSize(FileManipulatorThread*, unsigned int)),
414 this, SLOT(setBarSize(FileManipulatorThread*, unsigned int)));
415 connect(thread, SIGNAL(updateProgress(FileManipulatorThread*, int)),
416 this, SLOT(updateProgress(FileManipulatorThread*, int)));
417 connect(thread, SIGNAL(operationPaused(FileManipulatorThread*)),
418 this, SLOT(showPaused(FileManipulatorThread*)));
420 connect(thread->progressBar, SIGNAL(togglePauseOperation(FileManipulatorThread*)),
421 this, SLOT(togglePauseOperation(FileManipulatorThread*)));
422 connect(thread->progressBar, SIGNAL(abortOperation(FileManipulatorThread*)),
423 this, SLOT(abortOperation(FileManipulatorThread*)));
426 layout()->addWidget(thread->progressBar);
427 thread->start(QThread::LowestPriority);
431 FileManipulatorThread::FileManipulatorThread(const QFileInfoList files, QDir dest) :
432 progressBar(new ProgressBar(this)),
437 response(FileOperator::NONE),
438 overwriteAll(FileOperator::NONE),
447 memset(ignoreAll, false, sizeof(ignoreAll));
451 FileManipulatorThread::~FileManipulatorThread() {
452 if (!abort && progressBar->value() < progressBar->maximum()) {
453 std::cout << "WARNING: deleting a progressbar which's value " << progressBar->value() <<
454 " has not reached maximum of " << progressBar->maximum() << std::endl;
460 void FileManipulatorThread::setResponse(
461 const FileOperator::Response response,
462 const bool applyToAll,
467 this->response = response;
470 if (response == FileOperator::KEEP
471 || response == FileOperator::OVERWRITE
472 || response == FileOperator::NONE)
474 overwriteAll = response;
477 if (response == FileOperator::IGNORE) {
478 ignoreAll[err] = true;
482 if (response == FileOperator::ABORT) abort = true;
489 void FileManipulatorThread::processFiles(const QFileInfoList &files) {
490 for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
498 bool FileManipulatorThread::remove(QString &fileName, const bool doUpdates) {
499 return remove(QFileInfo(fileName), doUpdates);
503 bool FileManipulatorThread::remove(const QFileInfoList &files, const bool doUpdates) {
505 for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
506 if (!remove(*it, doUpdates)) res = false;
514 bool FileManipulatorThread::remove(const QFileInfo &file, const bool doUpdates) {
515 std::cout << "DELETING " << file.absoluteFilePath().toStdString() << std::endl;
517 QString path = file.absoluteFilePath();
519 if (removeExcludeFiles.contains(path)) {
520 if (doUpdates) updateProgress(1);
524 QFSFileEngine engine(path);
526 if (doUpdates) updateFile(path);
529 if (!remove(listDirFiles(path), doUpdates)) {
530 if (doUpdates) updateProgress(1);
534 if (!listDirFiles(path).size()) {
535 ERROR_PROMPT(!engine.rmdir(path, false), tr("Error deleting directory %1."), path)
538 ERROR_PROMPT(!engine.remove(), tr("Error deleting file %1."), path)
541 if (!abort && doUpdates) updateProgress(1);
544 if (abort || response == FileOperator::IGNORE) return false;
549 void FileManipulatorThread::copy(const QFileInfo &file) {
550 std::cout << "COPYING " << file.absoluteFilePath().toStdString()
551 << " to " << dest.absolutePath().toStdString() << std::endl;
553 QString path(file.absoluteFilePath());
554 QFSFileEngine engine(path);
555 QFileInfo newFile(dest.absolutePath() + "/" + file.fileName());
559 // hack to prevent asking about the same file if we already asked in the rename(...) function
560 if (overwriteAll == FileOperator::DONT_ASK_ONCE) {
561 overwriteAll = FileOperator::NONE;
563 OVERWRITE_PROMPT(file, newFile)
566 QString newPath(newFile.absoluteFilePath());
567 QFSFileEngine newEngine(newPath);
573 // save the overwrite response, because the response variable will get ovewritten in remove(...)
574 FileOperator::Response overwriteResponse = response;
576 if (newFile.exists() && !newFile.isDir()) {
577 // overwriting a file, so check for KEEP and handle it
578 if (response == FileOperator::KEEP) {
579 updateProgress(fileSizeMap[path]);
580 removeExcludeFiles.insert(path);
584 // if it should not be kept, remove it and return on failure
585 if(!remove(newPath)) {
586 updateProgress(fileSizeMap[path]);
589 // create new info since we deleted the file - is it needed?
590 newFile = QFileInfo(newPath);
592 // overwriting a directory - response KEEP means to keep the files inside,
593 // SKIP_DIR means to skip the dir completely
594 if (response == FileOperator::SKIP_DIR) {
595 updateProgress(fileSizeMap[path]);
596 removeExcludeFiles.insert(path);
601 if (!newFile.exists()) {
602 SPECIAL_COPY_ERROR_PROMPT(!engine.mkdir(newPath, false),
603 tr("Error creating directory %1."), newPath)
606 // we've done the job with the dir, so update progress and recurse into the dir
609 // change the dest for the recursion
610 QDir destBackup = dest;
613 // and set overwriteAll to the response we got a while ago
614 // because it applies to the files inside the dir
615 FileOperator::Response tmpResp = overwriteAll;
616 overwriteAll = overwriteResponse;
618 processFiles(listDirFiles(path));
620 overwriteAll = tmpResp;
622 ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
623 tr("Error setting permissions for directory %1."), newPath)
630 if (response == FileOperator::KEEP) {
631 updateProgress(fileSizeMap[path]);
632 removeExcludeFiles.insert(path);
636 SPECIAL_COPY_ERROR_PROMPT(checkSequentialFile(engine), tr("Cannot copy file %1."), path)
638 if (newFile.exists() && newFile.isDir()) {
639 SPECIAL_COPY_ERROR_PROMPT(!remove(newPath),
640 tr("Cannot replace directory %1 due to previous errors."), newPath)
643 SPECIAL_COPY_ERROR_PROMPT(!engine.open(QIODevice::ReadOnly), tr("Error reading file %1."), path)
645 bool ignore = false, newFileWritten = false;
646 while (!abort && !ignore) {
650 ERROR_PROMPT(!newEngine.open(QIODevice::WriteOnly | QIODevice::Truncate),
651 tr("Error writing file %1."), newPath)
653 if (abort || response == FileOperator::IGNORE) {
654 if (response == FileOperator::IGNORE) {
655 updateProgress(fileSizeMap[path]);
656 removeExcludeFiles.insert(path);
662 newFileWritten = true;
665 char block[BLOCK_SIZE];
667 while ((bytes = engine.read(block, sizeof(block))) > 0) {
668 if (bytes == -1 || bytes != newEngine.write(block, bytes)) {
670 SHOW_ERROR_PROMPT(tr("Error while reading from file %1."), path);
672 SHOW_ERROR_PROMPT(tr("Error while writing to file %1."), newPath);
676 if (response == FileOperator::IGNORE) {
677 updateProgress(fileSizeMap[path] - fileValue);
678 removeExcludeFiles.insert(path);
681 updateProgress(-fileValue);
702 if (abort || ignore) {
703 if (newFileWritten) {
707 ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
708 tr("Error setting permissions for file %1."), newPath)
714 unsigned int FileManipulatorThread::calculateFileSize(const QFileInfoList &files,
718 unsigned int res = 0;
720 for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
721 unsigned int size = 0;
727 size += calculateFileSize(listDirFiles(it->absoluteFilePath()), count, addSize);
734 size += ceil(static_cast<float>(it->size()) / BLOCK_SIZE);
736 fileSizeMap[it->absoluteFilePath()] = size;
750 QFileInfoList FileManipulatorThread::listDirFiles(const QString &dirPath) {
752 return dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries | QDir::System | QDir::Hidden);
756 void FileManipulatorThread::setBarSize(unsigned int size) {
758 emit setBarSize(this, size);
762 void FileManipulatorThread::updateProgress(int value) {
765 emit updateProgress(this, value);
769 void FileManipulatorThread::updateFile(const QString &name) {
771 fileName = FileOperator::shortenPath(name);
772 emit updateProgress(this, 0);
776 void FileManipulatorThread::waitOnCond() {
778 waitCond.wait(&mutex);
782 bool FileManipulatorThread::checkSequentialFile(const QFSFileEngine &engine) {
784 if (engine.isSequential()) {
785 if (!errno) errno = 255;
793 void FileManipulatorThread::wake() {
794 startTime += time(0) - waitTime;
799 void FileManipulatorThread::setText(int value) {
800 if (progressBar->value() + value > progressBar->maximum()) {
801 std::cout << "WARNING: exceeding progressbar maximum (" << progressBar->maximum()
802 << ") by " << value << std::endl;
805 if (!fileName.size()) {
807 progressBar->setFormat(tr("Gathering information...") + " (" + tr("paused") + ")");
809 progressBar->setFormat(tr("Gathering information..."));
814 time_t now = time(0);
815 if (lastTimeUpdate < now) {
816 lastTimeUpdate = now;
818 time_t elapsed = now - startTime;
819 time_t remaining = (time_t) ((float) elapsed / barValue * (barSize - barValue));
820 struct tm *ts = gmtime(&remaining);
822 if (remaining < 60) {
823 strftime(timeBuf, sizeof(timeBuf), "%Ss", ts);
824 } else if (remaining < 3600) {
825 strftime(timeBuf, sizeof(timeBuf), "%M:%S", ts);
827 strftime(timeBuf, sizeof(timeBuf), "%H:%M:%S", ts);
831 QString newFormat = barText.arg(fileName) + "\n%p% ETA " + timeBuf;
832 if (pause) newFormat += " (" + tr("paused") + ")";
834 progressBar->setFormat(newFormat);
835 progressBar->setValue(progressBar->value() + value);
839 DeleteThread::DeleteThread(const QFileInfoList &files) : FileManipulatorThread(files) {
840 barText = tr("deleting %1");
844 void DeleteThread::run() {
847 setBarSize(calculateFileSize(files, true));
857 void DeleteThread::perform(const QFileInfo &file) {
862 CopyThread::CopyThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {
863 barText = tr("copying %1");
867 void CopyThread::run() {
870 setBarSize(calculateFileSize(files, false, true));
880 void CopyThread::perform(const QFileInfo &file) {
885 MoveThread::MoveThread(const QFileInfoList &files, QDir &dest) : FileManipulatorThread(files, dest) {
886 barText = tr("moving %1");
890 void MoveThread::run() {
900 void MoveThread::rename(const QFileInfoList &files, const QDir &dest) {
901 setBarSize(barSize + files.size());
904 for (int i = 0; i < files.size(); ++i) {
905 QString path = files[i].absoluteFilePath();
906 QFSFileEngine engine(path);
907 QFileInfo newFile(dest.absolutePath() + "/" + files[i].fileName());
911 OVERWRITE_PROMPT(files[i], newFile)
913 // if we are owerwriting dir over a dir, we will get SKIP_DIR
914 // as a response from OVERWRITE_PROMT meaning we should skip it
915 // (KEEP would mean to keep the files inside)
916 if (files[i].isDir() && newFile.exists() && newFile.isDir()) {
917 if (response == FileOperator::SKIP_DIR) {
921 removeExcludeFiles.insert(path);
925 if (response == FileOperator::KEEP) {
929 removeExcludeFiles.insert(path);
934 QString newPath(newFile.absoluteFilePath());
935 QFSFileEngine newEngine(newPath);
939 while (!abort && !engine.rename(newPath)) {
940 // source and target are on different partitions
941 // this should happen on the first file, unless some are skipped by overwrite prompt
942 // we calculate the actual file sizes, because from now on copy & remove takes over
943 if (errno == EXDEV) {
944 overwriteAll = response;
945 // hack: we already checked the first file we are sending to processFiles(...)
946 // so we don't want to ask about this one again
947 if (overwriteAll == FileOperator::NONE) overwriteAll = FileOperator::DONT_ASK_ONCE;
949 QFileInfoList remainingFiles = files.mid(i);
951 setBarSize(barValue + calculateFileSize(remainingFiles, true, true));
953 processFiles(remainingFiles);
955 barText = tr("deleting %1");
957 remove(remainingFiles, true);
961 // the target is nonempty dir. lets call this recursively and rename the contents one by one
962 } else if (errno == ENOTEMPTY || errno == EEXIST) {
963 FileOperator::Response tmpResp = overwriteAll;
964 overwriteAll = response;
966 rename(listDirFiles(path), QDir(newPath));
970 overwriteAll = tmpResp;
975 // source and target are nonmatching types(file and dir)
976 // remove the target and let it loop once again
977 } else if (errno == ENOTDIR || errno == EISDIR) {
978 if (!remove(newPath)) break;
980 SHOW_ERROR_PROMPT(tr("Error moving %1."), path)
982 if (response == FileOperator::IGNORE) {
998 void MoveThread::perform(const QFileInfo &file) {