diff --git a/Libs/Core/ctkAbstractJob.cpp b/Libs/Core/ctkAbstractJob.cpp index feff3ab5cc..1e1e6115b7 100644 --- a/Libs/Core/ctkAbstractJob.cpp +++ b/Libs/Core/ctkAbstractJob.cpp @@ -213,20 +213,15 @@ void ctkAbstractJob::setRunningThreadID(QString runningThreadID) } //---------------------------------------------------------------------------- -QString ctkAbstractJob::loggedText() const +QString ctkAbstractJob::log() const { - return this->LoggedText; + return this->Log; } //---------------------------------------------------------------------------- -void ctkAbstractJob::addLoggedText(QString loggedText) +void ctkAbstractJob::addLog(QString log) { - if (loggedText.isEmpty()) - { - return; - } - - this->LoggedText += loggedText; + this->Log += log; } //---------------------------------------------------------------------------- diff --git a/Libs/Core/ctkAbstractJob.h b/Libs/Core/ctkAbstractJob.h index 7ce7b70a79..7354716be7 100644 --- a/Libs/Core/ctkAbstractJob.h +++ b/Libs/Core/ctkAbstractJob.h @@ -55,7 +55,7 @@ class CTK_CORE_EXPORT ctkAbstractJob : public QObject Q_PROPERTY(QDateTime startDateTime READ startDateTime); Q_PROPERTY(QDateTime completionDateTime READ completionDateTime); Q_PROPERTY(QString runningThreadID READ runningThreadID WRITE setRunningThreadID); - Q_PROPERTY(QString loggedText READ loggedText WRITE addLoggedText); + Q_PROPERTY(QString log READ log); Q_PROPERTY(bool destroyAfterUse READ destroyAfterUse WRITE setDestroyAfterUse); public: @@ -158,8 +158,8 @@ class CTK_CORE_EXPORT ctkAbstractJob : public QObject ///@{ /// Logged Text - QString loggedText() const; - void addLoggedText(QString loggedText); + QString log() const; + void addLog(QString log); ///@} /// Generate worker for job @@ -179,10 +179,10 @@ class CTK_CORE_EXPORT ctkAbstractJob : public QObject Q_INVOKABLE virtual QVariant toVariant(); /// Free used resources from job after worker is done - Q_INVOKABLE virtual void freeUsedResources() = 0; + Q_INVOKABLE virtual void releaseResources() = 0; ///@{ - /// Destroy job pointer after worker is done + /// Destroy job object after worker is done /// default: false bool destroyAfterUse() const; void setDestroyAfterUse(bool destroyAfterUse); @@ -208,7 +208,7 @@ class CTK_CORE_EXPORT ctkAbstractJob : public QObject QDateTime StartDateTime; QDateTime CompletionDateTime; QString RunningThreadID; - QString LoggedText; + QString Log; bool DestroyAfterUse; private: @@ -227,7 +227,7 @@ struct CTK_CORE_EXPORT ctkJobDetail { this->StartDateTime = job.startDateTime().toString("HH:mm:ss.zzz ddd dd MMM yyyy"); this->CompletionDateTime = job.completionDateTime().toString("HH:mm:ss.zzz ddd dd MMM yyyy"); this->RunningThreadID = job.runningThreadID(); - this->Logging = job.loggedText(); + this->Logging = job.log(); } virtual ~ctkJobDetail() = default; diff --git a/Libs/Core/ctkCorePythonQtDecorators.h b/Libs/Core/ctkCorePythonQtDecorators.h index 94224dc5d6..d22363477f 100644 --- a/Libs/Core/ctkCorePythonQtDecorators.h +++ b/Libs/Core/ctkCorePythonQtDecorators.h @@ -27,8 +27,9 @@ // CTK includes #include // For ctkJobDetail #include -#include #include +#include +#include #include #include @@ -39,6 +40,8 @@ // for non-static methods. // +static ctkLogger logger("org.commontk.core.ctkCorePythonQtDecorators"); + /// \ingroup Core class ctkCorePythonQtDecorators : public QObject { @@ -245,64 +248,147 @@ public Q_SLOTS: void setJobClass(ctkJobDetail* td, const QString& jobClass) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setJobClass - Invalid ctkJobDetail"); + return; + } + td->JobClass = jobClass; } QString jobClass(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::jobClass - Invalid ctkJobDetail"); + return ""; + } + return td->JobClass; } void setJobUID(ctkJobDetail* td, const QString& jobUID) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setJobUID - Invalid ctkJobDetail"); + return; + } + td->JobUID = jobUID; } QString JobUID(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::JobUID - Invalid ctkJobDetail"); + return ""; + } + return td->JobUID; } - void setCreationDateTime(ctkJobDetail* td, QString creationDateTime) + + void setCreationDateTime(ctkJobDetail* td, QString creationDateTime) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setCreationDateTime - Invalid ctkJobDetail"); + return; + } + td->CreationDateTime = creationDateTime; } - QString creationDateTime(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::creationDateTime - Invalid ctkJobDetail"); + return ""; + } + return td->CreationDateTime; } void setStartDateTime(ctkJobDetail* td, QString startDateTime) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setStartDateTime - Invalid ctkJobDetail"); + return; + } + td->StartDateTime = startDateTime; } QString startDateTime(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::startDateTime - Invalid ctkJobDetail"); + return ""; + } + return td->StartDateTime; } void setCompletionDateTime(ctkJobDetail* td, QString completionDateTime) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setCompletionDateTime - Invalid ctkJobDetail"); + return; + } + td->CompletionDateTime = completionDateTime; } QString completionDateTime(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::completionDateTime - Invalid ctkJobDetail"); + return ""; + } + return td->CompletionDateTime; } void setRunningThreadID(ctkJobDetail* td, QString runningThreadID) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setRunningThreadID - Invalid ctkJobDetail"); + return; + } + td->RunningThreadID = runningThreadID; } QString runningThreadID(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::runningThreadID - Invalid ctkJobDetail"); + return ""; + } + return td->RunningThreadID; } void setLogging(ctkJobDetail* td, QString logging) { + if (td == nullptr) + { + logger.error("ctkJobDetail::setLogging - Invalid ctkJobDetail"); + return; + } td->Logging = logging; } QString logging(ctkJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkJobDetail::logging - Invalid ctkJobDetail"); + return ""; + } + return td->Logging; } }; diff --git a/Libs/Core/ctkJobScheduler.cpp b/Libs/Core/ctkJobScheduler.cpp index 7ecdbdb3c9..3495b7516a 100644 --- a/Libs/Core/ctkJobScheduler.cpp +++ b/Libs/Core/ctkJobScheduler.cpp @@ -65,7 +65,7 @@ void ctkJobSchedulerPrivate::init() } //------------------------------------------------------------------------------ -void ctkJobSchedulerPrivate::onQueueJobsInThreadPool() +void ctkJobSchedulerPrivate::queueJobsInThreadPool() { Q_Q(ctkJobScheduler); @@ -74,6 +74,9 @@ void ctkJobSchedulerPrivate::onQueueJobsInThreadPool() return; } + // No need to queue jobs with a signal/slot mechanism, since the mutex makes + // sure that concurrent threads append/clean/delete the jobs map. + { // The QMutexLocker is enclosed within brackets to restrict its scope and // prevent conflicts with other QMutexLockers within the scheduler's methods. @@ -190,7 +193,7 @@ bool ctkJobSchedulerPrivate::insertJob(QSharedPointer job) } emit q->jobInitialized(job->toVariant()); - this->onQueueJobsInThreadPool(); + this->queueJobsInThreadPool(); return true; } @@ -211,10 +214,10 @@ bool ctkJobSchedulerPrivate::cleanJob(const QString &jobUID) return false; } - job->freeUsedResources(); + job->releaseResources(); } - this->onQueueJobsInThreadPool(); + this->queueJobsInThreadPool(); return true; } @@ -223,7 +226,7 @@ void ctkJobSchedulerPrivate::cleanJobs(const QStringList &jobUIDs) { Q_Q(ctkJobScheduler); - QList datas; + QList dataObjects; { // The QMutexLocker is enclosed within brackets to restrict its scope and // prevent conflicts with other QMutexLockers within the scheduler's methods. @@ -237,12 +240,12 @@ void ctkJobSchedulerPrivate::cleanJobs(const QStringList &jobUIDs) continue; } - datas.append(job->toVariant()); - job->freeUsedResources(); + dataObjects.append(job->toVariant()); + job->releaseResources(); } } - emit q->jobUserStopped(datas); + emit q->jobUserStopped(dataObjects); } //------------------------------------------------------------------------------ @@ -274,14 +277,14 @@ bool ctkJobSchedulerPrivate::removeJob(const QString& jobUID) this->JobsQueue.remove(jobUID); } - this->onQueueJobsInThreadPool(); + this->queueJobsInThreadPool(); return true; } //------------------------------------------------------------------------------ void ctkJobSchedulerPrivate::removeJobs(const QStringList &jobUIDs) { - QList datas; + QList dataObjects; { // The QMutexLocker is enclosed within brackets to restrict its scope and // prevent conflicts with other QMutexLockers within the scheduler's methods. @@ -295,7 +298,7 @@ void ctkJobSchedulerPrivate::removeJobs(const QStringList &jobUIDs) continue; } - datas.append(job->toVariant()); + dataObjects.append(job->toVariant()); QMap connections = this->JobsConnections.value(jobUID); QObject::disconnect(connections.value("started")); @@ -720,7 +723,7 @@ bool ctkJobScheduler::retryJob(const QString &jobUID) job->setStatus(ctkAbstractJob::JobStatus::Initialized); emit this->jobInitialized(job->toVariant()); - d->onQueueJobsInThreadPool(); + d->queueJobsInThreadPool(); return true; } diff --git a/Libs/Core/ctkJobScheduler_p.h b/Libs/Core/ctkJobScheduler_p.h index 66fe453d53..d6313f2f0c 100644 --- a/Libs/Core/ctkJobScheduler_p.h +++ b/Libs/Core/ctkJobScheduler_p.h @@ -44,9 +44,6 @@ class CTK_CORE_EXPORT ctkJobSchedulerPrivate : public QObject protected: ctkJobScheduler* const q_ptr; -public Q_SLOTS: - virtual void onQueueJobsInThreadPool(); - public: ctkJobSchedulerPrivate(ctkJobScheduler& object); virtual ~ctkJobSchedulerPrivate(); @@ -59,9 +56,10 @@ public Q_SLOTS: virtual void cleanJobs(const QStringList& jobUIDs); virtual bool removeJob(const QString& jobUID); virtual void removeJobs(const QStringList& jobUIDs); - int getSameTypeJobsInThreadPoolQueueOrRunning(QSharedPointer job); - QString generateUniqueJobUID(); - void clearBactchedJobsLists(); + virtual int getSameTypeJobsInThreadPoolQueueOrRunning(QSharedPointer job); + virtual QString generateUniqueJobUID(); + virtual void queueJobsInThreadPool(); + virtual void clearBactchedJobsLists(); QMutex QueueMutex; diff --git a/Libs/DICOM/Core/ctkDICOMCorePythonQtDecorators.h b/Libs/DICOM/Core/ctkDICOMCorePythonQtDecorators.h index b32ff144d1..03f9b81045 100644 --- a/Libs/DICOM/Core/ctkDICOMCorePythonQtDecorators.h +++ b/Libs/DICOM/Core/ctkDICOMCorePythonQtDecorators.h @@ -24,6 +24,9 @@ // PythonQt includes #include +// CTK Core includes +#include + // CTK includes #include #include @@ -37,6 +40,8 @@ // for non-static methods. // +static ctkLogger logger("org.commontk.core.ctkDICOMCorePythonQtDecorators"); + /// \ingroup DICOM_Core class ctkDICOMCorePythonQtDecorators : public QObject { @@ -60,138 +65,276 @@ public slots: return new ctkDICOMJobDetail(); } - void setJobClass(ctkDICOMJobDetail* td, QString jobClass) - { - td->JobClass = jobClass; - } - QString jobClass(ctkDICOMJobDetail* td) - { - return td->JobClass; - } - - void setJobUID(ctkDICOMJobDetail* td, QString jobUID) - { - td->JobUID = jobUID; - } - QString jobUID(ctkDICOMJobDetail* td) - { - return td->JobUID; - } - void setPatientID(ctkDICOMJobDetail* td, const QString& patientID) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setPatientID - Invalid ctkJobDetail"); + return; + } + td->PatientID = patientID; } QString patientID(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::patientID - Invalid ctkJobDetail"); + return ""; + } + return td->PatientID; } void setStudyInstanceUID(ctkDICOMJobDetail* td, const QString& studyInstanceUID) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setStudyInstanceUID - Invalid ctkJobDetail"); + return; + } + td->StudyInstanceUID = studyInstanceUID; } QString studyInstanceUID(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::studyInstanceUID - Invalid ctkJobDetail"); + return ""; + } + return td->StudyInstanceUID; } void setSeriesInstanceUID(ctkDICOMJobDetail* td, const QString& seriesInstanceUID) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setSeriesInstanceUID - Invalid ctkJobDetail"); + return; + } + td->SeriesInstanceUID = seriesInstanceUID; } QString seriesInstanceUID(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::seriesInstanceUID - Invalid ctkJobDetail"); + return ""; + } + return td->SeriesInstanceUID; } void setSOPInstanceUID(ctkDICOMJobDetail* td, const QString& sopInstanceUID) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setSOPInstanceUID - Invalid ctkJobDetail"); + return; + } + td->SOPInstanceUID = sopInstanceUID; } QString sopInstanceUID(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::sopInstanceUID - Invalid ctkJobDetail"); + return ""; + } + return td->SOPInstanceUID; } void setReferenceInserterJobUID(ctkDICOMJobDetail* td, const QString& referenceInserterJobUID) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setReferenceInserterJobUID - Invalid ctkJobDetail"); + return; + } + td->ReferenceInserterJobUID = referenceInserterJobUID; } QString referenceInserterJobUID(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::referenceInserterJobUID - Invalid ctkJobDetail"); + return ""; + } + return td->ReferenceInserterJobUID; } void setQueriedPatientIDs(ctkDICOMJobDetail* td, const QStringList& queriedPatientIDs) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setQueriedPatientIDs - Invalid ctkJobDetail"); + return; + } + td->QueriedPatientIDs = queriedPatientIDs; } QStringList queriedPatientIDs(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::queriedPatientIDs - Invalid ctkJobDetail"); + return QStringList(); + } + return td->QueriedPatientIDs; } void setQueriedStudyInstanceUIDs(ctkDICOMJobDetail* td, const QStringList& queriedStudyInstanceUIDs) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setQueriedStudyInstanceUIDs - Invalid ctkJobDetail"); + return; + } + td->QueriedStudyInstanceUIDs = queriedStudyInstanceUIDs; } QStringList queriedStudyInstanceUIDs(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::queriedStudyInstanceUIDs - Invalid ctkJobDetail"); + return QStringList(); + } + return td->QueriedStudyInstanceUIDs; } void setQueriedSeriesInstanceUIDs(ctkDICOMJobDetail* td, const QStringList& queriedSeriesInstanceUIDs) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setQueriedSeriesInstanceUIDs - Invalid ctkJobDetail"); + return; + } + td->QueriedSeriesInstanceUIDs = queriedSeriesInstanceUIDs; } QStringList queriedSeriesInstanceUIDs(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::queriedSeriesInstanceUIDs - Invalid ctkJobDetail"); + return QStringList(); + } + return td->QueriedSeriesInstanceUIDs; } void setQueriedSOPInstanceUIDs(ctkDICOMJobDetail* td, const QStringList& queriedSOPInstanceUIDs) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setQueriedSOPInstanceUIDs - Invalid ctkJobDetail"); + return; + } + td->QueriedSOPInstanceUIDs = queriedSOPInstanceUIDs; } QStringList queriedSOPInstanceUIDs(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::queriedSOPInstanceUIDs - Invalid ctkJobDetail"); + return QStringList(); + } + return td->QueriedSOPInstanceUIDs; } void setConnectionName(ctkDICOMJobDetail* td, const QString& connectionName) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setConnectionName - Invalid ctkJobDetail"); + return; + } + td->ConnectionName = connectionName; } QString connectionName(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::connectionName - Invalid ctkJobDetail"); + return ""; + } + return td->ConnectionName; } void setDICOMLevel(ctkDICOMJobDetail* td, ctkDICOMJob::DICOMLevels level) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setDICOMLevel - Invalid ctkJobDetail"); + return; + } + td->DICOMLevel = level; } ctkDICOMJob::DICOMLevels DICOMLevel(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::DICOMLevel - Invalid ctkJobDetail"); + return ctkDICOMJob::DICOMLevels::None; + } + return td->DICOMLevel; } void setJobType(ctkDICOMJobDetail* td, ctkDICOMJobResponseSet::JobType jobType) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setJobType - Invalid ctkJobDetail"); + return; + } + td->JobType = jobType; } ctkDICOMJobResponseSet::JobType jobType(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::jobType - Invalid ctkJobDetail"); + return ctkDICOMJobResponseSet::JobType::None; + } + return td->JobType; } void setNumberOfDataSets(ctkDICOMJobDetail* td, int numberOfDataSets) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::setNumberOfDataSets - Invalid ctkJobDetail"); + return; + } + td->NumberOfDataSets = numberOfDataSets; } int numberOfDataSets(ctkDICOMJobDetail* td) { + if (td == nullptr) + { + logger.error("ctkDICOMJobDetail::numberOfDataSets - Invalid ctkJobDetail"); + return -1; + } + return td->NumberOfDataSets; } diff --git a/Libs/DICOM/Core/ctkDICOMEcho.cpp b/Libs/DICOM/Core/ctkDICOMEcho.cpp index 14ba5081c9..e9bd798fc6 100644 --- a/Libs/DICOM/Core/ctkDICOMEcho.cpp +++ b/Libs/DICOM/Core/ctkDICOMEcho.cpp @@ -33,6 +33,9 @@ #include /* for class OFStandard */ #include +//------------------------------------------------------------------------------ +// Using dcmtk root log4cplus logger instead of ctkLogger because with ctkDICOMJobsAppender (dcmtk::log4cplus::Appender), +// logging is filtered by threadID and reported in the GUI per job. dcmtk::log4cplus::Logger rootLogEcho = dcmtk::log4cplus::Logger::getRoot(); //------------------------------------------------------------------------------ @@ -66,11 +69,6 @@ class ctkDICOMEchoPrivate //------------------------------------------------------------------------------ ctkDICOMEchoPrivate::ctkDICOMEchoPrivate() { - this->ConnectionName = ""; - this->CallingAETitle = ""; - this->CalledAETitle = ""; - this->Host = ""; - this->JobUID = ""; this->Port = 80; OFList transferSyntaxes; @@ -188,17 +186,17 @@ bool ctkDICOMEcho::echo() if (!d->SCU->initNetwork().good()) { - QString error = ctkDICOMEcho::tr("Error initializing the network"); + QString error = "Error initializing the network"; DCMTK_LOG4CPLUS_ERROR_STR(rootLogEcho, error.toStdString().c_str()); return false; } - QString debug = ctkDICOMEcho::tr("Negotiating Association"); + QString debug = "Negotiating Association"; DCMTK_LOG4CPLUS_DEBUG_STR(rootLogEcho, debug.toStdString().c_str()); OFCondition result = d->SCU->negotiateAssociation(); if (result.bad()) { - QString error = ctkDICOMEcho::tr("Error negotiating the association: ") + QString(result.text()); + QString error = "Error negotiating the association: " + QString(result.text()); DCMTK_LOG4CPLUS_ERROR_STR(rootLogEcho, error.toStdString().c_str()); return false; } @@ -208,19 +206,19 @@ bool ctkDICOMEcho::echo() "" /* don't care about transfer syntax */); if (d->PresentationContext == 0) { - QString error = ctkDICOMEcho::tr("ECHO Request failed: No valid verification Presentation Context available"); + QString error = "ECHO Request failed: No valid verification Presentation Context available"; DCMTK_LOG4CPLUS_ERROR_STR(rootLogEcho, error.toStdString().c_str()); d->releaseAssociation(); return false; } - QString info = ctkDICOMEcho::tr("Seding Echo"); + QString info = "Seding Echo"; DCMTK_LOG4CPLUS_INFO_STR(rootLogEcho, info.toStdString().c_str()); // Issue ECHO request and let scu find presentation context itself (0) OFCondition status = d->SCU->sendECHORequest(d->PresentationContext); if (!status.good()) { - QString error = ctkDICOMEcho::tr("Echo failed"); + QString error = "Echo failed"; DCMTK_LOG4CPLUS_ERROR_STR(rootLogEcho, error.toStdString().c_str()); d->releaseAssociation(); return false; diff --git a/Libs/DICOM/Core/ctkDICOMEchoJob.cpp b/Libs/DICOM/Core/ctkDICOMEchoJob.cpp index ec0d48282a..7d9550225d 100644 --- a/Libs/DICOM/Core/ctkDICOMEchoJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMEchoJob.cpp @@ -93,8 +93,8 @@ QString ctkDICOMEchoJob::loggerReport(const QString& status) .arg(status); QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Core/ctkDICOMInserterJob.cpp b/Libs/DICOM/Core/ctkDICOMInserterJob.cpp index 8bfdac7919..61dc97e3c4 100644 --- a/Libs/DICOM/Core/ctkDICOMInserterJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMInserterJob.cpp @@ -34,7 +34,6 @@ static ctkLogger logger ("org.commontk.dicom.DICOMInserterJob"); //------------------------------------------------------------------------------ ctkDICOMInserterJob::ctkDICOMInserterJob() { - this->DatabaseFilename = ""; this->MaximumConcurrentJobsPerType = 1; } @@ -66,8 +65,8 @@ QString ctkDICOMInserterJob::loggerReport(const QString& status) } QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } diff --git a/Libs/DICOM/Core/ctkDICOMJob.cpp b/Libs/DICOM/Core/ctkDICOMJob.cpp index f97fe73988..6b8b78b7b3 100644 --- a/Libs/DICOM/Core/ctkDICOMJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMJob.cpp @@ -37,11 +37,6 @@ static ctkLogger logger ("org.commontk.dicom.DICOMJob"); ctkDICOMJob::ctkDICOMJob() { this->DICOMLevel = DICOMLevels::None; - this->PatientID = ""; - this->StudyInstanceUID = ""; - this->SeriesInstanceUID = ""; - this->SOPInstanceUID = ""; - this->ReferenceInserterJobUID = ""; } //------------------------------------------------------------------------------ @@ -186,7 +181,7 @@ QVariant ctkDICOMJob::toVariant() } //------------------------------------------------------------------------------ -void ctkDICOMJob::freeUsedResources() +void ctkDICOMJob::releaseResources() { this->JobResponseSets.clear(); } diff --git a/Libs/DICOM/Core/ctkDICOMJob.h b/Libs/DICOM/Core/ctkDICOMJob.h index 9d2014380c..ade12b6aa7 100644 --- a/Libs/DICOM/Core/ctkDICOMJob.h +++ b/Libs/DICOM/Core/ctkDICOMJob.h @@ -118,8 +118,8 @@ class CTK_DICOM_CORE_EXPORT ctkDICOMJob : public ctkAbstractJob Q_INVOKABLE virtual QVariant toVariant() override; /// Free used resources from job - /// \sa ctkAbstractJob::freeUsedResources - Q_INVOKABLE virtual void freeUsedResources() override; + /// \sa ctkAbstractJob::releaseResources + Q_INVOKABLE virtual void releaseResources() override; Q_SIGNALS: void progressJobDetail(QVariant); diff --git a/Libs/DICOM/Core/ctkDICOMJobResponseSet.cpp b/Libs/DICOM/Core/ctkDICOMJobResponseSet.cpp index 554cce0b12..390c2b714b 100644 --- a/Libs/DICOM/Core/ctkDICOMJobResponseSet.cpp +++ b/Libs/DICOM/Core/ctkDICOMJobResponseSet.cpp @@ -69,15 +69,8 @@ ctkDICOMJobResponseSetPrivate::ctkDICOMJobResponseSetPrivate(ctkDICOMJobResponse : q_ptr(&obj) { this->JobType = ctkDICOMJobResponseSet::JobType::None; - this->JobUID = ""; - this->PatientID = ""; - this->StudyInstanceUID = ""; - this->SeriesInstanceUID = ""; - this->SOPInstanceUID = ""; - this->ConnectionName = ""; this->CopyFile = false; this->OverwriteExistingDataset = false; - this->FilePath = ""; } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Core/ctkDICOMQuery.cpp b/Libs/DICOM/Core/ctkDICOMQuery.cpp index 3ee5bb2f64..6045c564ca 100644 --- a/Libs/DICOM/Core/ctkDICOMQuery.cpp +++ b/Libs/DICOM/Core/ctkDICOMQuery.cpp @@ -51,8 +51,29 @@ #include /* for class OFStandard */ #include /* for class DicomDirInterface */ +//------------------------------------------------------------------------------ +// Using dcmtk root log4cplus logger instead of ctkLogger because with ctkDICOMJobsAppender (dcmtk::log4cplus::Appender), +// logging is filtered by threadID and reported in the GUI per job. dcmtk::log4cplus::Logger rootLogQuery = dcmtk::log4cplus::Logger::getRoot(); +#define LOG_AND_EMIT_DEBUG(debugStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debugStr.toStdString().c_str()); \ + emit signal(debugStr); \ +} \ + +#define LOG_AND_EMIT_WARN(warnStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_WARN_STR(rootLogQuery, warnStr.toStdString().c_str()); \ + emit signal(warnStr); \ +} \ + +#define LOG_AND_EMIT_ERROR(errorStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, errorStr.toStdString().c_str()); \ + emit signal(errorStr); \ +} \ + //------------------------------------------------------------------------------ // A customized implementation so that Qt signals can be emitted // when query results are obtained @@ -82,9 +103,7 @@ class ctkDICOMQuerySCUPrivate : public DcmSCU return EC_IllegalCall; } - QString debug = ctkDICOMQuery::tr("FIND RESPONSE"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit this->query->debug(/*no tr*/"Got a find response!"); + LOG_AND_EMIT_DEBUG(QString("FIND RESPONSE"), this->query->debug); return this->DcmSCU::handleFINDResponse(presID, response, waitForNextResponse); }; }; @@ -295,24 +314,19 @@ QList> ctkDICOMQuery::jobResponseSetsShar bool ctkDICOMQuery::query(ctkDICOMDatabase& database) { Q_D(ctkDICOMQuery); - // In the following, we emit progress(int) after progress(QString), this - // is in case the connected object doesn't refresh its ui when the progress - // message is updated but only if the progress value is (e.g. QProgressDialog) if (database.database().isOpen()) { - QString debug = ctkDICOMQuery::tr("DB open in Query"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("DB open in Query"), debug); } else { - QString warn = ctkDICOMQuery::tr("DB not open in Query"); - DCMTK_LOG4CPLUS_WARN_STR(rootLogQuery, warn.toStdString().c_str()); - emit progress(warn); + LOG_AND_EMIT_WARN(QString("DB not open in Query"), warn); } + emit progress(0); if (d->Canceled) { + emit done(false); return false; } @@ -322,6 +336,7 @@ bool ctkDICOMQuery::query(ctkDICOMDatabase& database) // initSCU if (!this->initializeSCU()) { + emit done(false); return false; } @@ -349,49 +364,45 @@ bool ctkDICOMQuery::query(ctkDICOMDatabase& database) QString seriesDescription = this->applyFilters(d->Filters); if (d->Canceled) { + emit done(false); return false; } OFList responses; - Uint16 presentationContext = 0; // Check for any accepted presentation context for FIND in study root (don't care about transfer syntax) presentationContext = d->SCU->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel, ""); if (presentationContext == 0) { - QString error = ctkDICOMQuery::tr("Failed to find acceptable presentation context"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Failed to find acceptable presentation context"), error); } else { - QString debug = ctkDICOMQuery::tr("Found useful presentation context"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Found useful presentation context"), debug) } + emit progress(40); if (d->Canceled) { + emit done(false); return false; } OFCondition status = d->SCU->sendFINDRequest(presentationContext, d->QueryDcmDataset.data(), &responses); if (!status.good()) { - QString error = ctkDICOMQuery::tr("Find failed"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find failed"), error); d->releaseAssociation(); - emit progress(100); + emit done(false); return false; } - QString debug = ctkDICOMQuery::tr("Find succeeded"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded"), debug) + emit progress(50); if (d->Canceled) { + emit done(false); return false; } @@ -404,10 +415,11 @@ bool ctkDICOMQuery::query(ctkDICOMDatabase& database) OFString StudyInstanceUID; dataset->findAndGetOFString(DCM_StudyInstanceUID, StudyInstanceUID); d->addStudyInstanceUIDAndDataset(StudyInstanceUID.c_str(), dataset); - emit progress(tr("Processing: ") + QString(StudyInstanceUID.c_str())); + emit progress("Processing: " + QString(StudyInstanceUID.c_str())); emit progress(50); if (d->Canceled) { + emit done(false); return false; } } @@ -440,13 +452,12 @@ bool ctkDICOMQuery::query(ctkDICOMDatabase& database) studyDataset->findAndGetElement(DCM_PatientName, patientName); studyDataset->findAndGetElement(DCM_PatientID, patientID); - QString debug = ctkDICOMQuery::tr("Starting Series C-FIND for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Starting Series C-FIND for Study: %1").arg(studyInstanceUID), debug) emit progress(50 + (progressRatio * i++)); if (d->Canceled) { - return false; + emit done(false); + return false; } d->QueryDcmDataset->putAndInsertString (DCM_StudyInstanceUID, studyInstanceUID.toStdString().c_str()); @@ -470,29 +481,28 @@ bool ctkDICOMQuery::query(ctkDICOMDatabase& database) } } - QString debug = ctkDICOMQuery::tr("Find succeeded on Series level for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded on Series level for Study: %1").arg(studyInstanceUID), debug) emit progress(50 + (progressRatio * i++)); if (d->Canceled) { - return false; + emit done(false); + return false; } } else { - QString error = ctkDICOMQuery::tr("Find on Series level failed for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find on Series level failed for Study: %1").arg(studyInstanceUID), error) } emit progress(50 + (progressRatio * i++)); if (d->Canceled) { + emit done(false); return false; } } d->releaseAssociation(); emit progress(100); + emit done(true); return true; } @@ -501,12 +511,10 @@ bool ctkDICOMQuery::queryPatients() { Q_D(ctkDICOMQuery); - // In the following, we emit progress(int) after progress(QString), this - // is in case the connected object doesn't refresh its ui when the progress - // message is updated but only if the progress value is (e.g. QProgressDialog) emit progress(0); if (d->Canceled) { + emit done(false); return false; } @@ -515,6 +523,7 @@ bool ctkDICOMQuery::queryPatients() // initSCU if (!this->initializeSCU()) { + emit done(false); return false; } @@ -536,6 +545,7 @@ bool ctkDICOMQuery::queryPatients() this->applyFilters(filters); if (d->Canceled) { + emit done(false); return false; } @@ -544,28 +554,24 @@ bool ctkDICOMQuery::queryPatients() presentationContext = d->SCU->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel, ""); if (presentationContext == 0) { - QString error = ctkDICOMQuery::tr("Failed to find acceptable presentation context"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Failed to find acceptable presentation context"), error) } else { - QString debug = ctkDICOMQuery::tr("Found useful presentation context"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Found useful presentation context"), debug) } emit progress(40); if (d->Canceled) { + emit done(false); return false; } - QString debug = ctkDICOMQuery::tr("Starting Patients C-FIND"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Starting Patients C-FIND"), debug) emit progress(50); if (d->Canceled) { + emit done(false); return false; } @@ -586,10 +592,8 @@ bool ctkDICOMQuery::queryPatients() contResponses++; if (contResponses > d->MaximumPatientsQuery) { - QString warn = ctkDICOMQuery::tr("The number of responses of the query task at patients level " - "surpassed the maximum value of permitted results (i.e. %1).").arg(d->MaximumPatientsQuery); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, warn.toStdString().c_str()); - emit progress(warn); + LOG_AND_EMIT_WARN(QString("The number of responses of the query task at patients level " + "surpassed the maximum value of permitted results (i.e. %1).").arg(d->MaximumPatientsQuery), warn) break; } DcmDataset *dataset = (*it)->m_dataset; @@ -603,32 +607,28 @@ bool ctkDICOMQuery::queryPatients() if (contResponses == 0) { - QString warn = ctkDICOMQuery::tr("The patients query provided no results. Please refine your filters."); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, warn.toStdString().c_str()); - emit progress(warn); + LOG_AND_EMIT_WARN(QString("The patients query provided no results. Please refine your filters."), warn) } JobResponseSet->setDatasets(datasetsMap); d->JobResponseSets.append(JobResponseSet); - QString debug = ctkDICOMQuery::tr("Find succeeded on Patient level"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded on Patient level"), debug) } else { - QString error = ctkDICOMQuery::tr("Find on Patient level failed"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find on Patient level failed"), error) } emit progress(100); if (d->Canceled) { + emit done(false); return false; } d->releaseAssociation(); + emit done(true); return true; } @@ -636,12 +636,11 @@ bool ctkDICOMQuery::queryPatients() bool ctkDICOMQuery::queryStudies(const QString& patientID) { Q_D(ctkDICOMQuery); - // In the following, we emit progress(int) after progress(QString), this - // is in case the connected object doesn't refresh its ui when the progress - // message is updated but only if the progress value is (e.g. QProgressDialog) + emit progress(0); if (d->Canceled) { + emit done(false); return false; } @@ -650,6 +649,7 @@ bool ctkDICOMQuery::queryStudies(const QString& patientID) // initSCU if (!this->initializeSCU()) { + emit done(false); return false; } @@ -684,6 +684,7 @@ bool ctkDICOMQuery::queryStudies(const QString& patientID) this->applyFilters(filters); if (d->Canceled) { + emit done(false); return false; } @@ -692,28 +693,24 @@ bool ctkDICOMQuery::queryStudies(const QString& patientID) presentationContext = d->SCU->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel, ""); if (presentationContext == 0) { - QString error = ctkDICOMQuery::tr("Failed to find acceptable presentation context"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Failed to find acceptable presentation context"), error); } else { - QString debug = ctkDICOMQuery::tr("Found useful presentation context"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Found useful presentation context"), debug); } emit progress(40); if (d->Canceled) { + emit done(false); return false; } - QString debug = ctkDICOMQuery::tr("Starting Studies C-FIND for Patient: ") + patientID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Starting Studies C-FIND for Patient: %1").arg(patientID), debug) emit progress(50); if (d->Canceled) { + emit done(false); return false; } @@ -746,24 +743,22 @@ bool ctkDICOMQuery::queryStudies(const QString& patientID) JobResponseSet->setDatasets(datasetsMap); d->JobResponseSets.append(JobResponseSet); - QString debug = ctkDICOMQuery::tr("Find succeeded on Study level for Patient: ") + patientID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded on Study level for Patient: %1").arg(patientID), debug) } else { - QString error = ctkDICOMQuery::tr("Find on Study level failed for Patient: ") + patientID; - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find on Study level failed for Patient: %1").arg(patientID), error) } emit progress(100); if (d->Canceled) { + emit done(false); return false; } d->releaseAssociation(); + emit done(true); return true; } @@ -773,12 +768,10 @@ bool ctkDICOMQuery::querySeries(const QString& patientID, { Q_D(ctkDICOMQuery); - // In the following, we emit progress(int) after progress(QString), this - // is in case the connected object doesn't refresh its ui when the progress - // message is updated but only if the progress value is (e.g. QProgressDialog) emit progress(0); if (d->Canceled) { + emit done(false); return false; } @@ -787,6 +780,7 @@ bool ctkDICOMQuery::querySeries(const QString& patientID, // initSCU if (!this->initializeSCU()) { + emit done(false); return false; } @@ -811,6 +805,7 @@ bool ctkDICOMQuery::querySeries(const QString& patientID, QString seriesDescription = this->applyFilters(filters); if (d->Canceled) { + emit done(false); return false; } @@ -823,28 +818,24 @@ bool ctkDICOMQuery::querySeries(const QString& patientID, presentationContext = d->SCU->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel, ""); if (presentationContext == 0) { - QString error = ctkDICOMQuery::tr("Failed to find acceptable presentation context"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Failed to find acceptable presentation context"), error); } else { - QString debug = ctkDICOMQuery::tr("Found useful presentation context"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Found useful presentation context"), debug); } emit progress(40); if (d->Canceled) { + emit done(false); return false; } - QString debug = ctkDICOMQuery::tr("Starting Series C-FIND for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Starting Series C-FIND for Study: %1").arg(studyInstanceUID), debug) emit progress(50); if (d->Canceled) { + emit done(false); return false; } @@ -879,24 +870,22 @@ bool ctkDICOMQuery::querySeries(const QString& patientID, JobResponseSet->setDatasets(datasetsMap); d->JobResponseSets.append(JobResponseSet); - QString debug = ctkDICOMQuery::tr("Find succeeded on Series level for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded on Series level for Study: %1").arg(studyInstanceUID), debug) } else { - QString error = ctkDICOMQuery::tr("Find on Series level failed for Study: ") + studyInstanceUID; - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find on Series level failed for Study: %1").arg(studyInstanceUID), error) } emit progress(100); if (d->Canceled) { + emit done(false); return false; } d->releaseAssociation(); + emit done(true); return true; } @@ -907,12 +896,10 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, { Q_D(ctkDICOMQuery); - // In the following, we emit progress(int) after progress(QString), this - // is in case the connected object doesn't refresh its ui when the progress - // message is updated but only if the progress value is (e.g. QProgressDialog) emit progress(0); if (d->Canceled) { + emit done(false); return false; } @@ -921,6 +908,7 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, // initSCU if (!this->initializeSCU()) { + emit done(false); return false; } @@ -942,6 +930,7 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, QString seriesDescription = this->applyFilters(filters); if (d->Canceled) { + emit done(false); return false; } @@ -953,28 +942,24 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, d->PresentationContext = d->SCU->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel, ""); if (d->PresentationContext == 0) { - QString error = ctkDICOMQuery::tr("Failed to find acceptable presentation context"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Failed to find acceptable presentation context"), error) } else { - QString debug = ctkDICOMQuery::tr("Found useful presentation context"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Found useful presentation context"), debug) } emit progress(40); if (d->Canceled) { + emit done(false); return false; } - QString debug = ctkDICOMQuery::tr("Starting Instances C-FIND for Series: ") + seriesInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Starting Instances C-FIND for Series: %1").arg(seriesInstanceUID), debug) emit progress(50); if (d->Canceled) { + emit done(false); return false; } @@ -1008,15 +993,11 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, } } - QString debug = ctkDICOMQuery::tr("Find succeeded on Series level for Series: ") + seriesInstanceUID; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Find succeeded on Series level for Series: %1").arg(seriesInstanceUID), debug) } else { - QString error = ctkDICOMQuery::tr("Find on Series level failed for Series: ") + seriesInstanceUID; - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); + LOG_AND_EMIT_ERROR(QString("Find on Series level failed for Series: %1").arg(seriesInstanceUID), error) } JobResponseSet->setDatasets(datasetsMap); @@ -1025,10 +1006,12 @@ bool ctkDICOMQuery::queryInstances(const QString& patientID, emit progress(100); if (d->Canceled) { + emit done(false); return false; } d->releaseAssociation(); + emit done(true); return true; } @@ -1062,9 +1045,7 @@ bool ctkDICOMQuery::initializeSCU() d->SCU->setPeerHostName(OFString(this->host().toStdString().c_str())); d->SCU->setPeerPort(this->port()); - QString debug = ctkDICOMQuery::tr("Setting Transfer Syntaxes"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Setting Transfer Syntaxes"), debug) emit progress(10); if (d->Canceled) { @@ -1079,16 +1060,11 @@ bool ctkDICOMQuery::initializeSCU() d->SCU->addPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel, transferSyntaxes); if (!d->SCU->initNetwork().good()) { - QString error = ctkDICOMQuery::tr("Error initializing the network"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); - emit progress(100); + LOG_AND_EMIT_ERROR(QString("Error initializing the network"), error) return false; } - debug = ctkDICOMQuery::tr("Negotiating Association"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Negotiating Association"), debug) emit progress(20); if (d->Canceled) { @@ -1098,10 +1074,7 @@ bool ctkDICOMQuery::initializeSCU() OFCondition result = d->SCU->negotiateAssociation(); if (result.bad()) { - QString error = ctkDICOMQuery::tr("Error negotiating the association: ") + QString(result.text()); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogQuery, error.toStdString().c_str()); - emit progress(error); - emit progress(100); + LOG_AND_EMIT_ERROR(QString("Error negotiating the association: %1").arg(result.text()), error) return false; } @@ -1154,10 +1127,7 @@ QString ctkDICOMQuery::applyFilters(QMap filters) } modalitySearch.chop(1); // remove final backslash - QString debug = ctkDICOMQuery::tr("modalityInStudySearch ") + modalitySearch; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); - + LOG_AND_EMIT_DEBUG(QString("modalityInStudySearch %1").arg(modalitySearch), debug) d->QueryDcmDataset->putAndInsertString(DCM_ModalitiesInStudy, modalitySearch.toLatin1().data()); } // Remember Series Description for later series query if we go through the keys now @@ -1168,9 +1138,7 @@ QString ctkDICOMQuery::applyFilters(QMap filters) } else { - QString debug = ctkDICOMQuery::tr("Ignoring unknown search key: ") + key; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Ignoring unknown search key: %1").arg(key), debug) } } @@ -1182,9 +1150,7 @@ QString ctkDICOMQuery::applyFilters(QMap filters) filters["EndDate"].toString(); d->QueryDcmDataset->putAndInsertString (DCM_StudyDate, dateRange.toLatin1().data()); - QString debug = ctkDICOMQuery::tr("Query on study date ") + dateRange; - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogQuery, debug.toStdString().c_str()); - emit progress(debug); + LOG_AND_EMIT_DEBUG(QString("Query on study date: %1").arg(dateRange), debug) } emit progress(30); diff --git a/Libs/DICOM/Core/ctkDICOMQuery.h b/Libs/DICOM/Core/ctkDICOMQuery.h index 379c31b304..07ed6a436e 100644 --- a/Libs/DICOM/Core/ctkDICOMQuery.h +++ b/Libs/DICOM/Core/ctkDICOMQuery.h @@ -176,6 +176,8 @@ class CTK_DICOM_CORE_EXPORT ctkDICOMQuery : public QObject /// Signal is emitted inside the query() function. It sends /// detailed feedback for debugging void debug(const QString& message); + /// Signal is emitted inside the query() function. It send any warning messages + void warn(const QString& message); /// Signal is emitted inside the query() function. It send any error messages void error(const QString& message); /// Signal is emitted inside the query() function when finished with value diff --git a/Libs/DICOM/Core/ctkDICOMQueryJob.cpp b/Libs/DICOM/Core/ctkDICOMQueryJob.cpp index e6e668373c..7fd9bf77b0 100644 --- a/Libs/DICOM/Core/ctkDICOMQueryJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMQueryJob.cpp @@ -170,8 +170,8 @@ QString ctkDICOMQueryJob::loggerReport(const QString& status) QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } diff --git a/Libs/DICOM/Core/ctkDICOMRetrieve.cpp b/Libs/DICOM/Core/ctkDICOMRetrieve.cpp index 5f91e1edf5..c90478fbe4 100644 --- a/Libs/DICOM/Core/ctkDICOMRetrieve.cpp +++ b/Libs/DICOM/Core/ctkDICOMRetrieve.cpp @@ -18,8 +18,6 @@ =========================================================================*/ -#include - // Qt includes #include @@ -47,8 +45,29 @@ #include /* for DcmRLEDecoderRegistration */ #include /* for DcmRLEEncoderRegistration */ +//------------------------------------------------------------------------------ +// Using dcmtk root log4cplus logger instead of ctkLogger because with ctkDICOMJobsAppender (dcmtk::log4cplus::Appender), +// logging is filtered by threadID and reported in the GUI per job. dcmtk::log4cplus::Logger rootLogRetrieve = dcmtk::log4cplus::Logger::getRoot(); +#define LOG_AND_EMIT_DEBUG(debugStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debugStr.toStdString().c_str()); \ + emit signal(debugStr); \ +} \ + +#define LOG_AND_EMIT_WARN(warnStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_WARN_STR(rootLogRetrieve, warnStr.toStdString().c_str()); \ + emit signal(warnStr); \ +} \ + +#define LOG_AND_EMIT_ERROR(errorStr, signal) \ +{ \ + DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, errorStr.toStdString().c_str()); \ + emit signal(errorStr); \ +} \ + //------------------------------------------------------------------------------ // A customized local implementation of the DcmSCU so that Qt signals can be emitted // when retrieve results are obtained @@ -258,12 +277,6 @@ ctkDICOMRetrievePrivate::ctkDICOMRetrievePrivate(ctkDICOMRetrieve& obj) this->AssociationClosing = false; this->LastRetrieveType = ctkDICOMRetrieve::RetrieveNone; - this->PatientID = ""; - this->StudyInstanceUID = ""; - this->SeriesInstanceUID = ""; - this->ConnectionName = ""; - this->JobUID = ""; - // Register the JPEG libraries in case we need them // (registration only happens once, so it's okay to call repeatedly) // register global JPEG decompression codecs @@ -344,6 +357,8 @@ bool ctkDICOMRetrievePrivate::initializeSCU(const QString& patientID, const ctkDICOMRetrieve::RetrieveType retrieveType, DcmDataset *retrieveParameters) { + Q_Q(ctkDICOMRetrieve); + // If we like to query another server than before, be sure to disconnect first if (this->SCU->isConnected() && this->ConnectionParamsChanged) { @@ -353,28 +368,23 @@ bool ctkDICOMRetrievePrivate::initializeSCU(const QString& patientID, if (!this->SCU->isConnected()) { // Check and initialize networking parameters in DCMTK - if ( !this->SCU->initNetwork().good() ) + if (!this->SCU->initNetwork().good()) { - QString error = ctkDICOMRetrieve::tr("Error initializing the network"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Error initializing the network"), q->error); return false; } // Negotiate (i.e. start the) association - QString debug = ctkDICOMRetrieve::tr("Negotiating Association"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); - - if ( !this->SCU->negotiateAssociation().good() ) + LOG_AND_EMIT_DEBUG(QString("Negotiating Association"), q->debug); + if (!this->SCU->negotiateAssociation().good()) { - QString error = ctkDICOMRetrieve::tr("Error negotiating association"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); - return false;; + LOG_AND_EMIT_ERROR(QString("Error negotiating association"), q->error); + return false; } } this->ConnectionParamsChanged = false; // Setup query about what to be received from the PACS - QString debug = ctkDICOMRetrieve::tr("Setting Retrieve Parameters"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Setting Retrieve Parameters"), q->debug) if (retrieveType == ctkDICOMRetrieve::RetrieveSOPInstance) { retrieveParameters->putAndInsertString(DCM_QueryRetrieveLevel, "IMAGE"); @@ -438,6 +448,7 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, if (this->Canceled) { + emit q->done(false); return false; } @@ -450,40 +461,47 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, retrieveParameters)) { delete retrieveParameters; - QString error = ctkDICOMRetrieve::tr("MOVE Request failed: SCU initialization failed"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("MOVE Request failed: SCU initialization failed"), q->error) + emit q->done(false); return false; } // Issue request - QString debug = ctkDICOMRetrieve::tr("Sending Move Request"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Sending MOVE Request"), q->debug) + OFList responses; this->PresentationContext = this->SCU->findPresentationContextID( UID_MOVEStudyRootQueryRetrieveInformationModel, "" /* don't care about transfer syntax */); if (this->PresentationContext == 0) { - QString error = ctkDICOMRetrieve::tr("MOVE Request failed: No valid Study Root MOVE Presentation Context available"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("MOVE Request failed: No valid Study Root MOVE Presentation Context available"), q->error) if (!this->KeepAssociationOpen) { this->releaseAssociation(); } delete retrieveParameters; + emit q->done(false); return false; } if (this->Canceled) { + emit q->done(false); return false; } + LOG_AND_EMIT_DEBUG(QString("Found Presentation Context"), q->debug) + emit q->progress(1); + // do the actual move request OFCondition status = this->SCU->sendMOVERequest( this->PresentationContext, this->MoveDestinationAETitle.toStdString().c_str(), retrieveParameters, &responses); + LOG_AND_EMIT_DEBUG(QString("Sent MOVE Request"), q->debug) + emit q->progress(2); + // Close association if we do not want to explicitly keep it open if (!this->KeepAssociationOpen) { @@ -493,18 +511,22 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, delete retrieveParameters; // If we do not receive a single response, something is fishy - if ( responses.begin() == responses.end() ) + if (responses.begin() == responses.end()) { - QString error = ctkDICOMRetrieve::tr("No responses received at all! (at least one empty response always expected)"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("No responses received at all! (at least one empty response always expected)"), q->error) + emit q->done(false); return false; } if (this->Canceled) { + emit q->done(false); return false; } + LOG_AND_EMIT_DEBUG(QString("Got Responses"), q->debug) + emit q->progress(3); + /* The server is permitted to acknowledge every image that was received, or * to send a single move response. * If there is only a single response, this can mean the following: @@ -513,38 +535,35 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, * 3) Error code, i.e. no images transferred * 4) Warning (one or more failures, i.e. some images transferred) */ - if ( responses.size() == 1 ) + if (responses.size() == 1) { RetrieveResponse* rsp = *responses.begin(); - QString debug = ctkDICOMRetrieve::tr("MOVE response receveid with status: ")+ - QString(DU_cmoveStatusString(rsp->m_status)); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("MOVE response received with status: %1").arg(DU_cmoveStatusString(rsp->m_status)), q->debug) - if ( (rsp->m_status == STATUS_Success) + if ((rsp->m_status == STATUS_Success) || (rsp->m_status == STATUS_MOVE_Warning_SubOperationsCompleteOneOrMoreFailures)) { if (rsp->m_numberOfCompletedSubops == 0) { - QString error = ctkDICOMRetrieve::tr("No images transferred by PACS!"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); - + LOG_AND_EMIT_ERROR(QString("No images transferred by PACS!"), q->error) + emit q->done(false); return false; } } else { - QString debug = ctkDICOMRetrieve::tr("MOVE request failed, server does report error"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("MOVE request failed, server does report error"), q->debug) - QString statusDetail(ctkDICOMRetrieve::tr("No details")); + QString statusDetail("No details"); if (rsp->m_statusDetail != NULL) { std::ostringstream out; rsp->m_statusDetail->print(out); - statusDetail = ctkDICOMRetrieve::tr("Status Detail: ") + statusDetail.fromStdString(out.str()); + statusDetail = "Status Detail: " + statusDetail.fromStdString(out.str()); } - statusDetail.prepend(ctkDICOMRetrieve::tr("MOVE request failed: ")); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, statusDetail.toStdString().c_str()); + statusDetail.prepend("MOVE request failed: "); + LOG_AND_EMIT_DEBUG(statusDetail, q->debug) + emit q->done(false); return false; } } @@ -557,18 +576,19 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, it++; } - debug = ctkDICOMRetrieve::tr("MOVE responses report for study: %1\n" + LOG_AND_EMIT_DEBUG(QString("MOVE responses report for study: %1\n" "%2 images transferred, and\n" "%3 images transferred with warning, and\n" "%4 images transfers failed") .arg(studyInstanceUID) .arg(QString::number(static_cast((*it)->m_numberOfCompletedSubops))) .arg(QString::number(static_cast((*it)->m_numberOfWarningSubops))) - .arg(QString::number(static_cast((*it)->m_numberOfFailedSubops))); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + .arg(QString::number(static_cast((*it)->m_numberOfFailedSubops))), + q->debug) if (this->Canceled) { + emit q->done(false); return false; } @@ -593,6 +613,8 @@ bool ctkDICOMRetrievePrivate::move(const QString& patientID, jobResponseSet->setJobUID(q->jobUID()); q->addJobResponseSet(jobResponseSet); + emit q->progress(100); + emit q->done(true); return true; } @@ -613,6 +635,7 @@ bool ctkDICOMRetrievePrivate::get(const QString& patientID, if (this->Canceled) { + emit q->done(false); return false; } @@ -625,49 +648,50 @@ bool ctkDICOMRetrievePrivate::get(const QString& patientID, retrieveParameters)) { delete retrieveParameters; - QString error = ctkDICOMRetrieve::tr("MOVE Request failed: SCU initialization failed"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("GET Request failed: SCU initialization failed"), q->error) + emit q->done(false); return false; } if (this->Canceled) { + emit q->done(false); return false; } // Issue request - QString debug = ctkDICOMRetrieve::tr( "Sending Get Request"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); - emit q->progress(debug); + LOG_AND_EMIT_DEBUG(QString("Sending GET Request"), q->debug) emit q->progress(0); + OFList responses; this->PresentationContext = this->SCU->findPresentationContextID( UID_GETStudyRootQueryRetrieveInformationModel, "" /* don't care about transfer syntax */ ); if (this->PresentationContext == 0) { - QString error = ctkDICOMRetrieve::tr("GET Request failed: No valid Study Root GET Presentation Context available"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("GET Request failed: No valid Study Root GET Presentation Context available"), q->error) if (!this->KeepAssociationOpen) { this->releaseAssociation(); } delete retrieveParameters; + emit q->done(false); return false; } if (this->Canceled) { + emit q->done(false); return false; } - emit q->progress(ctkDICOMRetrieve::tr("Found Presentation Context")); + LOG_AND_EMIT_DEBUG(QString("Found Presentation Context"), q->debug) emit q->progress(1); // do the actual move request OFCondition status = this->SCU->sendCGETRequest(this->PresentationContext, retrieveParameters, &responses); - emit q->progress(ctkDICOMRetrieve::tr("Sent Get Request")); + LOG_AND_EMIT_DEBUG(QString("Sent GET Request"), q->debug) emit q->progress(2); // Close association if we do not want to explicitly keep it open @@ -679,20 +703,20 @@ bool ctkDICOMRetrievePrivate::get(const QString& patientID, delete retrieveParameters; // If we do not receive a single response, something is fishy - if ( responses.begin() == responses.end() ) + if (responses.begin() == responses.end()) { - QString error = ctkDICOMRetrieve::tr("No responses received at all! (at least one empty response always expected)"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); - emit q->progress(error); + LOG_AND_EMIT_ERROR(QString("No responses received at all! (at least one empty response always expected)"), q->error) + emit q->done(false); return false; } if (this->Canceled) { + emit q->done(false); return false; } - emit q->progress(ctkDICOMRetrieve::tr("Got Responses")); + LOG_AND_EMIT_DEBUG(QString("Got Responses"), q->debug) emit q->progress(3); /* The server is permitted to acknowledge every image that was received, or @@ -703,38 +727,36 @@ bool ctkDICOMRetrievePrivate::get(const QString& patientID, * 3) Error code, i.e. no images transferred * 4) Warning (one or more failures, i.e. some images transferred) */ - if ( responses.size() == 1 ) + if (responses.size() == 1) { RetrieveResponse* rsp = *responses.begin(); - QString debug = ctkDICOMRetrieve::tr("GET response receveid with status: ") + - QString(DU_cmoveStatusString(rsp->m_status)); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("GET response received with status: %1").arg(DU_cmoveStatusString(rsp->m_status)), q->debug) - if ( (rsp->m_status == STATUS_Success) + if ((rsp->m_status == STATUS_Success) || (rsp->m_status == STATUS_GET_Warning_SubOperationsCompleteOneOrMoreFailures)) { if (rsp->m_numberOfCompletedSubops == 0) { - QString error = ctkDICOMRetrieve::tr("No images transferred by PACS!"); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("No images transferred by PACS!"), q->error) + emit q->done(false); return false; } } else { - QString debug = ctkDICOMRetrieve::tr("GET request failed, server does report error"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("GET request failed, server does report error"), q->debug) - QString statusDetail(ctkDICOMRetrieve::tr("No details")); + QString statusDetail("No details"); if (rsp->m_statusDetail != NULL) { std::ostringstream out; rsp->m_statusDetail->print(out); - statusDetail = ctkDICOMRetrieve::tr("Status Detail: ") + statusDetail.fromStdString(out.str()); + statusDetail = "Status Detail: " + statusDetail.fromStdString(out.str()); } - statusDetail.prepend(ctkDICOMRetrieve::tr("GET request failed: ")); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, statusDetail.toStdString().c_str()); + statusDetail.prepend("GET request failed: "); + LOG_AND_EMIT_DEBUG(statusDetail, q->debug) + emit q->done(false); return false; } } @@ -746,19 +768,18 @@ bool ctkDICOMRetrievePrivate::get(const QString& patientID, it++; } - debug = ctkDICOMRetrieve::tr("GET responses report for study: %1\n" - "%2 images transferred, and\n" - "%3 images transferred with warning, and\n" - "%4 images transfers failed") + LOG_AND_EMIT_DEBUG(QString("GET responses report for study: %1\n" + "%2 images transferred, and\n" + "%3 images transferred with warning, and\n" + "%4 images transfers failed") .arg(studyInstanceUID) .arg(QString::number(static_cast((*it)->m_numberOfCompletedSubops))) .arg(QString::number(static_cast((*it)->m_numberOfWarningSubops))) - .arg(QString::number(static_cast((*it)->m_numberOfFailedSubops))); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + .arg(QString::number(static_cast((*it)->m_numberOfFailedSubops))), + q->debug) - emit q->progress(ctkDICOMRetrieve::tr("Finished Get")); emit q->progress(100); - + emit q->done(true); return true; } @@ -990,13 +1011,11 @@ bool ctkDICOMRetrieve::moveStudy(const QString& studyInstanceUID, if (studyInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive series: Study Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive study: Study Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr("Starting moveStudy"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Starting moveStudy"), debug) return d->move(patientID, studyInstanceUID, "", "", ctkDICOMRetrieve::RetrieveStudy); } @@ -1008,13 +1027,11 @@ bool ctkDICOMRetrieve::getStudy(const QString& studyInstanceUID, if (studyInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive study: Study Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive study: Study Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr(("Starting getStudy")); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Starting getStudy"), debug) return d->get(patientID, studyInstanceUID, "", "", ctkDICOMRetrieve::RetrieveStudy); } @@ -1028,13 +1045,11 @@ bool ctkDICOMRetrieve::moveSeries(const QString& studyInstanceUID, if (studyInstanceUID.isEmpty() || seriesInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive series: Study or Series Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive series: Study or Series Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr("Starting moveSeries"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Starting moveSeries"), debug) return d->move(patientID, studyInstanceUID, seriesInstanceUID, "", ctkDICOMRetrieve::RetrieveSeries); } @@ -1048,13 +1063,11 @@ bool ctkDICOMRetrieve::getSeries(const QString& studyInstanceUID, if (studyInstanceUID.isEmpty() || seriesInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive series: Study or Series Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive series: Study or Series Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr("Starting getSeries"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Starting getSeries"), debug) return d->get(patientID, studyInstanceUID, seriesInstanceUID, "", ctkDICOMRetrieve::RetrieveSeries); } @@ -1070,13 +1083,11 @@ bool ctkDICOMRetrieve::moveSOPInstance(const QString& studyInstanceUID, seriesInstanceUID.isEmpty() || SOPInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive SOPInstance: Study, Series or SOP Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive SOPInstance: Study, Series or SOP Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr("Starting moveSOPInstance"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); + LOG_AND_EMIT_DEBUG(QString("Starting moveSOPInstance"), debug) return d->move(patientID, studyInstanceUID, seriesInstanceUID, SOPInstanceUID, ctkDICOMRetrieve::RetrieveSOPInstance); } @@ -1092,14 +1103,12 @@ bool ctkDICOMRetrieve::getSOPInstance(const QString& studyInstanceUID, seriesInstanceUID.isEmpty() || SOPInstanceUID.isEmpty()) { - QString error = ctkDICOMRetrieve::tr("Cannot receive SOPInstance: Study, Series or SOP Instance UID empty."); - DCMTK_LOG4CPLUS_ERROR_STR(rootLogRetrieve, error.toStdString().c_str()); + LOG_AND_EMIT_ERROR(QString("Cannot receive SOPInstance: Study, Series or SOP Instance UID empty."), error) return false; } - QString debug = ctkDICOMRetrieve::tr("Starting getSOPInstance"); - DCMTK_LOG4CPLUS_DEBUG_STR(rootLogRetrieve, debug.toStdString().c_str()); - return d->get(patientID, studyInstanceUID, seriesInstanceUID, SOPInstanceUID, ctkDICOMRetrieve::RetrieveSOPInstance); + LOG_AND_EMIT_DEBUG(QString("Starting getSOPInstance"), debug) + return d->get(patientID, studyInstanceUID, seriesInstanceUID, SOPInstanceUID, ctkDICOMRetrieve::RetrieveSOPInstance); } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Core/ctkDICOMRetrieve.h b/Libs/DICOM/Core/ctkDICOMRetrieve.h index 41888becf9..10f78eeaf9 100644 --- a/Libs/DICOM/Core/ctkDICOMRetrieve.h +++ b/Libs/DICOM/Core/ctkDICOMRetrieve.h @@ -195,6 +195,8 @@ public Q_SLOTS: /// Signal is emitted inside the retrieve() function. It sends /// detailed feedback for debugging void debug(const QString& message); + /// Signal is emitted inside the query() function. It send any warning messages + void warn(const QString& message); /// Signal is emitted inside the retrieve() function. It send any error messages void error(const QString& message); /// Signal is emitted inside the retrieve() function when finished with value diff --git a/Libs/DICOM/Core/ctkDICOMRetrieveJob.cpp b/Libs/DICOM/Core/ctkDICOMRetrieveJob.cpp index eb5deaafd4..02497be58d 100644 --- a/Libs/DICOM/Core/ctkDICOMRetrieveJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMRetrieveJob.cpp @@ -163,8 +163,8 @@ QString ctkDICOMRetrieveJob::loggerReport(const QString& status) QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Core/ctkDICOMScheduler.cpp b/Libs/DICOM/Core/ctkDICOMScheduler.cpp index b3bc2fcbb9..6377fd471b 100644 --- a/Libs/DICOM/Core/ctkDICOMScheduler.cpp +++ b/Libs/DICOM/Core/ctkDICOMScheduler.cpp @@ -655,7 +655,7 @@ int ctkDICOMScheduler::storageServersCount() } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMScheduler::getNthServer(int id) +ctkDICOMServer* ctkDICOMScheduler::server(int id) { Q_D(ctkDICOMScheduler); if (id < 0 || id > d->Servers.size() - 1) @@ -666,10 +666,10 @@ ctkDICOMServer* ctkDICOMScheduler::getNthServer(int id) } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMScheduler::getServer(const QString& connectionName) +ctkDICOMServer* ctkDICOMScheduler::server(const QString& connectionName) { Q_D(ctkDICOMScheduler); - ctkDICOMServer* server = this->getNthServer(this->getServerIndexFromName(connectionName)); + ctkDICOMServer* server = this->server(this->getServerIndexFromName(connectionName)); if (!server) { server = d->getServerFromProxyServersByConnectionName(connectionName); @@ -705,11 +705,11 @@ void ctkDICOMScheduler::addServer(QSharedPointer server) //---------------------------------------------------------------------------- void ctkDICOMScheduler::removeServer(const QString& connectionName) { - this->removeNthServer(this->getServerIndexFromName(connectionName)); + this->removeServer(this->getServerIndexFromName(connectionName)); } //---------------------------------------------------------------------------- -void ctkDICOMScheduler::removeNthServer(int id) +void ctkDICOMScheduler::removeServer(int id) { Q_D(ctkDICOMScheduler); if (id < 0 || id > d->Servers.size() - 1) @@ -717,7 +717,7 @@ void ctkDICOMScheduler::removeNthServer(int id) return; } - ctkDICOMServer* server = this->getNthServer(id); + ctkDICOMServer* server = this->server(id); if (!server) { return; @@ -1115,8 +1115,7 @@ void ctkDICOMScheduler::onJobStarted(ctkAbstractJob* job) ctkDICOMJobsAppender* appender = dynamic_cast(d->Appender.get()); if (appender) { - QString loggedText = appender->messageByThreadID(job->runningThreadID()); - job->addLoggedText(loggedText); + job->addLog(appender->messageByThreadID(job->runningThreadID())); } ctkJobScheduler::onJobStarted(job); @@ -1134,8 +1133,7 @@ void ctkDICOMScheduler::onJobUserStopped(ctkAbstractJob* job) ctkDICOMJobsAppender* appender = dynamic_cast(d->Appender.get()); if (appender) { - QString loggedText = appender->messageByThreadID(job->runningThreadID()); - job->addLoggedText(loggedText); + job->addLog(appender->messageByThreadID(job->runningThreadID())); } ctkJobScheduler::onJobUserStopped(job); @@ -1153,8 +1151,7 @@ void ctkDICOMScheduler::onJobFinished(ctkAbstractJob* job) ctkDICOMJobsAppender* appender = dynamic_cast(d->Appender.get()); if (appender) { - QString loggedText = appender->messageByThreadID(job->runningThreadID()); - job->addLoggedText(loggedText); + job->addLog(appender->messageByThreadID(job->runningThreadID())); } ctkJobScheduler::onJobFinished(job); @@ -1172,8 +1169,7 @@ void ctkDICOMScheduler::onJobAttemptFailed(ctkAbstractJob* job) ctkDICOMJobsAppender* appender = dynamic_cast(d->Appender.get()); if (appender) { - QString loggedText = appender->messageByThreadID(job->runningThreadID()); - job->addLoggedText(loggedText); + job->addLog(appender->messageByThreadID(job->runningThreadID())); } ctkJobScheduler::onJobAttemptFailed(job); @@ -1191,8 +1187,7 @@ void ctkDICOMScheduler::onJobFailed(ctkAbstractJob* job) ctkDICOMJobsAppender* appender = dynamic_cast(d->Appender.get()); if (appender) { - QString loggedText = appender->messageByThreadID(job->runningThreadID()); - job->addLoggedText(loggedText); + job->addLog(appender->messageByThreadID(job->runningThreadID())); } ctkJobScheduler::onJobFailed(job); diff --git a/Libs/DICOM/Core/ctkDICOMScheduler.h b/Libs/DICOM/Core/ctkDICOMScheduler.h index 9ea77d996c..c363d1c001 100644 --- a/Libs/DICOM/Core/ctkDICOMScheduler.h +++ b/Libs/DICOM/Core/ctkDICOMScheduler.h @@ -169,12 +169,12 @@ class CTK_DICOM_CORE_EXPORT ctkDICOMScheduler : public ctkJobScheduler Q_INVOKABLE int serversCount(); Q_INVOKABLE int queryRetrieveServersCount(); Q_INVOKABLE int storageServersCount(); - Q_INVOKABLE ctkDICOMServer* getNthServer(int id); - Q_INVOKABLE ctkDICOMServer* getServer(const QString& connectionName); + Q_INVOKABLE ctkDICOMServer* server(int id); + Q_INVOKABLE ctkDICOMServer* server(const QString& connectionName); Q_INVOKABLE void addServer(ctkDICOMServer& server); void addServer(QSharedPointer server); Q_INVOKABLE void removeServer(const QString& connectionName); - Q_INVOKABLE void removeNthServer(int id); + Q_INVOKABLE void removeServer(int id); Q_INVOKABLE void removeAllServers(); Q_INVOKABLE QString getServerNameFromIndex(int id); Q_INVOKABLE int getServerIndexFromName(const QString& connectionName); diff --git a/Libs/DICOM/Core/ctkDICOMServer.cpp b/Libs/DICOM/Core/ctkDICOMServer.cpp index a238eb67f0..6a79be2115 100644 --- a/Libs/DICOM/Core/ctkDICOMServer.cpp +++ b/Libs/DICOM/Core/ctkDICOMServer.cpp @@ -67,11 +67,6 @@ class ctkDICOMServerPrivate : public QObject ctkDICOMServerPrivate::ctkDICOMServerPrivate(ctkDICOMServer& obj) : q_ptr(&obj) { - this->ConnectionName = ""; - this->CallingAETitle = ""; - this->CalledAETitle = ""; - this->Host = ""; - this->MoveDestinationAETitle = ""; this->QueryRetrieveEnabled = true; this->StorageEnabled = true; this->TrustedEnabled = true; diff --git a/Libs/DICOM/Core/ctkDICOMStorageListener.cpp b/Libs/DICOM/Core/ctkDICOMStorageListener.cpp index 98e2fdaae3..0a3a2d0de6 100644 --- a/Libs/DICOM/Core/ctkDICOMStorageListener.cpp +++ b/Libs/DICOM/Core/ctkDICOMStorageListener.cpp @@ -31,6 +31,9 @@ // DCMTK includes #include /* for DcmStorageSCP */ +//------------------------------------------------------------------------------ +// Using dcmtk root log4cplus logger instead of ctkLogger because with ctkDICOMJobsAppender (dcmtk::log4cplus::Appender), +// logging is filtered by threadID and reported in the GUI per job. dcmtk::log4cplus::Logger rootLogStorageListener = dcmtk::log4cplus::Logger::getRoot(); //------------------------------------------------------------------------------ @@ -223,7 +226,7 @@ QString ctkDICOMStorageListenerPrivate::defaultConfigFile() const } else { - QString error = ctkDICOMStorageListener::tr("Failed to find listener configuration file"); + QString error = "Failed to find listener configuration file"; DCMTK_LOG4CPLUS_ERROR_STR(rootLogStorageListener, error.toStdString().c_str()); return ""; } @@ -241,7 +244,7 @@ QString ctkDICOMStorageListenerPrivate::defaultConfigFile() const } else { - QString error = ctkDICOMStorageListener::tr("Failed to find listener configuration file"); + QString error = "Failed to find listener configuration file"; DCMTK_LOG4CPLUS_ERROR_STR(rootLogStorageListener, error.toStdString().c_str()); return ""; } @@ -289,9 +292,9 @@ bool ctkDICOMStorageListener::listen() OFCondition status = d->SCU.listen(); if (status.bad() || d->Canceled) { - QString error = ctkDICOMStorageListener::tr("SCP stopped, it was listening on port %1 : %2 ") - .arg(QString::number(d->Port)) - .arg(status.text()); + QString error = QString("SCP stopped, it was listening on port %1 : %2 ") + .arg(QString::number(d->Port)) + .arg(status.text()); DCMTK_LOG4CPLUS_ERROR_STR(rootLogStorageListener, error.toStdString().c_str()); return false; } @@ -324,7 +327,7 @@ bool ctkDICOMStorageListener::initializeSCU() OFString(d->defaultConfigFile().toStdString().c_str()), "alldicom"); if (status.bad()) { - QString error = ctkDICOMStorageListener::tr("Cannot load association configuration: %1").arg(status.text()); + QString error = QString("Cannot load association configuration: %1").arg(status.text()); DCMTK_LOG4CPLUS_ERROR_STR(rootLogStorageListener, error.toStdString().c_str()); return false; } diff --git a/Libs/DICOM/Core/ctkDICOMStorageListenerJob.cpp b/Libs/DICOM/Core/ctkDICOMStorageListenerJob.cpp index d3df92083d..4f6ee52b16 100644 --- a/Libs/DICOM/Core/ctkDICOMStorageListenerJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMStorageListenerJob.cpp @@ -83,8 +83,8 @@ QString ctkDICOMStorageListenerJob::loggerReport(const QString& status) .arg(status); QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Core/ctkDICOMThumbnailGenerator.cpp b/Libs/DICOM/Core/ctkDICOMThumbnailGenerator.cpp index 579254f581..e076c9255e 100644 --- a/Libs/DICOM/Core/ctkDICOMThumbnailGenerator.cpp +++ b/Libs/DICOM/Core/ctkDICOMThumbnailGenerator.cpp @@ -32,6 +32,9 @@ // DCMTK includes #include "dcmtk/dcmimgle/dcmimage.h" +//------------------------------------------------------------------------------ +// Using dcmtk root log4cplus logger instead of ctkLogger because with ctkDICOMJobsAppender (dcmtk::log4cplus::Appender), +// logging is filtered by threadID and reported in the GUI per job. dcmtk::log4cplus::Logger rootLogThumbnailGenerator = dcmtk::log4cplus::Logger::getRoot(); //------------------------------------------------------------------------------ @@ -132,7 +135,7 @@ bool ctkDICOMThumbnailGenerator::generateThumbnail(DicomImage *dcmImage, QImage& EI_Status result = dcmImage->getStatus(); if (result != EIS_Normal) { - QString warn = ctkDICOMThumbnailGenerator::tr("Rendering of DICOM image failed for thumbnail failed: ") + DicomImage::getString(result); + QString warn = QString("Rendering of DICOM image failed for thumbnail failed: ") + DicomImage::getString(result); DCMTK_LOG4CPLUS_WARN_STR(rootLogThumbnailGenerator, warn.toStdString().c_str()); return false; } diff --git a/Libs/DICOM/Core/ctkDICOMThumbnailGeneratorJob.cpp b/Libs/DICOM/Core/ctkDICOMThumbnailGeneratorJob.cpp index 269db0fa2d..5804237a53 100644 --- a/Libs/DICOM/Core/ctkDICOMThumbnailGeneratorJob.cpp +++ b/Libs/DICOM/Core/ctkDICOMThumbnailGeneratorJob.cpp @@ -38,9 +38,6 @@ static ctkLogger logger ( "org.commontk.dicom.DICOMThumbnailGeneratorJob" ); ctkDICOMThumbnailGeneratorJobPrivate::ctkDICOMThumbnailGeneratorJobPrivate(ctkDICOMThumbnailGeneratorJob* object) : q_ptr(object) { - this->DatabaseFilename = ""; - this->DicomFilePath = ""; - this->Modality = ""; this->BackgroundColor = Qt::darkGray; } @@ -86,8 +83,8 @@ QString ctkDICOMThumbnailGeneratorJob::loggerReport(const QString& status) .arg(status); QString currentDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz"); QString logHeader = currentDateTime + " INFO: "; - this->LoggedText += logHeader; - this->LoggedText += logMsg; + this->Log += logHeader; + this->Log += logMsg; return fullLogMsg; } //------------------------------------------------------------------------------ diff --git a/Libs/DICOM/Widgets/ctkDICOMPatientItemWidget.cpp b/Libs/DICOM/Widgets/ctkDICOMPatientItemWidget.cpp index 680f7590ad..ec7cbd7089 100644 --- a/Libs/DICOM/Widgets/ctkDICOMPatientItemWidget.cpp +++ b/Libs/DICOM/Widgets/ctkDICOMPatientItemWidget.cpp @@ -117,14 +117,6 @@ ctkDICOMPatientItemWidgetPrivate::ctkDICOMPatientItemWidgetPrivate(ctkDICOMPatie this->FilteringDate = ctkDICOMPatientItemWidget::DateType::Any; this->NumberOfOpenedStudiesPerPatient = 2; this->ThumbnailSize = ctkDICOMStudyItemWidget::ThumbnailSizeOption::Medium; - this->PatientItem = ""; - this->PatientID = ""; - this->PatientName = ""; - this->PatientBirthDate = ""; - this->PatientSex = ""; - - this->FilteringStudyDescription = ""; - this->FilteringSeriesDescription = ""; this->DicomDatabase = nullptr; this->Scheduler = nullptr; @@ -134,7 +126,6 @@ ctkDICOMPatientItemWidgetPrivate::ctkDICOMPatientItemWidgetPrivate(ctkDICOMPatie this->AllowedServers = QStringList(); this->Status = ctkDICOMPatientItemWidget::NoOperation; - this->StoppedJobUID = ""; this->IsGUIUpdating = false; this->QueryOn = true; @@ -471,7 +462,7 @@ void ctkDICOMPatientItemWidgetPrivate::updateAllowedServersUIFromDB() } else { - ctkDICOMServer* server = this->Scheduler->getServer(connectionName); + ctkDICOMServer* server = this->Scheduler->server(connectionName); if (server && server->trustedEnabled()) { this->AllowedServers.append(connectionName); @@ -529,7 +520,7 @@ void ctkDICOMPatientItemWidgetPrivate::saveAllowedServersStringListFromUI() } else if (checkState == Qt::CheckState::PartiallyChecked) { - ctkDICOMServer* server = this->Scheduler->getServer(connectionName); + ctkDICOMServer* server = this->Scheduler->server(connectionName); if (server && server->trustedEnabled()) { this->AllowedServers.append(connectionName); diff --git a/Libs/DICOM/Widgets/ctkDICOMSeriesItemWidget.cpp b/Libs/DICOM/Widgets/ctkDICOMSeriesItemWidget.cpp index 2c78bc3acb..cb3c97b9d5 100644 --- a/Libs/DICOM/Widgets/ctkDICOMSeriesItemWidget.cpp +++ b/Libs/DICOM/Widgets/ctkDICOMSeriesItemWidget.cpp @@ -129,18 +129,6 @@ class ctkDICOMSeriesItemWidgetPrivate : public Ui_ctkDICOMSeriesItemWidget ctkDICOMSeriesItemWidgetPrivate::ctkDICOMSeriesItemWidgetPrivate(ctkDICOMSeriesItemWidget& obj) : q_ptr(&obj) { - this->PatientID = ""; - this->SeriesItem = ""; - this->StudyInstanceUID = ""; - this->SeriesInstanceUID = ""; - this->CentralFrameSOPInstanceUID = ""; - this->SeriesNumber = ""; - this->Modality = ""; - this->ReferenceSeriesInserterJobUID = ""; - this->ReferenceInstanceInserterJobUID = ""; - - this->StoppedJobUID = ""; - this->IsCloud = false; this->RetrieveFailed = false; this->RetrieveSeries = false; @@ -706,14 +694,23 @@ void ctkDICOMSeriesItemWidgetPrivate::updateRetrieveUIOnFinished() filesList.removeAll(QString("")); int numberOfFiles = filesList.count(); - if (numberOfFrames > 1 && numberOfFiles < numberOfFrames) + if (numberOfFrames > 1 && numberOfFiles == 1) + { + // Thumbnail frame has been retrieved, but series has more than 1 frame, continue processing... + this->IsCloud = true; + this->SeriesThumbnail->operationProgressBar()->show(); + return; + } + else if (numberOfFrames > 0 && numberOfFiles < numberOfFrames) { + // Failed to retrieve all frames, warn the user this->RetrieveFailed = true; this->IsCloud = false; this->SeriesThumbnail->operationProgressBar()->hide(); } else if (numberOfFrames > 0 && numberOfFiles == numberOfFrames) { + // All frames have been retrieved successfully this->IsCloud = false; this->SeriesThumbnail->operationProgressBar()->hide(); } @@ -1055,22 +1052,20 @@ void ctkDICOMSeriesItemWidget::onJobFinished(const QVariant &data) } } } - else if (td.JobType == ctkDICOMJobResponseSet::JobType::Inserter && - (d->ReferenceSeriesInserterJobUID == td.JobUID || - d->ReferenceSeriesInserterJobUID == "StorageListener")) + else if (td.JobType == ctkDICOMJobResponseSet::JobType::Inserter) { - QStringList instancesList = d->DicomDatabase->instancesForSeries(d->SeriesInstanceUID); - if (instancesList.count() == 1) + if (d->ReferenceSeriesInserterJobUID == td.JobUID || + d->ReferenceSeriesInserterJobUID == "StorageListener") { - d->SeriesThumbnail->setOperationStatus(ctkThumbnailLabel::Completed); - d->SeriesThumbnail->setStatusIcon(QIcon(":/Icons/accept.svg")); - d->updateRetrieveUIOnFinished(); + d->ReferenceSeriesInserterJobUID = ""; } - else + else if (d->ReferenceInstanceInserterJobUID == td.JobUID || + d->ReferenceInstanceInserterJobUID == "StorageListener") { - d->ReferenceSeriesInserterJobUID = ""; - d->updateRetrieveUIOnFinished(); + d->ReferenceInstanceInserterJobUID = ""; } + + d->updateRetrieveUIOnFinished(); } } diff --git a/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.cpp b/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.cpp index 91ac9bc7a1..fdc777cb03 100644 --- a/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.cpp +++ b/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.cpp @@ -1271,11 +1271,11 @@ void ctkDICOMServerNodeWidget2::updateGUIState() if (d->Scheduler && d->Scheduler->isStorageListenerActive()) { - d->StorageStatusValueLabel->setText(ctkDICOMServerNodeWidget2::tr("Active")); + d->StorageStatusValueLabel->setText(tr("Active")); } else { - d->StorageStatusValueLabel->setText(ctkDICOMServerNodeWidget2::tr("Inactive")); + d->StorageStatusValueLabel->setText(tr("Inactive")); } d->updateProxyComboBoxes(); @@ -1290,7 +1290,7 @@ void ctkDICOMServerNodeWidget2::updateGUIFromServerNodes() d->NodeTable->setRowCount(0); for (int serverIndex = 0; serverIndex < d->Scheduler->serversCount(); ++serverIndex) { - ctkDICOMServer* server = d->Scheduler->getNthServer(serverIndex); + ctkDICOMServer* server = d->Scheduler->server(serverIndex); if (!server) { continue; @@ -1343,7 +1343,7 @@ void ctkDICOMServerNodeWidget2::onCellSettingsModified(int row, int column) if (lineEdit) { lineEdit->setReadOnly(false); - lineEdit->setText(ctkDICOMServerNodeWidget2::tr("unknown")); + lineEdit->setText(tr("unknown")); lineEdit->setReadOnly(true); QColor serverNodeWidgetColor = this->palette().color(QPalette::Normal, this->backgroundRole()); @@ -1445,7 +1445,7 @@ void ctkDICOMServerNodeWidget2::saveSettings() QString tmpProxyName = tmpNode["Retrieve Proxy"].toString(); if (serverName == tmpProxyName) { - ctkDICOMServer* server = this->getServer(tmpServerName.toStdString().c_str()); + ctkDICOMServer* server = this->server(tmpServerName.toStdString().c_str()); if (server) { server->setProxyServer(*proxyServer); @@ -1498,7 +1498,7 @@ void ctkDICOMServerNodeWidget2::readSettings() // a dummy example QMap defaultServerNode; defaultServerNode["Name"] = QString("ExampleHost"); - defaultServerNode["Verification"] = ctkDICOMServerNodeWidget2::tr("unknown"); + defaultServerNode["Verification"] = tr("unknown"); defaultServerNode["QueryRetrieveCheckState"] = static_cast(Qt::Unchecked); defaultServerNode["StorageCheckState"] = static_cast(Qt::Unchecked); defaultServerNode["TrustedCheckState"] = static_cast(Qt::Unchecked); @@ -1514,7 +1514,7 @@ void ctkDICOMServerNodeWidget2::readSettings() // the uk example - see http://www.dicomserver.co.uk/ // and http://www.medicalconnections.co.uk/ defaultServerNode["Name"] = QString("MedicalConnections"); - defaultServerNode["Verification"] = ctkDICOMServerNodeWidget2::tr("unknown"); + defaultServerNode["Verification"] = tr("unknown"); defaultServerNode["QueryRetrieveCheckState"] = static_cast(Qt::Unchecked); defaultServerNode["StorageCheckState"] = static_cast(Qt::Unchecked); defaultServerNode["TrustedCheckState"] = static_cast(Qt::Unchecked); @@ -1669,29 +1669,29 @@ int ctkDICOMServerNodeWidget2::serversCount() } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMServerNodeWidget2::getNthServer(int id) +ctkDICOMServer* ctkDICOMServerNodeWidget2::server(int id) { Q_D(ctkDICOMServerNodeWidget2); if (!d->Scheduler) { - logger.error("getNthServer failed, no task pool has been set. \n"); + logger.error("server failed, no task pool has been set. \n"); return nullptr; } - return d->Scheduler->getNthServer(id); + return d->Scheduler->server(id); } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMServerNodeWidget2::getServer(const QString& connectionName) +ctkDICOMServer* ctkDICOMServerNodeWidget2::server(const QString& connectionName) { Q_D(ctkDICOMServerNodeWidget2); if (!d->Scheduler) { - logger.error("getServer failed, no task pool has been set. \n"); + logger.error("server failed, no task pool has been set. \n"); return nullptr; } - return d->Scheduler->getServer(connectionName); + return d->Scheduler->server(connectionName); } //---------------------------------------------------------------------------- @@ -1719,16 +1719,16 @@ void ctkDICOMServerNodeWidget2::removeServer(const QString& connectionName) return; } - this->removeNthServer(this->getServerIndexFromName(connectionName)); + this->removeServer(this->getServerIndexFromName(connectionName)); } //---------------------------------------------------------------------------- -void ctkDICOMServerNodeWidget2::removeNthServer(int id) +void ctkDICOMServerNodeWidget2::removeServer(int id) { Q_D(ctkDICOMServerNodeWidget2); if (!d->Scheduler) { - logger.error("removeNthServer failed, no task pool has been set. \n"); + logger.error("removeServer failed, no task pool has been set. \n"); return; } diff --git a/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.h b/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.h index 8811fb4531..a6087fed88 100644 --- a/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.h +++ b/Libs/DICOM/Widgets/ctkDICOMServerNodeWidget2.h @@ -90,11 +90,12 @@ class CTK_DICOM_WIDGETS_EXPORT ctkDICOMServerNodeWidget2 : public QWidget /// Servers ///@{ Q_INVOKABLE int serversCount(); - Q_INVOKABLE ctkDICOMServer* getNthServer(int id); - Q_INVOKABLE ctkDICOMServer* getServer(const QString& connectionName); + Q_INVOKABLE ctkDICOMServer* server(int id); + Q_INVOKABLE ctkDICOMServer* server(const QString& connectionName); + /// Return the row index added into the servers table. If -1 the the operation failed. Q_INVOKABLE int addServer(ctkDICOMServer* server); Q_INVOKABLE void removeServer(const QString& connectionName); - Q_INVOKABLE void removeNthServer(int id); + Q_INVOKABLE void removeServer(int id); Q_INVOKABLE void removeAllServers(); Q_INVOKABLE QString getServerNameFromIndex(int id); Q_INVOKABLE int getServerIndexFromName(const QString& connectionName); diff --git a/Libs/DICOM/Widgets/ctkDICOMStudyItemWidget.cpp b/Libs/DICOM/Widgets/ctkDICOMStudyItemWidget.cpp index 546655fed8..9aab6b9da8 100644 --- a/Libs/DICOM/Widgets/ctkDICOMStudyItemWidget.cpp +++ b/Libs/DICOM/Widgets/ctkDICOMStudyItemWidget.cpp @@ -106,14 +106,9 @@ ctkDICOMStudyItemWidgetPrivate::ctkDICOMStudyItemWidgetPrivate(ctkDICOMStudyItem { this->ThumbnailSize = ctkDICOMStudyItemWidget::ThumbnailSizeOption::Medium; this->ThumbnailSizePixel = 200; - this->FilteringSeriesDescription = ""; - this->PatientID = ""; - this->StudyInstanceUID = ""; - this->StudyItem = ""; this->AllowedServers = QStringList(); this->Status = ctkDICOMStudyItemWidget::NoOperation; - this->StoppedJobUID = ""; this->DicomDatabase = nullptr; this->Scheduler = nullptr; diff --git a/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.cpp b/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.cpp index 6b29f160ca..7246c489b2 100644 --- a/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.cpp +++ b/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.cpp @@ -280,20 +280,11 @@ ctkDICOMVisualBrowserWidgetPrivate::ctkDICOMVisualBrowserWidgetPrivate(ctkDICOMV this->MetadataDialog->setObjectName("DICOMMetadata"); this->MetadataDialog->setWindowTitle(ctkDICOMVisualBrowserWidget::tr("DICOM File Metadata")); - this->DatabaseDirectorySettingsKey = ""; - this->DatabaseDirectoryBase = ""; - this->DefaultDatabaseDirectory = ""; - this->DatabaseDirectory = ""; - this->NumberOfOpenedStudiesPerPatient = 2; this->ThumbnailSize = ctkDICOMStudyItemWidget::ThumbnailSizeOption::Medium; this->SendActionVisible = false; this->DeleteActionVisible = true; - this->FilteringPatientID = ""; - this->FilteringPatientName = ""; - this->FilteringStudyDescription = ""; - this->FilteringSeriesDescription = ""; this->FilteringDate = ctkDICOMPatientItemWidget::DateType::Any; this->FilteringModalities.append("Any"); @@ -1946,17 +1937,17 @@ int ctkDICOMVisualBrowserWidget::serversCount() } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMVisualBrowserWidget::getNthServer(int id) +ctkDICOMServer* ctkDICOMVisualBrowserWidget::server(int id) { Q_D(ctkDICOMVisualBrowserWidget); - return d->ServerNodeWidget->getNthServer(id); + return d->ServerNodeWidget->server(id); } //---------------------------------------------------------------------------- -ctkDICOMServer* ctkDICOMVisualBrowserWidget::getServer(const QString& connectionName) +ctkDICOMServer* ctkDICOMVisualBrowserWidget::server(const QString& connectionName) { Q_D(ctkDICOMVisualBrowserWidget); - return d->ServerNodeWidget->getServer(connectionName); + return d->ServerNodeWidget->server(connectionName); } //---------------------------------------------------------------------------- @@ -1974,10 +1965,10 @@ void ctkDICOMVisualBrowserWidget::removeServer(const QString& connectionName) } //---------------------------------------------------------------------------- -void ctkDICOMVisualBrowserWidget::removeNthServer(int id) +void ctkDICOMVisualBrowserWidget::removeServer(int id) { Q_D(ctkDICOMVisualBrowserWidget); - return d->ServerNodeWidget->removeNthServer(id); + return d->ServerNodeWidget->removeServer(id); } //---------------------------------------------------------------------------- @@ -2152,7 +2143,7 @@ void ctkDICOMVisualBrowserWidget::removePatientItemWidget(const QString& patient } //------------------------------------------------------------------------------ -ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::getPatientItemWidgetByPatientItem(const QString &patientItem) +ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::patientItemWidgetByPatientItem(const QString &patientItem) { Q_D(ctkDICOMVisualBrowserWidget); @@ -2177,7 +2168,7 @@ ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::getPatientItemWidgetByPa } //------------------------------------------------------------------------------ -ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::getPatientItemWidgetByPatientID(const QString &patientID) +ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::patientItemWidgetByPatientID(const QString &patientID) { Q_D(ctkDICOMVisualBrowserWidget); @@ -2202,7 +2193,7 @@ ctkDICOMPatientItemWidget *ctkDICOMVisualBrowserWidget::getPatientItemWidgetByPa } //------------------------------------------------------------------------------ -ctkDICOMPatientItemWidget* ctkDICOMVisualBrowserWidget::getPatientItemWidgetByPatientName(const QString& patientName) +ctkDICOMPatientItemWidget* ctkDICOMVisualBrowserWidget::patientItemWidgetByPatientName(const QString& patientName) { Q_D(ctkDICOMVisualBrowserWidget); @@ -2330,11 +2321,11 @@ void ctkDICOMVisualBrowserWidget::setDatabaseDirectory(const QString& directory) if (!QDir(absDirectory).exists() || (!ctk::isDirEmpty(QDir(absDirectory)) && !QFile(databaseFileName).exists())) { - logger.warn(ctkDICOMVisualBrowserWidget::tr("Database folder does not contain ctkDICOM.sql file: ") + absDirectory + "\n"); + logger.warn("Database folder does not contain ctkDICOM.sql file: " + absDirectory + "\n"); d->DatabaseDirectoryProblemFrame->show(); d->DatabaseDirectoryProblemLabel->setText( //: %1 is the folder path - ctkDICOMVisualBrowserWidget::tr("No valid DICOM database found in folder %1.").arg(absDirectory) + tr("No valid DICOM database found in folder %1.").arg(absDirectory) ); d->UpdateDatabaseButton->hide(); d->CreateNewDatabaseButton->show(); @@ -2357,12 +2348,12 @@ void ctkDICOMVisualBrowserWidget::setDatabaseDirectory(const QString& directory) } if (!databaseOpenSuccess || d->DicomDatabase->schemaVersionLoaded().isEmpty()) { - logger.warn(ctkDICOMVisualBrowserWidget::tr("Database error: %1 \n").arg(d->DicomDatabase->lastError())); + logger.warn(tr("Database error: %1 \n").arg(d->DicomDatabase->lastError())); d->DicomDatabase->closeDatabase(); d->DatabaseDirectoryProblemFrame->show(); d->DatabaseDirectoryProblemLabel->setText( //: %1 is the folder path - ctkDICOMVisualBrowserWidget::tr("No valid DICOM database found in folder %1.").arg(absDirectory) + tr("No valid DICOM database found in folder %1.").arg(absDirectory) ); d->UpdateDatabaseButton->hide(); d->CreateNewDatabaseButton->show(); @@ -2375,13 +2366,13 @@ void ctkDICOMVisualBrowserWidget::setDatabaseDirectory(const QString& directory) { if (d->DicomDatabase->schemaVersionLoaded() != d->DicomDatabase->schemaVersion()) { - logger.warn(ctkDICOMVisualBrowserWidget::tr("Database version mismatch: version of selected database = %1, version required = %2 \n") + logger.warn(QString("Database version mismatch: version of selected database = %1, version required = %2 \n") .arg(d->DicomDatabase->schemaVersionLoaded()).arg(d->DicomDatabase->schemaVersion())); d->DicomDatabase->closeDatabase(); d->DatabaseDirectoryProblemFrame->show(); d->DatabaseDirectoryProblemLabel->setText( //: %1 is the folder path - ctkDICOMVisualBrowserWidget::tr("Incompatible DICOM database version found in folder %1.").arg(absDirectory) + tr("Incompatible DICOM database version found in folder %1.").arg(absDirectory) ); d->UpdateDatabaseButton->show(); d->CreateNewDatabaseButton->show(); @@ -2598,7 +2589,7 @@ void ctkDICOMVisualBrowserWidget::createNewDatabaseDirectory() d->DatabaseDirectoryProblemFrame->show(); d->DatabaseDirectoryProblemLabel->setText( //: %1 is the folder path - ctkDICOMVisualBrowserWidget::tr("Failed to create new database in folder %1.").arg(QDir(baseFolder).absolutePath()) + tr("Failed to create new database in folder %1.").arg(QDir(baseFolder).absolutePath()) ); d->UpdateDatabaseButton->hide(); d->CreateNewDatabaseButton->show(); @@ -2939,7 +2930,7 @@ void ctkDICOMVisualBrowserWidget::onShowPatients() { d->setBackgroundColorToFilterWidgets(true); - d->WarningPushButton->setText(ctkDICOMVisualBrowserWidget::tr("No patients have been found in the local database.")); + d->WarningPushButton->setText(tr("No patients have been found in the local database.")); d->WarningPushButton->show(); d->patientsTabMenuToolButton->hide(); return; @@ -3004,10 +2995,10 @@ void ctkDICOMVisualBrowserWidget::onQueryPatients() { d->setBackgroundColorToFilterWidgets(true); - d->WarningPushButton->setText(ctkDICOMVisualBrowserWidget::tr("No filters or query/retrieve servers have been set and" - " no patients have been found in the local database." - "\nPlease set at least one filter to query the servers and " - "check that at least one server has the Query/Retrieve property toggled.")); + d->WarningPushButton->setText(tr("No filters or query/retrieve servers have been set and" + " no patients have been found in the local database." + "\nPlease set at least one filter to query the servers and " + "check that at least one server has the Query/Retrieve property toggled.")); d->WarningPushButton->show(); d->patientsTabMenuToolButton->hide(); return; @@ -3085,7 +3076,7 @@ void ctkDICOMVisualBrowserWidget::updateGUIFromScheduler(QList datas) td.JobType == ctkDICOMJobResponseSet::JobType::ThumbnailGenerator || td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSeries) { - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientID(td.PatientID); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientID(td.PatientID); if (patientItemWidget) { patientItemWidget->updateGUIFromScheduler(data); @@ -3106,7 +3097,7 @@ void ctkDICOMVisualBrowserWidget::updateGUIFromScheduler(QList datas) d->updateFiltersWarnings(); if (td.NumberOfDataSets == 0) { - d->WarningPushButton->setText(ctkDICOMVisualBrowserWidget::tr("The patients query provided no results. Please refine your filters.")); + d->WarningPushButton->setText(tr("The patients query provided no results. Please refine your filters.")); d->WarningPushButton->show(); d->SearchMenuButton->setIcon(QIcon(":/Icons/query_failed.svg")); } @@ -3159,7 +3150,7 @@ void ctkDICOMVisualBrowserWidget::onJobStarted(QList datas) td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSOPInstance || td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSeries) { - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientID(td.PatientID); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientID(td.PatientID); if (patientItemWidget) { patientItemWidget->onJobStarted(data); @@ -3205,7 +3196,7 @@ void ctkDICOMVisualBrowserWidget::onJobUserStopped(QList datas) td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSOPInstance || td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSeries) { - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientID(td.PatientID); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientID(td.PatientID); if (patientItemWidget) { patientItemWidget->onJobUserStopped(data); @@ -3231,7 +3222,7 @@ void ctkDICOMVisualBrowserWidget::onJobFailed(QList datas) { d->updateFiltersWarnings(); d->SearchMenuButton->setIcon(QIcon(":/Icons/query_failed.svg")); - d->WarningPushButton->setText(ctkDICOMVisualBrowserWidget::tr("The patients query failed. Please check the servers settings.")); + d->WarningPushButton->setText(tr("The patients query failed. Please check the servers settings.")); d->WarningPushButton->show(); } else if (td.JobType == ctkDICOMJobResponseSet::JobType::QueryStudies) @@ -3253,7 +3244,7 @@ void ctkDICOMVisualBrowserWidget::onJobFailed(QList datas) td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSOPInstance || td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSeries) { - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientID(td.PatientID); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientID(td.PatientID); if (patientItemWidget) { patientItemWidget->onJobFailed(data); @@ -3297,7 +3288,7 @@ void ctkDICOMVisualBrowserWidget::onJobFinished(QList datas) td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSOPInstance || td.JobType == ctkDICOMJobResponseSet::JobType::RetrieveSeries) { - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientID(td.PatientID); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientID(td.PatientID); if (patientItemWidget) { patientItemWidget->onJobFinished(data); @@ -3408,24 +3399,24 @@ void ctkDICOMVisualBrowserWidget::showPatientContextMenu(const QPoint& point) QPoint globalPos = patientItemWidget->mapToGlobal(point); QMenu* patientMenu = new QMenu(); - QString loadString = ctkDICOMVisualBrowserWidget::tr("Load patient files"); + QString loadString = tr("Load patient files"); QAction* loadAction = new QAction(loadString, patientMenu); patientMenu->addAction(loadAction); - QString metadataString = ctkDICOMVisualBrowserWidget::tr("View patient DICOM metadata"); + QString metadataString = tr("View patient DICOM metadata"); QAction* metadataAction = new QAction(metadataString, patientMenu); patientMenu->addAction(metadataAction); - QString deleteString = ctkDICOMVisualBrowserWidget::tr("Delete patient from local database"); + QString deleteString = tr("Delete patient from local database"); QAction* deleteAction = new QAction(deleteString, patientMenu); patientMenu->addAction(deleteAction); deleteAction->setVisible(this->isDeleteActionVisible()); - QString exportString = ctkDICOMVisualBrowserWidget::tr("Export patient to file system"); + QString exportString = tr("Export patient to file system"); QAction* exportAction = new QAction(exportString, patientMenu); patientMenu->addAction(exportAction); - QString sendString = ctkDICOMVisualBrowserWidget::tr("Send patient to DICOM server"); + QString sendString = tr("Send patient to DICOM server"); QAction* sendAction = new QAction(sendString, patientMenu); sendAction->setVisible(this->isSendActionVisible()); patientMenu->addAction(sendAction); @@ -3499,34 +3490,34 @@ void ctkDICOMVisualBrowserWidget::showStudyContextMenu(const QPoint& point) QPoint globalPos = studyItemWidget->mapToGlobal(point); QMenu* studyMenu = new QMenu(); - QString loadString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("Load study") : - ctkDICOMVisualBrowserWidget::tr("Load %1 studies").arg(numberOfSelectedStudies); + QString loadString = numberOfSelectedStudies == 1 ? tr("Load study") : + tr("Load %1 studies").arg(numberOfSelectedStudies); QAction* loadAction = new QAction(loadString, studyMenu); studyMenu->addAction(loadAction); - QString metadataString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("View study DICOM metadata") : - ctkDICOMVisualBrowserWidget::tr("View %1 studies DICOM metadata").arg(numberOfSelectedStudies); + QString metadataString = numberOfSelectedStudies == 1 ? tr("View study DICOM metadata") : + tr("View %1 studies DICOM metadata").arg(numberOfSelectedStudies); QAction* metadataAction = new QAction(metadataString, studyMenu); studyMenu->addAction(metadataAction); - QString forceRetrieveString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("Force retrieve series") : - ctkDICOMVisualBrowserWidget::tr("Force retrieve series for %1 studies").arg(numberOfSelectedStudies); + QString forceRetrieveString = numberOfSelectedStudies == 1 ? tr("Force retrieve series") : + tr("Force retrieve series for %1 studies").arg(numberOfSelectedStudies); QAction *forceRetrieveAction = new QAction(forceRetrieveString, studyMenu); studyMenu->addAction(forceRetrieveAction); - QString deleteString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("Delete study from local database") : - ctkDICOMVisualBrowserWidget::tr("Delete %1 studies from local database").arg(numberOfSelectedStudies); + QString deleteString = numberOfSelectedStudies == 1 ? tr("Delete study from local database") : + tr("Delete %1 studies from local database").arg(numberOfSelectedStudies); QAction* deleteAction = new QAction(deleteString, studyMenu); studyMenu->addAction(deleteAction); deleteAction->setVisible(this->isDeleteActionVisible()); - QString exportString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("Export study to file system") : - ctkDICOMVisualBrowserWidget::tr("Export %1 studies to file system").arg(numberOfSelectedStudies); + QString exportString = numberOfSelectedStudies == 1 ? tr("Export study to file system") : + tr("Export %1 studies to file system").arg(numberOfSelectedStudies); QAction* exportAction = new QAction(exportString, studyMenu); studyMenu->addAction(exportAction); - QString sendString = numberOfSelectedStudies == 1 ? ctkDICOMVisualBrowserWidget::tr("Send study to DICOM server") : - ctkDICOMVisualBrowserWidget::tr("Send %1 studies to DICOM server").arg(numberOfSelectedStudies); + QString sendString = numberOfSelectedStudies == 1 ? tr("Send study to DICOM server") : + tr("Send %1 studies to DICOM server").arg(numberOfSelectedStudies); QAction* sendAction = new QAction(sendString, studyMenu); sendAction->setVisible(this->isSendActionVisible()); studyMenu->addAction(sendAction); @@ -3609,34 +3600,34 @@ void ctkDICOMVisualBrowserWidget::showSeriesContextMenu(const QPoint& point) QPoint globalPos = selectedSeriesItemWidget->mapToGlobal(point); QMenu* seriesMenu = new QMenu(); - QString loadString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("Load series") : - ctkDICOMVisualBrowserWidget::tr("Load %1 series").arg(numberOfSelectedSeries); + QString loadString = numberOfSelectedSeries == 1 ? tr("Load series") : + tr("Load %1 series").arg(numberOfSelectedSeries); QAction *loadAction = new QAction(loadString, seriesMenu); seriesMenu->addAction(loadAction); - QString metadataString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("View series DICOM metadata") : - ctkDICOMVisualBrowserWidget::tr("View %1 series DICOM metadata").arg(numberOfSelectedSeries); + QString metadataString = numberOfSelectedSeries == 1 ? tr("View series DICOM metadata") : + tr("View %1 series DICOM metadata").arg(numberOfSelectedSeries); QAction *metadataAction = new QAction(metadataString, seriesMenu); seriesMenu->addAction(metadataAction); - QString forceRetrieveString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("Force retrieve series") : - ctkDICOMVisualBrowserWidget::tr("Force retrieve for %1 series").arg(numberOfSelectedSeries); + QString forceRetrieveString = numberOfSelectedSeries == 1 ? tr("Force retrieve series") : + tr("Force retrieve for %1 series").arg(numberOfSelectedSeries); QAction *forceRetrieveAction = new QAction(forceRetrieveString, seriesMenu); seriesMenu->addAction(forceRetrieveAction); - QString deleteString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("Delete series from local database") : - ctkDICOMVisualBrowserWidget::tr("Delete %1 series from local database").arg(numberOfSelectedSeries); + QString deleteString = numberOfSelectedSeries == 1 ? tr("Delete series from local database") : + tr("Delete %1 series from local database").arg(numberOfSelectedSeries); QAction *deleteAction = new QAction(deleteString, seriesMenu); seriesMenu->addAction(deleteAction); deleteAction->setVisible(this->isDeleteActionVisible()); - QString exportString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("Export series to file system") : - ctkDICOMVisualBrowserWidget::tr("Export %1 series to file system").arg(numberOfSelectedSeries); + QString exportString = numberOfSelectedSeries == 1 ? tr("Export series to file system") : + tr("Export %1 series to file system").arg(numberOfSelectedSeries); QAction *exportAction = new QAction(exportString, seriesMenu); seriesMenu->addAction(exportAction); - QString sendString = numberOfSelectedSeries == 1 ? ctkDICOMVisualBrowserWidget::tr("Send series to DICOM server") : - ctkDICOMVisualBrowserWidget::tr("Send %1 series to DICOM server").arg(numberOfSelectedSeries); + QString sendString = numberOfSelectedSeries == 1 ? tr("Send series to DICOM server") : + tr("Send %1 series to DICOM server").arg(numberOfSelectedSeries); QAction* sendAction = new QAction(sendString, seriesMenu); sendAction->setVisible(this->isSendActionVisible()); seriesMenu->addAction(sendAction); @@ -3706,7 +3697,7 @@ void ctkDICOMVisualBrowserWidget::onPatientsTabMenuToolButtonClicked() } patientMenu->addSeparator(); - QString deleteString = ctkDICOMVisualBrowserWidget::tr("Delete all Patients from local database"); + QString deleteString = tr("Delete all Patients from local database"); QAction* deleteAction = new QAction(deleteString, patientMenu); deleteAction->setIcon(QIcon(":Icons/delete.svg")); patientMenu->addAction(deleteAction); @@ -3721,7 +3712,7 @@ void ctkDICOMVisualBrowserWidget::onPatientsTabMenuToolButtonClicked() else if (selectedAction) { QString patientName = selectedAction->text(); - ctkDICOMPatientItemWidget* patientItemWidget = this->getPatientItemWidgetByPatientName(patientName); + ctkDICOMPatientItemWidget* patientItemWidget = this->patientItemWidgetByPatientName(patientName); if (patientItemWidget) { d->PatientsTabWidget->setCurrentWidget(patientItemWidget); @@ -3827,7 +3818,7 @@ void ctkDICOMVisualBrowserWidget::exportSeries(const QString& dirPath, const QSt if (!QDir().mkpath(destinationDir)) { //: %1 is the destination directory - QString errorString = ctkDICOMVisualBrowserWidget::tr("Unable to create export destination directory:\n\n%1" + QString errorString = tr("Unable to create export destination directory:\n\n%1" "\n\nHalting export.") .arg(destinationDir); ctkMessageBox createDirectoryErrorMessageBox(this); @@ -3841,14 +3832,13 @@ void ctkDICOMVisualBrowserWidget::exportSeries(const QString& dirPath, const QSt // show progress if (d->ExportProgress == 0) { - d->ExportProgress = new QProgressDialog(ctkDICOMVisualBrowserWidget::tr("DICOM Export"), - ctkDICOMVisualBrowserWidget::tr("Close"), 0, 100, this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); + d->ExportProgress = new QProgressDialog(tr("DICOM Export"), tr("Close"), 0, 100, this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); d->ExportProgress->setWindowModality(Qt::ApplicationModal); d->ExportProgress->setMinimumDuration(0); } QLabel* exportLabel = new QLabel( //: %1 is the series number - ctkDICOMVisualBrowserWidget::tr("Exporting series %1").arg(seriesNumber) + tr("Exporting series %1").arg(seriesNumber) ); d->ExportProgress->setLabel(exportLabel); d->ExportProgress->setValue(0); @@ -3865,7 +3855,7 @@ void ctkDICOMVisualBrowserWidget::exportSeries(const QString& dirPath, const QSt { d->ExportProgress->setValue(numFiles); //: %1 is the file path - QString errorString = ctkDICOMVisualBrowserWidget::tr("Export source file not found:\n\n%1" + QString errorString = tr("Export source file not found:\n\n%1" "\n\nHalting export.\n\nError may be fixed via Repair.") .arg(filePath); ctkMessageBox copyErrorMessageBox; @@ -3878,7 +3868,7 @@ void ctkDICOMVisualBrowserWidget::exportSeries(const QString& dirPath, const QSt { d->ExportProgress->setValue(numFiles); //: %1 is the destination file name - QString errorString = ctkDICOMVisualBrowserWidget::tr("Export destination file already exists:\n\n%1" + QString errorString = tr("Export destination file already exists:\n\n%1" "\n\nHalting export.") .arg(destinationFileName); ctkMessageBox copyErrorMessageBox(this); @@ -3893,7 +3883,7 @@ void ctkDICOMVisualBrowserWidget::exportSeries(const QString& dirPath, const QSt { d->ExportProgress->setValue(numFiles); //: %1 and %2 refers to source and destination file paths - QString errorString = ctkDICOMVisualBrowserWidget::tr("Failed to copy\n\n%1\n\nto\n\n%2" + QString errorString = tr("Failed to copy\n\n%1\n\nto\n\n%2" "\n\nHalting export.") .arg(filePath) .arg(destinationFileName); @@ -4031,8 +4021,8 @@ bool ctkDICOMVisualBrowserWidget::confirmDeleteSelectedUIDs(const QStringList& u } ctkMessageBox confirmDeleteDialog(this); - QString message = ctkDICOMVisualBrowserWidget::tr("Do you want to delete the following selected items from the LOCAL database? \n" - "The data will not be deleted from the PACs server. \n"); + QString message = tr("Do you want to delete the following selected items from the LOCAL database? \n" + "The data will not be deleted from the PACs server. \n"); // add the information about the selected UIDs int numUIDs = uids.size(); @@ -4066,8 +4056,8 @@ bool ctkDICOMVisualBrowserWidget::confirmDeleteSelectedUIDs(const QStringList& u confirmDeleteDialog.setText(message); confirmDeleteDialog.setIcon(QMessageBox::Question); - confirmDeleteDialog.addButton(ctkDICOMVisualBrowserWidget::tr("Delete"), QMessageBox::AcceptRole); - confirmDeleteDialog.addButton(ctkDICOMVisualBrowserWidget::tr("Cancel"), QMessageBox::RejectRole); + confirmDeleteDialog.addButton(tr("Delete"), QMessageBox::AcceptRole); + confirmDeleteDialog.addButton(tr("Cancel"), QMessageBox::RejectRole); confirmDeleteDialog.setDontShowAgainSettingsKey("VisualDICOMBrowser/DontConfirmDeleteSelected"); int response = confirmDeleteDialog.exec(); diff --git a/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.h b/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.h index a60566648d..7578a8b1d9 100644 --- a/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.h +++ b/Libs/DICOM/Widgets/ctkDICOMVisualBrowserWidget.h @@ -160,11 +160,11 @@ class CTK_DICOM_WIDGETS_EXPORT ctkDICOMVisualBrowserWidget : public QWidget ///@{ /// Servers Q_INVOKABLE int serversCount(); - Q_INVOKABLE ctkDICOMServer* getNthServer(int id); - Q_INVOKABLE ctkDICOMServer* getServer(const QString& connectionName); + Q_INVOKABLE ctkDICOMServer* server(int id); + Q_INVOKABLE ctkDICOMServer* server(const QString& connectionName); Q_INVOKABLE int addServer(ctkDICOMServer* server); Q_INVOKABLE void removeServer(const QString& connectionName); - Q_INVOKABLE void removeNthServer(int id); + Q_INVOKABLE void removeServer(int id); Q_INVOKABLE void removeAllServers(); Q_INVOKABLE QString getServerNameFromIndex(int id); Q_INVOKABLE int getServerIndexFromName(const QString& connectionName); @@ -254,9 +254,9 @@ class CTK_DICOM_WIDGETS_EXPORT ctkDICOMVisualBrowserWidget : public QWidget /// Add/Remove Patient item widget Q_INVOKABLE int addPatientItemWidget(const QString& patientItem); Q_INVOKABLE void removePatientItemWidget(const QString& patientItem); - Q_INVOKABLE ctkDICOMPatientItemWidget* getPatientItemWidgetByPatientItem(const QString& patientItem); - Q_INVOKABLE ctkDICOMPatientItemWidget* getPatientItemWidgetByPatientID(const QString& patientID); - Q_INVOKABLE ctkDICOMPatientItemWidget* getPatientItemWidgetByPatientName(const QString& patientName); + Q_INVOKABLE ctkDICOMPatientItemWidget* patientItemWidgetByPatientItem(const QString& patientItem); + Q_INVOKABLE ctkDICOMPatientItemWidget* patientItemWidgetByPatientID(const QString& patientID); + Q_INVOKABLE ctkDICOMPatientItemWidget* patientItemWidgetByPatientName(const QString& patientName); ///@} /// Get Patients tab widget