Add C-Store protocol.
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#include "dicomviewerhelper.h"
|
#include "dicomviewerhelper.h"
|
||||||
#include <qDebug>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
|
||||||
struct host {
|
struct host
|
||||||
|
{
|
||||||
QString name;
|
QString name;
|
||||||
QString ae;
|
QString ae;
|
||||||
QString ip;
|
QString ip;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ bool GetWorker::initDcmSCU()
|
|||||||
|
|
||||||
void GetWorker::getBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID, const QString& aDicomType)
|
void GetWorker::getBySeriesUID(const QString& studyInstanceUID, const QString& seriesInstanceUID, const QString& aDicomType)
|
||||||
{
|
{
|
||||||
qDebug(aDicomType.toLatin1());
|
|
||||||
if (!initDcmSCU())
|
if (!initDcmSCU())
|
||||||
{
|
{
|
||||||
mScu->abortAssociation();
|
mScu->abortAssociation();
|
||||||
|
|||||||
89
src/src/PACS/Network/StoreWorker.cpp
Normal file
89
src/src/PACS/Network/StoreWorker.cpp
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#include "StoreWorker.h"
|
||||||
|
#include "dcmtk/dcmnet/scu.h"
|
||||||
|
|
||||||
|
StoreWorker::StoreWorker(QObject* aParent)
|
||||||
|
: QObject(aParent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreWorker::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 StoreWorker::setPacsInfo(const std::string& aPeerIP, unsigned short aPeerPort, const std::string& aPeerTitle, const std::string& aOurTitle)
|
||||||
|
{
|
||||||
|
mPeerIP = aPeerIP;
|
||||||
|
mPeerPort = aPeerPort;
|
||||||
|
mPeerTitle = aPeerTitle;
|
||||||
|
mOurTitle = aOurTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreWorker::cancel()
|
||||||
|
{
|
||||||
|
mCancelFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreWorker::store(const QStringList& aFilePathList, const QString& aDicomType)
|
||||||
|
{
|
||||||
|
if (!initDcmSCU())
|
||||||
|
{
|
||||||
|
mScu->abortAssociation();
|
||||||
|
emit notifyStoreDone(0);
|
||||||
|
emit notifyStoreFinished();
|
||||||
|
delete mScu;
|
||||||
|
mScu = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
T_ASC_PresentationContextID pcid;
|
||||||
|
Uint16 response;
|
||||||
|
DcmDataset dataset;
|
||||||
|
for(int i = 0;i < aFilePathList.size(); ++i)
|
||||||
|
{
|
||||||
|
if(mCancelFlag)
|
||||||
|
{
|
||||||
|
mCancelFlag = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(aDicomType.toLower() == "mr")
|
||||||
|
{
|
||||||
|
pcid = mScu->findPresentationContextID(UID_MRImageStorage,"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcid = mScu->findPresentationContextID(UID_CTImageStorage,"");
|
||||||
|
}
|
||||||
|
OFCondition cond = mScu->sendSTORERequest(pcid,aFilePathList.at(i).toStdString(), &dataset, response);
|
||||||
|
if (cond.bad() || cond != EC_Normal || response != 0)
|
||||||
|
{
|
||||||
|
mScu->closeAssociation(DCMSCU_ABORT_ASSOCIATION);
|
||||||
|
emit notifyStoreDone(0);
|
||||||
|
emit notifyStoreFinished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit notifyStoreDone(i+1);
|
||||||
|
}
|
||||||
|
mScu->releaseAssociation();
|
||||||
|
delete mScu;
|
||||||
|
mScu = nullptr;
|
||||||
|
emit notifyStoreFinished();
|
||||||
|
}
|
||||||
35
src/src/PACS/Network/StoreWorker.h
Normal file
35
src/src/PACS/Network/StoreWorker.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef STOREWORKER_H
|
||||||
|
#define STOREWORKER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class DcmSCU;
|
||||||
|
|
||||||
|
class StoreWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
StoreWorker(QObject* aParent);
|
||||||
|
void setPacsInfo(const std::string& aPeerIP, unsigned short aPeerPort, const std::string& aPeerTitle, const std::string& aOurTitle);
|
||||||
|
void cancel();
|
||||||
|
Q_INVOKABLE void store(const QStringList& aFilePathList, const QString& aDicomType);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void notifyStoreDone(int aIndex); //0 failed,1,2,3.. sucessed
|
||||||
|
void notifyStoreFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initDcmSCU();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DcmSCU* mScu;
|
||||||
|
QString mStoreFilePath;
|
||||||
|
std::string mPeerTitle;
|
||||||
|
std::string mPeerIP;
|
||||||
|
std::string mOurTitle;
|
||||||
|
unsigned short mPeerPort;
|
||||||
|
unsigned short mOurPort;
|
||||||
|
bool mCancelFlag = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STOREWORKER_H
|
||||||
57
src/src/PACS/Widget/StoreDialog.cpp
Normal file
57
src/src/PACS/Widget/StoreDialog.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include "StoreDialog.h"
|
||||||
|
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSpacerItem>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const QString SENDING_IMAGES_TO_PACS = "Sending images to PACS...";
|
||||||
|
QString makeText(int aTotalNum, int aCurrentNum)
|
||||||
|
{
|
||||||
|
return SENDING_IMAGES_TO_PACS + "[" + QString::number(aCurrentNum) + "/" + QString::number(aTotalNum) + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StoreDialog::StoreDialog(QWidget* aParent)
|
||||||
|
: QDialog(aParent)
|
||||||
|
, mFileSize(0)
|
||||||
|
, mProgressBar(new QProgressBar(this))
|
||||||
|
, mText(new QLabel(this))
|
||||||
|
, mCancelButton(nullptr)
|
||||||
|
{
|
||||||
|
setFixedSize(QSize(380,105));
|
||||||
|
initWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreDialog::initWidget()
|
||||||
|
{
|
||||||
|
mProgressBar->setTextVisible(false);
|
||||||
|
QVBoxLayout* vLayout = new QVBoxLayout(this);
|
||||||
|
vLayout->addWidget(mProgressBar);
|
||||||
|
vLayout->addWidget(mText);
|
||||||
|
QWidget* buttonContainer = new QWidget(this);
|
||||||
|
vLayout->addWidget(buttonContainer);
|
||||||
|
QHBoxLayout* hLayout = new QHBoxLayout(buttonContainer);
|
||||||
|
hLayout->addSpacerItem(new QSpacerItem(280,105));
|
||||||
|
mCancelButton = new QPushButton(tr("Cancel"),buttonContainer);
|
||||||
|
mCancelButton->setFixedHeight(23);
|
||||||
|
hLayout->addWidget(mCancelButton);
|
||||||
|
connect(mCancelButton,&QPushButton::clicked,this,&QDialog::reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreDialog::setFileSize(int aFileSize)
|
||||||
|
{
|
||||||
|
mFileSize = aFileSize;
|
||||||
|
mText->setText(makeText(mFileSize, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoreDialog::setStoreProgress(int aNum)
|
||||||
|
{
|
||||||
|
mProgressBar->setValue((aNum*100)/mFileSize);
|
||||||
|
mText->setText(makeText(mFileSize, aNum));
|
||||||
|
}
|
||||||
|
|
||||||
27
src/src/PACS/Widget/StoreDialog.h
Normal file
27
src/src/PACS/Widget/StoreDialog.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef STOREDIALOG_H
|
||||||
|
#define STOREDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
class QProgressBar;
|
||||||
|
class QPushButton;
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
class StoreDialog : public QDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StoreDialog(QWidget* aParent = nullptr);
|
||||||
|
void setStoreProgress(int aNum);
|
||||||
|
void setFileSize(int aFileSize);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int mFileSize;
|
||||||
|
QProgressBar* mProgressBar;
|
||||||
|
QLabel* mText;
|
||||||
|
QPushButton* mCancelButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STOREDIALOG_H
|
||||||
@@ -8,8 +8,9 @@
|
|||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include "Rendering/Measure/Measure.h"
|
#include "Rendering/Measure/Measure.h"
|
||||||
|
|
||||||
#include "Common/QGlobals.h"
|
#include "Common/QGlobals.h"
|
||||||
|
#include "ExportToolButton.h"
|
||||||
|
|
||||||
typedef tuple<const char *, const char *, int> ActionProperty;
|
typedef tuple<const char *, const char *, int> ActionProperty;
|
||||||
namespace {
|
namespace {
|
||||||
const char *SYNC_MANUAL_URL = ":/InfiniteViewer/Icon/sync/sync_manual.png";
|
const char *SYNC_MANUAL_URL = ":/InfiniteViewer/Icon/sync/sync_manual.png";
|
||||||
@@ -30,7 +31,7 @@ namespace {
|
|||||||
DefaultToolBar::DefaultToolBar(QWidget *parent) : QToolBar(parent)
|
DefaultToolBar::DefaultToolBar(QWidget *parent) : QToolBar(parent)
|
||||||
, mBtnFile(new QToolButton(this))
|
, mBtnFile(new QToolButton(this))
|
||||||
, mBtnImport(new QToolButton(this))
|
, mBtnImport(new QToolButton(this))
|
||||||
, mBtnSave(new QToolButton(this))
|
, mBtnSave(new ExportToolButton(this))
|
||||||
, mBtnGrid(new QToolButton(this))
|
, mBtnGrid(new QToolButton(this))
|
||||||
, mBtnSync(new QToolButton(this))
|
, mBtnSync(new QToolButton(this))
|
||||||
, mBtnAnonymize(new QToolButton(this))
|
, mBtnAnonymize(new QToolButton(this))
|
||||||
@@ -52,7 +53,8 @@ DefaultToolBar::DefaultToolBar(QWidget *parent) : QToolBar(parent)
|
|||||||
, mActionMinimize(nullptr)
|
, mActionMinimize(nullptr)
|
||||||
, mActionMaximize(nullptr)
|
, mActionMaximize(nullptr)
|
||||||
, mActionClose(nullptr)
|
, mActionClose(nullptr)
|
||||||
, mActionFullScreen(nullptr) {
|
, mActionFullScreen(nullptr)
|
||||||
|
{
|
||||||
//init icons
|
//init icons
|
||||||
mManualIcon.addFile(SYNC_MANUAL_URL);
|
mManualIcon.addFile(SYNC_MANUAL_URL);
|
||||||
mAutoIcon.addFile(SYNC_AUTO_URL);
|
mAutoIcon.addFile(SYNC_AUTO_URL);
|
||||||
@@ -64,6 +66,12 @@ DefaultToolBar::~DefaultToolBar() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DefaultToolBar::setViewManager(ImageViewManager *aManager)
|
||||||
|
{
|
||||||
|
mImageViewManager = aManager;
|
||||||
|
mBtnSave->setImageViewManager(mImageViewManager);
|
||||||
|
}
|
||||||
|
|
||||||
QAction* DefaultToolBar::addButton(QToolButton* button, const char* objectName) {
|
QAction* DefaultToolBar::addButton(QToolButton* button, const char* objectName) {
|
||||||
button->setObjectName(objectName);
|
button->setObjectName(objectName);
|
||||||
button->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
button->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
@@ -164,6 +172,7 @@ void DefaultToolBar::initImportButton() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DefaultToolBar::initExportButton() {
|
void DefaultToolBar::initExportButton() {
|
||||||
|
mBtnSave->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
mBtnSave->setToolTip(QString("Export images"));
|
mBtnSave->setToolTip(QString("Export images"));
|
||||||
connect(mBtnSave, &QToolButton::clicked, this, &DefaultToolBar::save);
|
connect(mBtnSave, &QToolButton::clicked, this, &DefaultToolBar::save);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "UI/Manager/ImageViewStateCheckWorker.h"
|
#include "UI/Manager/ImageViewStateCheckWorker.h"
|
||||||
|
|
||||||
class QButtonGroup;
|
class QButtonGroup;
|
||||||
|
class ExportToolButton;
|
||||||
|
|
||||||
class DefaultToolBar : public QToolBar {
|
class DefaultToolBar : public QToolBar {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -21,6 +22,7 @@ public:
|
|||||||
|
|
||||||
void resetNeedCheckFunctionButtons();
|
void resetNeedCheckFunctionButtons();
|
||||||
void updateNeedCheckFunctionButtons(ViewFunctionState state);
|
void updateNeedCheckFunctionButtons(ViewFunctionState state);
|
||||||
|
void setViewManager(ImageViewManager* aManager);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void openFile();
|
void openFile();
|
||||||
@@ -70,7 +72,7 @@ private:
|
|||||||
QIcon mDisIcon;
|
QIcon mDisIcon;
|
||||||
QToolButton *mBtnFile;
|
QToolButton *mBtnFile;
|
||||||
QToolButton *mBtnImport;
|
QToolButton *mBtnImport;
|
||||||
QToolButton *mBtnSave;
|
ExportToolButton *mBtnSave;
|
||||||
QToolButton *mBtnGrid;
|
QToolButton *mBtnGrid;
|
||||||
QToolButton *mBtnSync;
|
QToolButton *mBtnSync;
|
||||||
QToolButton *mBtnAnonymize;
|
QToolButton *mBtnAnonymize;
|
||||||
@@ -99,6 +101,7 @@ private:
|
|||||||
QAction *mActionHideMeasure;
|
QAction *mActionHideMeasure;
|
||||||
QAction *mActionHidePatData;
|
QAction *mActionHidePatData;
|
||||||
QAction* mSyncActions[3]={nullptr,nullptr,nullptr};
|
QAction* mSyncActions[3]={nullptr,nullptr,nullptr};
|
||||||
|
ImageViewManager* mImageViewManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
179
src/src/UI/Widget/ToolBar/ExportToolButton.cpp
Normal file
179
src/src/UI/Widget/ToolBar/ExportToolButton.cpp
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#include "ExportToolButton.h"
|
||||||
|
|
||||||
|
#include "Common/ImageSetStore.h"
|
||||||
|
#include "PACS/Common/dicomviewerhelper.h"
|
||||||
|
#include "PACS/Network/StoreWorker.h"
|
||||||
|
#include "PACS/Widget/StoreDialog.h"
|
||||||
|
#include "UI/Manager/ImageViewManager.h"
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void createFilePathListFromAllOpenedStudies(QStringList& aResult,ExtendMedicalImageProperties* aProperty)
|
||||||
|
{
|
||||||
|
if (aProperty == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::pair<std::string,long>> fileNames = aProperty->GetFileNames();
|
||||||
|
auto itr1 = fileNames.begin();
|
||||||
|
for(; itr1 != fileNames.end();++itr1)
|
||||||
|
{
|
||||||
|
aResult.push_back(itr1->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void createFilePathListFromCurrentStudy(QStringList& aResult,ExtendMedicalImageProperties* aProperty, const QString& aCurrentStudyUid)
|
||||||
|
{
|
||||||
|
if (aProperty == nullptr || aCurrentStudyUid != aProperty->GetStudyUID())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::pair<std::string,long>> fileNames = aProperty->GetFileNames();
|
||||||
|
auto itr1 = fileNames.begin();
|
||||||
|
for(; itr1 != fileNames.end();++itr1)
|
||||||
|
{
|
||||||
|
aResult.push_back(itr1->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void createFilePathListFromCurrentSeries(QStringList& aResult,ExtendMedicalImageProperties* aProperty, const QString& aCurrentSeriesUid)
|
||||||
|
{
|
||||||
|
if (aProperty == nullptr || aCurrentSeriesUid != aProperty->GetSeriesUID())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<std::pair<std::string,long>> fileNames = aProperty->GetFileNames();
|
||||||
|
auto itr1 = fileNames.begin();
|
||||||
|
for(; itr1 != fileNames.end();++itr1)
|
||||||
|
{
|
||||||
|
aResult.push_back(itr1->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ExportToolButton::ExportToolButton(QWidget* aParent)
|
||||||
|
: QToolButton(aParent)
|
||||||
|
, mImageViewManager(nullptr)
|
||||||
|
, mStoreDialog(nullptr)
|
||||||
|
, mStoreWorker(nullptr)
|
||||||
|
, mThread(nullptr)
|
||||||
|
{
|
||||||
|
initSendToPacsMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExportToolButton::initSendToPacsMenu()
|
||||||
|
{
|
||||||
|
QMenu* saveMenu = new QMenu(this);
|
||||||
|
QMenu* sendPacs = new QMenu(tr("Send to PACS"), this);
|
||||||
|
QMenu* allOpenedStudies = new QMenu(tr("All opened studies"), sendPacs);
|
||||||
|
QMenu* currentStudy = new QMenu(tr("Current study"), sendPacs);
|
||||||
|
QMenu* currentSeries = new QMenu(tr("Current series"), sendPacs);
|
||||||
|
QList<host> hosts;
|
||||||
|
DicomViewerHelper::pacsInfo(hosts);
|
||||||
|
foreach(auto h,hosts)
|
||||||
|
{
|
||||||
|
QString text = h.name + " [" + h.ae + "@" + h.ip + ":" + h.port + "]";
|
||||||
|
auto sendToPacs = [h,this]()
|
||||||
|
{
|
||||||
|
QAction* action = qobject_cast<QAction*>(sender());
|
||||||
|
if (action == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<ExtendMedicalImageProperties*> openedFile = ImageSetStore::GetInstance()->getProperties();
|
||||||
|
if (mImageViewManager == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DicomImageView* imageView = mImageViewManager->getCurrentView();
|
||||||
|
if(imageView == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SeriesImageSet* imageSet = imageView->getSeriesInstance();
|
||||||
|
if(imageSet == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto itr = openedFile.begin();
|
||||||
|
QStringList filePathList;
|
||||||
|
for(;itr != openedFile.end();++itr)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<std::string,long>> fileNames = (*itr)->GetFileNames();
|
||||||
|
if(action->data().toString() == "All opened studies")
|
||||||
|
{
|
||||||
|
createFilePathListFromAllOpenedStudies(filePathList, (*itr));
|
||||||
|
}
|
||||||
|
else if(action->data().toString() == "Current study")
|
||||||
|
{
|
||||||
|
createFilePathListFromCurrentStudy(filePathList, (*itr), imageSet->getStudyUID());
|
||||||
|
}
|
||||||
|
else if(action->data().toString() == "Current series")
|
||||||
|
{
|
||||||
|
createFilePathListFromCurrentSeries(filePathList, (*itr), imageSet->getSeriesName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(filePathList.isEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mThread == nullptr)
|
||||||
|
{
|
||||||
|
mThread = new QThread(this);
|
||||||
|
}
|
||||||
|
if (mStoreWorker == nullptr)
|
||||||
|
{
|
||||||
|
mStoreWorker = QSharedPointer<StoreWorker>(new StoreWorker(nullptr));
|
||||||
|
mStoreWorker->moveToThread(mThread);
|
||||||
|
connect(mStoreWorker.data(),&StoreWorker::notifyStoreFinished,mThread,&QThread::quit);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mStoreDialog == nullptr)
|
||||||
|
{
|
||||||
|
mStoreDialog = new StoreDialog(this);
|
||||||
|
connect(mStoreDialog,&QDialog::rejected,this,[this]()
|
||||||
|
{
|
||||||
|
mStoreWorker->cancel();
|
||||||
|
});
|
||||||
|
connect(mStoreWorker.data(),&StoreWorker::notifyStoreDone,mStoreDialog,&StoreDialog::setStoreProgress);
|
||||||
|
connect(mStoreWorker.data(),&StoreWorker::notifyStoreFinished,mStoreDialog,&StoreDialog::accept);
|
||||||
|
}
|
||||||
|
mThread->start();
|
||||||
|
mStoreWorker->setPacsInfo(h.ip.toStdString(), static_cast<unsigned short>(h.port.toShort()),
|
||||||
|
h.ae.toStdString(), DicomViewerHelper::ourTitle().toStdString());
|
||||||
|
QMetaObject::invokeMethod(mStoreWorker.data(), "store", Qt::QueuedConnection, Q_ARG(QStringList, filePathList), Q_ARG(QString, ""));
|
||||||
|
mStoreDialog->setFileSize(filePathList.size());
|
||||||
|
mStoreDialog->exec();
|
||||||
|
};
|
||||||
|
QAction* allAction = new QAction(text,allOpenedStudies);
|
||||||
|
allAction->setData("All opened studies");
|
||||||
|
connect(allAction,&QAction::triggered,this,sendToPacs);
|
||||||
|
allOpenedStudies->addAction(allAction);
|
||||||
|
|
||||||
|
QAction* studyAction = new QAction(text,currentStudy);
|
||||||
|
studyAction->setData("Current study");
|
||||||
|
connect(studyAction,&QAction::triggered,this,sendToPacs);
|
||||||
|
currentStudy->addAction(studyAction);
|
||||||
|
|
||||||
|
QAction* seriesAction = new QAction(text,currentSeries);
|
||||||
|
seriesAction->setData("Current series");
|
||||||
|
connect(seriesAction,&QAction::triggered,this,sendToPacs);
|
||||||
|
currentSeries->addAction(seriesAction);
|
||||||
|
}
|
||||||
|
saveMenu->addMenu(sendPacs);
|
||||||
|
sendPacs->addMenu(allOpenedStudies);
|
||||||
|
sendPacs->addMenu(currentStudy);
|
||||||
|
sendPacs->addMenu(currentSeries);
|
||||||
|
|
||||||
|
setPopupMode(QToolButton::MenuButtonPopup);
|
||||||
|
setMenu(saveMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExportToolButton::setImageViewManager(ImageViewManager* aImageViewManager)
|
||||||
|
{
|
||||||
|
mImageViewManager = aImageViewManager;
|
||||||
|
}
|
||||||
28
src/src/UI/Widget/ToolBar/ExportToolButton.h
Normal file
28
src/src/UI/Widget/ToolBar/ExportToolButton.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EXPORTTOOLBUTTON_H
|
||||||
|
#define EXPORTTOOLBUTTON_H
|
||||||
|
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
|
class ImageViewManager;
|
||||||
|
class StoreDialog;
|
||||||
|
class StoreWorker;
|
||||||
|
class QThread;
|
||||||
|
|
||||||
|
class ExportToolButton : public QToolButton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExportToolButton(QWidget* aParent);
|
||||||
|
void setImageViewManager(ImageViewManager* aImageViewManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initSendToPacsMenu();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageViewManager* mImageViewManager;
|
||||||
|
StoreDialog* mStoreDialog;
|
||||||
|
QSharedPointer<StoreWorker> mStoreWorker;
|
||||||
|
QThread* mThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EXPORTTOOLBUTTON_H
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "QDicomViewer.h"
|
#include "QDicomViewer.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -23,6 +23,7 @@ QDicomViewer::QDicomViewer(QWidget *parent) : QMainWindow(parent),
|
|||||||
m_import(nullptr) {
|
m_import(nullptr) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->statusBar()->showMessage(tr("Ready"));
|
this->statusBar()->showMessage(tr("Ready"));
|
||||||
|
ui->toolBar->setViewManager(ui->viewContainer->getViewManager());
|
||||||
QWidget::setWindowTitle(Project_NAME);
|
QWidget::setWindowTitle(Project_NAME);
|
||||||
|
|
||||||
this->Initial();
|
this->Initial();
|
||||||
|
|||||||
Reference in New Issue
Block a user