diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 6f16a2b9f..c165d69a0 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -667,41 +667,47 @@ void MainWindow::contributors() void MainWindow::sdsync() { + QString sdPath = g.profile[g.id()].sdPath(); + if (sdPath.isEmpty()) { + QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No SD directory configured!")); + return; + } QString massstoragePath = findMassstoragePath("SOUNDS"); if (massstoragePath.isEmpty()) { QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No Radio connected!")); return; } - massstoragePath += "/.."; + massstoragePath = massstoragePath.left(massstoragePath.length() - 7); ProgressDialog progressDialog(this, tr("Synchronize SD"), CompanionIcon("sdsync.png")); SyncProcess syncProcess(massstoragePath, g.profile[g.id()].sdPath(), progressDialog.progress()); - syncProcess.run(); - progressDialog.exec(); + if (!syncProcess.run()) { + progressDialog.exec(); + } } void MainWindow::changelog() { - ReleaseNotesDialog * dialog = new ReleaseNotesDialog(this); - dialog->exec(); + ReleaseNotesDialog * dialog = new ReleaseNotesDialog(this); + dialog->exec(); } void MainWindow::fwchangelog() { - Firmware *currfirm = GetCurrentFirmware(); - QString rn=currfirm->getReleaseNotesUrl(); - if (rn.isEmpty()) { - QMessageBox::information(this, tr("Firmware updates"), tr("Current firmware does not provide release notes informations.")); - } - else { - ReleaseNotesFirmwareDialog * dialog = new ReleaseNotesFirmwareDialog(this, rn); - dialog->exec(); - } + Firmware * firmware = GetCurrentFirmware(); + QString url = firmware->getReleaseNotesUrl(); + if (url.isEmpty()) { + QMessageBox::information(this, tr("Firmware updates"), tr("Current firmware does not provide release notes informations.")); + } + else { + ReleaseNotesFirmwareDialog * dialog = new ReleaseNotesFirmwareDialog(this, url); + dialog->exec(); + } } void MainWindow::customizeSplash() { - customizeSplashDialog *cd = new customizeSplashDialog(this); - cd->exec(); + customizeSplashDialog * dialog = new customizeSplashDialog(this); + dialog->exec(); } void MainWindow::cut() diff --git a/companion/src/process_sync.cpp b/companion/src/process_sync.cpp index 50e3e8f47..3b1df0c30 100755 --- a/companion/src/process_sync.cpp +++ b/companion/src/process_sync.cpp @@ -5,119 +5,127 @@ #include #include #include +#include +#include -SyncProcess::SyncProcess(const QString &folder1, const QString &folder2, ProgressWidget *progress): -folder1(folder1), -folder2(folder2), -progress(progress), -simulation(false), -index(0) +SyncProcess::SyncProcess(const QString & folder1, const QString & folder2, ProgressWidget * progress): + folder1(folder1), + folder2(folder2), + progress(progress), + index(0), + count(0), + closed(false) { + connect(progress, SIGNAL(stopped()),this, SLOT(onClosed())); } -void SyncProcess::run() +void SyncProcess::onClosed() { - simulation = true; - index = 0; - if (synchronize()) { - int count = index; - progress->setMaximum(count); - simulation = false; - index = 0; - synchronize(); - progress->setValue(count); - } + closed = true; } -bool SyncProcess::synchronize() +bool SyncProcess::run() { if (!QFile::exists(folder1)) { QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder1)); - return false; + return true; } + if (!QFile::exists(folder2)) { QMessageBox::warning(NULL, QObject::tr("Synchronization error"), QObject::tr("The directory '%1' doesn't exist!").arg(folder2)); - return false; + return true; } + + count = getFilesCount(folder1) + getFilesCount(folder2); + progress->setMaximum(count); + QStringList errors = updateDir(folder1, folder2) + updateDir(folder2, folder1); if (errors.count() > 0) { QMessageBox::warning(NULL, QObject::tr("Synchronization error"), errors.join("\n")); - return false; } - return true; + + // don't close the window unless the user wanted + return closed; } -QStringList SyncProcess::updateDir(const QDir &source, const QDir &destination) +int SyncProcess::getFilesCount(const QString & directory) +{ + int result = 0; + QDirIterator it(directory, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + result++; + } + return result; +} + +QStringList SyncProcess::updateDir(const QString & source, const QString & destination) { QDirIterator it(source, QDirIterator::Subdirectories); - while (it.hasNext()) { - if (!simulation) { - progress->setValue(index); - } - QString path = it.next(); - // qDebug() << path; - QFileInfo sourceInfo(path); - QString relativePath = source.relativeFilePath(path); - QString destinationPath = destination.absoluteFilePath(relativePath); - QFileInfo destinationInfo(destinationPath); - if (sourceInfo.isDir()) { - if (!destinationInfo.exists()) { - ++index; - if (!simulation) { - progress->addText(tr("Create directory %1\n").arg(destinationPath)); - if (!destination.mkdir(relativePath)) { - errors << QObject::tr("Create '%1' failed").arg(destinationPath); - continue; - } - } - } - } - else { - if (!destinationInfo.exists()) { - // qDebug() << "Copy" << path << "to" << destinationPath; - ++index; - if (!simulation) { - progress->addText(tr("Copy %1 to %2\n").arg(path).arg(destinationPath)); - if (!QFile::copy(path, destinationPath)) { - errors << QObject::tr("Copy '%1' to '%2' failed").arg(path).arg(destinationPath); - continue; - } - } - } - else if (sourceInfo.lastModified() > destinationInfo.lastModified()) { - ++index; - if (!simulation) { - progress->addText(tr("Read %1\n").arg(path)); - // retrieve source contents - QFile sourceFile(path); - if (!sourceFile.open(QFile::ReadOnly)) { - errors << QObject::tr("Open '%1' failed").arg(path); - continue; - } - QString sourceContents = sourceFile.readAll(); - sourceFile.close(); - // try to retrieve destination contents - QFile destinationFile(path); - if (destinationFile.open(QFile::ReadOnly)) { - QString destinationContents = destinationFile.readAll(); - destinationFile.close(); - if (sourceContents == destinationContents) { - // qDebug() << "Skip" << path; - continue; - } - } - if (!destinationFile.open(QFile::WriteOnly)) { - errors << QObject::tr("Write '%1' failed").arg(destinationPath); - continue; - } - progress->addText(tr("Write %1\n").arg(destinationPath)); - // qDebug() << "Write" << destinationPath; - QTextStream destinationStream(&destinationFile); - destinationStream << sourceContents; - destinationFile.close(); - } - } + while (!closed && it.hasNext()) { + QEventLoop loop; + QTimer::singleShot(10, &loop, SLOT(quit())); + loop.exec(); + index++; + progress->setInfo(tr("%1/%2 files").arg(index).arg(count)); + progress->setValue(index); + QString result = updateEntry(it.next(), source, destination); + if (!result.isEmpty()) { + errors << result; } } return errors; } + +QString SyncProcess::updateEntry(const QString & path, const QDir & source, const QDir & destination) +{ + QFileInfo sourceInfo(path); + QString relativePath = source.relativeFilePath(path); + QString destinationPath = destination.absoluteFilePath(relativePath); + QFileInfo destinationInfo(destinationPath); + if (sourceInfo.isDir()) { + if (!destinationInfo.exists()) { + progress->addText(tr("Create directory %1\n").arg(destinationPath)); + if (!destination.mkdir(relativePath)) { + return QObject::tr("Create '%1' failed").arg(destinationPath); + } + } + } + else { + if (!destinationInfo.exists()) { + // qDebug() << "Copy" << path << "to" << destinationPath; + progress->addText(tr("Copy %1 to %2\n").arg(path).arg(destinationPath)); + if (!QFile::copy(path, destinationPath)) { + return QObject::tr("Copy '%1' to '%2' failed").arg(path).arg(destinationPath); + } + } + else if (sourceInfo.lastModified() > destinationInfo.lastModified()) { + // retrieve source contents + QFile sourceFile(path); + if (!sourceFile.open(QFile::ReadOnly)) { + return QObject::tr("Open '%1' failed").arg(path); + } + QString sourceContents = sourceFile.readAll(); + sourceFile.close(); + // try to retrieve destination contents + QFile destinationFile(path); + if (destinationFile.open(QFile::ReadOnly)) { + QString destinationContents = destinationFile.readAll(); + destinationFile.close(); + if (sourceContents == destinationContents) { + // qDebug() << "Skip" << path; + return QString(); + } + } + if (!destinationFile.open(QFile::WriteOnly)) { + return QObject::tr("Write '%1' failed").arg(destinationPath); + } + progress->addText(tr("Write %1\n").arg(destinationPath)); + // qDebug() << "Write" << destinationPath; + QTextStream destinationStream(&destinationFile); + destinationStream << sourceContents; + destinationFile.close(); + } + } + return QString(); +} diff --git a/companion/src/process_sync.h b/companion/src/process_sync.h index d5949f5de..0835d933d 100755 --- a/companion/src/process_sync.h +++ b/companion/src/process_sync.h @@ -1,7 +1,6 @@ #ifndef SYNCPROCESS_H_ #define SYNCPROCESS_H_ -#include #include #include @@ -10,21 +9,26 @@ class ProgressWidget; class SyncProcess : public QObject { - Q_OBJECT + Q_OBJECT -public: - SyncProcess(const QString &folder1, const QString &folder2, ProgressWidget *progress); - void run(); + public: + SyncProcess(const QString & folder1, const QString & folder2, ProgressWidget * progress); + bool run(); -protected: - bool synchronize(); - QStringList updateDir(const QDir &source, const QDir &destination); - QString folder1; - QString folder2; - ProgressWidget *progress; - QStringList errors; - bool simulation; - int index; + protected slots: + void onClosed(); + + protected: + int getFilesCount(const QString & directory); + QStringList updateDir(const QString & source, const QString & destination); + QString updateEntry(const QString & path, const QDir & source, const QDir & destination); + QString folder1; + QString folder2; + ProgressWidget * progress; + QStringList errors; + int index; + int count; + bool closed; }; #endif /* SYNCPROCESS_H_ */ diff --git a/companion/src/progressdialog.cpp b/companion/src/progressdialog.cpp index d4e793af4..57f016d37 100755 --- a/companion/src/progressdialog.cpp +++ b/companion/src/progressdialog.cpp @@ -23,7 +23,7 @@ ProgressDialog::~ProgressDialog() delete ui; } -ProgressWidget *ProgressDialog::progress() +ProgressWidget * ProgressDialog::progress() { return ui->outputProgress; } @@ -31,6 +31,7 @@ ProgressWidget *ProgressDialog::progress() void ProgressDialog::on_closeButton_clicked() { if (!locked) { + ui->outputProgress->stop(); close(); } } diff --git a/companion/src/progressdialog.h b/companion/src/progressdialog.h index 59e688f0e..1547f08d2 100755 --- a/companion/src/progressdialog.h +++ b/companion/src/progressdialog.h @@ -18,7 +18,7 @@ public: ProgressDialog(QWidget *parent, const QString &label, const QIcon &icon, bool forceOpen=false); ~ProgressDialog(); - ProgressWidget *progress(); + ProgressWidget * progress(); private slots: void on_closeButton_clicked(); diff --git a/companion/src/progresswidget.cpp b/companion/src/progresswidget.cpp index 9c19aa01e..472af5ca9 100755 --- a/companion/src/progresswidget.cpp +++ b/companion/src/progresswidget.cpp @@ -29,6 +29,11 @@ ProgressWidget::~ProgressWidget() delete ui; } +void ProgressWidget::stop() +{ + emit stopped(); +} + void ProgressWidget::forceOpen() { ui->checkBox->hide(); diff --git a/companion/src/progresswidget.h b/companion/src/progresswidget.h index ba1007963..19d4500cd 100755 --- a/companion/src/progresswidget.h +++ b/companion/src/progresswidget.h @@ -24,10 +24,12 @@ class ProgressWidget : public QWidget void setProgressColor(const QColor &color); void addSeparator(); void forceOpen(); + void stop(); signals: void detailsToggled(); void locked(bool); + void stopped(); protected slots: void on_checkBox_toggled(bool checked);