//=========================================== // Lumina-DE source code // Copyright (c) 2014, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "FODialog.h" #include "ui_FODialog.h" #include #include #define DEBUG 1 FODialog::FODialog(QWidget *parent) : QDialog(parent), ui(new Ui::FODialog){ ui->setupUi(this); //load the designer file ui->label->setText(tr("Calculating")); ui->progressBar->setVisible(false); ui->push_stop->setIcon( LXDG::findIcon("edit-delete","") ); WorkThread = new QThread(); Worker = new FOWorker(); connect(Worker, SIGNAL(startingItem(int,int,QString,QString)), this, SLOT(UpdateItem(int,int,QString,QString)) ); connect(Worker, SIGNAL(finished(QStringList)), this, SLOT(WorkDone(QStringList)) ); Worker->moveToThread(WorkThread); WorkThread->start(); //Make sure this dialog is centered on the parent if(parent!=0){ QPoint ctr = parent->mapToGlobal(parent->geometry().center()); this->move( ctr.x()-(this->width()/2), ctr.y()-(this->height()/2) ); } this->show(); } FODialog::~FODialog(){ Worker->stopped = true; //just in case it might still be running when closed WorkThread->quit(); WorkThread->wait(); delete Worker; //delete WorkThread; } void FODialog::setOverwrite(bool ovw){ if(ovw){ Worker->overwrite = 1; } else{ Worker->overwrite = 0; } } //Public "start" functions bool FODialog::RemoveFiles(QStringList paths){ Worker->ofiles = paths; Worker->isRM = true; if(CheckOverwrite()){ QTimer::singleShot(10,Worker, SLOT(slotStartOperations())); return true; }else{ this->close(); return false; } } bool FODialog::CopyFiles(QStringList oldPaths, QStringList newPaths){ //same permissions as old files if(oldPaths.length() == newPaths.length()){ Worker->ofiles = oldPaths; Worker->nfiles = newPaths; } Worker->isCP=true; if(CheckOverwrite()){ QTimer::singleShot(10,Worker, SLOT(slotStartOperations())); return true; }else{ this->close(); return false; } } bool FODialog::RestoreFiles(QStringList oldPaths, QStringList newPaths){ //user/group rw permissions if(oldPaths.length() == newPaths.length()){ Worker->ofiles = oldPaths; Worker->nfiles = newPaths; } Worker->isRESTORE = true; if(CheckOverwrite()){ QTimer::singleShot(10,Worker, SLOT(slotStartOperations())); return true; }else{ this->close(); return false; } } bool FODialog::MoveFiles(QStringList oldPaths, QStringList newPaths){ //no change in permissions if(oldPaths.length() == newPaths.length()){ Worker->ofiles = oldPaths; Worker->nfiles = newPaths; } Worker->isMV=true; if(CheckOverwrite()){ QTimer::singleShot(10,Worker, SLOT(slotStartOperations())); return true; }else{ this->close(); return false; } } bool FODialog::CheckOverwrite(){ bool ok = true; //Quick check that a file is not supposed to be moved/copied/restored onto itself if(!Worker->isRM){ for(int i=0; infiles.length(); i++){ if(Worker->nfiles[i] == Worker->ofiles[i]){ //duplicate - remove it from the queue Worker->nfiles.removeAt(i); Worker->ofiles.removeAt(i); i--; } } } if(!Worker->isRM && Worker->overwrite==-1){ //Check if the new files already exist, and prompt for action QStringList existing; for(int i=0; infiles.length(); i++){ if(QFile::exists(Worker->nfiles[i])){ existing << Worker->nfiles[i].section("/",-1); } } if(!existing.isEmpty()){ //Prompt for whether to overwrite, not overwrite, or cancel QMessageBox::StandardButton ans = QMessageBox::question(this, tr("Overwrite Files?"), tr("Do you want to overwrite the existing files?")+"\n"+tr("Note: It will just add a number to the filename otherwise.")+"\n\n"+existing.join(", "), QMessageBox::YesToAll | QMessageBox::NoToAll | QMessageBox::Cancel, QMessageBox::NoToAll); if(ans==QMessageBox::NoToAll){ Worker->overwrite = 0; } //don't overwrite else if(ans==QMessageBox::YesToAll){ Worker->overwrite = 1; } //overwrite else{ qDebug() << " - Cancelled"; Worker->overwrite = -1; ok = false; } //cancel operations if(DEBUG){ qDebug() << " - Overwrite:" << Worker->overwrite; } } } QApplication::processEvents(); QApplication::processEvents(); return ok; } void FODialog::UpdateItem(int cur, int tot, QString oitem, QString nitem){ ui->progressBar->setRange(0,tot); ui->progressBar->setValue(cur); ui->progressBar->setVisible(true); QString msg; if(Worker->isRM){ msg = tr("Removing: %1"); } else if(Worker->isCP){ msg = tr("Copying: %1 to %2"); } else if(Worker->isRESTORE){ msg = tr("Restoring: %1 as %2"); } else if(Worker->isMV){ msg = tr("Moving: %1 to %2"); } if(msg.contains("%2")){ msg = msg.arg(oitem.section("/",-1), nitem.section("/",-1)); }else{ msg = msg.arg(oitem.section("/",-1)); } msg = ui->label->fontMetrics().elidedText(msg, Qt::ElideRight, ui->label->width()); ui->label->setText( msg ); } void FODialog::WorkDone(QStringList errlist){ if(!errlist.isEmpty()){ QString msg; if(Worker->isRM){ msg = tr("Could not remove these files:"); } else if(Worker->isCP){ msg = tr("Could not copy these files:"); } else if(Worker->isRESTORE){ msg = tr("Could not restore these files:"); } else if(Worker->isMV){ msg = tr("Could not move these files:"); } QMessageBox::warning(this, tr("File Errors"), msg+"\n\n"+errlist.join("\n")); } noerrors = errlist.isEmpty(); this->close(); } void FODialog::on_push_stop_clicked(){ Worker->stopped = true; } // =================== // ==== FOWorker Class ==== // =================== QStringList FOWorker::subfiles(QString dirpath, bool dirsfirst){ //NOTE: dirpath (input) is always the first/last item in the output as well! QStringList out; if(dirsfirst){ out << dirpath; } if( QFileInfo(dirpath).isDir() ){ QDir dir(dirpath); if(dirsfirst){ //Now recursively add any subdirectories and their contents QStringList subdirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden, QDir::NoSort); for(int i=0; i