Refactor Network Module and add C-GET protocol.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#include "dicomviewerhelper.h"
|
||||
#include "dicomviewerhelper.h"
|
||||
#include <qDebug>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
@@ -123,6 +123,7 @@ bool DicomViewerProductCfg::pacsInfo(QList<host>& 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<host>& info)
|
||||
o["ae"] = beg->ae;
|
||||
o["ip"] = beg->ip;
|
||||
o["port"] = beg->port;
|
||||
o["protocol"] = beg->protocol;
|
||||
arr.append(o);
|
||||
beg++;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef _DICOM_VIEWER_HELPER_H_
|
||||
#ifndef _DICOM_VIEWER_HELPER_H_
|
||||
#define _DICOM_VIEWER_HELPER_H_
|
||||
|
||||
#include <QString>
|
||||
@@ -13,6 +13,7 @@ struct host {
|
||||
QString ae;
|
||||
QString ip;
|
||||
QString port;
|
||||
unsigned short protocol = 0; //0:C-Move,1:C-Get
|
||||
};
|
||||
|
||||
|
||||
|
||||
97
src/src/PACS/Network/GetWorker.cpp
Normal file
97
src/src/PACS/Network/GetWorker.cpp
Normal file
@@ -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<OFString> 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<RetrieveResponse*> 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;
|
||||
}
|
||||
|
||||
33
src/src/PACS/Network/GetWorker.h
Normal file
33
src/src/PACS/Network/GetWorker.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef GETWORKER_H
|
||||
#define GETWORKER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
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
|
||||
12
src/src/PACS/Network/MoveStoreScp.cpp
Normal file
12
src/src/PACS/Network/MoveStoreScp.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "MoveStoreScp.h"
|
||||
|
||||
MoveStoreScp::MoveStoreScp()
|
||||
: DcmStorageSCP()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool MoveStoreScp::stopAfterCurrentAssociation()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
13
src/src/PACS/Network/MoveStoreScp.h
Normal file
13
src/src/PACS/Network/MoveStoreScp.h
Normal file
@@ -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
|
||||
41
src/src/PACS/Network/MoveStoreThread.cpp
Normal file
41
src/src/PACS/Network/MoveStoreThread.cpp
Normal file
@@ -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<OFString> 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;
|
||||
}
|
||||
23
src/src/PACS/Network/MoveStoreThread.h
Normal file
23
src/src/PACS/Network/MoveStoreThread.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef MOVESTORETHREAD_H
|
||||
#define MOVESTORETHREAD_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef _CALLBACKHELPER_H_
|
||||
#define _CALLBACKHELPER_H_
|
||||
|
||||
#include <QObject>
|
||||
|
||||
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_
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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_
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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_
|
||||
|
||||
@@ -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<unsigned short>(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<OFString> 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<unsigned short>(mUlOurPort));
|
||||
mMoveStoreThread->start();
|
||||
T_ASC_PresentationContextID pcid = mScu->findPresentationContextID(UID_MOVEPatientRootQueryRetrieveInformationModel,"");
|
||||
OFList<RetrieveResponse*> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@
|
||||
#define _MOVEWORKER_H_
|
||||
|
||||
#include <QObject>
|
||||
#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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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<OFString> 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<QRResponse*> 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<int>(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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
#define _QUERYWORKER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
#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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -15,14 +15,13 @@
|
||||
#include <QProgressBar>
|
||||
|
||||
#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>("PACSStudyInfo");
|
||||
qRegisterMetaType<PACSSeriesInfo>("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<host>::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<host> hosts;
|
||||
DicomViewerHelper::pacsInfo(hosts);
|
||||
|
||||
QList<host>::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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,10 @@
|
||||
#include <QList>
|
||||
#include <QThread>
|
||||
|
||||
#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
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QFrame>
|
||||
#include <QEvent>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QStandardItemModel>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QHeaderView>
|
||||
@@ -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<QAction*>(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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user