in case rename(...) call is not used, remove all files after everything
is copied (instead of removing each right after it was copied) and don't
remove at all if the target was present and not overwritten (temporary,
I'm not sure of the expected behavior in this case)
Signed-off-by: Lukas Hrazky <lukkash@email.cz>
+#define BLOCK_SIZE 524288
+
+
#define SHOW_ERROR_PROMPT(promptString, fileName) \
response = FileOperator::NONE; \
if (ignoreAll[errno]) { \
#define SHOW_ERROR_PROMPT(promptString, fileName) \
response = FileOperator::NONE; \
if (ignoreAll[errno]) { \
FileManipulatorThread::~FileManipulatorThread() {
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;
+ }
-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) {
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;
}
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);
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)
+ }
- 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;
}
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());
<< " to " << dest.absolutePath().toStdString() << std::endl;
QString path(file.absoluteFilePath());
- // 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;
+ }
FileOperator::Response overwriteResponse = response;
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)
- 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]),
updateProgress(fileSizeMap[path]),
- 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);
- 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;
- 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;
- engine.close();
- newEngine.close();
-
- if (abort || ignore) {
- newEngine.remove();
- } else {
- ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
- tr("Error setting permissions for file %1."), newPath)
- }
+ 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 res = 0;
for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
- 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);
- fileSizeMap[it->absoluteFilePath()] = size;
void FileManipulatorThread::setText(int value) {
if (progressBar->value() + value > progressBar->maximum()) {
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;
void DeleteThread::run() {
mutex.lock();
void DeleteThread::run() {
mutex.lock();
- setBarSize(countFiles(files));
+ setBarSize(calculateFileSize(files, true));
void DeleteThread::perform(const QFileInfo &file) {
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);
void CopyThread::run() {
mutex.lock();
void CopyThread::run() {
mutex.lock();
- setBarSize(calculateFileSize(files));
+ setBarSize(calculateFileSize(files, false, true));
void CopyThread::perform(const QFileInfo &file) {
void CopyThread::perform(const QFileInfo &file) {
OVERWRITE_PROMPT(files[i], QFileInfo(newPath))
if (response == FileOperator::KEEP) {
OVERWRITE_PROMPT(files[i], QFileInfo(newPath))
if (response == FileOperator::KEEP) {
+ // TODO lets not remove the source for now, I'm not sure what is correct behavior
+ // remove(path);
if (abort) break;
updateProgress(1);
continue;
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) {
// 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;
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;
// just to quit the loops, we are done
abort = true;
void MoveThread::perform(const QFileInfo &file) {
void MoveThread::perform(const QFileInfo &file) {
void processFiles(const QFileInfoList &files);
virtual void perform(const QFileInfo &file) = 0;
void processFiles(const QFileInfoList &files);
virtual void perform(const QFileInfo &file) = 0;
- bool remove(QString &fileName, const bool ignoreDirNotEmpty = false);
- bool remove(const QFileInfoList &files, const bool ignoreDirNotEmpty = false);
- bool remove(const QFileInfo &file, const bool ignoreDirNotEmpty = false);
+ bool remove(QString &fileName, const bool doUpdates = false);
+ bool remove(const QFileInfoList &files, const bool doUpdates = false);
+ bool remove(const QFileInfo &file, const bool doUpdates = false);
- void copy(const QFileInfo &file, const bool removeAfterCopy);
+ void copy(const QFileInfo &file);
- unsigned int countFiles(const QFileInfoList &files);
- unsigned int calculateFileSize(const QFileInfoList &files);
+ unsigned int calculateFileSize(const QFileInfoList &files,
+ const bool count = false,
+ const bool addSize = false);
QFileInfoList listDirFiles(const QString &dirPath);
QFileInfoList listDirFiles(const QString &dirPath);