AMScanConfiguration *AMScanActionInfo::getConfigurationFromDb() const { // no need to bother if we don't have a scan id to use if(scanID_ == -1) return 0; //NULL // turn off automatic raw-data loading for scans... This will make loading the scan to access it's config much faster. bool scanAutoLoadingOn = AMScan::autoLoadData(); AMScan::setAutoLoadData(false); // Dynamically create and load a detailed subclass of AMDbObject from the database... whatever type it is. AMDbObject* dbo = AMDbObjectSupport::s()->createAndLoadObjectAt(AMDatabase::database("user"), AMDbObjectSupport::s()->tableNameForClass<AMScan>(), scanID_); if(!dbo) { AMErrorMon::alert(this, AMSCANACTIONINFO_CANNOT_LOAD_FROM_DB, "Could not load scan from the database."); return 0; //NULL } // restore AMScan's auto-loading of data to whatever it was before. AMScan::setAutoLoadData(scanAutoLoadingOn); // Is it a scan? AMScan* scan = qobject_cast<AMScan*>( dbo ); if(!scan) { AMErrorMon::alert(this, AMSCANACTIONINFO_DB_OBJECT_NOT_A_SCAN, "Object loaded from the database was not a scan."); dbo->deleteLater(); return 0; //NULL } // Does the scan have a configuration? AMScanConfiguration* config = scan->scanConfiguration(); if(!config) { AMErrorMon::alert(this, AMSCANACTIONINFO_SCAN_HAS_NO_CONFIGURATION, "Scan does not have a valid scan configuration."); scan->deleteLater(); return 0; //NULL } // need to create a copy of the config so we can delete the scan (and hence the config instance owned by the scan). The view will take ownership of the copy. config = config->createCopy(); scan->deleteLater(); if(!config) { AMErrorMon::alert(this, AMSCANACTIONINFO_CREATE_CONFIGURATION_COPY_FAILED, "Failed to create a copy of the scan configuration."); } return config; }
void AMExportController::continueScanExport() { if(state_ != Exporting) return; // done, or paused. Don't keep going. // 0. emit progress and signals emit progressChanged(exportScanIndex_, scanCount()); // 1. Check for finished: if(exportScanIndex_ >= scanCount()) { emit stateChanged(state_ = Finished); // Reset whether the exporter should overwrite files with matching filenames. exporter_->setOverwriteOption(AMExporter::Default); QString message = "Exported " % QString::number(succeededCount()) % " scans."; if(failedCount()) message.append(" (" % QString::number(failedCount()) % " scans could not be exported.)"); AMErrorMon::report(AMErrorReport(this, AMErrorReport::Information, 0, message)); AMUser::user()->setLastExportDestination(destinationFolderPath()); AMUser::user()->storeToDb(AMUser::user()->database()); deleteLater(); return; // We're done! } try { // 2. Load scan from db and check loaded successfully AMScan* scan = 0; AMDbObject* databaseObject = 0; if(usingScanURLs_){ const QUrl& url = scanURLsToExport_.at(exportScanIndex_); AMDatabase* db = 0; QStringList path; QString tableName; int id = 0; bool idOkay = false; // parse the URL and make sure it's valid if(!( url.scheme() == "amd" && (db = AMDatabase::database(url.host())) && (path = url.path().split('/', QString::SkipEmptyParts)).count() == 2 && (id = path.at(1).toInt(&idOkay)) > 0 && idOkay == true && (tableName = path.at(0)).isEmpty() == false )) throw QString("The export system couldn't understand the scan URL '" % url.toString() % "', so this scan has not been exported."); emit statusChanged(status_ = "Opening: " % url.toString()); databaseObject = AMDbObjectSupport::s()->createAndLoadObjectAt(db, tableName, id); scan = qobject_cast<AMScan*>(databaseObject); if(!scan) { databaseObject->deleteLater(); throw QString("The export system couldn't load a scan out of the database (" % url.toString() % "), so this scan has not been exported."); } } else if(usingScanObjects_) { scan = scanObjectsToExport_.at(exportScanIndex_); if(!scan) throw QString("An invalid scan reference was provided, so this scan has not been exported."); } emit statusChanged(status_ = "Opening: " % scan->name()); // this is kinda pointless... emit statusChanged(status_ = "Writing: " % scan->fullName()); // 3. Check that it can be exported with the exporter and option selected if(!exporter_->isValidFor(scan, option_)) { QString err("The exporter '" % exporter_->description() % "' and the template '" % option_->name() % "' are not compatible with this scan (" % scan->fullName() % "), so it has not been exported."); emit statusChanged(status_ = err); if (usingScanURLs_) scan->deleteLater(); throw err; } // 4. Export // 4.1 check and create the export folder for the current run QString destinationFolderPathWithRun = destinationFolderPath_; exporter_->setCurrentScan(scan); // we must set this, otherwise we can't get the name of the current run QString currentRunExportFilePath = exporter_->currentRunExportFilePath(); if(currentRunExportFilePath.length() > 0) { QDir exportDir; exportDir.setCurrent(destinationFolderPath_); if (!exportDir.entryList(QDir::AllDirs).contains(currentRunExportFilePath)) { if(!exportDir.mkdir(currentRunExportFilePath)){ QString err("Could not create the export folder." % exportDir.absolutePath()); emit statusChanged(status_ = err); throw err; } } destinationFolderPathWithRun = destinationFolderPathWithRun % "/" % currentRunExportFilePath; } // 4.2 export QString writtenFile = exporter_->exportScan(scan, destinationFolderPathWithRun, option_, exportScanIndex_); if(writtenFile.isNull()) { QString err("Export failed for scan '" % scan->fullName() % " to " % destinationFolderPathWithRun % "'."); emit statusChanged(status_ = err); if (usingScanURLs_) scan->deleteLater(); throw err; } emit statusChanged(status_ = "Wrote: " % writtenFile); succeededCount_++; if (usingScanURLs_) scan->deleteLater(); } catch(QString errMsg) { failedCount_++; AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, -1, errMsg)); } // 5. increment exportScanIndex_ and re-schedule next one exportScanIndex_++; QTimer::singleShot(5, this, SLOT(continueScanExport())); }