diff --git a/src/src/UI/Manager/ImageViewManager.cpp b/src/src/UI/Manager/ImageViewManager.cpp index 34a34ac..560f790 100644 --- a/src/src/UI/Manager/ImageViewManager.cpp +++ b/src/src/UI/Manager/ImageViewManager.cpp @@ -35,6 +35,8 @@ void ImageViewManager::add(DicomImageView *view) { connect(view, &DicomImageView::onViewDoubleClick, this, &ImageViewManager::viewDoubleClicked); + connect(view, &DicomImageView::afterViewCleared,this, &ImageViewManager::viewCleared); + connect(view, &DicomImageView::onDragDrop, [=](DicomImageView *view, const std::string &id) { setCurrentView(view); viewReload(id); @@ -68,6 +70,7 @@ void ImageViewManager::setCurrentView(DicomImageView *view) { currentView = view; currentView->setHighlight(true); emit currentViewChanged(currentView->getSeriesInstance()->getUniqueID()); + checkCurrentViewFusion(); } } @@ -218,6 +221,11 @@ void ImageViewManager::viewReload(const std::string &unique_info) { DicomLoader *helper = DicomLoader::GetInstance(); currentView->loadSeries(helper->getSeriesImageSet(unique_info)); currentView->render(); + checkCurrentViewFusion(); +} + +void ImageViewManager::viewCleared() { + emit fusionCheckStateChanged(false); } void ImageViewManager::setInteractionMode(int InteractionMode) { @@ -292,15 +300,16 @@ void ImageViewManager::switchFusion() { } } -bool ImageViewManager::checkCurrentViewFusion() { +void ImageViewManager::checkCurrentViewFusion() { for (int i = 0; i < getViewCount(); ++i) { if (getView(i) == getCurrentView()) continue; DicomImageView *overlap_view = getView(i); if (currentView->checkFusion(overlap_view)) { currentFusionView = overlap_view; - return true; + emit fusionCheckStateChanged(true); + return; } } currentFusionView = nullptr; - return false; + emit fusionCheckStateChanged(false); } diff --git a/src/src/UI/Manager/ImageViewManager.h b/src/src/UI/Manager/ImageViewManager.h index cbe37c5..db70c59 100644 --- a/src/src/UI/Manager/ImageViewManager.h +++ b/src/src/UI/Manager/ImageViewManager.h @@ -40,7 +40,7 @@ public: return currentView; } - bool checkCurrentViewFusion(); + void checkCurrentViewFusion(); int getViewCount() { return vList.size(); @@ -68,6 +68,8 @@ public: void viewReload(const std::string &unique_info); + void viewCleared(); + void setInteractionMode(int InteractionMode); void renderAll(); @@ -103,6 +105,7 @@ public: signals: void currentViewChanged(const std::string& seriesID); + void fusionCheckStateChanged(bool able); private: QList vList; diff --git a/src/src/UI/Widget/dicomimageview.cpp b/src/src/UI/Widget/dicomimageview.cpp index 861347e..822f8e2 100644 --- a/src/src/UI/Widget/dicomimageview.cpp +++ b/src/src/UI/Widget/dicomimageview.cpp @@ -194,7 +194,7 @@ void DicomImageView::scrollBarValueChanged(int slice) { void DicomImageView::viewCleared() { resetView(); - emit afterViewClear(this); + emit afterViewCleared(this); } void DicomImageView::doubleClicked() { diff --git a/src/src/UI/Widget/dicomimageview.h b/src/src/UI/Widget/dicomimageview.h index 7eef906..e34b86b 100644 --- a/src/src/UI/Widget/dicomimageview.h +++ b/src/src/UI/Widget/dicomimageview.h @@ -167,7 +167,7 @@ public: signals: - void afterViewClear(DicomImageView *view); + void afterViewCleared(DicomImageView *view); void onViewClick(DicomImageView *view); diff --git a/src/src/UI/Window/QDicomViewer.cpp b/src/src/UI/Window/QDicomViewer.cpp index 0900617..afe7861 100644 --- a/src/src/UI/Window/QDicomViewer.cpp +++ b/src/src/UI/Window/QDicomViewer.cpp @@ -11,35 +11,69 @@ #include "UI/Widget/gridpopwidget.h" #include "UI/Widget/cine/pqVCRToolbar.h" -/************************************************************************ -* Consider: -* 1. [Done]series id only maps to a single instance, this situation needs to be improved. -* 2. [Done]Corner Info Auto tune -* 3. [Undone]disable open icon when dicom data loading is not finished -* 4. [Done]Import from PACS inherits Qthread in the near future! +QDicomViewer::QDicomViewer(QWidget *parent) : QMainWindow(parent), + ui(new Ui::QDicomViewerClass), + m_import(nullptr) { + ui->setupUi(this); + this->statusBar()->showMessage(tr("Ready")); + QWidget::setWindowTitle(Project_NAME); -* Notice: -* 1. You'd better set to new instance before delete the older, may leads to crash problem. -* 2. + //init icons + icon_manual.addFile(QStringLiteral(SYNC_MANUAL_URL)); + icon_auto.addFile(QStringLiteral(SYNC_AUTO_URL)); + icon_dis.addFile(QStringLiteral(SYNC_DIS_URL)); -* Bug: -* 1. getRelevantViewList() should consider in memory not in view instance -/************************************************************************/ -#define SINGLE_INSTANCE 1 + this->Initial(); -#define addbutton(name,png)\ + loadStyleSheet("Combinear"); + + QSize size(27, 27); + this->setIconSize(size); + + //init fontsizehelper + QScreen *screen = QGuiApplication::primaryScreen(); + QRect rect = screen->geometry(); + FontSizeHelper::desktop_width = rect.width(); + FontSizeHelper::desktop_height = rect.height(); + + //hidden humbnailBar as default + displayThumbnailBar(false); + + //TODO:目前为方向是写死的正交方向 + orientationHelper::init(); +} + +QDicomViewer::~QDicomViewer() { +} + +void QDicomViewer::Initial() { + this->createToolButton(); + this->SetupConnections(); +} + +void QDicomViewer::loadStyleSheet(const QString &sheetName) { + QFile file(":/StyleSheet/" + sheetName + ".qss"); + file.open(QFile::ReadOnly); + if (file.isOpen()) { + QString styleSheet = this->styleSheet(); + styleSheet += QLatin1String(file.readAll()); + this->setStyleSheet(styleSheet); + } +} + +void QDicomViewer::createToolButton() { +#define addbutton(name, png)\ QToolButton* btn##name = new QToolButton(this);\ {\ QPixmap map(png);\ btn##name->setIcon(QIcon(map));\ btn##name->setMinimumSize(QSize(48, 48));\ - btn##name->setMaximumSize(QSize(48, 48));\ - btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ + btn##name->setMaximumSize(QSize(48, 48));\ + btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ this->ui->toolBar->addWidget(btn##name);\ - }\ + } - -#define addGroupedButton(name,png,group)\ +#define addGroupedButton(name, png, group)\ QToolButton* btn##name = new QToolButton(this);\ {\ QPixmap map(png);\ @@ -47,836 +81,607 @@ btn##name->setCheckable(true);\ btn##name->setAutoExclusive(true);\ btn##name->setMinimumSize(QSize(48, 48));\ - btn##name->setMaximumSize(QSize(48, 48));\ - btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ + btn##name->setMaximumSize(QSize(48, 48));\ + btn##name->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\ group->addButton(btn##name);\ this->ui->toolBar->addWidget(btn##name);\ - }\ + } - -#define addbutton2(name,png)\ +#define addbutton2(name, png)\ QToolButton* btn##name = new QToolButton(this);\ {\ QPixmap map(png);\ btn##name->setIcon(QIcon(map));\ btn##name->setMinimumSize(QSize(25, 25));\ - btn##name->setMaximumSize(QSize(25, 25));\ - this->ui->toolBar->addWidget(btn##name); \ - }\ + btn##name->setMaximumSize(QSize(25, 25));\ + this->ui->toolBar->addWidget(btn##name); \ + } -QDicomViewer::QDicomViewer(QWidget* parent) :QMainWindow(parent), -ui(new Ui::QDicomViewerClass), -m_import(nullptr) + ui->toolBar->setContextMenuPolicy(Qt::ContextMenuPolicy::PreventContextMenu); + ui->toolBar->setFixedHeight(VCRHelper::toolbar_Height); + ui->toolBar->setMovable(false); + ui->toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); -{ - ui->setupUi(this); - this->statusBar()->showMessage(tr("Ready")); - QWidget::setWindowTitle(Project_NAME); + addbutton(file, ":/InfiniteViewer/Icon/openfile.png") + addbutton(import, ":/InfiniteViewer/Icon/import.png") + addbutton(save, ":/InfiniteViewer/Icon/save.png") + this->ui->toolBar->addSeparator(); - //init icons - icon_manual.addFile(QStringLiteral(SYNC_MANUAL_URL)); - icon_auto.addFile(QStringLiteral(SYNC_AUTO_URL)); - icon_dis.addFile(QStringLiteral(SYNC_DIS_URL)); + addbutton(grid, ":/InfiniteViewer/Icon/grid.png") + addbutton(sync, ":/InfiniteViewer/Icon/sync/sync_dis.png") + addbutton(anno, ":/InfiniteViewer/Icon/anno.png") + this->ui->toolBar->addSeparator(); - this->Initial(); + QButtonGroup *modegroup = new QButtonGroup(this); + addGroupedButton(slice, ":/InfiniteViewer/Icon/slice.png", modegroup) + addGroupedButton(windowlevel, ":/InfiniteViewer/Icon/windowlevel.png", modegroup) + addGroupedButton(pan, ":/InfiniteViewer/Icon/pan.png", modegroup) + addGroupedButton(zoom, ":/InfiniteViewer/Icon/zoom.png", modegroup) + addGroupedButton(measure, ":/InfiniteViewer/Icon/distance.png", modegroup) + addbutton(empty, ":/InfiniteViewer/Icon/trashbin.png") + this->ui->toolBar->addSeparator(); - loadStyleSheet("Combinear"); - QSize size(27, 27); - this->setIconSize(size); + addbutton(flip, ":/InfiniteViewer/Icon/flip.png") + addbutton(cine, ":/InfiniteViewer/Icon/cine.png") + addbutton(fusion, ":/InfiniteViewer/Icon/fusion.png") + addbutton(MPR, ":/InfiniteViewer/Icon/MPR.png") - //init fontsizehelper - QScreen* screen = QGuiApplication::primaryScreen(); - QRect rect = screen->geometry(); - FontSizeHelper::desktop_width = rect.width(); - FontSizeHelper::desktop_height = rect.height(); + QWidget *spacer = new QWidget(this); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + this->ui->toolBar->addWidget(spacer); - //hidden humbnailBar as default - displayThumbnailBar(false); + act_num_of_minimize = ui->toolBar->actions().count(); + addbutton2(minimize, ":/InfiniteViewer/Icon/minimize.png") - //TODO:目前为方向是写死的正交方向 - orientationHelper::init(); + act_num_of_maximize = ui->toolBar->actions().count(); + addbutton2(maximize, ":/InfiniteViewer/Icon/maximize-restore.png") + + act_num_of_close = ui->toolBar->actions().count(); + addbutton2(close, ":/InfiniteViewer/Icon/close.png") + + act_num_of_fullscreen = ui->toolBar->actions().count(); + addbutton2(fullscreen, ":/InfiniteViewer/Icon/full_screen.png") + + ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); + ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); + ui->toolBar->actions().at(act_num_of_close)->setVisible(false); + + this->SetupFileTool(btnfile); + this->SetupImportTool(btnimport); + this->SetupExportTool(btnsave); + + this->SetupGridTool(btngrid); + this->SetupSyncTool(btnsync); + this->SetupAnnoTool(btnanno); + + this->SetupSliceTool(btnslice); + this->SetupAdjustTool(btnwindowlevel); + this->SetupPanTool(btnpan); + this->SetupZoomTool(btnzoom); + this->SetupMeasureTool(btnmeasure); + this->SetupEmptyTool(btnempty); + + this->SetupFlipTool(btnflip); + this->SetupFusionTool(btnfusion); + this->SetupCineTool(btncine); + + this->SetupFullScreenTool(btnfullscreen); + this->SetupMaximizeTool(btnmaximize); + this->SetupMinimizeTool(btnminimize); + this->SetupCloseTool(btnclose); + + connect(btnMPR, &QToolButton::clicked, ui->viewContainer->getViewManager(), + &ImageViewManager::switchSliceOrientation); } -QDicomViewer::~QDicomViewer() { +void QDicomViewer::SetupFullScreenTool(QToolButton *btnfullscreen) { + btnfullscreen->setToolTip(QString("Full screen")); + connect(btnfullscreen, &QToolButton::clicked, this, [=] { + ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(false); + ui->toolBar->actions().at(act_num_of_minimize)->setVisible(true); + ui->toolBar->actions().at(act_num_of_maximize)->setVisible(true); + ui->toolBar->actions().at(act_num_of_close)->setVisible(true); + + setWindowState(Qt::WindowState::WindowFullScreen); + }); } +void QDicomViewer::SetupMaximizeTool(QToolButton *btnmaximize) { + btnmaximize->setToolTip(QString("Exit full screen mode")); + connect(btnmaximize, &QToolButton::clicked, this, [=] { -void QDicomViewer::loadStyleSheet(const QString& sheetName) -{ - QFile file(":/StyleSheet/" + sheetName + ".qss"); - file.open(QFile::ReadOnly); - if (file.isOpen()) - { - QString styleSheet = this->styleSheet(); - styleSheet += QLatin1String(file.readAll()); - this->setStyleSheet(styleSheet); - } + ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); + ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); + ui->toolBar->actions().at(act_num_of_close)->setVisible(false); + ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(true); + + setWindowState(Qt::WindowState::WindowMaximized); + }); } -void QDicomViewer::Initial() -{ - this->createToolButton(); - this->SetupConnections(); +void QDicomViewer::SetupMinimizeTool(QToolButton *btnminimize) { + btnminimize->setToolTip(QString("Minimize")); + connect(btnminimize, &QToolButton::clicked, this, [=] { + setWindowState(Qt::WindowState::WindowMinimized); + }); } -void QDicomViewer::createToolButton() -{ - //this->ui->vcr_toolbar->setMovable(true); - //this->ui->vcr_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); - ui->toolBar->setContextMenuPolicy(Qt::ContextMenuPolicy::PreventContextMenu); - ui->toolBar->setFixedHeight(VCRHelper::toolbar_Height); - ui->toolBar->setMovable(false); - ui->toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); - - addbutton(file, ":/InfiniteViewer/Icon/openfile.png"); - addbutton(import, ":/InfiniteViewer/Icon/import.png"); - addbutton(save, ":/InfiniteViewer/Icon/save.png"); - this->ui->toolBar->addSeparator(); - - addbutton(grid, ":/InfiniteViewer/Icon/grid.png"); - addbutton(sync, ":/InfiniteViewer/Icon/sync/sync_dis.png"); - addbutton(anno, ":/InfiniteViewer/Icon/anno.png"); - this->ui->toolBar->addSeparator(); - - QButtonGroup* modegroup = new QButtonGroup(this); - addGroupedButton(slice, ":/InfiniteViewer/Icon/slice.png", modegroup); - addGroupedButton(windowlevel, ":/InfiniteViewer/Icon/windowlevel.png", modegroup); - addGroupedButton(pan, ":/InfiniteViewer/Icon/pan.png", modegroup); - addGroupedButton(zoom, ":/InfiniteViewer/Icon/zoom.png", modegroup); - addGroupedButton(measure, ":/InfiniteViewer/Icon/distance.png", modegroup); - addbutton(empty, ":/InfiniteViewer/Icon/trashbin.png"); - this->ui->toolBar->addSeparator(); - - - addbutton(flip, ":/InfiniteViewer/Icon/flip.png"); - addbutton(cine, ":/InfiniteViewer/Icon/cine.png"); - addbutton(fusion, ":/InfiniteViewer/Icon/fusion.png"); - addbutton(MPR, ":/InfiniteViewer/Icon/MPR.png"); - - QWidget* spacer = new QWidget(this); - spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - this->ui->toolBar->addWidget(spacer); - - //this->ui->toolBar_2->setFixedHeight(VCRHelper::toolbtn2_Size); - //this->ui->toolBar_2->setMovable(false); - //this->ui->toolBar_2->setToolButtonStyle(Qt::ToolButtonIconOnly); - - - - act_num_of_minimize = ui->toolBar->actions().count(); - addbutton2(minimize, ":/InfiniteViewer/Icon/minimize.png"); - - act_num_of_maximize = ui->toolBar->actions().count(); - addbutton2(maximize, ":/InfiniteViewer/Icon/maximize-restore.png"); - - act_num_of_close = ui->toolBar->actions().count(); - addbutton2(close, ":/InfiniteViewer/Icon/close.png"); - - act_num_of_fullscreen = ui->toolBar->actions().count(); - addbutton2(fullscreen, ":/InfiniteViewer/Icon/full_screen.png"); - - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_close)->setVisible(false); - - this->SetupFileTool(btnfile); - this->SetupImportTool(btnimport); - this->SetupExportTool(btnsave); - - this->SetupGridTool(btngrid); - this->SetupSyncTool(btnsync); - this->SetupAnnoTool(btnanno); - - this->SetupSliceTool(btnslice); - this->SetupAdjustTool(btnwindowlevel); - this->SetupPanTool(btnpan); - this->SetupZoomTool(btnzoom); - this->SetupMeasureTool(btnmeasure); - this->SetupEmptyTool(btnempty); - - this->SetupFlipTool(btnflip); - this->SetupFusionTool(btnfusion); - this->SetupCineTool(btncine); - - this->SetupFullScreenTool(btnfullscreen); - this->SetupMaximizeTool(btnmaximize); - this->SetupMinimizeTool(btnminimize); - this->SetupCloseTool(btnclose); - - connect(btnMPR,&QToolButton::clicked,ui->viewContainer->getViewManager(), &ImageViewManager::switchSliceOrientation); +void QDicomViewer::SetupCloseTool(QToolButton *btnclose) { + btnclose->setToolTip(QString("Close")); + connect(btnclose, &QToolButton::clicked, this, &QWidget::close); } -void QDicomViewer::SetupFullScreenTool(QToolButton* btnfullscreen) -{ - btnfullscreen->setToolTip(QString("Full screen")); - connect(btnfullscreen, &QToolButton::clicked, this, [=] { - ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(false); - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(true); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(true); - ui->toolBar->actions().at(act_num_of_close)->setVisible(true); - - setWindowState(Qt::WindowState::WindowFullScreen); - }); -} - -void QDicomViewer::SetupMaximizeTool(QToolButton* btnmaximize) -{ - btnmaximize->setToolTip(QString("Exit full screen mode")); - connect(btnmaximize, &QToolButton::clicked, this, [=] { - - ui->toolBar->actions().at(act_num_of_minimize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_maximize)->setVisible(false); - ui->toolBar->actions().at(act_num_of_close)->setVisible(false); - ui->toolBar->actions().at(act_num_of_fullscreen)->setVisible(true); - - setWindowState(Qt::WindowState::WindowMaximized); - }); -} - - -void QDicomViewer::SetupMinimizeTool(QToolButton* btnminimize) -{ - btnminimize->setToolTip(QString("Minimize")); - connect(btnminimize, &QToolButton::clicked, this, [=] { - setWindowState(Qt::WindowState::WindowMinimized); - - }); -} - -void QDicomViewer::SetupCloseTool(QToolButton* btnclose) -{ - btnclose->setToolTip(QString("Close")); - connect(btnclose, &QToolButton::clicked, this, [=] { - close(); - }); -} - - - -void QDicomViewer::SetupAnnoTool(QToolButton* annoBtn) -{ +void QDicomViewer::SetupAnnoTool(QToolButton *annoBtn) { //主要设置了四角标签的操作逻辑 - annoBtn->setToolTip(QString("Toggle annotations")); - //视窗操作,显隐脚注 + annoBtn->setToolTip(QString("Toggle annotations")); + //视窗操作,显隐脚注 - connect(annoBtn, &QToolButton::clicked, this, [=] { - AnnoHelper::toggleAnno(); + connect(annoBtn, &QToolButton::clicked, this, [=] { + AnnoHelper::toggleAnno(); ui->viewContainer->getViewManager()->updateCornerInfoAll(); - }); + }); //视窗操作,显隐测量 - QMenu* m; - m = new QMenu(this); - connect(m, &QMenu::triggered, this, [=] - { - //load data - m_measure_hidden_action->setChecked(Measure::GetHidden()); - }); + QMenu *m; + m = new QMenu(this); + connect(m, &QMenu::triggered, this, [=] { + //load data + m_measure_hidden_action->setChecked(Measure::GetHidden()); + }); //视窗操作,显隐测量 - m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) { + m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) { Measure::SetHidden(value); ui->viewContainer->getViewManager()->renderAll(); - }); + }); - m->addSeparator(); + m->addSeparator(); //视窗操作,匿名化 - m_patient_hidden_action = m->addAction(tr("Hide patient data"), this, [=] { - if (m_patient_hidden_action->isChecked()) - { - AnnoHelper::PrivacyOn(); - } - else - { - AnnoHelper::PrivacyOff(); - } + m_patient_hidden_action = m->addAction(tr("Hide patient data"), this, [=] { + if (m_patient_hidden_action->isChecked()) { + AnnoHelper::PrivacyOn(); + } else { + AnnoHelper::PrivacyOff(); + } ui->viewContainer->getViewManager()->updateCornerInfoPrivacy(); - }); - m_patient_hidden_action->setCheckable(true); - m_patient_hidden_action->setChecked(false); + }); + m_patient_hidden_action->setCheckable(true); + m_patient_hidden_action->setChecked(false); - m->addAction(tr("Show Dicom tags"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV->hasSeries()) - { + m->addAction(tr("Show Dicom tags"), this, [&] { + DicomImageView *curV = ui->viewContainer->getCurrentView(); + if (curV->hasSeries()) { curV->showMetaData(); - } - }); + } + }); - m_measure_hidden_action->setCheckable(true); - m_measure_hidden_action->setChecked(false); + m_measure_hidden_action->setCheckable(true); + m_measure_hidden_action->setChecked(false); - - annoBtn->setPopupMode(QToolButton::MenuButtonPopup); - annoBtn->setMenu(m); + annoBtn->setPopupMode(QToolButton::MenuButtonPopup); + annoBtn->setMenu(m); } +namespace { + const int ACTION_COUNT = 7; + const ActionProperty MEASURE_ACTIIONS[ACTION_COUNT] = { + {"Length", ":/InfiniteViewer/Icon/distance.png", AnnotationActorType::RulerAnn}, + {"Angle", ":/InfiniteViewer/Icon/angle.png", AnnotationActorType::AngleAnn}, + {"Closed polygon", ":/InfiniteViewer/Icon/polygon.png", AnnotationActorType::ClosedPolygonAnn}, + {"Open polygon", ":/InfiniteViewer/Icon/polyline.png", AnnotationActorType::OpenPolygonAnn}, + {"Arrow", ":/InfiniteViewer/Icon/arrow.png", AnnotationActorType::ArrowAnn}, + {"Ellipse", ":/InfiniteViewer/Icon/ellipse.png", AnnotationActorType::EllipseAnn}, + {"Text", ":/InfiniteViewer/Icon/text.png", AnnotationActorType::TextAnn} + }; +} //AnnotationActor执行相关 -void QDicomViewer::executeActiveMeasure() -{ +void QDicomViewer::SetupMeasureTool(QToolButton *measureBtn) { +#define ADD_MEASURE_ACTION(index)\ + m->addAction(tr(std::get<0>(MEASURE_ACTIIONS[index])), this, [=] {\ + measureBtn->setChecked(true);\ + QPixmap map(std::get<1>(MEASURE_ACTIIONS[index]));\ + measureBtn->setIcon(QIcon(map));\ + MeasureHelper::setMeasureType(std::get<2>(MEASURE_ACTIIONS[index]));\ + ui->viewContainer->getViewManager()->activeMeasure();\ +}) + +#define ADD_DEL_ACTION(text, type, func)\ + m->addAction(tr(text), this, [=] {\ + measureBtn->setChecked(true);\ + m_cur_measure = type;\ + DicomImageView* curV = ui->viewContainer->getCurrentView();\ + if (curV != nullptr)\ + {\ + curV->func();\ + }\ +}) + + measureBtn->setToolTip(QString("Measurements")); + + connect(measureBtn, &QToolButton::clicked, this, &QDicomViewer::executeActiveMeasure); + + QMenu *m; + m = new QMenu(this); + + for (int j = 0; j < ACTION_COUNT; ++j) { + ADD_MEASURE_ACTION(j); + } + m->addSeparator(); + ADD_DEL_ACTION("Delete selected", AnnotationActorType::DeleteSelectedAnn, deleteSelectedMeasure); + ADD_DEL_ACTION("Delete all in current slice", AnnotationActorType::DeleteSliceAnn, deleteCurrentSliceMeasure); + ADD_DEL_ACTION("Delete all in current series", AnnotationActorType::DeleteSeriesAnn, deleteCurrentSeriesMeasure); + measureBtn->setPopupMode(QToolButton::MenuButtonPopup); + measureBtn->setMenu(m); +} + +void QDicomViewer::executeActiveMeasure() { ui->viewContainer->getViewManager()->activeMeasure(); - DicomImageView* curV = ui->viewContainer->getCurrentView(); - switch (MeasureHelper::getMeasureType()) - { - case AnnotationActorType::DeleteSelectedAnn: - if (curV != nullptr) - { - curV->deleteSelectedMeasure(); - } - break; - case AnnotationActorType::DeleteSliceAnn: - if (curV != nullptr) - { - curV->deleteCurrentSliceMeasure(); - } - break; - case AnnotationActorType::DeleteSeriesAnn: - if (curV != nullptr) - { - curV->deleteCurrentSeriesMeasure(); - } - break; - default: - ui->viewContainer->getViewManager()->activeMeasure(); - break; - } -} - -//视窗操作,AnnotationActor新增相关 -void QDicomViewer::SetupMeasureTool(QToolButton* measureBtn) -{ - measureBtn->setToolTip(QString("Measurements")); - - connect(measureBtn, &QToolButton::clicked, this, [=] { - executeActiveMeasure(); - }); - - QMenu* m; - m = new QMenu(this); - - m->addAction(tr("Length"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/distance.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::RulerAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addAction(tr("Angle"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/angle.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::AngleAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addAction(tr("Closed polygon"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/polygon.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::ClosedPolygonAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addAction(tr("Open polygon"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/polyline.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::OpenPolygonAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addAction(tr("Arrow"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/arrow.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::ArrowAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addAction(tr("Ellipse"), this, [=] { - QPixmap map(":/InfiniteViewer/Icon/ellipse.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::EllipseAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - m->addAction(tr("Text"), this, [=] { - measureBtn->setChecked(true); - QPixmap map(":/InfiniteViewer/Icon/text.png"); - measureBtn->setIcon(QIcon(map)); - MeasureHelper::setMeasureType(AnnotationActorType::TextAnn); - ui->viewContainer->getViewManager()->activeMeasure(); - }); - - m->addSeparator(); - - m->addAction(tr("Delete selected"), this, [=] { - measureBtn->setChecked(true); - m_cur_measure = AnnotationActorType::DeleteSelectedAnn; - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr) - { - curV->deleteSelectedMeasure(); - } - }); - m->addAction(tr("Delete all in current slice"), this, [=] { - measureBtn->setChecked(true); - m_cur_measure = AnnotationActorType::DeleteSliceAnn; - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr) - { - curV->deleteCurrentSliceMeasure(); - } - }); - m->addAction(tr("Delete all in current series"), this, [=] { - measureBtn->setChecked(true); - m_cur_measure = AnnotationActorType::DeleteSeriesAnn; - - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr) - { - curV->deleteCurrentSeriesMeasure(); - } - }); - - - measureBtn->setPopupMode(QToolButton::MenuButtonPopup); - measureBtn->setMenu(m); -} - -void QDicomViewer::createVCRToolbar(DicomImageView* v) -{ - pqVCRToolbar* vcr_toolbar = new pqVCRToolbar(this); - //this->addToolBar(Qt::ToolBarArea::AllToolBarAreas, vcr_toolbar); - vcr_toolbar->setAllowedAreas(Qt::AllToolBarAreas); - vcr_toolbar->setMovable(false); - vcr_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); - vcr_toolbar->setFixedWidth(VCRHelper::vcr_toolbar_Width); - //vcr_toolbar->move(0, 0); - v->setVCRToolbar(vcr_toolbar); + DicomImageView *curV = ui->viewContainer->getCurrentView(); + switch (MeasureHelper::getMeasureType()) { + case AnnotationActorType::DeleteSelectedAnn: + if (curV != nullptr) { + curV->deleteSelectedMeasure(); + } + break; + case AnnotationActorType::DeleteSliceAnn: + if (curV != nullptr) { + curV->deleteCurrentSliceMeasure(); + } + break; + case AnnotationActorType::DeleteSeriesAnn: + if (curV != nullptr) { + curV->deleteCurrentSeriesMeasure(); + } + break; + default: + ui->viewContainer->getViewManager()->activeMeasure(); + break; + } } //视窗操作,播放相关 -void QDicomViewer::SetupCineTool(QToolButton* cineBtn) -{ - cineBtn->setToolTip(QString("Cine")); - connect(cineBtn, &QToolButton::clicked, this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV->hasSeries()) - { - if (curV->IsCine()) - { - curV->setVCRVisible(!curV->isVCRVisible()); - } - else - { - createVCRToolbar(curV); - curV->cineModeOn(); - } - - - } - }); +void QDicomViewer::SetupCineTool(QToolButton *cineBtn) { + cineBtn->setToolTip(QString("Cine")); + connect(cineBtn, &QToolButton::clicked, this, [&] { + DicomImageView *curV = ui->viewContainer->getCurrentView(); + if (curV->hasSeries()) { + if (curV->IsCine()) { + curV->setVCRVisible(!curV->isVCRVisible()); + } else { + createVCRToolbar(curV); + curV->cineModeOn(); + } + } + }); +} +void QDicomViewer::createVCRToolbar(DicomImageView *v) { + pqVCRToolbar *vcr_toolbar = new pqVCRToolbar(this); + //this->addToolBar(Qt::ToolBarArea::AllToolBarAreas, vcr_toolbar); + vcr_toolbar->setAllowedAreas(Qt::AllToolBarAreas); + vcr_toolbar->setMovable(false); + vcr_toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); + vcr_toolbar->setFixedWidth(VCRHelper::vcr_toolbar_Width); + //vcr_toolbar->move(0, 0); + v->setVCRToolbar(vcr_toolbar); } //视窗操作,fusion相关 -void QDicomViewer::SetupFusionTool(QToolButton* fusionBtn) -{ - fusionBtn->setToolTip(QString("Fusion")); - connect(fusionBtn, &QToolButton::clicked, ui->viewContainer->getViewManager(), &ImageViewManager::switchFusion); - QMenu* m; - m = new QMenu(this); - m->addAction(tr("Reset Fusion"), ui->viewContainer->getViewManager(), &ImageViewManager::unloadFusion); - fusionBtn->setPopupMode(QToolButton::MenuButtonPopup); - fusionBtn->setMenu(m); +void QDicomViewer::SetupFusionTool(QToolButton *fusionBtn) { + fusionBtn->setToolTip(QString("Fusion")); + connect(fusionBtn, &QToolButton::clicked, ui->viewContainer->getViewManager(), &ImageViewManager::switchFusion); + QMenu *m = new QMenu(this); + m->addAction(tr("Reset Fusion"), ui->viewContainer->getViewManager(), &ImageViewManager::unloadFusion); + fusionBtn->setPopupMode(QToolButton::MenuButtonPopup); + fusionBtn->setMenu(m); + fusionBtn->setEnabled(false); + connect(ui->viewContainer->getViewManager(), + &ImageViewManager::fusionCheckStateChanged,[=](bool v){ + fusionBtn->setEnabled(v); + }); } + //视窗操作,slice -void QDicomViewer::SetupSliceTool(QToolButton* sliceBtn) -{ - sliceBtn->setToolTip(QString("Browse series")); - connect(sliceBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupSliceTool(QToolButton *sliceBtn) { + sliceBtn->setToolTip(QString("Browse series")); + connect(sliceBtn, &QToolButton::clicked, this, [&] { ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_SLICING); - }); + }); } + //视窗操作,pan -void QDicomViewer::SetupPanTool(QToolButton* panBtn) -{ - panBtn->setToolTip(QString("Pan image")); - connect(panBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupPanTool(QToolButton *panBtn) { + panBtn->setToolTip(QString("Pan image")); + connect(panBtn, &QToolButton::clicked, this, [&] { ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_PAN); - }); + }); } + //视窗操作,zoom -void QDicomViewer::SetupZoomTool(QToolButton* zoomBtn) -{ - zoomBtn->setToolTip(QString("Zoom image")); - connect(zoomBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupZoomTool(QToolButton *zoomBtn) { + zoomBtn->setToolTip(QString("Zoom image")); + connect(zoomBtn, &QToolButton::clicked, this, [&] { ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_ZOOM); - }); + }); } //视窗操作,wwwl -void QDicomViewer::SetupAdjustTool(QToolButton* winlevelBtn) -{ - winlevelBtn->setToolTip(QString("Adjust window level")); - connect(winlevelBtn, &QToolButton::clicked, this, [&] { +void QDicomViewer::SetupAdjustTool(QToolButton *winlevelBtn) { + winlevelBtn->setToolTip(QString("Adjust window level")); + connect(winlevelBtn, &QToolButton::clicked, this, [&] { ui->viewContainer->getViewManager()->setInteractionMode(VTKIS_IMAGE_WINDOWLEVEL); - }); + }); - // Menu - QMenu* m; - //QAction *a; - m = new QMenu(this); - m->addAction(tr("Custom Window"), this, [=](bool value) { - winlevelBtn->setChecked(true); - if (nullptr == m_customwin) { - m_customwin = new Customwindow(this); - } - m_customwin->setCurrentView(ui->viewContainer->getCurrentView()); - //show custom window subwindow - m_customwin->setModal(true); - //m_customwin->show(); - m_customwin->exec(); + // Menu + QMenu *m = new QMenu(this); + m->addAction(tr("Custom Window"), this, [=](bool value) { + winlevelBtn->setChecked(true); + if (nullptr == m_customwin) { + m_customwin = new Customwindow(this); + } + m_customwin->setCurrentView(ui->viewContainer->getCurrentView()); + //show custom window subwindow + m_customwin->setModal(true); + m_customwin->exec(); + }); - }); - - m->addAction(tr("Negative"), this, [=](bool value) { - winlevelBtn->setChecked(true); - DicomImageView* curV = ui->viewContainer->getViewManager()->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { + m->addAction(tr("Negative"), this, [=](bool value) { + winlevelBtn->setChecked(true); + DicomImageView *curV = ui->viewContainer->getViewManager()->getCurrentView(); + if (curV != nullptr && curV->hasSeries()) { curV->negativeWindow(); - } - }); + } + }); - winlevelBtn->setPopupMode(QToolButton::MenuButtonPopup); - winlevelBtn->setMenu(m); + winlevelBtn->setPopupMode(QToolButton::MenuButtonPopup); + winlevelBtn->setMenu(m); } //视窗操作,clear -void QDicomViewer::SetupEmptyTool(QToolButton* emptyBtn) -{ - emptyBtn->setToolTip(QString("Delete current series")); - connect(emptyBtn, &QToolButton::clicked,ui->viewContainer->getCurrentView(),&DicomImageView::viewCleared); +void QDicomViewer::SetupEmptyTool(QToolButton *emptyBtn) { + emptyBtn->setToolTip(QString("Delete current series")); + connect(emptyBtn, &QToolButton::clicked, ui->viewContainer->getCurrentView(), &DicomImageView::viewCleared); } //视窗操作,flip and rotation -void QDicomViewer::SetupFlipTool(QToolButton* flipBtn) -{ - flipBtn->setToolTip(QString("Transformations")); - QMenu* m; - m = new QMenu(this); - m->addAction(tr("Rotate 90 CCW"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { +void QDicomViewer::SetupFlipTool(QToolButton *flipBtn) { + flipBtn->setToolTip(QString("Transformations")); + QMenu *m = new QMenu(this); + +#define ADD_TRANSFORM_ACTION(text,func,...)\ + m->addAction(tr(text), this, [&] {\ + DicomImageView *curV = ui->viewContainer->getCurrentView();\ + if (curV != nullptr && curV->hasSeries()) {\ + curV->func(__VA_ARGS__);\ + }\ +}) + + ADD_TRANSFORM_ACTION("Rotate 90 CCW",rotateImage,90, ROTATE_90_CCW); + ADD_TRANSFORM_ACTION("Rotate 90 CW",rotateImage,-90, ROTATE_90_CW); + ADD_TRANSFORM_ACTION("Rotate 180",rotateImage,180, ROTATE_180); + m->addSeparator(); + ADD_TRANSFORM_ACTION("Flip horizontal",hFlipImage); + ADD_TRANSFORM_ACTION("Flip vertical",vFlipImage); + m->addSeparator(); + ADD_TRANSFORM_ACTION("Clear transformations",ClearTransformations); + flipBtn->setPopupMode(QToolButton::MenuButtonPopup); + flipBtn->setMenu(m); + connect(flipBtn, &QPushButton::clicked, this, [&] { + DicomImageView *curV = ui->viewContainer->getCurrentView(); + if (curV != nullptr && curV->hasSeries()) { curV->rotateImage(90, ROTATE_90_CCW); - } - - }); - m->addAction(tr("Rotate 90 CW"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->rotateImage(-90, ROTATE_90_CW); - } - }); - m->addAction(tr("Rotate 180"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->rotateImage(180, ROTATE_180); - } - - }); - m->addSeparator(); - m->addAction(tr("Flip horizontal"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->hFlipImage(); - } - }); - m->addAction(tr("Flip vertical"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->vFlipImage(); - } - - }); - m->addSeparator(); - m->addAction(tr("Clear transformations"), this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->ClearTransformations(); - } - }); - flipBtn->setPopupMode(QToolButton::MenuButtonPopup); - flipBtn->setMenu(m); - - connect(flipBtn, &QPushButton::clicked, this, [&] { - DicomImageView* curV = ui->viewContainer->getCurrentView(); - if (curV != nullptr && curV->hasSeries()) - { - curV->rotateImage(90, ROTATE_90_CCW); - } - }); + } + }); } //视窗操作,sync mode -void QDicomViewer::SetupSyncTool(QToolButton* syncBtn) -{ - syncBtn->setToolTip(QString("Toggle series synchronization")); - // Menu - QMenu* m; - m = new QMenu(this); +void QDicomViewer::SetupSyncTool(QToolButton *syncBtn) { + syncBtn->setToolTip(QString("Toggle series synchronization")); + // Menu + QMenu * m = new QMenu(this); - //QAction *a; - SyncState curst = SyncHelper::getSyncState(); - m_sync_state_action = m->addAction(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[curst]), this, [&](bool value) { - }); - m_sync_state_action->setCheckable(false); + //QAction *a; + SyncState curst = SyncHelper::getSyncState(); + m_sync_state_action = m->addAction(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[curst]), this, + [&](bool value) { + }); + m_sync_state_action->setCheckable(false); - this->ui->toolBar->addSeparator(); + this->ui->toolBar->addSeparator(); - m_sync_item_action[0] = m->addAction(tr("Sychronize slice position"), this, [&](bool value) { - SyncHelper::setSyncItem(SyncItem::SLICE_POS, value); - }); - m_sync_item_action[0]->setCheckable(true); - m_sync_item_action[0]->setChecked(false); - m_sync_item_action[0]->setDisabled(true); +#define ADD_SYNC_ITEM(index,text,type)\ + m_sync_item_action[index] = m->addAction(tr(text), this, [&](bool value) {\ + SyncHelper::setSyncItem(type, value);\ + });\ + m_sync_item_action[index]->setCheckable(true);\ + m_sync_item_action[index]->setChecked(false);\ + m_sync_item_action[index]->setDisabled(true); + ADD_SYNC_ITEM(0,"Sychronize slice position",SyncItem::SLICE_POS) + ADD_SYNC_ITEM(1,"Sychronize zoom & pan",SyncItem::ZOOM_PAN) + ADD_SYNC_ITEM(2,"Sychronize window level & width",SyncItem::WIDTH_LEVEL) - m_sync_item_action[1] = m->addAction(tr("Sychronize zoom & pan"), this, [&](bool value) { - SyncHelper::setSyncItem(SyncItem::ZOOM_PAN, value); - }); - m_sync_item_action[1]->setCheckable(true); - m_sync_item_action[1]->setChecked(false); - m_sync_item_action[1]->setDisabled(true); + syncBtn->setPopupMode(QToolButton::MenuButtonPopup); + syncBtn->setMenu(m); + //loop click + connect(syncBtn, &QToolButton::clicked, this, + &QDicomViewer::syncStateChanged); +} - m_sync_item_action[2] = m->addAction(tr("Sychronize window level & width"), this, [&](bool value) { - SyncHelper::setSyncItem(SyncItem::WIDTH_LEVEL, value); - }); - m_sync_item_action[2]->setCheckable(true); - m_sync_item_action[2]->setChecked(false); - m_sync_item_action[2]->setDisabled(true); - syncBtn->setPopupMode(QToolButton::MenuButtonPopup); - syncBtn->setMenu(m); +void QDicomViewer::syncStateChanged() const { + QToolButton* syncBtn = qobject_cast(sender()); + SyncState curst = SyncHelper::getSyncState(); + switch (curst) { + case AUTO_SYNC: + syncBtn->setIcon(icon_manual); + m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[MANUAL_SYNC])); - //loop click - connect(syncBtn, &QToolButton::clicked, this, [=] { - SyncState curst = SyncHelper::getSyncState(); - - switch (curst) - { - case AUTO_SYNC: - syncBtn->setIcon(icon_manual); - m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[MANUAL_SYNC])); - - SyncHelper::setSyncState(MANUAL_SYNC); - m_sync_item_action[SyncItem::SLICE_POS]->setChecked(SyncHelper::getSyncItem(SyncItem::SLICE_POS)); - m_sync_item_action[SyncItem::WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(SyncItem::WIDTH_LEVEL)); - m_sync_item_action[SyncItem::ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(SyncItem::ZOOM_PAN)); - - //curst = MANUAL_SYNC; - - break; - case MANUAL_SYNC: - syncBtn->setIcon(icon_dis); - m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[DIS_SYNC])); - - SyncHelper::setSyncState(DIS_SYNC); - for (int i = 0; i < SYNC_ITEM_NUM; i++) - { - m_sync_item_action[i]->setChecked(false); - m_sync_item_action[i]->setDisabled(true); - } - //curst = DIS_SYNC; - break; - case DIS_SYNC: - syncBtn->setIcon(icon_auto); - m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[AUTO_SYNC])); - - SyncHelper::setSyncState(AUTO_SYNC); - for (int i = 0; i < SYNC_ITEM_NUM; i++) - { - m_sync_item_action[i]->setDisabled(false); - } - m_sync_item_action[SyncItem::SLICE_POS]->setChecked(SyncHelper::getSyncItem(SyncItem::SLICE_POS)); - m_sync_item_action[SyncItem::WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(SyncItem::WIDTH_LEVEL)); - m_sync_item_action[SyncItem::ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(SyncItem::ZOOM_PAN)); - //curst = AUTO_SYNC; - break; - default: - break; - } - - }); + SyncHelper::setSyncState(MANUAL_SYNC); + m_sync_item_action[SLICE_POS]->setChecked(SyncHelper::getSyncItem(SLICE_POS)); + m_sync_item_action[WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(WIDTH_LEVEL)); + m_sync_item_action[ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(ZOOM_PAN)); + break; + case MANUAL_SYNC: + syncBtn->setIcon(icon_dis); + m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[DIS_SYNC])); + SyncHelper::setSyncState(DIS_SYNC); + for (int i = 0; i < SYNC_ITEM_NUM; i++) { + m_sync_item_action[i]->setChecked(false); + m_sync_item_action[i]->setDisabled(true); + } + break; + case DIS_SYNC: + syncBtn->setIcon(icon_auto); + m_sync_state_action->setText(QString(tr("CUR STATE: %1")).arg(SyncHelper::SyncStateName[AUTO_SYNC])); + SyncHelper::setSyncState(AUTO_SYNC); + for (int i = 0; i < SYNC_ITEM_NUM; i++) { + m_sync_item_action[i]->setDisabled(false); + } + m_sync_item_action[SLICE_POS]->setChecked(SyncHelper::getSyncItem(SLICE_POS)); + m_sync_item_action[WIDTH_LEVEL]->setChecked(SyncHelper::getSyncItem(WIDTH_LEVEL)); + m_sync_item_action[ZOOM_PAN]->setChecked(SyncHelper::getSyncItem(ZOOM_PAN)); + break; + default: + break; + } } //视窗操作?,file open相关 -void QDicomViewer::SetupFileTool(QToolButton* fileBtn) { - // Menu - fileBtn->setToolTip(QString("Open Dicom series from directory")); - QMenu* m; - m = new QMenu(this); - m->addAction(tr("Open DICOM folder"), this, [&] { - QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), m_qs.value("DIR_PATH_ID").toString()); - if (!p.isEmpty()) { - m_qs.setValue("DIR_PATH_ID", p); - openAndDrawDICOM(p.toLocal8Bit().toStdString(), DIR_OPEN_MODE); - } - }); +void QDicomViewer::SetupFileTool(QToolButton *fileBtn) { + // Menu + fileBtn->setToolTip(QString("Open Dicom series from directory")); + QMenu *m; + m = new QMenu(this); + m->addAction(tr("Open DICOM folder"), this, [&] { + QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), + m_qs.value("DIR_PATH_ID").toString()); + if (!p.isEmpty()) { + m_qs.setValue("DIR_PATH_ID", p); + openDICOM(p.toLocal8Bit().toStdString(), DIR_OPEN_MODE); + } + }); - m->addAction(tr("Open DICOM file"), this, [&] { - //QSettings s; - //QString p = s.value(FILE_PATH_ID).toString(); - QString fn = QFileDialog::getOpenFileName(this, tr("Open dicom files"), m_qs.value("FILE_PATH_ID").toString()); - if (!fn.isEmpty()) { - m_qs.setValue("FILE_PATH_ID", fn); - openAndDrawDICOM(fn.toLocal8Bit().toStdString(), FILE_OPEN_MODE); - } - }); + m->addAction(tr("Open DICOM file"), this, [&] { + //QSettings s; + //QString p = s.value(FILE_PATH_ID).toString(); + QString fn = QFileDialog::getOpenFileName(this, tr("Open dicom files"), m_qs.value("FILE_PATH_ID").toString()); + if (!fn.isEmpty()) { + m_qs.setValue("FILE_PATH_ID", fn); + openDICOM(fn.toLocal8Bit().toStdString(), FILE_OPEN_MODE); + } + }); - m->addAction(tr("Close all"), this, [&] { - //ui->thumbnailBar_->clear(); - }); + m->addSeparator(); + m->addAction(tr("Quit"), this, &QDicomViewer::close); + fileBtn->setPopupMode(QToolButton::MenuButtonPopup); + fileBtn->setMenu(m); - m->addSeparator(); - m->addAction(tr("Quit"), this, &QDicomViewer::close); - fileBtn->setPopupMode(QToolButton::MenuButtonPopup); - fileBtn->setMenu(m); - - // connect - connect(fileBtn, &QToolButton::clicked, this, [&] { - //QSettings s; - //QString p = s.value(DIR_PATH_ID, ".").toString(); - QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), m_qs.value("DIR_PATH_ID").toString()); - if (!p.isEmpty()) { - m_qs.setValue("DIR_PATH_ID", p); - //ui->thumbnailBar_->setImagePaths(QStringList() << p); - openAndDrawDICOM(p.toLocal8Bit().toStdString(), DIR_OPEN_MODE); - } - }); + // connect + connect(fileBtn, &QToolButton::clicked, this, [&] { + QString p = QFileDialog::getExistingDirectory(this, tr("Open dicom directory"), + m_qs.value("DIR_PATH_ID").toString()); + if (!p.isEmpty()) { + m_qs.setValue("DIR_PATH_ID", p); + openDICOM(p.toLocal8Bit().toStdString(), DIR_OPEN_MODE); + } + }); } -void QDicomViewer::SetupImportTool(QToolButton* importBtn) -{ - importBtn->setToolTip(QString("Search and download studies from PACS locations")); - connect(importBtn, &QToolButton::clicked, this, [&] { - if (nullptr == m_import) { - m_import = new ImportWidget(this); - connect(m_import, &ImportWidget::sigMoveDone, this, &QDicomViewer::openDICOMFromPACS); - } - m_import->show(); - }); +void QDicomViewer::SetupImportTool(QToolButton *importBtn) { + importBtn->setToolTip(QString("Search and download studies from PACS locations")); + connect(importBtn, &QToolButton::clicked, this, [&] { + if (nullptr == m_import) { + m_import = new ImportWidget(this); + connect(m_import, &ImportWidget::sigMoveDone, this, &QDicomViewer::openDICOMFromPACS); + } + m_import->show(); + }); +} +void QDicomViewer::SetupExportTool(QToolButton *saveBtn) { + saveBtn->setToolTip(QString("Export images")); + connect(saveBtn, &QToolButton::clicked, this, [=] { + if (nullptr == exportDialog) { + exportDialog = new ExportDialog(this); + //exportDialog->setViewContainer(ui->viewContainer); + exportDialog->setCurView(ui->viewContainer->getCurrentView()); + exportDialog->setModal(false); + } + exportDialog->show(); + + }); +} + +void QDicomViewer::displayThumbnailBar(bool value) { + VCRHelper::setThumbnailbar(value); + ui->thumbnailBar->setVisible(value); + m_preview_display_action->setChecked(value); +} + +void QDicomViewer::SetupGridTool(QToolButton *gridBtn) { + // Menu + //qDebug() << &gridBtn; + gridBtn->setToolTip(QString("Split Screen")); + QMenu *m; + m = new QMenu(this); + m_preview_display_action = m->addAction(tr("Preview bar"), this, [&](bool value) { + displayThumbnailBar(value); + + }); + m_preview_display_action->setCheckable(true); + m_preview_display_action->setChecked(false); + + gridBtn->setPopupMode(QToolButton::MenuButtonPopup); + gridBtn->setMenu(m); + // connect + connect(gridBtn, &QToolButton::clicked, this, [=] { + // auto delete while hidden + //qDebug() << &gridBtn; + GridPopWidget *gpw = new GridPopWidget(gridBtn); + connect(gpw, &GridPopWidget::Signal_ViewLayout, + ui->viewContainer, &ViewContainerWidget::viewLayoutChanged); + gpw->move(this->geometry().topLeft() + gridBtn->geometry().bottomLeft() + QPoint(25, 25)); + gpw->show(); + }); +} + +void QDicomViewer::SetupConnections() { + //通知左侧的缩略图bar ,当前选中series的变换 + connect(ui->viewContainer, &ViewContainerWidget::onThumbnailTrigger, + ui->thumbnailBar, &ThumbnailBarWidget::Slot_setCurrentThumbnail); + + //通知右侧显示区域,当前有series被点击 + connect(ui->thumbnailBar, &ThumbnailBarWidget::Signal_ThumbClicked, + ui->viewContainer->getViewManager(), &ImageViewManager::viewReload); + + connect(ui->toolBar, &QToolBar::visibilityChanged, + this, &QDicomViewer::Slot_ToolbarVisibilityChanged); } -void QDicomViewer::SetupExportTool(QToolButton* saveBtn) -{ - saveBtn->setToolTip(QString("Export images")); - connect(saveBtn, &QToolButton::clicked, this, [=] { - if (nullptr == exportDialog) { - exportDialog = new ExportDialog(this); - //exportDialog->setViewContainer(ui->viewContainer); - exportDialog->setCurView(ui->viewContainer->getCurrentView()); - exportDialog->setModal(false); - } - exportDialog->show(); - - }); +void QDicomViewer::Slot_ToolbarVisibilityChanged(bool visible) { + VCRHelper::setToolbar(visible); } -void QDicomViewer::displayThumbnailBar(bool value) -{ - VCRHelper::setThumbnailbar(value); - ui->thumbnailBar->setVisible(value); - m_preview_display_action->setChecked(value); -} - -void QDicomViewer::SetupGridTool(QToolButton* gridBtn) { - // Menu - //qDebug() << &gridBtn; - gridBtn->setToolTip(QString("Split Screen")); - QMenu* m; - m = new QMenu(this); - m_preview_display_action = m->addAction(tr("Preview bar"), this, [&](bool value) { - displayThumbnailBar(value); - - }); - m_preview_display_action->setCheckable(true); - m_preview_display_action->setChecked(false); - - gridBtn->setPopupMode(QToolButton::MenuButtonPopup); - gridBtn->setMenu(m); - // connect - connect(gridBtn, &QToolButton::clicked, this, [=] { - // auto delete while hidden - //qDebug() << &gridBtn; - GridPopWidget* gpw = new GridPopWidget(gridBtn); - connect(gpw, &GridPopWidget::Signal_ViewLayout, - ui->viewContainer, &ViewContainerWidget::viewLayoutChanged); - gpw->move(this->geometry().topLeft() + gridBtn->geometry().bottomLeft() + QPoint(25, 25)); - gpw->show(); - }); -} - -void QDicomViewer::SetupConnections() -{ - //通知左侧的缩略图bar ,当前选中series的变换 - connect(ui->viewContainer, &ViewContainerWidget::onThumbnailTrigger, - ui->thumbnailBar, &ThumbnailBarWidget::Slot_setCurrentThumbnail); - - //通知右侧显示区域,当前有series被点击 - connect(ui->thumbnailBar, &ThumbnailBarWidget::Signal_ThumbClicked, - ui->viewContainer->getViewManager(), &ImageViewManager::viewReload); - - connect(ui->toolBar,&QToolBar::visibilityChanged, - this, &QDicomViewer::Slot_ToolbarVisibilityChanged); - - - - //connect(ui->viewContainer, SIGNAL(onThumbnailTrigger(DicomImageView*)), - // ui->vcr_toolbar, SLOT(setImageView(DicomImageView*))); - - //connect(ui->thumbnailBar, SIGNAL(Signal_CopyDicomView(SeriesInfo_t*)), - // this, SLOT(Slot_CopyDicomView(SeriesInfo_t*))); -} - - - -void QDicomViewer::Slot_ToolbarVisibilityChanged(bool visible) -{ - VCRHelper::setToolbar(visible); -} - -void QDicomViewer::openDICOMFromPACS(int err, std::string dirName) -{ - if (err == NOERROR) { - openAndDrawDICOM(dirName, DIR_OPEN_MODE); - } - else - { - //pop out msg box - QMessageBox::warning(this, "Warning", "open DICOM Images From PACS Fail"); - } +void QDicomViewer::openDICOMFromPACS(int err, std::string dirName) { + if (err == NOERROR) { + openDICOM(dirName, DIR_OPEN_MODE); + } else { + //pop out msg box + QMessageBox::warning(this, "Warning", "open DICOM Images From PACS Fail"); + } } //TODO: 覆盖逻辑和增加逻辑待补充 -void QDicomViewer::openAndDrawDICOM(const std::string& dicomName, SeriesOpenMode openMode) { +void QDicomViewer::openDICOM(const std::string &dicomName, SeriesOpenMode openMode) { displayThumbnailBar(true); @@ -889,10 +694,7 @@ void QDicomViewer::openAndDrawDICOM(const std::string& dicomName, SeriesOpenMode auto unique = helper->getDefaultUniqueID(); ui->viewContainer->getViewManager()->viewReload(unique); - //view clicked will notify thumbnailbar update ui->thumbnailBar->updateThumbnailBar(); - - } diff --git a/src/src/UI/Window/QDicomViewer.h b/src/src/UI/Window/QDicomViewer.h index b10f51f..3ccd410 100644 --- a/src/src/UI/Window/QDicomViewer.h +++ b/src/src/UI/Window/QDicomViewer.h @@ -7,6 +7,8 @@ #include "customwindow.h" #include "UI/Widget/Measure/pqFontPropertyWidget.h" +typedef tuple ActionProperty; + /** * @brief 主窗口Class * 继承自QMainWindow,主要用于显示整个界面 @@ -82,7 +84,7 @@ private: * @param dicomName DICOM文件路径 * @param openMode 文件打开方式,文件方式或文件夹方式 */ - void openAndDrawDICOM(const std::string &dicomName, SeriesOpenMode openMode); + void openDICOM(const std::string &dicomName, SeriesOpenMode openMode); /** * 设置部分空间的槽函数连接 @@ -94,7 +96,7 @@ private: */ void executeActiveMeasure(); - /** + /** * 为对应的DicomImageView构建对应的播放控件 * @param v */ @@ -121,4 +123,5 @@ private: AnnotationActorType m_cur_measure = AnnotationActorType::RulerAnn; + void syncStateChanged() const; };