diff --git a/src/Athlete.cpp b/src/Athlete.cpp index c7d2c272a..eb9f3c502 100644 --- a/src/Athlete.cpp +++ b/src/Athlete.cpp @@ -121,8 +121,9 @@ Athlete::Athlete(Context *context, const QDir &homeDir) } } - // read athlete's autoimport configuration + // read athlete's autoimport configuration and initialize the autoimport process autoImportConfig = new RideAutoImportConfig(home->config()); + autoImport = NULL; // read athlete's charts.xml and translate etc loadCharts(); @@ -230,6 +231,9 @@ Athlete::~Athlete() delete zones_; delete hrzones_; for (int i=0; i<2; i++) delete pacezones_[i]; + delete autoImportConfig; + delete autoImport; + } void Athlete::selectRideFile(QString fileName) @@ -343,16 +347,15 @@ Athlete::configChanged(qint32 state) void Athlete::importFilesWhenOpeningAthlete() { + autoImport = NULL; // just do it if something is configured if (autoImportConfig->hasRules()) { - RideImportWizard *import = new RideImportWizard(autoImportConfig, context); + autoImport = new RideImportWizard(autoImportConfig, context); // only process the popup if we have any files available at all - if ( import->getNumberOfFiles() > 0) { - import->process(); - } else { - delete import; + if ( autoImport->getNumberOfFiles() > 0) { + autoImport->process(); } } } diff --git a/src/Athlete.h b/src/Athlete.h index 6590386a4..1c53bd70d 100644 --- a/src/Athlete.h +++ b/src/Athlete.h @@ -51,6 +51,7 @@ class PMCData; class LTMSettings; class Routes; class AthleteDirectoryStructure; +class RideImportWizard; class RideAutoImportConfig; class RideCache; class IntervalCache; @@ -118,7 +119,8 @@ class Athlete : public QObject CalDAV *davCalendar; #endif - // Athlete's autoimport configuration + // Athlete's autoimport handling + RideImportWizard *autoImport; RideAutoImportConfig *autoImportConfig; // ride metadata definitions diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index e597593dd..01f63ca19 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -1015,20 +1015,32 @@ MainWindow::closeEvent(QCloseEvent* event) { QList closing = tabList; bool needtosave = false; + bool importrunning = false; // close all the tabs .. if any refuse we need to ignore // the close event foreach(Tab *tab, closing) { - // do we need to save? - if (tab->context->mainWindow->saveRideExitDialog(tab->context) == true) - removeTab(tab); - else - needtosave = true; + // check for if RideImport is is process and let it finalize / or be stopped by the user + if (tab->context->athlete->autoImport) { + if (tab->context->athlete->autoImport->importInProcess() ) { + importrunning = true; + QMessageBox::information(this, tr("Activity Import"), tr("Closing of athlete window not possible while background activity import is in progress...")); + } + } + + // only check for unsaved if autoimport is not running any more + if (!importrunning) { + // do we need to save? + if (tab->context->mainWindow->saveRideExitDialog(tab->context) == true) + removeTab(tab); + else + needtosave = true; + } } - // were any left hanging around? - if (needtosave) event->ignore(); + // were any left hanging around? or autoimport in action on any windows, then don't close any + if (needtosave || importrunning) event->ignore(); else { // finish off the job and leave @@ -1631,7 +1643,17 @@ MainWindow::openTab(QString name) void MainWindow::closeTabClicked(int index) { + Tab *tab = tabList[index]; + + // check for autoimport and let it finalize + if (tab->context->athlete->autoImport) { + if (tab->context->athlete->autoImport->importInProcess() ) { + QMessageBox::information(this, tr("Activity Import"), tr("Closing of athlete window not possible while background activity import is in progress...")); + return; + } + } + if (saveRideExitDialog(tab->context) == false) return; // lets wipe it @@ -1641,6 +1663,14 @@ MainWindow::closeTabClicked(int index) bool MainWindow::closeTab() { + // check for autoimport and let it finalize + if (currentTab->context->athlete->autoImport) { + if (currentTab->context->athlete->autoImport->importInProcess() ) { + QMessageBox::information(this, tr("Activity Import"), tr("Closing of athlete window not possible while background activity import is in progress...")); + return false; + } + } + // wipe it down ... if (saveRideExitDialog(currentTab->context) == false) return false; diff --git a/src/RideAutoImportConfig.cpp b/src/RideAutoImportConfig.cpp index 487bb6772..b88aa6a20 100644 --- a/src/RideAutoImportConfig.cpp +++ b/src/RideAutoImportConfig.cpp @@ -35,6 +35,10 @@ RideAutoImportRule::RideAutoImportRule() { _ruleDescriptions.append(tr("Autoimport with dialog - past 90 days")); _ruleDescriptions.append(tr("Autoimport with dialog - past 180 days")); _ruleDescriptions.append(tr("Autoimport with dialog - past 360 days")); + _ruleDescriptions.append(tr("Autoimport in background")); + _ruleDescriptions.append(tr("Autoimport in background - past 90 days")); + _ruleDescriptions.append(tr("Autoimport in background - past 180 days")); + _ruleDescriptions.append(tr("Autoimport in background - past 360 days")); } diff --git a/src/RideAutoImportConfig.h b/src/RideAutoImportConfig.h index 2053abaca..a67573460 100644 --- a/src/RideAutoImportConfig.h +++ b/src/RideAutoImportConfig.h @@ -30,7 +30,8 @@ class RideAutoImportRule { public: static QList rules; - enum ImportRule { noImport=0, importAll=1, importLast90days=2, importLast180days=3, importLast360days=4 }; + enum ImportRule { noImport=0, importAll=1, importLast90days=2, importLast180days=3, importLast360days=4, + importBackgroundAll=5, importBackground90=6, importBackground180=7, importBackground360=8 }; RideAutoImportRule(); diff --git a/src/RideImportWizard.cpp b/src/RideImportWizard.cpp index f843b01dc..e4e573007 100644 --- a/src/RideImportWizard.cpp +++ b/src/RideImportWizard.cpp @@ -41,29 +41,42 @@ // drag and drop passes urls ... convert to a list of files and call main constructor RideImportWizard::RideImportWizard(QList *urls, Context *context, QWidget *parent) : QDialog(parent), context(context) { + _importInProcess = true; setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); QList filenames; for (int i=0; icount(); i++) filenames.append(QFileInfo(urls->value(i).toLocalFile()).absoluteFilePath()); autoImportMode = false; + autoImportStealth = false; init(filenames, context); filenames.clear(); + _importInProcess = false; + } RideImportWizard::RideImportWizard(QList files, Context *context, QWidget *parent) : QDialog(parent), context(context) { + _importInProcess = true; + setAttribute(Qt::WA_DeleteOnClose); autoImportMode = false; + autoImportStealth = false; init(files, context); + _importInProcess = false; + } RideImportWizard::RideImportWizard(RideAutoImportConfig *dirs, Context *context, QWidget *parent) : QDialog(parent), context(context), importConfig(dirs) { + _importInProcess = true; autoImportMode = true; + autoImportStealth = true; + + if (autoImportStealth) hide(); QList files; - // get the directories + // get the directories & rules QList rules = importConfig->getConfig(); // prepare the widget to show the status of the directory @@ -142,16 +155,30 @@ RideImportWizard::RideImportWizard(RideAutoImportConfig *dirs, Context *context, QDate selectAfter = QDate::currentDate(); switch(rule.getImportRule()) { case RideAutoImportRule::importLast90days: + case RideAutoImportRule::importBackground90: selectAfter = selectAfter.addDays(Q_INT64_C(-90)); break; case RideAutoImportRule::importLast180days: + case RideAutoImportRule::importBackground180: selectAfter = selectAfter.addDays(Q_INT64_C(-180)); break; case RideAutoImportRule::importLast360days: + case RideAutoImportRule::importBackground360: selectAfter = selectAfter.addDays(Q_INT64_C(-360)); break; } + // if any of the rules says "with Dialog" then we keep the dialog - if not it's stealth + switch (rule.getImportRule()) { + + case RideAutoImportRule::importAll: + case RideAutoImportRule::importLast90days: + case RideAutoImportRule::importLast180days: + case RideAutoImportRule::importLast360days: + autoImportStealth = false; + break; + } + // now get the files with their full names QFileInfoList fileInfos = importDir->entryInfoList(allFormats, QDir::Files, QDir::NoSort); if (!fileInfos.isEmpty()) { @@ -160,12 +187,16 @@ RideImportWizard::RideImportWizard(RideAutoImportConfig *dirs, Context *context, // append following the import rules switch (rule.getImportRule()) { case RideAutoImportRule::importAll: + case RideAutoImportRule::importBackgroundAll: files.append(f.absoluteFilePath()); j++; break; case RideAutoImportRule::importLast90days: case RideAutoImportRule::importLast180days: case RideAutoImportRule::importLast360days: + case RideAutoImportRule::importBackground90: + case RideAutoImportRule::importBackground180: + case RideAutoImportRule::importBackground360: if (f.created().date() >= selectAfter || f.lastModified().date() >= selectAfter) { files.append(f.absoluteFilePath()); j++; @@ -190,6 +221,9 @@ RideImportWizard::RideImportWizard(RideAutoImportConfig *dirs, Context *context, init(files, context); + _importInProcess = false; + + } @@ -379,9 +413,14 @@ int RideImportWizard::process() { + // import process is starting + _importInProcess = true; + // Make visible and put in front prior to running down the list & processing... - if (!isActiveWindow()) activateWindow(); - this->show(); + if (!autoImportStealth) { + if (!isActiveWindow()) activateWindow(); + this->show(); + } // set progress bar limits - for each file we // will make 5 passes over the files @@ -427,7 +466,7 @@ RideImportWizard::process() } - if (aborted) { done(0); } + if (aborted) { done(0); return 0; } repaint(); QApplication::processEvents(); @@ -447,7 +486,7 @@ RideImportWizard::process() tableWidget->setCurrentCell(i,5); QApplication::processEvents(); - if (aborted) { done(0); } + if (aborted) { done(0); return 0; } this->repaint(); QApplication::processEvents(); @@ -611,7 +650,7 @@ RideImportWizard::process() } progressBar->setValue(progressBar->value()+1); QApplication::processEvents(); - if (aborted) { done(0); } + if (aborted) { done(0); return 0; } this->repaint(); next:; @@ -637,8 +676,13 @@ RideImportWizard::process() progressBar->repaint(); } // get it on top to save / correct missing dates - if (!isActiveWindow()) activateWindow(); - + if (autoImportStealth && needdates > 0) { + // leave the stealth mode + this->show(); + activateWindow(); + } else { + if (!isActiveWindow()) activateWindow(); + } // Wait for user to press save abortButton->setText(tr("Save")); aborted = false; @@ -656,8 +700,8 @@ RideImportWizard::process() // without user intervention abortButton->setDisabled(false); + if (autoImportStealth) abortClicked(); // simulate "Save" by User - // abortClicked(); } else { // de-activate Save button until the dates and times are sorted @@ -856,6 +900,10 @@ RideImportWizard::abortClicked() if (label == tr("Finish")) { // phew. our work is done. -- lets force an update stats... hide(); + if (autoImportStealth) { + // inform the user that the work is done + QMessageBox::information(NULL, tr("Auto Import"), tr("Automatic import from defined directories is completed.")); + } done(0); return; } @@ -914,7 +962,7 @@ RideImportWizard::abortClicked() tableWidget->item(i,5)->setText(tr("Saving...")); tableWidget->setCurrentCell(i,5); QApplication::processEvents(); - if (aborted) { done(0); } + if (aborted) { done(0); return; } this->repaint(); @@ -1021,7 +1069,7 @@ RideImportWizard::abortClicked() delete ride; QApplication::processEvents(); - if (aborted) { done(0); } + if (aborted) { done(0); return; } progressBar->setValue(progressBar->value()+1); this->repaint(); } @@ -1040,8 +1088,12 @@ RideImportWizard::abortClicked() progressBar->setValue(progressBar->maximum()); phaseLabel->setText(donemessage); abortButton->setText(tr("Finish")); - if (!isActiveWindow()) activateWindow(); aborted = false; + if (autoImportStealth) { + abortClicked(); // simulate pressing the "Finish" button - even if the window got visible + } else { + if (!isActiveWindow()) activateWindow(); + } } @@ -1068,6 +1120,23 @@ RideImportWizard::moveFile(const QString &source, const QString &target) { } + +void +RideImportWizard::closeEvent(QCloseEvent* event) +{ + if (_importInProcess) + event->ignore(); + else + event->accept(); +} + +void +RideImportWizard::done(int rc) +{ + _importInProcess = false; + QDialog::done(rc); +} + // clean up files RideImportWizard::~RideImportWizard() { diff --git a/src/RideImportWizard.h b/src/RideImportWizard.h index a2ac1e013..ae69cdb82 100644 --- a/src/RideImportWizard.h +++ b/src/RideImportWizard.h @@ -48,10 +48,13 @@ public: RideImportWizard(RideAutoImportConfig *dirs, Context *context, QWidget *parent = 0); ~RideImportWizard(); + void closeEvent(QCloseEvent*); + void done(int); + int getNumberOfFiles(); // get the number of files selected for processing int process(); - -signals: + bool importInProcess() { return _importInProcess; } + bool isAutoImport() { return autoImportMode;} private slots: void abortClicked(); @@ -72,6 +75,8 @@ private: QDir tmpActivities; // activitiy .JSON is stored here until rideCache() update was successfull bool aborted; bool autoImportMode; + bool autoImportStealth; + bool _importInProcess; QLabel *phaseLabel; QTableWidget *tableWidget; QTableWidget *directoryWidget;