From 6e1dfb868e62d00cd106f0e8680fbdffee9d66d4 Mon Sep 17 00:00:00 2001 From: sunwen Date: Fri, 21 Oct 2022 15:57:01 +0800 Subject: [PATCH] Refactor Network Module and add C-GET protocol. --- src/src/PACS/Common/dicomviewerhelper.cpp | 4 +- src/src/PACS/Common/dicomviewerhelper.h | 3 +- src/src/PACS/Network/GetWorker.cpp | 97 +++++ src/src/PACS/Network/GetWorker.h | 33 ++ src/src/PACS/Network/MoveStoreScp.cpp | 12 + src/src/PACS/Network/MoveStoreScp.h | 13 + src/src/PACS/Network/MoveStoreThread.cpp | 41 +++ src/src/PACS/Network/MoveStoreThread.h | 23 ++ src/src/PACS/Network/callbackhelper.cpp | 26 -- src/src/PACS/Network/callbackhelper.h | 30 -- src/src/PACS/Network/cfindcallback.cpp | 26 -- src/src/PACS/Network/cfindcallback.h | 21 -- src/src/PACS/Network/cmovecallback.cpp | 26 -- src/src/PACS/Network/cmovecallback.h | 24 -- .../PACS/Network/cmovestorescpcallback.cpp | 45 --- src/src/PACS/Network/cmovestorescpcallback.h | 27 -- src/src/PACS/Network/moveworker.cpp | 129 +++++-- src/src/PACS/Network/moveworker.h | 28 +- src/src/PACS/Network/queryworker.cpp | 297 +++++++-------- src/src/PACS/Network/queryworker.h | 15 +- src/src/PACS/Widget/importwidget.cpp | 344 +++++++++++------- src/src/PACS/Widget/importwidget.h | 25 +- src/src/PACS/Widget/pacsconfiguration.cpp | 69 +++- src/src/PACS/Widget/pacsconfiguration.h | 5 + 24 files changed, 785 insertions(+), 578 deletions(-) create mode 100644 src/src/PACS/Network/GetWorker.cpp create mode 100644 src/src/PACS/Network/GetWorker.h create mode 100644 src/src/PACS/Network/MoveStoreScp.cpp create mode 100644 src/src/PACS/Network/MoveStoreScp.h create mode 100644 src/src/PACS/Network/MoveStoreThread.cpp create mode 100644 src/src/PACS/Network/MoveStoreThread.h delete mode 100644 src/src/PACS/Network/callbackhelper.cpp delete mode 100644 src/src/PACS/Network/callbackhelper.h delete mode 100644 src/src/PACS/Network/cfindcallback.cpp delete mode 100644 src/src/PACS/Network/cfindcallback.h delete mode 100644 src/src/PACS/Network/cmovecallback.cpp delete mode 100644 src/src/PACS/Network/cmovecallback.h delete mode 100644 src/src/PACS/Network/cmovestorescpcallback.cpp delete mode 100644 src/src/PACS/Network/cmovestorescpcallback.h diff --git a/src/src/PACS/Common/dicomviewerhelper.cpp b/src/src/PACS/Common/dicomviewerhelper.cpp index ad67753..052e025 100644 --- a/src/src/PACS/Common/dicomviewerhelper.cpp +++ b/src/src/PACS/Common/dicomviewerhelper.cpp @@ -1,4 +1,4 @@ -#include "dicomviewerhelper.h" +#include "dicomviewerhelper.h" #include #include #include @@ -123,6 +123,7 @@ bool DicomViewerProductCfg::pacsInfo(QList& info) h.ae = (obj.find("ae").value().toString()); h.ip = (obj.find("ip").value().toString()); h.port = (obj.find("port").value().toString()); + h.protocol = (obj.find("protocol").value().toInt()); info.push_back(h); beg++; } @@ -145,6 +146,7 @@ bool DicomViewerProductCfg::setPacsInfo(QList& info) o["ae"] = beg->ae; o["ip"] = beg->ip; o["port"] = beg->port; + o["protocol"] = beg->protocol; arr.append(o); beg++; } diff --git a/src/src/PACS/Common/dicomviewerhelper.h b/src/src/PACS/Common/dicomviewerhelper.h index 3a27b52..3ccca3b 100644 --- a/src/src/PACS/Common/dicomviewerhelper.h +++ b/src/src/PACS/Common/dicomviewerhelper.h @@ -1,4 +1,4 @@ -#ifndef _DICOM_VIEWER_HELPER_H_ +#ifndef _DICOM_VIEWER_HELPER_H_ #define _DICOM_VIEWER_HELPER_H_ #include @@ -13,6 +13,7 @@ struct host { QString ae; QString ip; QString port; + unsigned short protocol = 0; //0:C-Move,1:C-Get }; diff --git a/src/src/PACS/Network/GetWorker.cpp b/src/src/PACS/Network/GetWorker.cpp new file mode 100644 index 0000000..8f0f85f --- /dev/null +++ b/src/src/PACS/Network/GetWorker.cpp @@ -0,0 +1,97 @@ +#include "GetWorker.h" +#include "dcmtk/dcmnet/scu.h" + + +GetWorker::GetWorker(QObject* aParent) + : QObject(aParent) + , mScu(nullptr) +{ + +} + +void GetWorker::setOutputDirectory(const QString& outputDirectory) +{ + mOutputDirPath = outputDirectory; +} + +void GetWorker::setPacsInfo(const std::string& peerIP, unsigned short peerPort, const std::string& peerTitle, const std::string& ourTitle, unsigned short ourPort) +{ + mPeerIP = peerIP; + mPeerPort = peerPort; + mPeerTitle = peerTitle; + mOurPort = ourPort; + mOurTitle = ourTitle; +} + +bool GetWorker::initDcmSCU() +{ + mScu = new DcmSCU(); + mScu->setAETitle(mOurTitle); + mScu->setPeerHostName(mPeerIP); + mScu->setPeerPort(OFstatic_cast(Uint16, mPeerPort)); + mScu->setPeerAETitle(mPeerTitle); + OFList syntaxes; + syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); + mScu->addPresentationContext(UID_CTImageStorage, syntaxes); + mScu->addPresentationContext(UID_MRImageStorage, syntaxes); + OFCondition cond = mScu->initNetwork(); + if (cond.bad()) + { + return false; + } + cond = mScu->negotiateAssociation(); + if (cond.bad()) + { + return false; + } + return true; +} + +void GetWorker::getBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID, const QString& aDicomType) +{ + qDebug(aDicomType.toLatin1()); + if (!initDcmSCU()) + { + mScu->abortAssociation(); + emit notifyGetDone(1, ""); + delete mScu; + mScu = nullptr; + return; + } + mScu->setStorageDir(mOutputDirPath.toStdString()); + T_ASC_PresentationContextID pcid; + if(aDicomType.toLower() == "mr") + { + pcid = mScu->findPresentationContextID(UID_MRImageStorage,""); + } + else + { + pcid = mScu->findPresentationContextID(UID_CTImageStorage,""); + } + + + + OFList responses; + DcmDataset dataset; + dataset.putAndInsertOFStringArray(DCM_QueryRetrieveLevel,"STUDY"); + dataset.putAndInsertOFStringArray(DCM_StudyInstanceUID,studyInstanceUID.toStdString()); + dataset.putAndInsertOFStringArray(DCM_SeriesInstanceUID,seriesInstanceUID.toStdString()); + OFCondition cond = mScu->sendCGETRequest(pcid, &dataset, &responses); + + if(responses.begin() != responses.end() && (*responses.begin())->m_numberOfCompletedSubops > 0) + { + emit notifyGetDone(0,mOutputDirPath); + } + + if (cond.bad()|| cond != EC_Normal) + { + mScu->closeAssociation(DCMSCU_ABORT_ASSOCIATION); + } + else + { + mScu->releaseAssociation(); + } + delete mScu; + mScu = nullptr; +} + diff --git a/src/src/PACS/Network/GetWorker.h b/src/src/PACS/Network/GetWorker.h new file mode 100644 index 0000000..42c8ec5 --- /dev/null +++ b/src/src/PACS/Network/GetWorker.h @@ -0,0 +1,33 @@ +#ifndef GETWORKER_H +#define GETWORKER_H + +#include + +class DcmSCU; + +class GetWorker : public QObject +{ + Q_OBJECT +public: + GetWorker(QObject* aParent); + void setOutputDirectory(const QString& outputDir); + void setPacsInfo(const std::string& peerIP, unsigned short peerPort, const std::string& peerTitle, const std::string& ourTitle, unsigned short ourPort); + Q_INVOKABLE void getBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID, const QString& aDicomType); + +signals: + void notifyGetDone(int, QString aDirPath); + +private: + bool initDcmSCU(); + +private: + DcmSCU* mScu; + QString mOutputDirPath; + std::string mPeerTitle; + std::string mPeerIP; + std::string mOurTitle; + unsigned short mPeerPort; + unsigned short mOurPort; +}; + +#endif // GETWORKER_H diff --git a/src/src/PACS/Network/MoveStoreScp.cpp b/src/src/PACS/Network/MoveStoreScp.cpp new file mode 100644 index 0000000..e586eae --- /dev/null +++ b/src/src/PACS/Network/MoveStoreScp.cpp @@ -0,0 +1,12 @@ +#include "MoveStoreScp.h" + +MoveStoreScp::MoveStoreScp() + : DcmStorageSCP() +{ + +} + +bool MoveStoreScp::stopAfterCurrentAssociation() +{ + return true; +} diff --git a/src/src/PACS/Network/MoveStoreScp.h b/src/src/PACS/Network/MoveStoreScp.h new file mode 100644 index 0000000..b6fbb5f --- /dev/null +++ b/src/src/PACS/Network/MoveStoreScp.h @@ -0,0 +1,13 @@ +#ifndef MOVESTORESCP_H +#define MOVESTORESCP_H + +#include "dcmtk/dcmnet/dstorscp.h" + +class MoveStoreScp : public DcmStorageSCP +{ +public: + MoveStoreScp(); + bool stopAfterCurrentAssociation(); +}; + +#endif // MOVESTORESCP_H diff --git a/src/src/PACS/Network/MoveStoreThread.cpp b/src/src/PACS/Network/MoveStoreThread.cpp new file mode 100644 index 0000000..418d56f --- /dev/null +++ b/src/src/PACS/Network/MoveStoreThread.cpp @@ -0,0 +1,41 @@ +#include "MoveStoreThread.h" +#include "MoveStoreScp.h" + +MoveStoreThread::MoveStoreThread(const std::string aAETitle, unsigned short aPort, QObject* aParent) + : QThread(aParent) + , mAETitle(aAETitle) + , mPort(aPort) +{ + +} + +MoveStoreThread::~MoveStoreThread() +{ +} + +void MoveStoreThread::run() +{ + MoveStoreScp scp; + scp.setAETitle(mAETitle); + scp.setPort(mPort); + scp.setVerbosePCMode(false); + scp.setOutputDirectory(mOutputPath); + OFList syntaxes; + syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); + syntaxes.push_back(UID_LittleEndianImplicitTransferSyntax); + scp.addPresentationContext(UID_CTImageStorage,syntaxes); + scp.addPresentationContext(UID_MRImageStorage,syntaxes); + scp.listen(); + exit(0); +} + +void MoveStoreThread::setScpConfig(const std::string aAETitle, unsigned short aPort) +{ + mAETitle = aAETitle; + mPort = aPort; +} + +void MoveStoreThread::setOutputPath(const std::string& aOutputPath) +{ + mOutputPath = aOutputPath; +} diff --git a/src/src/PACS/Network/MoveStoreThread.h b/src/src/PACS/Network/MoveStoreThread.h new file mode 100644 index 0000000..4f3bded --- /dev/null +++ b/src/src/PACS/Network/MoveStoreThread.h @@ -0,0 +1,23 @@ +#ifndef MOVESTORETHREAD_H +#define MOVESTORETHREAD_H + +#include + +class MoveStoreScp; + +class MoveStoreThread : public QThread +{ +public: + MoveStoreThread(const std::string aAETitle, unsigned short aPort, QObject* aParent = nullptr); + ~MoveStoreThread(); + void run(); + void setScpConfig(const std::string aAETitle, unsigned short aPort); + void setOutputPath(const std::string& aOutputPath); + +private: + std::string mAETitle; + unsigned short mPort; + std::string mOutputPath; +}; + +#endif // MOVESTORETHREAD_H diff --git a/src/src/PACS/Network/callbackhelper.cpp b/src/src/PACS/Network/callbackhelper.cpp deleted file mode 100644 index f37066d..0000000 --- a/src/src/PACS/Network/callbackhelper.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "callbackhelper.h" -#include "dcmtk/dcmdata/dcdatset.h" - -CallbackHelper::CallbackHelper(QObject *parent) - : QObject(parent) -{ -} - -CallbackHelper::~CallbackHelper() -{ -} - -void CallbackHelper::foundResult(int index, DcmDataset *response) -{ - emit sig_foundResult(index, response); -} - -void CallbackHelper::moveProgress(int progress, int total) -{ - emit sig_moveProgress(progress, total); -} - -void CallbackHelper::moveStoreProgress(int code, std::string filename) -{ - emit sig_moveStoreProgress(code, filename); -} \ No newline at end of file diff --git a/src/src/PACS/Network/callbackhelper.h b/src/src/PACS/Network/callbackhelper.h deleted file mode 100644 index 986fdf7..0000000 --- a/src/src/PACS/Network/callbackhelper.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _CALLBACKHELPER_H_ -#define _CALLBACKHELPER_H_ - -#include - -class DcmDataset; - -// A helper class which connect callback and uppper Qt application through signal/slot - -class CallbackHelper : public QObject -{ - Q_OBJECT - -public: - explicit CallbackHelper(QObject *parent = Q_NULLPTR); - ~CallbackHelper(); - - void foundResult(int index, DcmDataset *response); - void moveProgress(int progress, int total); - void moveStoreProgress(int code, std::string filename); - - -signals: - void sig_foundResult(int index, DcmDataset *response); - void sig_moveProgress(int progress, int total); - void sig_moveStoreProgress(int code, std::string filename); - -}; - -#endif // !_CALLBACKHELPER_H_ diff --git a/src/src/PACS/Network/cfindcallback.cpp b/src/src/PACS/Network/cfindcallback.cpp deleted file mode 100644 index 7667c50..0000000 --- a/src/src/PACS/Network/cfindcallback.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "cfindcallback.h" - -CFindCallback::CFindCallback() - : dcm_cfind_callback() - , CFindCallbackHelper(nullptr) -{ -} - -CFindCallback::~CFindCallback() -{ -} - -void CFindCallback::setHelper(CallbackHelper *helper) -{ - CFindCallbackHelper = helper; -} - -void CFindCallback::callback(T_DIMSE_C_FindRQ *request, int &responseCount, T_DIMSE_C_FindRSP *rsp, DcmDataset *responseIdentifiers) -{ - if (CFindCallbackHelper != nullptr) - { - //std::string name; - //responseIdentifiers->findAndGetOFString(DCM_PatientName, name); - CFindCallbackHelper->foundResult(responseCount, responseIdentifiers); - } -} diff --git a/src/src/PACS/Network/cfindcallback.h b/src/src/PACS/Network/cfindcallback.h deleted file mode 100644 index 9c2e961..0000000 --- a/src/src/PACS/Network/cfindcallback.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _CFIND_CALLBACK_H_ -#define _CFIND_CALLBACK_H_ - -#include "dcm_find.h" -#include "callbackhelper.h" - -class CFindCallback : public dcm_cfind_callback -{ - -public: - CFindCallback(); - virtual ~CFindCallback(); - virtual void callback(T_DIMSE_C_FindRQ *request, int &responseCount, T_DIMSE_C_FindRSP *rsp, DcmDataset *responseIndentifiers); - - void setHelper(CallbackHelper *h); - -private: - CallbackHelper *CFindCallbackHelper; -}; - -#endif diff --git a/src/src/PACS/Network/cmovecallback.cpp b/src/src/PACS/Network/cmovecallback.cpp deleted file mode 100644 index 4f47d8c..0000000 --- a/src/src/PACS/Network/cmovecallback.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "cmovecallback.h" - -CMoveCallback::CMoveCallback() - : dcm_cmove_callback() - , CMoveCallbackHelper(nullptr) -{ - -} - -CMoveCallback::~CMoveCallback() -{ - -} - -void CMoveCallback::setHelper(CallbackHelper *helper) -{ - CMoveCallbackHelper = helper; -} - -void CMoveCallback::callback(T_DIMSE_C_MoveRQ *request, int responseCount, T_DIMSE_C_MoveRSP *response) -{ - if (CMoveCallbackHelper != nullptr) - { - CMoveCallbackHelper ->moveProgress(response->NumberOfCompletedSubOperations, response->NumberOfCompletedSubOperations + response->NumberOfRemainingSubOperations); - } -} \ No newline at end of file diff --git a/src/src/PACS/Network/cmovecallback.h b/src/src/PACS/Network/cmovecallback.h deleted file mode 100644 index 6fa4567..0000000 --- a/src/src/PACS/Network/cmovecallback.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _CMOVE_CALLBACK_H_ -#define _CMOVE_CALLBACK_H_ - -#include "dcm_move.h" -#include "callbackhelper.h" - -class CMoveCallback : public dcm_cmove_callback -{ - -public: - CMoveCallback(); - ~CMoveCallback(); - - virtual void callback(T_DIMSE_C_MoveRQ *request, int responseCount, T_DIMSE_C_MoveRSP *response); - - void setHelper(CallbackHelper *helper); - -private: - CallbackHelper *CMoveCallbackHelper; -}; - - -#endif // !_CMOVE_CALLBACK_H_ - diff --git a/src/src/PACS/Network/cmovestorescpcallback.cpp b/src/src/PACS/Network/cmovestorescpcallback.cpp deleted file mode 100644 index 0779684..0000000 --- a/src/src/PACS/Network/cmovestorescpcallback.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "cmovestorescpcallback.h" - -CMoveStoreSCPCallback::CMoveStoreSCPCallback(std::string outDirectory) - : dcm_cmove_storescp_callback() - , CMoveStoreScpCallbackHelper(nullptr) -{ - outDirectory_ = outDirectory; -} - -CMoveStoreSCPCallback::~CMoveStoreSCPCallback() -{ - -} - -void CMoveStoreSCPCallback::setHelper(CallbackHelper *helper) -{ - CMoveStoreScpCallbackHelper = helper; -} - -void CMoveStoreSCPCallback::callback(T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *request, char *imageFileName, DcmDataset **imageDataSet, T_DIMSE_C_StoreRSP *response, DcmDataset **statusDetail) -{ - - if (progress->state == DIMSE_StoreEnd) - { - if (imageDataSet != nullptr && *imageDataSet != nullptr) - { - std::string ofname; - OFStandard::combineDirAndFilename(ofname, outDirectory_, imageFile_, true); // use base class's imageFile_ - E_TransferSyntax xfer = (*imageDataSet)->getOriginalXfer(); - - OFCondition cond = dcmff_->saveFile(ofname.c_str(), xfer, EET_ExplicitLength, EGL_recalcGL, EPD_withoutPadding, 0, 0, EWM_fileformat); - if (cond.bad()) - { - OFStandard::deleteFile(ofname); - if (CMoveStoreScpCallbackHelper != nullptr) - CMoveStoreScpCallbackHelper->moveStoreProgress(1, imageFile_); - } - else - { - if (CMoveStoreScpCallbackHelper != nullptr) - CMoveStoreScpCallbackHelper->moveStoreProgress(0, imageFile_); - } - } - } -} diff --git a/src/src/PACS/Network/cmovestorescpcallback.h b/src/src/PACS/Network/cmovestorescpcallback.h deleted file mode 100644 index 4887d01..0000000 --- a/src/src/PACS/Network/cmovestorescpcallback.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _CMOVE_STORESCP_CALLBACK_H_ -#define _CMOVE_STORESCP_CALLBACK_H_ - -#include "dcm_move.h" -#include "callbackhelper.h" - -class CMoveStoreSCPCallback : public dcm_cmove_storescp_callback -{ - -public: - CMoveStoreSCPCallback(std::string outDirectory); - ~CMoveStoreSCPCallback(); - - virtual void callback(T_DIMSE_StoreProgress *progress, T_DIMSE_C_StoreRQ *request, char *imageFileName, DcmDataset **imageDataSet, T_DIMSE_C_StoreRSP *response, DcmDataset **statusDetail); - - void setHelper(CallbackHelper *helper); - -private: - CallbackHelper *CMoveStoreScpCallbackHelper; - std::string outDirectory_; - -}; - - - -#endif // !_CMOVE_STORESCP_CALLBACK_H_ - diff --git a/src/src/PACS/Network/moveworker.cpp b/src/src/PACS/Network/moveworker.cpp index 9c529e9..af9607d 100644 --- a/src/src/PACS/Network/moveworker.cpp +++ b/src/src/PACS/Network/moveworker.cpp @@ -1,54 +1,111 @@ #include "moveworker.h" +#include "MoveStoreThread.h" +#include "dcmtk/dcmnet/scu.h" -MoveWorker::MoveWorker(const QString& peerIP, unsigned long long peerPort, const QString& peerTitle, unsigned long long ourPort, const QString& ourTitle, const QString& outputDirectory, QObject *parent) +MoveWorker::MoveWorker(const std::string& peerIP, unsigned long long peerPort, const std::string& peerTitle, unsigned long long ourPort, const std::string& ourTitle, const QString& outputDirectory, QObject *parent) : QObject(parent) - , m_pCallbackHelper(nullptr) + , mMoveStoreThread(new MoveStoreThread(ourTitle, static_cast(ourPort),this)) + , mScu(nullptr) + , mIsSendMoveMsgSucessed(false) { - m_strPeerIP_ = peerIP; - m_ulPeerPort_ = peerPort; - m_strPeerTitle_ = peerTitle; - m_ulOurPort_ = ourPort; - m_strOurTitle_ = ourTitle; - m_strOutputDirectory_ = outputDirectory; + mStrPeerIP = peerIP; + mUlPeerPort = peerPort; + mStrPeerTitle = peerTitle; + mUlOurPort = ourPort; + mStrOurTitle = ourTitle; + mStrOutputDirectory = outputDirectory; + connect(mMoveStoreThread,&QThread::finished,this,&MoveWorker::onMoveDone); } void MoveWorker::setOutputDirectory(const QString& outputDirectory) { - m_strOutputDirectory_ = outputDirectory; + mStrOutputDirectory = outputDirectory; + mMoveStoreThread->setOutputPath(mStrOutputDirectory.toStdString()); +} + +void MoveWorker::setPacsInfo(const std::string& peerIP, unsigned long peerPort, const std::string& peerTitle, const std::string& ourTitle, unsigned long ourPort) +{ + mStrPeerIP = peerIP; + mUlPeerPort = peerPort; + mStrPeerTitle = peerTitle; + mUlOurPort = ourPort; + mStrOurTitle = ourTitle; +} + +bool MoveWorker::initDcmSCU() +{ + mScu = new DcmSCU(); + mScu->setAETitle(mStrOurTitle); + mScu->setPeerHostName(mStrPeerIP); + mScu->setPeerPort(OFstatic_cast(Uint16, mUlPeerPort)); + mScu->setPeerAETitle(mStrPeerTitle); + OFList syntaxes; + syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); + mScu->addPresentationContext(UID_MOVEPatientRootQueryRetrieveInformationModel, syntaxes); + OFCondition cond = mScu->initNetwork(); + if (cond.bad()) + { + return false; + } + cond = mScu->negotiateAssociation(); + if (cond.bad()) + { + return false; + } + return true; } void MoveWorker::moveBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID) { - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long long ullPeerPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - unsigned long long ullOurPort = m_ulOurPort_; - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cmove *cmove = new dcm_cmove(strPeerIP.c_str(), ullPeerPort, strPeerTitle.c_str(), ullOurPort, strOurTitle.c_str()); + if (!initDcmSCU()) + { + mScu->abortAssociation(); + emit notifyMoveDone(1, ""); + delete mScu; + mScu = nullptr; + return; + } + mMoveStoreThread->setScpConfig(mStrOurTitle,static_cast(mUlOurPort)); + mMoveStoreThread->start(); + T_ASC_PresentationContextID pcid = mScu->findPresentationContextID(UID_MOVEPatientRootQueryRetrieveInformationModel,""); + OFList responses; + DcmDataset dataset; + std::string strStudyInstanceUID = studyInstanceUID.toStdString(); + std::string strSeriesInstanceUID = seriesInstanceUID.toStdString(); + dataset.putAndInsertOFStringArray(DCM_QueryRetrieveLevel,"STUDY"); + dataset.putAndInsertOFStringArray(DCM_StudyInstanceUID,strStudyInstanceUID); + dataset.putAndInsertOFStringArray(DCM_SeriesInstanceUID,strSeriesInstanceUID); + OFCondition cond = mScu->sendMOVERequest(pcid,mStrOurTitle, &dataset, &responses); - CMoveCallback *moveCallback = new CMoveCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_moveProgress(int, int)), this, SLOT(onMoveProgress(int, int)), Qt::DirectConnection); - connect(m_pCallbackHelper, &CallbackHelper::sig_moveStoreProgress, [=](int i,std::string str){ - onMoveStoreProgress(i, str.c_str()); - }); - } - moveCallback->setHelper(m_pCallbackHelper); - cmove->set_cmove_callback(moveCallback); + if(responses.begin() != responses.end() && (*responses.begin())->m_numberOfCompletedSubops > 0) + { + mIsSendMoveMsgSucessed = true; + } + else + { + mMoveStoreThread->terminate(); + } - std::string strOutputDirectory = m_strOutputDirectory_.toStdString(); - CMoveStoreSCPCallback *moveStoreCallback = new CMoveStoreSCPCallback(strOutputDirectory); - moveStoreCallback->setHelper(m_pCallbackHelper); - cmove->set_cmove_scp_callback(moveStoreCallback); + if (cond.bad()|| cond != EC_Normal) + { + mScu->closeAssociation(DCMSCU_ABORT_ASSOCIATION); + } + else + { + mScu->releaseAssociation(); + } + delete mScu; + mScu = nullptr; - std::string strStudyInstanceUID = studyInstanceUID.toStdString(); - std::string strSeriesInstanceUID = seriesInstanceUID.toStdString(); - int ret = cmove->move_by_series_uid(strStudyInstanceUID, strSeriesInstanceUID); - - emit notifyMoveDone(ret, m_strOutputDirectory_); +} +void MoveWorker::onMoveDone() +{ + if(mIsSendMoveMsgSucessed) + { + emit notifyMoveDone(0, mStrOutputDirectory); + mIsSendMoveMsgSucessed = false; + } } void MoveWorker::onMoveProgress(int progress, int total) @@ -59,4 +116,4 @@ void MoveWorker::onMoveProgress(int progress, int total) void MoveWorker::onMoveStoreProgress(int code, QString filename) { emit notifyMoveStoreProgress(code, filename); -} \ No newline at end of file +} diff --git a/src/src/PACS/Network/moveworker.h b/src/src/PACS/Network/moveworker.h index 4fcf394..1ddea71 100644 --- a/src/src/PACS/Network/moveworker.h +++ b/src/src/PACS/Network/moveworker.h @@ -2,18 +2,18 @@ #define _MOVEWORKER_H_ #include -#include "callbackhelper.h" -#include "cmovecallback.h" -#include "cmovestorescpcallback.h" +class MoveStoreThread; +class DcmSCU; class MoveWorker : public QObject { Q_OBJECT public: - explicit MoveWorker(const QString& peerIP, unsigned long long peerPort, const QString& peerTitle, unsigned long long ourPort, const QString& ourTitle, const QString& outputDirectory, QObject *parent = Q_NULLPTR); + explicit MoveWorker(const std::string& peerIP, unsigned long long peerPort, const std::string& peerTitle, unsigned long long ourPort, const std::string& ourTitle, const QString& outputDirectory, QObject *parent = Q_NULLPTR); void setOutputDirectory(const QString& outputDir); + void setPacsInfo(const std::string& peerIP, unsigned long peerPort, const std::string& peerTitle, const std::string& ourTitle, unsigned long ourPort); Q_INVOKABLE void moveBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID); signals: @@ -24,15 +24,21 @@ signals: public slots: void onMoveProgress(int, int); void onMoveStoreProgress(int, QString); + void onMoveDone(); private: - QString m_strPeerIP_; - unsigned long long m_ulPeerPort_; - QString m_strPeerTitle_; - unsigned long long m_ulOurPort_; - QString m_strOurTitle_; - QString m_strOutputDirectory_; - CallbackHelper* m_pCallbackHelper; + bool initDcmSCU(); + +private: + std::string mStrPeerIP; + unsigned long long mUlPeerPort; + std::string mStrPeerTitle; + unsigned long long mUlOurPort; + std::string mStrOurTitle; + QString mStrOutputDirectory; + MoveStoreThread* mMoveStoreThread; + DcmSCU* mScu; + bool mIsSendMoveMsgSucessed; }; diff --git a/src/src/PACS/Network/queryworker.cpp b/src/src/PACS/Network/queryworker.cpp index 85554a0..94822fb 100644 --- a/src/src/PACS/Network/queryworker.cpp +++ b/src/src/PACS/Network/queryworker.cpp @@ -1,15 +1,23 @@ #include "queryworker.h" #include "dcmtk/dcmdata/dcdatset.h" +#include "dcmtk/dcmnet/scu.h" QueryWorker::QueryWorker(const QString& peerIP, unsigned long peerPort, const QString& peerTitle, const QString& ourTitle, QObject *parent) : QObject(parent) - , m_pCallbackHelper(nullptr) + , m_Scu(nullptr) + , m_QueryDataSet(new DcmDataset()) { m_strPeerIP_ = peerIP; m_ulPeerPort_ = peerPort; m_strPeerTitle_ = peerTitle; m_strOurTitle_ = ourTitle; m_iQueryLevel = 0; + initQueryDataSet(); +} + +QueryWorker::~QueryWorker() +{ + delete m_QueryDataSet; } void QueryWorker::setPacsInfo(const QString& peerIP, unsigned long peerPort, const QString& peerTitle, const QString& ourTitle) @@ -20,195 +28,166 @@ void QueryWorker::setPacsInfo(const QString& peerIP, unsigned long peerPort, con m_strOurTitle_ = ourTitle; } +bool QueryWorker::initDcmSCU() +{ + m_Scu = new DcmSCU(); + m_Scu->setAETitle(m_strOurTitle_.toStdString()); + m_Scu->setPeerHostName(m_strPeerIP_.toStdString()); + m_Scu->setPeerPort(OFstatic_cast(Uint16, m_ulPeerPort_)); + m_Scu->setPeerAETitle(m_strPeerTitle_.toStdString()); + OFList syntaxes; + syntaxes.push_back(UID_LittleEndianExplicitTransferSyntax); + m_Scu->addPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel, syntaxes); + OFCondition cond = m_Scu->initNetwork(); + if (cond.bad()) + { + return false; + } + cond = m_Scu->negotiateAssociation(); + if (cond.bad()) + { + return false; + } + return true; +} + +void QueryWorker::initQueryDataSet() +{ + m_QueryDataSet->putAndInsertOFStringArray(DCM_QueryRetrieveLevel,"STUDY"); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientName,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_AccessionNumber,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientBirthDate,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientSex,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyInstanceUID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_RequestingPhysician,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_SeriesInstanceUID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_Modality,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_SeriesNumber,""); +} + +void QueryWorker::executeCFind(DcmDataset* aQueryKeys) +{ + if (!initDcmSCU()) + { + m_Scu->abortAssociation(); + emit sendFindDone(0); + delete m_Scu; + m_Scu = nullptr; + return; + } + OFList responses; + T_ASC_PresentationContextID pcid = m_Scu->findPresentationContextID(UID_FINDStudyRootQueryRetrieveInformationModel,""); + OFCondition cond = m_Scu->sendFINDRequest(pcid, aQueryKeys, &responses); + emit sendFindDone(responses.empty() ? 0 : static_cast(responses.size())-1); + if (!responses.empty()) + { + for(auto item : responses) + { + if(item->m_dataset == nullptr) continue; + onFoundResult(0,item->m_dataset); + } + } + if (cond == EC_Normal) + { + m_Scu->releaseAssociation(); + } + else + { + m_Scu->closeAssociation(DCMSCU_ABORT_ASSOCIATION); + } + delete m_Scu; + m_Scu = nullptr; +} + void QueryWorker::queryByPatientName(const QString& patientName) { - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_patient_name(patientName.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_iQueryLevel = 0; + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientName,patientName.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientName,""); } void QueryWorker::queryByPatientNameAndDate(const QString& patientName, const QString& studyStartDate, const QString& studyEndDate) { - QString patientName_ = "*"; - patientName_ += patientName; - patientName_ += "*"; - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_patient_name_and_date(patientName_.toStdString(), studyStartDate.toStdString(), studyEndDate.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + initQueryDataSet(); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientName,patientName.toStdString()); + QString dateQuery = studyStartDate; + if(!studyEndDate.isEmpty()) + { + dateQuery += "-"+studyEndDate; + } + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,dateQuery.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientName,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,""); } void QueryWorker::queryByPatientID(const QString& patientID) { - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_patient_id(patientID.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_iQueryLevel = 0; + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientID,patientID.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientID,""); } void QueryWorker::queryByPatientIDAndDate(const QString& patientID, const QString& studyStartDate, const QString& studyEndDate) { - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_patient_id_and_date(patientID.toStdString(), studyStartDate.toStdString(), studyEndDate.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_iQueryLevel = 0; + initQueryDataSet(); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientID,patientID.toStdString()); + QString dateQuery = studyStartDate; + if(!studyEndDate.isEmpty()) + { + dateQuery += "-"+studyEndDate; + } + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,dateQuery.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_PatientID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,""); } void QueryWorker::queryByAccessNo(const QString& accsessionNo) { - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_accession_no(accsessionNo.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_iQueryLevel = 0; + m_QueryDataSet->putAndInsertOFStringArray(DCM_AccessionNumber,accsessionNo.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_AccessionNumber,""); } void QueryWorker::queryByAccessNoAndDate(const QString& accessionNo, const QString& studyStartDate, const QString& studyEndDate) { - m_iQueryLevel = 0; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_accession_no_and_date(accessionNo.toStdString(), studyStartDate.toStdString(), studyEndDate.toStdString()); - - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_iQueryLevel = 0; + initQueryDataSet(); + m_QueryDataSet->putAndInsertOFStringArray(DCM_AccessionNumber,accessionNo.toStdString()); + QString dateQuery = studyStartDate; + if(!studyEndDate.isEmpty()) + { + dateQuery += "-"+studyEndDate; + } + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,dateQuery.toStdString()); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_AccessionNumber,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyDate,""); } void QueryWorker::queryBySeriesUID(const QString& studyInstanceUID) { m_iQueryLevel = 1; - std::string strPeerIP = m_strPeerIP_.toStdString(); - unsigned long ulPort = m_ulPeerPort_; - std::string strPeerTitle = m_strPeerTitle_.toStdString(); - std::string strOurTitle = m_strOurTitle_.toStdString(); - dcm_cfind *cfind = new dcm_cfind(strPeerIP.c_str(), ulPort, strPeerTitle.c_str(), strOurTitle.c_str()); - - CFindCallback *findCallback = new CFindCallback(); - if (m_pCallbackHelper == nullptr) - { - m_pCallbackHelper = new CallbackHelper(); - connect(m_pCallbackHelper, SIGNAL(sig_foundResult(int, DcmDataset *)), this, SLOT(onFoundResult(int, DcmDataset *)), Qt::DirectConnection); - } - findCallback->setHelper(m_pCallbackHelper); - cfind->set_find_callback(findCallback); - - int ret = cfind->find_by_series_uid(studyInstanceUID.toStdString()); - emit sendFindDone(ret); - - delete findCallback; - delete cfind; + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyInstanceUID,studyInstanceUID.toStdString()); + m_QueryDataSet->putAndInsertOFStringArray(DCM_QueryRetrieveLevel,"SERIES"); + executeCFind(m_QueryDataSet); + m_QueryDataSet->putAndInsertOFStringArray(DCM_StudyInstanceUID,""); + m_QueryDataSet->putAndInsertOFStringArray(DCM_QueryRetrieveLevel,"STUDY"); } void QueryWorker::onFoundResult(int index, DcmDataset *response) { std::string studyDate_, patientName_, patientID_, accessionNumber_, - patientBirthDate_, patientSex_, patientAge_, studyInstanceUID_, + patientBirthDate_, patientSex_, studyInstanceUID_, studyID_, requestingPhysician_, seriesUid_, modality_, seriesNumber_; response->findAndGetOFString(DCM_StudyDate, studyDate_); response->findAndGetOFString(DCM_PatientName, patientName_); @@ -216,7 +195,6 @@ void QueryWorker::onFoundResult(int index, DcmDataset *response) response->findAndGetOFString(DCM_AccessionNumber, accessionNumber_); response->findAndGetOFString(DCM_PatientBirthDate, patientBirthDate_); response->findAndGetOFString(DCM_PatientSex, patientSex_); - response->findAndGetOFString(DCM_PatientAge, patientAge_); response->findAndGetOFString(DCM_StudyInstanceUID, studyInstanceUID_); response->findAndGetOFString(DCM_StudyID, studyID_); response->findAndGetOFString(DCM_RequestingPhysician, requestingPhysician_); @@ -233,7 +211,6 @@ void QueryWorker::onFoundResult(int index, DcmDataset *response) study.accessionNumber = QString::fromStdString(accessionNumber_); study.patientBirthDate = QString::fromStdString(patientBirthDate_); study.patientSex = QString::fromStdString(patientSex_); - study.patientAge = QString::fromStdString(patientAge_); study.studyInstanceUID = QString::fromStdString(studyInstanceUID_); study.studyID = QString::fromStdString(studyID_); study.requestingPhysician = QString::fromStdString(requestingPhysician_); @@ -251,4 +228,4 @@ void QueryWorker::onFoundResult(int index, DcmDataset *response) emit sendSeriesItemFound(series); } -} \ No newline at end of file +} diff --git a/src/src/PACS/Network/queryworker.h b/src/src/PACS/Network/queryworker.h index 164ba62..b886382 100644 --- a/src/src/PACS/Network/queryworker.h +++ b/src/src/PACS/Network/queryworker.h @@ -2,12 +2,12 @@ #define _QUERYWORKER_H_ #include +#include #include "../Common/dicomviewertype.h" -#include "callbackhelper.h" -#include "cfindcallback.h" class DcmDataset; +class DcmSCU; class QueryWorker : public QObject { @@ -15,7 +15,8 @@ class QueryWorker : public QObject public: explicit QueryWorker(const QString& peerIP, unsigned long peerPort, const QString& peerTitle, const QString& ourTitle, QObject *parent = Q_NULLPTR); - void setPacsInfo(const QString& peerIP, unsigned long peerPort, const QString& peerTitle, const QString& ourTitle); + ~QueryWorker(); + void setPacsInfo(const QString& peerIP, unsigned long peerPort, const QString& peerTitle, const QString& ourTitle); Q_INVOKABLE void queryByPatientName(const QString& patientName); Q_INVOKABLE void queryByPatientNameAndDate(const QString& patientName, const QString& studyStartDate, const QString& studyEndDate); Q_INVOKABLE void queryByPatientID(const QString& patientID); @@ -32,13 +33,19 @@ signals: public slots: void onFoundResult(int index, DcmDataset *response); +private: + bool initDcmSCU(); + void initQueryDataSet(); + void executeCFind(DcmDataset* aQueryKeys); + private: QString m_strPeerIP_; unsigned long m_ulPeerPort_; QString m_strPeerTitle_; QString m_strOurTitle_; - CallbackHelper* m_pCallbackHelper; int m_iQueryLevel; // 0 - study, 1 - series // Here, should be a better solution + DcmSCU* m_Scu; + DcmDataset* m_QueryDataSet; }; diff --git a/src/src/PACS/Widget/importwidget.cpp b/src/src/PACS/Widget/importwidget.cpp index e5b15bb..1cd2349 100644 --- a/src/src/PACS/Widget/importwidget.cpp +++ b/src/src/PACS/Widget/importwidget.cpp @@ -15,14 +15,13 @@ #include #include "PACS/Dialog/promptdialog.h" -#include "PACS/Network/cfindcallback.h" -#include "PACS/Network/callbackhelper.h" #include "PACS/Common/dicomviewerhelper.h" #include "PACS/Common/dicomviewertype.h" +#include "PACS/Network/queryworker.h" +#include "PACS/Network/moveworker.h" +#include "PACS/Network/GetWorker.h" #include "dcmtk/dcmdata/dcdatset.h" #include "dcm_move.h" -#include "PACS/Network/cmovecallback.h" -#include "PACS/Network/cmovestorescpcallback.h" ImportWidget::ImportWidget(QWidget *parent) : QDialog(parent) @@ -50,10 +49,12 @@ ImportWidget::ImportWidget(QWidget *parent) , m_pProgressLayout(nullptr) , m_pProgressItem(nullptr) , m_pProgressBar(nullptr) - , m_pQueryWorkerThread(nullptr) - , m_pQueryWorker(nullptr) - , m_pMoveWorkerThread(nullptr) - , m_pMoveWorker(nullptr) + , mQueryWorkerThread(nullptr) + , mQueryWorker(nullptr) + , mMoveWorkerThread(nullptr) + , mMoveWorker(nullptr) + , mGetWorkerThread(nullptr) + , mGetWorker(nullptr) { qRegisterMetaType("PACSStudyInfo"); qRegisterMetaType("PACSSeriesInfo"); @@ -63,32 +64,32 @@ ImportWidget::ImportWidget(QWidget *parent) ImportWidget::~ImportWidget() { - if (m_pQueryWorkerThread != nullptr && !m_pQueryWorkerThread->isFinished()) + if (mQueryWorkerThread != nullptr && !mQueryWorkerThread->isFinished()) { - m_pQueryWorkerThread->exit(); - m_pQueryWorkerThread->wait(); - delete m_pQueryWorkerThread; - m_pQueryWorkerThread = nullptr; + mQueryWorkerThread->exit(); + mQueryWorkerThread->wait(); + delete mQueryWorkerThread; + mQueryWorkerThread = nullptr; } - if (m_pQueryWorker != nullptr) + if (mQueryWorker != nullptr) { - delete m_pQueryWorker; - m_pQueryWorker = nullptr; + delete mQueryWorker; + mQueryWorker = nullptr; } - if (m_pMoveWorkerThread != nullptr && !m_pMoveWorkerThread->isFinished()) + if (mMoveWorkerThread != nullptr && !mMoveWorkerThread->isFinished()) { - m_pMoveWorkerThread->exit(); - m_pMoveWorkerThread->wait(); - delete m_pMoveWorkerThread; - m_pMoveWorkerThread = nullptr; + mMoveWorkerThread->exit(); + mMoveWorkerThread->wait(); + delete mMoveWorkerThread; + mMoveWorkerThread = nullptr; } - if (m_pMoveWorker != nullptr) + if (mMoveWorker != nullptr) { - delete m_pMoveWorker; - m_pMoveWorker = nullptr; + delete mMoveWorker; + mMoveWorker = nullptr; } } @@ -184,13 +185,15 @@ void ImportWidget::initFilterPacs() { m_lHosts.clear(); DicomViewerHelper::pacsInfo(m_lHosts); - + QString currentText = m_pPacsComboBox->currentText(); m_pPacsComboBox->clear(); - - QList::const_iterator itr = m_lHosts.begin(); - for (; itr != m_lHosts.end(); ++itr) + for (int i = 0; i < m_lHosts.count(); ++i) { - m_pPacsComboBox->addItem(itr->name); + m_pPacsComboBox->addItem(m_lHosts[i].name); + if(m_lHosts[i].name == currentText) + { + m_pPacsComboBox->setCurrentIndex(i); + } } //for each (host var in m_lHosts) @@ -273,6 +276,7 @@ void ImportWidget::initSeries() //m_pSeriesSelectionModel = new QItemSelectionModel; //m_pSeriesResult->setSelectionModel(m_pSeriesSelectionModel); m_pSeriesResult->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); + m_pSeriesResult->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); m_pSeriesResult->verticalHeader()->setVisible(false); m_pSeriesResult->setShowGrid(false); m_pSeriesResult->setSelectionMode(QAbstractItemView::SingleSelection); @@ -341,16 +345,22 @@ void ImportWidget::getNetParams(std::string& peerIP, unsigned long& peerPort, st break; } } - //for each (host var in hosts) - //{ - // if (var.name == m_pPacsComboBox->currentText()) - // { - // peerIP = var.ip.toStdString(); - // peerPort = var.port.toULong(); - // peerTitle = var.ae.toStdString(); - // break; - // } - //} +} + +unsigned short ImportWidget::getProtocol() +{ + QList hosts; + DicomViewerHelper::pacsInfo(hosts); + + QList::ConstIterator itr = hosts.begin(); + for (; itr != hosts.end(); ++itr) + { + if (itr->name == m_pPacsComboBox->currentText()) + { + return itr->protocol; + } + } + return 0; } void ImportWidget::onQueryDone(int code) @@ -424,16 +434,16 @@ void ImportWidget::getDateIntervalForQuery(QString& startDate, QString& endDate) // if pacs info changed, need reset the info void ImportWidget::query() { - if (m_pQueryWorkerThread == nullptr) + if (mQueryWorkerThread == nullptr) { - m_pQueryWorkerThread = new QThread; + mQueryWorkerThread = new QThread; } else { - if (!m_pQueryWorkerThread->isFinished()) + if (!mQueryWorkerThread->isFinished()) { - m_pQueryWorkerThread->quit(); - m_pQueryWorkerThread->wait(); + mQueryWorkerThread->quit(); + mQueryWorkerThread->wait(); } } @@ -445,16 +455,16 @@ void ImportWidget::query() return; } - if (m_pQueryWorker == nullptr) + if (mQueryWorker == nullptr) { - m_pQueryWorker = new QueryWorker(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); - QObject::connect(m_pQueryWorker, SIGNAL(sendFindDone(int)), this, SLOT(onQueryDone(int)), Qt::QueuedConnection); - QObject::connect(m_pQueryWorker, SIGNAL(sendStudyItemFound(PACSStudyInfo)), this, SLOT(onStudyFoundResult(PACSStudyInfo)), Qt::QueuedConnection); - QObject::connect(m_pQueryWorker, SIGNAL(sendSeriesItemFound(PACSSeriesInfo)), this, SLOT(onSeriesFoundResult(PACSSeriesInfo)), Qt::QueuedConnection); + mQueryWorker = new QueryWorker(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); + QObject::connect(mQueryWorker, SIGNAL(sendFindDone(int)), this, SLOT(onQueryDone(int)), Qt::QueuedConnection); + QObject::connect(mQueryWorker, SIGNAL(sendStudyItemFound(PACSStudyInfo)), this, SLOT(onStudyFoundResult(PACSStudyInfo)), Qt::QueuedConnection); + QObject::connect(mQueryWorker, SIGNAL(sendSeriesItemFound(PACSSeriesInfo)), this, SLOT(onSeriesFoundResult(PACSSeriesInfo)), Qt::QueuedConnection); } - m_pQueryWorker->setPacsInfo(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); - m_pQueryWorker->moveToThread(m_pQueryWorkerThread); - m_pQueryWorkerThread->start(); + mQueryWorker->setPacsInfo(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); + mQueryWorker->moveToThread(mQueryWorkerThread); + mQueryWorkerThread->start(); m_studyInfo.clear(); @@ -463,23 +473,23 @@ void ImportWidget::query() if (m_pDicomComboBox->currentText() == "Patient ID") { if(m_pDateComboBox->currentText() == "All dates" || m_pDateComboBox->currentText() == "-----------") - QMetaObject::invokeMethod(m_pQueryWorker, "queryByPatientID", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); + QMetaObject::invokeMethod(mQueryWorker, "queryByPatientID", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); else - QMetaObject::invokeMethod(m_pQueryWorker, "queryByPatientIDAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); + QMetaObject::invokeMethod(mQueryWorker, "queryByPatientIDAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); } else if (m_pDicomComboBox->currentText() == "Patient name") { if (m_pDateComboBox->currentText() == "All dates" || m_pDateComboBox->currentText() == "-----------") - QMetaObject::invokeMethod(m_pQueryWorker, "queryByPatientName", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); + QMetaObject::invokeMethod(mQueryWorker, "queryByPatientName", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); else - QMetaObject::invokeMethod(m_pQueryWorker, "queryByPatientNameAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); + QMetaObject::invokeMethod(mQueryWorker, "queryByPatientNameAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); } else if (m_pDicomComboBox->currentText() == "Accession number") { if (m_pDateComboBox->currentText() == "All dates" || m_pDateComboBox->currentText() == "-----------") - QMetaObject::invokeMethod(m_pQueryWorker, "queryByAccessNo", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); + QMetaObject::invokeMethod(mQueryWorker, "queryByAccessNo", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text())); else - QMetaObject::invokeMethod(m_pQueryWorker, "queryByAccessNoAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); + QMetaObject::invokeMethod(mQueryWorker, "queryByAccessNoAndDate", Qt::QueuedConnection, Q_ARG(QString, m_pDicomEdit->text()), Q_ARG(QString, studyStartDate), Q_ARG(QString, studyEndDate)); } } @@ -556,40 +566,40 @@ void ImportWidget::onStudySelected(const QModelIndex ¤t) if (row < 0) return; - if (m_pQueryWorkerThread == nullptr) + if (mQueryWorkerThread == nullptr) { - m_pQueryWorkerThread = new QThread; + mQueryWorkerThread = new QThread; } else { - if (!m_pQueryWorkerThread->isFinished()) + if (!mQueryWorkerThread->isFinished()) { - m_pQueryWorkerThread->exit(); - m_pQueryWorkerThread->wait(); + mQueryWorkerThread->exit(); + mQueryWorkerThread->wait(); } } - if (m_pQueryWorker == nullptr) + if (mQueryWorker == nullptr) { std::string peerIP, peerTitle, ourTitle; unsigned long peerPort = 0, ourPort = 0; - getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); + getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); if (peerIP.empty() || peerTitle.empty() || ourTitle.empty() || peerPort == 0 || ourPort == 0) { return; } - m_pQueryWorker = new QueryWorker(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); - QObject::connect(m_pQueryWorker, SIGNAL(sendFindDone(int)), this, SLOT(onQueryDone(int)), Qt::QueuedConnection); - QObject::connect(m_pQueryWorker, SIGNAL(sendStudyItemFound(PACSStudyInfo)), this, SLOT(onStudyFoundResult(PACSStudyInfo)), Qt::QueuedConnection); - QObject::connect(m_pQueryWorker, SIGNAL(sendSeriesItemFound(PACSSeriesInfo)), this, SLOT(onSeriesFoundResult(PACSSeriesInfo)), Qt::QueuedConnection); + mQueryWorker = new QueryWorker(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), QString::fromStdString(ourTitle)); + QObject::connect(mQueryWorker, SIGNAL(sendFindDone(int)), this, SLOT(onQueryDone(int)), Qt::QueuedConnection); + QObject::connect(mQueryWorker, SIGNAL(sendStudyItemFound(PACSStudyInfo)), this, SLOT(onStudyFoundResult(PACSStudyInfo)), Qt::QueuedConnection); + QObject::connect(mQueryWorker, SIGNAL(sendSeriesItemFound(PACSSeriesInfo)), this, SLOT(onSeriesFoundResult(PACSSeriesInfo)), Qt::QueuedConnection); } - m_pQueryWorker->moveToThread(m_pQueryWorkerThread); - m_pQueryWorkerThread->start(); + mQueryWorker->moveToThread(mQueryWorkerThread); + mQueryWorkerThread->start(); m_seriesInfo.clear(); std::string studyInstanceUID = m_pStudyModel->index(row, 14).data().toString().toStdString(); - QMetaObject::invokeMethod(m_pQueryWorker, "queryBySeriesUID", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(studyInstanceUID))); + QMetaObject::invokeMethod(mQueryWorker, "queryBySeriesUID", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(studyInstanceUID))); } @@ -613,67 +623,149 @@ void ImportWidget::onSeriesSelected(const QModelIndex ¤t) void ImportWidget::onSeriesDoubleClicked(const QModelIndex ¤t) { - int row = current.row(); - if (row < 0) - return; + if(getProtocol() == 1) + { + executeCGet(current); + } + else + { + executeCMove(current); + } +} - if (currentSeriesRow != row && m_pProgressBar != nullptr) - { - m_pProgressBar->setValue(0); - currentSeriesRow = row; - } +void ImportWidget::executeCMove(const QModelIndex ¤t) +{ + int row = current.row(); + if (row < 0) + return; - if (m_pMoveWorkerThread == nullptr) - { - m_pMoveWorkerThread = new QThread; - } - else - { - if (!m_pMoveWorkerThread->isFinished()) - { - m_pMoveWorkerThread->exit(); - m_pMoveWorkerThread->wait(); - } - } + if (currentSeriesRow != row && m_pProgressBar != nullptr) + { + m_pProgressBar->setValue(0); + currentSeriesRow = row; + } - std::string seriesNumber = m_pSeriesModel->index(row, 1).data().toString().toStdString(); - std::string studyInstanceUID = m_pSeriesModel->index(row, 4).data().toString().toStdString(); - std::string studyID = m_pSeriesModel->index(row, 5).data().toString().toStdString(); - std::string seriesUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); - std::string patientName = m_pSeriesModel->index(row, 7).data().toString().toStdString(); - std::string outDirectory = DicomViewerHelper::applicationPath().toStdString(); + if (mMoveWorkerThread == nullptr) + { + mMoveWorkerThread = new QThread; + } + else + { + if (!mMoveWorkerThread->isFinished()) + { + mMoveWorkerThread->exit(); + mMoveWorkerThread->wait(); + } + } + + std::string seriesNumber = m_pSeriesModel->index(row, 1).data().toString().toStdString(); + std::string studyInstanceUID = m_pSeriesModel->index(row, 4).data().toString().toStdString(); + std::string studyID = m_pSeriesModel->index(row, 5).data().toString().toStdString(); + std::string seriesUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); + std::string patientName = m_pSeriesModel->index(row, 7).data().toString().toStdString(); + std::string outDirectory = DicomViewerHelper::applicationPath().toStdString(); outDirectory += "/"; - outDirectory += studyInstanceUID; - outDirectory += "/"; - outDirectory += seriesUID; + outDirectory += studyInstanceUID; + outDirectory += "/"; + outDirectory += seriesUID; - bool mkRet = false; - QDir d(QString::fromStdString(outDirectory)); - if (!d.exists()) - mkRet = d.mkpath(QString::fromStdString(outDirectory)); + bool mkRet = false; + QDir d(QString::fromStdString(outDirectory)); + if (!d.exists()) + mkRet = d.mkpath(QString::fromStdString(outDirectory)); - if (m_pMoveWorker == nullptr) - { - std::string peerIP, peerTitle, ourTitle; - unsigned long peerPort = 0, ourPort = 0; - getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); - if (peerIP.empty() || peerTitle.empty() || ourTitle.empty() || peerPort == 0 || ourPort == 0) - { - return; - } + if (mMoveWorker == nullptr) + { + std::string peerIP, peerTitle, ourTitle; + unsigned long peerPort = 0, ourPort = 0; + getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); + if (peerIP.empty() || peerTitle.empty() || ourTitle.empty() || peerPort == 0 || ourPort == 0) + { + return; + } - m_pMoveWorker = new MoveWorker(QString::fromStdString(peerIP), peerPort, QString::fromStdString(peerTitle), ourPort, QString::fromStdString(ourTitle), QString::fromStdString(outDirectory)); - QObject::connect(m_pMoveWorker, SIGNAL(notifyMoveDone(int, QString)), this, SLOT(moveDone(int, QString)), Qt::QueuedConnection); - QObject::connect(m_pMoveWorker, SIGNAL(notifyMoveProgress(int, int)), this, SLOT(moveProgress(int, int)), Qt::QueuedConnection); - QObject::connect(m_pMoveWorker, SIGNAL(notifyMoveStoreProgress(int, QString)), this, SLOT(moveStoreProgress(int, QString)), Qt::QueuedConnection); - } - m_pMoveWorker->setOutputDirectory(QString::fromStdString(outDirectory)); - m_pMoveWorker->moveToThread(m_pQueryWorkerThread); - m_pMoveWorkerThread->start(); + mMoveWorker = new MoveWorker(peerIP, peerPort, peerTitle, ourPort, ourTitle, QString::fromStdString(outDirectory)); + QObject::connect(mMoveWorker, SIGNAL(notifyMoveDone(int, QString)), this, SLOT(moveDone(int, QString)), Qt::QueuedConnection); + QObject::connect(mMoveWorker, SIGNAL(notifyMoveProgress(int, int)), this, SLOT(moveProgress(int, int)), Qt::QueuedConnection); + QObject::connect(mMoveWorker, SIGNAL(notifyMoveStoreProgress(int, QString)), this, SLOT(moveStoreProgress(int, QString)), Qt::QueuedConnection); + } + std::string peerIP, peerTitle, ourTitle; + unsigned long peerPort = 0, ourPort = 0; + getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); + if (peerIP.empty() || peerTitle.empty() || ourTitle.empty() || peerPort == 0 || ourPort == 0) + { + return; + } + mMoveWorker->setPacsInfo(peerIP,peerPort,peerTitle,ourTitle,ourPort); + mMoveWorker->setOutputDirectory(QString::fromStdString(outDirectory)); + mMoveWorker->moveToThread(mQueryWorkerThread); + mMoveWorkerThread->start(); - //std::string studyInstanceUID = m_pStudyModel->index(row, 14).data().toString().toStdString(); - std::string seriesInstanceUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); - QMetaObject::invokeMethod(m_pMoveWorker, "moveBySeriesUID", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(studyInstanceUID)), Q_ARG(QString, QString::fromStdString(seriesInstanceUID))); + std::string seriesInstanceUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); + QMetaObject::invokeMethod(mMoveWorker, "moveBySeriesUID", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(studyInstanceUID)), Q_ARG(QString, QString::fromStdString(seriesInstanceUID))); +} + +void ImportWidget::executeCGet(const QModelIndex ¤t) +{ + int row = current.row(); + if (row < 0) + return; + + if (currentSeriesRow != row && m_pProgressBar != nullptr) + { + m_pProgressBar->setValue(0); + currentSeriesRow = row; + } + + if (mGetWorkerThread == nullptr) + { + mGetWorkerThread = new QThread; + } + else + { + if (!mGetWorkerThread->isFinished()) + { + mGetWorkerThread->exit(); + mGetWorkerThread->wait(); + } + } + + std::string seriesNumber = m_pSeriesModel->index(row, 1).data().toString().toStdString(); + std::string studyInstanceUID = m_pSeriesModel->index(row, 4).data().toString().toStdString(); + std::string studyID = m_pSeriesModel->index(row, 5).data().toString().toStdString(); + std::string seriesUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); + std::string patientName = m_pSeriesModel->index(row, 7).data().toString().toStdString(); + std::string outDirectory = DicomViewerHelper::applicationPath().toStdString(); + outDirectory += "/"; + outDirectory += studyInstanceUID; + outDirectory += "/"; + outDirectory += seriesUID; + + bool mkRet = false; + QDir d(QString::fromStdString(outDirectory)); + if (!d.exists()) + mkRet = d.mkpath(QString::fromStdString(outDirectory)); + + if (mGetWorker == nullptr) + { + mGetWorker = new GetWorker(this); + QObject::connect(mGetWorker, SIGNAL(notifyGetDone(int, QString)), this, SLOT(moveDone(int, QString)), Qt::QueuedConnection); + } + std::string peerIP, peerTitle, ourTitle; + unsigned long peerPort = 0, ourPort = 0; + getNetParams(peerIP, peerPort, peerTitle, ourPort, ourTitle); + if (peerIP.empty() || peerTitle.empty() || ourTitle.empty() || peerPort == 0 || ourPort == 0) + { + return; + } + mGetWorker->setPacsInfo(peerIP,peerPort,peerTitle,ourTitle,ourPort); + mGetWorker->setOutputDirectory(QString::fromStdString(outDirectory)); + mGetWorker->moveToThread(mGetWorkerThread); + mGetWorkerThread->start(); + + std::string seriesInstanceUID = m_pSeriesModel->index(row, 6).data().toString().toStdString(); + std::string dicomType = m_pSeriesModel->index(row, 2).data().toString().toStdString(); + QMetaObject::invokeMethod(mGetWorker, "getBySeriesUID", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(studyInstanceUID)), Q_ARG(QString, QString::fromStdString(seriesInstanceUID)), Q_ARG(QString, QString::fromStdString(dicomType))); } @@ -778,4 +870,4 @@ void ImportWidget::onTitleBarDestroyed() { m_pTitleBar = Q_NULLPTR; } -} \ No newline at end of file +} diff --git a/src/src/PACS/Widget/importwidget.h b/src/src/PACS/Widget/importwidget.h index f7154d7..4b9cd0e 100644 --- a/src/src/PACS/Widget/importwidget.h +++ b/src/src/PACS/Widget/importwidget.h @@ -7,12 +7,10 @@ #include #include -#include "PACS/Network/queryworker.h" -#include "PACS/Network/moveworker.h" +#include "PACS/Common/dicomviewertype.h" #include "PACS/Common/dicomviewerhelper.h" #include "radiusprogressbar.h" - class QVBoxLayout; class QGridLayout; class QHBoxLayout; @@ -29,6 +27,9 @@ class CallbackHelper; class DcmDataset; class QProgressBar; class QSpacerItem; +class QueryWorker; +class MoveWorker; +class GetWorker; class ImportWidget : public QDialog { @@ -78,10 +79,13 @@ private: void initStudy(); void initSeriesHeader(); void initSeries(); - void getNetParams(std::string& peerIP, unsigned long& peerPort, std::string& peerTitle, unsigned long& ourPort, std::string& ourTitle); + void getNetParams(std::string& peerIP, unsigned long& peerPort, std::string& peerTitle, unsigned long& ourPort, std::string& ourTitle); void updateStudyView(); void updateSeriesView(); void getDateIntervalForQuery(QString& startDate, QString& endDate); + void executeCMove(const QModelIndex ¤t); + void executeCGet(const QModelIndex ¤t); + unsigned short getProtocol(); private: QVBoxLayout *m_pMainLayout; @@ -125,13 +129,12 @@ private: int currentSeriesRow; - QThread* m_pQueryWorkerThread; - QueryWorker* m_pQueryWorker; - QThread* m_pMoveWorkerThread; - MoveWorker* m_pMoveWorker; - -// QThread* m_pStoreWorkerThread; -// StoreWorker* m_pStoreWorker; + QThread* mQueryWorkerThread; + QueryWorker* mQueryWorker; + QThread* mMoveWorkerThread; + MoveWorker* mMoveWorker; + QThread* mGetWorkerThread; + GetWorker* mGetWorker; private: struct diff --git a/src/src/PACS/Widget/pacsconfiguration.cpp b/src/src/PACS/Widget/pacsconfiguration.cpp index cd490ae..98fa0ae 100644 --- a/src/src/PACS/Widget/pacsconfiguration.cpp +++ b/src/src/PACS/Widget/pacsconfiguration.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,8 @@ ConfigurationDialog::ConfigurationDialog(QWidget *parent) , m_pSpacerItem(nullptr) , m_pDelButton(nullptr) , m_pPacsInfo(nullptr) + , m_pPacsMenu(nullptr) + , m_pRetriveProtocolMenu(nullptr) , m_pEditWidget(nullptr) , m_pEditLayout(nullptr) , m_pPeerIpAddressLabel(nullptr) @@ -120,10 +123,24 @@ void ConfigurationDialog::initUi() m_pPacsInfo->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); m_pPacsInfo->verticalHeader()->setVisible(false); m_pPacsInfo->setShowGrid(false); + m_pPacsInfo->setContextMenuPolicy(Qt::CustomContextMenu); m_pPacsInfo->setSelectionMode(QAbstractItemView::SingleSelection); m_pPacsInfo->setSelectionBehavior(QAbstractItemView::SelectRows); m_pPacsInfo->setModel(m_pPacsModel); + connect(m_pPacsInfo,&QTableView::customContextMenuRequested,this,&ConfigurationDialog::pacsMenuRequest); m_pMainLayout->addWidget(m_pPacsInfo); + m_pPacsMenu = new QMenu(m_pPacsInfo); + m_pRetriveProtocolMenu = new QMenu(tr("Retrive Protocol"),m_pPacsMenu); + QAction* cGetAction = new QAction("C-GET",m_pRetriveProtocolMenu); + cGetAction->setCheckable(true); + connect(cGetAction,&QAction::triggered,this,&ConfigurationDialog::changeHostProtocol); + QAction* cMoveAction = new QAction("C-MOVE",m_pRetriveProtocolMenu); + cMoveAction->setCheckable(true); + connect(cMoveAction,&QAction::triggered,this,&ConfigurationDialog::changeHostProtocol); + m_pRetriveProtocolMenu->addAction(cGetAction); + m_pRetriveProtocolMenu->addAction(cMoveAction); + + m_pPacsMenu->addMenu(m_pRetriveProtocolMenu); m_pEditWidget = new QWidget(this); m_pEditLayout = new QGridLayout(this); @@ -197,7 +214,7 @@ void ConfigurationDialog::initSys() connect(m_pModifyButton, SIGNAL(clicked()), this, SLOT(modify())); connect(m_pSaveButton, SIGNAL(clicked()), this, SLOT(save())); connect(m_pCancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - connect(m_pPacsInfo, SIGNAL(clicked(const QModelIndex &)), this, SLOT(onSelected(const QModelIndex &))); + connect(m_pPacsInfo, SIGNAL(pressed(const QModelIndex &)), this, SLOT(onSelected(const QModelIndex &))); } void ConfigurationDialog::initHeaderInfo() @@ -239,7 +256,7 @@ void ConfigurationDialog::initPacsInfo() QStandardItem* port = new QStandardItem(var.port); port->setEditable(false); QStandardItem* ae = new QStandardItem(var.ae); ae->setEditable(false); QStandardItem* name = new QStandardItem(var.name); name->setEditable(false); - QStandardItem* protocol = new QStandardItem("C-MOVE"); protocol->setEditable(false); + QStandardItem* protocol = new QStandardItem(var.protocol == 0 ? "C-MOVE" : "C-GET"); protocol->setEditable(false); QStandardItem* count = new QStandardItem("1"); count->setEditable(false); QStandardItem* xfers = new QStandardItem("Explicit VR LE"); xfers->setEditable(false); QStandardItem* cset = new QStandardItem("Default"); cset->setEditable(false); @@ -265,7 +282,7 @@ void ConfigurationDialog::updatePacsView() QStandardItem* port = new QStandardItem(itr->port); port->setEditable(false); QStandardItem* ae = new QStandardItem(itr->ae); ae->setEditable(false); QStandardItem* name = new QStandardItem(itr->name); name->setEditable(false); - QStandardItem* protocol = new QStandardItem("C-MOVE"); protocol->setEditable(false); + QStandardItem* protocol = new QStandardItem(itr->protocol == 0 ? "C-MOVE" : "C-GET"); protocol->setEditable(false); QStandardItem* count = new QStandardItem("1"); count->setEditable(false); QStandardItem* xfers = new QStandardItem("Explicit VR LE"); xfers->setEditable(false); QStandardItem* cset = new QStandardItem("Default"); cset->setEditable(false); @@ -558,3 +575,49 @@ bool ConfigurationDialog::eventFilter(QObject *obj, QEvent *event) return QDialog::eventFilter(obj, event); } +void ConfigurationDialog::changeHostProtocol() +{ + QAction* action = qobject_cast(sender()); + if (action != nullptr && currentRow != -1) + { + QString selectedName = m_pPacsModel->index(currentRow, 3).data().toString(); + for (auto itr = m_lHostsNew.begin(); itr != m_lHostsNew.end(); ++itr) + { + if (selectedName == itr->name) + { + if (action->text() == "C-GET") + { + itr->protocol = 1; + } + else if(action->text() == "C-MOVE") + { + itr->protocol = 0; + } + updatePacsView(); + DicomViewerHelper::setPacsInfo(m_lHostsNew); + emit updatePacsInfo(); + return; + } + } + + } +} + +void ConfigurationDialog::pacsMenuRequest(QPoint pos) +{ + auto index = m_pPacsInfo->indexAt(pos); + auto actions = m_pRetriveProtocolMenu->actions(); + for(int i = 0; i < actions.count(); ++i) + { + if (actions.at(i)->text() == m_pPacsModel->item(index.row(),4)->text()) + { + actions.at(i)->setChecked(true); + } + else + { + actions.at(i)->setChecked(false); + } + } + m_pPacsMenu->exec(QCursor::pos()); +} + diff --git a/src/src/PACS/Widget/pacsconfiguration.h b/src/src/PACS/Widget/pacsconfiguration.h index 8a6e5ac..b67d263 100644 --- a/src/src/PACS/Widget/pacsconfiguration.h +++ b/src/src/PACS/Widget/pacsconfiguration.h @@ -13,6 +13,7 @@ class QLineEdit; class QPushButton; class QTableView; class QFrame; +class QMenu; class QSpacerItem; class QStandardItemModel; class QItemSelectionModel; @@ -51,6 +52,8 @@ private: void initPacsInfo(); void updatePacsView(); void clearModify(); + void pacsMenuRequest(QPoint pos); + void changeHostProtocol(); private: QVBoxLayout *m_pMainLayout; @@ -69,6 +72,8 @@ private: QSpacerItem *m_pSpacerItem; QPushButton *m_pDelButton; QTableView *m_pPacsInfo; + QMenu* m_pPacsMenu; + QMenu* m_pRetriveProtocolMenu; QWidget *m_pEditWidget; QGridLayout *m_pEditLayout; QLabel *m_pPeerIpAddressLabel;