- manipulator->abort = true;
- manipulator->pause = false;
- manipulator->wake();
- }
-}
-
-
-void FileOperator::caterNewThread(FileManipulatorThread *thread) {
- manipulatorList.append(thread);
-
- connect(thread, SIGNAL(showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int)),
- this, SLOT(showErrorPrompt(FileManipulatorThread*, const QString&, const QString&, const int)));
- connect(thread, SIGNAL(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)),
- this, SLOT(showOverwritePrompt(FileManipulatorThread*, const QString&, bool)));
- connect(thread, SIGNAL(showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, bool)),
- this, SLOT(showInputFilenamePrompt(FileManipulatorThread*, const QFileInfo&, bool)));
- connect(thread, SIGNAL(finished(FileManipulatorThread*)),
- this, SLOT(remove(FileManipulatorThread*)));
- connect(thread, SIGNAL(setBarSize(FileManipulatorThread*, unsigned int)),
- this, SLOT(setBarSize(FileManipulatorThread*, unsigned int)));
- connect(thread, SIGNAL(updateProgress(FileManipulatorThread*, int)),
- this, SLOT(updateProgress(FileManipulatorThread*, int)));
- connect(thread, SIGNAL(updateFileName(FileManipulatorThread*, QString)),
- this, SLOT(updateMainText(FileManipulatorThread*, QString)));
- connect(thread, SIGNAL(operationPaused(FileManipulatorThread*)),
- this, SLOT(showPaused(FileManipulatorThread*)));
-
- connect(thread->progressBar, SIGNAL(togglePauseOperation(FileManipulatorThread*)),
- this, SLOT(togglePauseOperation(FileManipulatorThread*)));
- connect(thread->progressBar, SIGNAL(abortOperation(FileManipulatorThread*)),
- this, SLOT(abortOperation(FileManipulatorThread*)));
-
- layout()->addWidget(thread->progressBar);
- thread->start(QThread::LowestPriority);
-}
-
-
-FileManipulatorThread::FileManipulatorThread(const QFileInfoList files, QDir dest) :
- progressBar(new ProgressBar(this)),
- abort(false),
- pause(false),
- files(files),
- dest(dest),
- response(FileOperator::NONE),
- overwriteAll(FileOperator::NONE),
- lastTimeUpdate(0),
- startTime(0),
- waitTime(0),
- barSize(0),
- barValue(0),
- fileSize(0),
- fileValue(0)
-{
- memset(ignoreAll, false, sizeof(ignoreAll));
-}
-
-
-FileManipulatorThread::~FileManipulatorThread() {
- if (!abort && 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;
-}
-
-
-void FileManipulatorThread::setResponse(
- const FileOperator::Response response,
- const bool applyToAll,
- const int err)
-{
- mutex.lock();
-
- this->response = response;
-
- if (applyToAll) {
- if (response == FileOperator::KEEP
- || response == FileOperator::OVERWRITE
- || response == FileOperator::NONE)
- {
- overwriteAll = response;
- }
-
- if (response == FileOperator::IGNORE) {
- ignoreAll[err] = true;
- }
- }
-
- if (response == FileOperator::ABORT) abort = true;
-
- mutex.unlock();
- wake();
-}
-
-
-void FileManipulatorThread::processFiles(const QFileInfoList &files) {
- for (QFileInfoList::const_iterator it = files.begin(); it != files.end(); ++it) {
- PAUSE();
- if (abort) break;
- perform(*it);
- }
-}
-
-
-bool FileManipulatorThread::remove(QString &fileName, const bool doUpdates) {
- return remove(QFileInfo(fileName), doUpdates);
-}
-
-
-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, doUpdates)) res = false;
- PAUSE();
- if (abort) break;
- }
- return res;
-}
-
-
-bool FileManipulatorThread::remove(const QFileInfo &file, const bool doUpdates) {
- std::cout << "DELETING " << file.absoluteFilePath().toStdString() << std::endl;
-
- QString path = file.absoluteFilePath();
-
- if (removeExcludeFiles.contains(path)) {
- if (doUpdates) updateProgress(1);
- return false;
- }
-
- QFSFileEngine engine(path);
-
- if (doUpdates) updateFile(path);
-
- if (file.isDir()) {
- if (!remove(listDirFiles(path), doUpdates)) {
- if (doUpdates) updateProgress(1);
- return false;
- }
-
- 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 && doUpdates) updateProgress(1);
-
- PAUSE();
- if (abort || response == FileOperator::IGNORE) return false;
- return true;
-}
-
-
-void FileManipulatorThread::copy(const QFileInfo &file) {
- std::cout << "COPYING " << file.absoluteFilePath().toStdString()
- << " to " << dest.absolutePath().toStdString() << std::endl;
-
- QString path(file.absoluteFilePath());
- QFSFileEngine engine(path);
- QFileInfo newFile(dest.absolutePath() + "/" + file.fileName());
-
- updateFile(path);
-
- // hack to prevent asking about the same file if we already asked in the rename(...) function
- if (overwriteAll == FileOperator::DONT_ASK_ONCE) {
- overwriteAll = FileOperator::NONE;
- } else {
- OVERWRITE_PROMPT(file, newFile)
- }
-
- QString newPath(newFile.absoluteFilePath());
- QFSFileEngine newEngine(newPath);
-
- PAUSE();
- if (abort) return;
-
- if (file.isDir()) {
- // save the overwrite response, because the response variable will get ovewritten in remove(...)
- FileOperator::Response overwriteResponse = response;
-
- if (newFile.exists() && !newFile.isDir()) {
- // overwriting a file, so check for KEEP and handle it
- if (response == FileOperator::KEEP) {
- updateProgress(fileSizeMap[path]);
- removeExcludeFiles.insert(path);
- return;
- }
-
- // if it should not be kept, remove it and return on failure
- if(!remove(newPath)) {
- updateProgress(fileSizeMap[path]);
- return;
- }
- // create new info since we deleted the file - is it needed?
- newFile = QFileInfo(newPath);
- } else {
- // overwriting a directory - response KEEP means to keep the files inside,
- // SKIP_DIR means to skip the dir completely
- if (response == FileOperator::SKIP_DIR) {
- updateProgress(fileSizeMap[path]);
- removeExcludeFiles.insert(path);
- return;
- }
- }
-
- if (!newFile.exists()) {
- SPECIAL_COPY_ERROR_PROMPT(!engine.mkdir(newPath, false),
- tr("Error creating directory %1."), newPath)
- }
-
- // we've done the job with the dir, so update progress and recurse into the dir
- updateProgress(1);
-
- // change the dest for the recursion
- QDir destBackup = dest;
- dest = newPath;
-
- // and set overwriteAll to the response we got a while ago
- // because it applies to the files inside the dir
- FileOperator::Response tmpResp = overwriteAll;
- overwriteAll = overwriteResponse;
-
- processFiles(listDirFiles(path));
-
- overwriteAll = tmpResp;
-
- ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
- tr("Error setting permissions for directory %1."), newPath)
-
- PAUSE();
- if (abort) return;
-
- dest = destBackup;
- } else {
- if (response == FileOperator::KEEP) {
- updateProgress(fileSizeMap[path]);
- removeExcludeFiles.insert(path);
- return;
- }
-
- SPECIAL_COPY_ERROR_PROMPT(checkSequentialFile(engine), tr("Cannot copy file %1."), path)
-
- if (newFile.exists() && newFile.isDir()) {
- SPECIAL_COPY_ERROR_PROMPT(!remove(newPath),
- tr("Cannot replace directory %1 due to previous errors."), newPath)
- }
-
- SPECIAL_COPY_ERROR_PROMPT(!engine.open(QIODevice::ReadOnly), tr("Error reading file %1."), path)
-
- bool ignore = false, newFileWritten = false;
- while (!abort && !ignore) {
- engine.seek(0);
- fileValue = 0;
-
- 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]);
- removeExcludeFiles.insert(path);
- ignore = true;
- }
- break;
- }
-
- newFileWritten = 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);
- }
-
- if (!abort) {
- if (response == FileOperator::IGNORE) {
- updateProgress(fileSizeMap[path] - fileValue);
- removeExcludeFiles.insert(path);
- ignore = true;
- } else {
- updateProgress(-fileValue);
- }
- }
- error = true;
- break;
- }
-
- PAUSE();
- if (abort) break;
-
- updateProgress(1);
- }
-
- if (!error) break;
- PAUSE();
- }
-
- engine.close();
- newEngine.close();
-
- PAUSE();
- if (abort || ignore) {
- if (newFileWritten) {
- newEngine.remove();
- }
- } else {
- ERROR_PROMPT(!newEngine.setPermissions(file.permissions()),
- tr("Error setting permissions for file %1."), newPath)
- }
- }
-}
-
-
-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 = 0;
-
- PAUSE();
- if (abort) break;
-
- if (it->isDir()) {
- size += calculateFileSize(listDirFiles(it->absoluteFilePath()), count, addSize);
- }
-
- if (addSize) {
- if (it->isDir()) {
- ++size;
- } else {
- size += ceil(static_cast<float>(it->size()) / BLOCK_SIZE);
- }
- fileSizeMap[it->absoluteFilePath()] = size;
- }
-
- if (count) {
- ++size;
- }
-
- res += size;