#include <iostream>
+#define BLOCK_SIZE 524288
+
+
#define SHOW_ERROR_PROMPT(promptString, fileName) \
response = FileOperator::NONE; \
if (ignoreAll[errno]) { \
FileManipulatorThread::~FileManipulatorThread() {
+ if (progressBar->value() < progressBar->maximum()) {
+ std::cout << "WARNING: deleting a progressbar which's value " << progressBar->value() <<
+ " has not reached maximum of " << progressBar->maximum() << std::endl;
+ }
delete progressBar;
}
}
-bool FileManipulatorThread::remove(QString &fileName, const bool ignoreDirNotEmpty) {
- return remove(QFileInfo(fileName), ignoreDirNotEmpty);
+bool FileManipulatorThread::remove(QString &fileName, const bool doUpdates) {
+ return remove(QFileInfo(fileName), doUpdates);
}
-bool FileManipulatorThread::remove(const QFileInfoList &files, const bool ignoreDirNotEmpty) {
+bool FileManipulatorThread::remove(const QFileInfoList &files, const bool doUpdates) {
bool res = true;
for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
- if (!remove(*it, ignoreDirNotEmpty)) res = false;
+ if (!remove(*it, doUpdates)) res = false;
if (abort) break;
}
return res;
}
-bool FileManipulatorThread::remove(const QFileInfo &file, const bool ignoreDirNotEmpty) {
+bool FileManipulatorThread::remove(const QFileInfo &file, const bool doUpdates) {
+ std::cout << "DELETING " << file.absoluteFilePath().toStdString() << std::endl;
+
QString path = file.absoluteFilePath();
QFSFileEngine engine(path);
- if (file.isDir()) {
- QFileInfoList list = listDirFiles(path);
+ if (doUpdates) updateFile(path);
- if (ignoreDirNotEmpty && list.size()) return true;
-
- if (!remove(list, ignoreDirNotEmpty)) return false;
+ if (file.isDir()) {
+ if (!remove(listDirFiles(path), doUpdates)) return false;
- ERROR_PROMPT(!engine.rmdir(path, false),
- tr("Error deleting directory %1."), path)
+ if (!listDirFiles(path).size()) {
+ ERROR_PROMPT(!engine.rmdir(path, false), tr("Error deleting directory %1."), path)
+ }
} else {
- ERROR_PROMPT(!engine.remove(),
- tr("Error deleting file %1."), path)
+ ERROR_PROMPT(!engine.remove(), tr("Error deleting file %1."), path)
}
+ if (!abort && doUpdates) updateProgress(1);
+
if (abort || response == FileOperator::IGNORE) return false;
return true;
}
-void FileManipulatorThread::copy(const QFileInfo &file, const bool removeAfterCopy) {
- std::cout << (removeAfterCopy ? "MOVING " : "COPYING ") << file.absoluteFilePath().toStdString()
+void FileManipulatorThread::copy(const QFileInfo &file) {
+ std::cout << "COPYING " << file.absoluteFilePath().toStdString()
<< " to " << dest.absolutePath().toStdString() << std::endl;
QString path(file.absoluteFilePath());
if (abort) return;
- // this loop is here only to allow easily breaking out to the end (and remove the source file/dir)
- while (1) {
- if (response == FileOperator::KEEP) {
- updateProgress(fileSizeMap[path]);
- break;
- }
+ if (response == FileOperator::KEEP) {
+ updateProgress(fileSizeMap[path]);
+ return;
+ }
+ if (file.isDir()) {
FileOperator::Response overwriteResponse = response;
- if (file.isDir()) {
- if (newFile.exists() && !newFile.isDir()) {
- if(!remove(newPath)) {
- updateProgress(fileSizeMap[path]);
- break;
- }
- newFile = QFileInfo(newPath);
+ if (newFile.exists() && !newFile.isDir()) {
+ if(!remove(newPath)) {
+ updateProgress(fileSizeMap[path]);
+ return;
}
+ newFile = QFileInfo(newPath);
+ }
- if (!newFile.exists()) {
- ERROR_PROMPT_XP(!engine.mkdir(newPath, false),
- tr("Error creating directory %1."), newPath,
- updateProgress(fileSizeMap[path]),
- break)
- }
+ if (!newFile.exists()) {
+ ERROR_PROMPT_XP(!engine.mkdir(newPath, false),
+ tr("Error creating directory %1."), newPath,
+ updateProgress(fileSizeMap[path]),
+ return)
+ }
- updateProgress(1);
-
- QDir destBackup = dest;
- dest = newPath;
+ updateProgress(1);
+
+ QDir destBackup = dest;
+ dest = newPath;
- FileOperator::Response tmpResp = overwriteAll;
- overwriteAll = overwriteResponse;
+ FileOperator::Response tmpResp = overwriteAll;
+ overwriteAll = overwriteResponse;
- processFiles(listDirFiles(path));
+ processFiles(listDirFiles(path));
- overwriteAll = tmpResp;
+ overwriteAll = tmpResp;
- ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
- tr("Error setting permissions for directory %1."), newPath)
+ ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
+ tr("Error setting permissions for directory %1."), newPath)
- if (abort) return;
+ if (abort) return;
- dest = destBackup;
- } else {
- ERROR_PROMPT_XP(engine.isSequential(),
- tr("Cannot copy sequential file %1."), path,
+ dest = destBackup;
+ } else {
+ ERROR_PROMPT_XP(engine.isSequential(),
+ tr("Cannot copy sequential file %1."), path,
+ updateProgress(fileSizeMap[path]),
+ return)
+
+ if (newFile.exists() && newFile.isDir()) {
+ ERROR_PROMPT_XP(!remove(newPath),
+ tr("Cannot replace directory %1 due to previous errors."), newPath,
updateProgress(fileSizeMap[path]),
- break)
+ return)
+ }
- if (newFile.exists() && newFile.isDir()) {
- ERROR_PROMPT_XP(!remove(newPath),
- tr("Cannot replace directory %1 due to previous errors."), newPath,
- updateProgress(fileSizeMap[path]),
- break)
- }
+ ERROR_PROMPT_XP(!engine.open(QIODevice::ReadOnly),
+ tr("Error reading file %1."), path,
+ updateProgress(fileSizeMap[path]),
+ return)
- ERROR_PROMPT_XP(!engine.open(QIODevice::ReadOnly),
- tr("Error reading file %1."), path,
- updateProgress(fileSizeMap[path]),
- break)
+ bool ignore = false;
+ while (!abort && !ignore) {
+ engine.seek(0);
- bool ignore = false;
- while (!abort && !ignore) {
- engine.seek(0);
+ ERROR_PROMPT(!newEngine.open(QIODevice::WriteOnly | QIODevice::Truncate),
+ tr("Error writing file %1."), newPath)
- ERROR_PROMPT(!newEngine.open(QIODevice::WriteOnly | QIODevice::Truncate),
- tr("Error writing file %1."), newPath)
+ if (abort || response == FileOperator::IGNORE) {
+ if (response == FileOperator::IGNORE) {
+ updateProgress(fileSizeMap[path] - fileValue);
+ ignore = true;
+ }
+ break;
+ }
- if (abort || response == FileOperator::IGNORE) {
- if (response == FileOperator::IGNORE) {
- updateProgress(fileSizeMap[path] - fileValue);
- ignore = true;
+ bool error = false;
+ char block[BLOCK_SIZE];
+ qint64 bytes;
+ while ((bytes = engine.read(block, sizeof(block))) > 0) {
+ if (bytes == -1 || bytes != newEngine.write(block, bytes)) {
+ if (bytes == -1) {
+ SHOW_ERROR_PROMPT(tr("Error while reading from file %1."), path);
+ } else {
+ SHOW_ERROR_PROMPT(tr("Error while writing to file %1."), newPath);
}
- break;
- }
- bool error = false;
- char block[524288];
- qint64 bytes;
- while ((bytes = engine.read(block, sizeof(block))) > 0) {
- if (bytes == -1 || bytes != newEngine.write(block, bytes)) {
- if (bytes == -1) {
- SHOW_ERROR_PROMPT(tr("Error while reading from file %1."), path);
+ if (!abort) {
+ if (response == FileOperator::IGNORE) {
+ updateProgress(fileSizeMap[path] - fileValue);
+ ignore = true;
} else {
- SHOW_ERROR_PROMPT(tr("Error while writing to file %1."), newPath);
+ updateProgress(-fileValue);
}
-
- if (!abort) {
- if (response == FileOperator::IGNORE) {
- updateProgress(fileSizeMap[path] - fileValue);
- ignore = true;
- } else {
- updateProgress(-fileValue);
- }
- }
- error = true;
- break;
}
-
- updateProgress(1);
+ error = true;
+ break;
}
- if (!error) break;
+ updateProgress(1);
}
- engine.close();
- newEngine.close();
-
- if (abort || ignore) {
- newEngine.remove();
- } else {
- ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
- tr("Error setting permissions for file %1."), newPath)
- }
+ if (!error) break;
}
- break;
- }
+ engine.close();
+ newEngine.close();
- if (removeAfterCopy && !abort) remove(path, true);
+ if (abort || ignore) {
+ newEngine.remove();
+ } else {
+ ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
+ tr("Error setting permissions for file %1."), newPath)
+ }
+ }
}
-unsigned int FileManipulatorThread::countFiles(const QFileInfoList &files) {
+unsigned int FileManipulatorThread::calculateFileSize(const QFileInfoList &files,
+ const bool count,
+ const bool addSize)
+{
unsigned int res = 0;
for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
- unsigned int size = 1;
+ unsigned int size = 0;
if (it->isDir()) {
- size += countFiles(listDirFiles(it->absoluteFilePath()));
+ size += calculateFileSize(listDirFiles(it->absoluteFilePath()), count, addSize);
}
- res += size;
- fileSizeMap[it->absoluteFilePath()] = size;
- }
-
- return res;
-}
-
-
-unsigned int FileManipulatorThread::calculateFileSize(const QFileInfoList &files) {
- unsigned int res = 0;
-
- for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
- unsigned int size = 1;
+ if (addSize) {
+ if (it->isDir()) {
+ ++size;
+ } else {
+ size += ceil(static_cast<float>(it->size()) / BLOCK_SIZE);
+ }
+ fileSizeMap[it->absoluteFilePath()] = size;
+ }
- if (it->isDir()) {
- size += calculateFileSize(listDirFiles(it->absoluteFilePath()));
- } else {
- size = ceil(static_cast<float>(it->size()) / 524288);
+ if (count) {
+ ++size;
}
res += size;
- fileSizeMap[it->absoluteFilePath()] = size;
}
return res;
void FileManipulatorThread::setText(int value) {
if (progressBar->value() + value > progressBar->maximum()) {
- std::cout << "WARNING, EXCEEDING MAXIMUM BY " << value << std::endl;
+ std::cout << "WARNING: exceeding progressbar maximum (" << progressBar->maximum()
+ << ") by " << value << std::endl;
}
time_t now = time(0);
void DeleteThread::run() {
mutex.lock();
- setBarSize(countFiles(files));
+ setBarSize(calculateFileSize(files, true));
processFiles(files);
void DeleteThread::perform(const QFileInfo &file) {
- std::cout << "DELETING " << file.absoluteFilePath().toStdString() << std::endl;
-
- QString path = file.absoluteFilePath();
- QFSFileEngine engine(path);
-
- updateFile(path);
-
- if (file.isDir()) {
- processFiles(listDirFiles(path));
-
- if (!listDirFiles(path).size()) {
- ERROR_PROMPT(!engine.rmdir(path, false),
- tr("Error deleting directory %1."), path)
- }
- } else {
- ERROR_PROMPT(!engine.remove(),
- tr("Error deleting file %1."), path)
- }
-
- if (!abort) updateProgress(1);
+ remove(file, true);
}
void CopyThread::run() {
mutex.lock();
- setBarSize(calculateFileSize(files));
+ setBarSize(calculateFileSize(files, false, true));
processFiles(files);
void CopyThread::perform(const QFileInfo &file) {
- copy(file, false);
+ copy(file);
}
OVERWRITE_PROMPT(files[i], QFileInfo(newPath))
if (response == FileOperator::KEEP) {
- remove(path);
+ // TODO lets not remove the source for now, I'm not sure what is correct behavior
+ // remove(path);
if (abort) break;
updateProgress(1);
continue;
// this should happen on the first file, unless some are skipped by overwrite prompt
// we calculate the actual file sizes, because from now on copy & remove takes over
if (errno == EXDEV) {
- setBarSize(barValue + calculateFileSize(files));
-
- FileOperator::Response tmpResp = overwriteAll;
overwriteAll = response;
// hack: we already checked the first file we are sending to processFiles(...)
// so we don't want to ask about this one again
if (overwriteAll == FileOperator::NONE) overwriteAll = FileOperator::DONT_ASK_ONCE;
- processFiles(files.mid(i));
+ QFileInfoList remainingFiles = files.mid(i);
- overwriteAll = tmpResp;
+ setBarSize(barValue + calculateFileSize(remainingFiles, true, true));
+
+ processFiles(remainingFiles);
+
+ barText = tr("deleting %1");
+
+ remove(remainingFiles, true);
// just to quit the loops, we are done
abort = true;
void MoveThread::perform(const QFileInfo &file) {
- copy(file, true);
+ copy(file);
}