diff --git a/src/src/QDicomViewer.cpp b/src/src/QDicomViewer.cpp index c4b8385..bbcdb0b 100644 --- a/src/src/QDicomViewer.cpp +++ b/src/src/QDicomViewer.cpp @@ -1,4 +1,4 @@ -#include "QDicomViewer.h" +#include "QDicomViewer.h" #include "global/include_all.h" #include "base/SeriesImageSet.h" #include "view/subview/gridpopwidget.h" @@ -269,34 +269,24 @@ void QDicomViewer::SetupAnnoTool(QToolButton* annoBtn) //主要设置了四角标签的操作逻辑 annoBtn->setToolTip(QString("Toggle annotations")); //视窗操作,显隐脚注 + connect(annoBtn, &QToolButton::clicked, this, [=] { AnnoHelper::toggleAnno(); - QList viewers = ui->viewContainer->getViewList(); - std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) { - v->updateCornerInfoAll(); - }); - }); + ui->viewContainer->updateCornerInfoAll(); + }); //视窗操作,显隐测量 QMenu* m; m = new QMenu(this); connect(m, &QMenu::triggered, this, [=] - { - //load data - m_measure_hidden_action->setChecked(Measure::GetHidden()); - }); + { + //load data + m_measure_hidden_action->setChecked(Measure::GetHidden()); + }); //视窗操作,显隐测量 m_measure_hidden_action = m->addAction(tr("Hide all measurements"), this, [=](bool value) { - //QPixmap map(":/InfiniteViewer/Icon/hidden.png"); - //m_cur_measure = AnnotationActorType::HiddenAnn; - //annoBtn->setIcon(QIcon(map)); - QList viewers = ui->viewContainer->getViewList(); - std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) { - Measure::SetHidden(value); - v->Render(); - - - }); + Measure::SetHidden(value); + ui->viewContainer->render(); }); m->addSeparator(); @@ -311,11 +301,8 @@ void QDicomViewer::SetupAnnoTool(QToolButton* annoBtn) { AnnoHelper::PrivacyOff(); } - QList viewers = ui->viewContainer->getViewList(); - std::for_each(viewers.begin(), viewers.end(), [=](DicomImageView* v) { - v->updateCornerInfoPrivacy(); - }); - }); + ui->viewContainer->updateCornerInfoPrivacy(); + }); m_patient_hidden_action->setCheckable(true); m_patient_hidden_action->setChecked(false); @@ -415,8 +402,6 @@ void QDicomViewer::executeActiveMeasure(ViewContainerWidget* Container, Annotati }); break; } - - } //视窗操作,AnnotationActor新增相关 @@ -426,7 +411,7 @@ void QDicomViewer::SetupMeasureTool(QToolButton* measureBtn) connect(measureBtn, &QToolButton::clicked, this, [=] { executeActiveMeasure(ui->viewContainer, m_cur_measure); - }); + }); QMenu* m; m = new QMenu(this); @@ -525,7 +510,6 @@ void QDicomViewer::SetupMeasureTool(QToolButton* measureBtn) m->addSeparator(); - m->addAction(tr("Delete selected"), this, [=] { measureBtn->setChecked(true); m_cur_measure = AnnotationActorType::DeleteSelectedAnn; diff --git a/src/src/view/ImageViewManager.cpp b/src/src/view/ImageViewManager.cpp index 0195cff..790eff6 100644 --- a/src/src/view/ImageViewManager.cpp +++ b/src/src/view/ImageViewManager.cpp @@ -19,37 +19,51 @@ void ImageViewManager::add(DicomImageView *view) { void ImageViewManager::remove(DicomImageView *view) { if (view && !contains(view)){ vList.removeOne(view); + delete view; } } -void ImageViewManager::smartDo(ImageViewManager::SmartDoCallback cb, ImageViewManager::DoScope scope,DicomImageView* exceptView) { +void ImageViewManager::remove(int idx) { + if (idx >= vList.size()) return; + auto view = vList.at(idx); + vList.removeOne(view); + delete view; +} + +void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, void* callData, DoScope scope) { switch (scope) { case DoScope::Current:{ if (currentView) - cb(currentView); + cb(currentView, callData); break; } case DoScope::SameSeries:{ - //TODO: need add same series and same direction check and do logic! + std::for_each(vList.begin(),vList.end(),[=](auto v){ + //check series + cb(v, callData); + }); break; } case DoScope::SameSeriesExceptSelf:{ - //TODO: need add same series and same direction check and do logic! + std::for_each(vList.begin(),vList.end(),[=](auto v){ + if (v == sourceView) return; + //check series + cb(v, callData); + }); break; } case DoScope::AllExceptSelf: + { std::for_each(vList.begin(),vList.end(),[=](auto v){ - if (v == exceptView) return; - cb(v); + if (v == sourceView) return; + cb(v, callData); }); + break; + } case DoScope::All: default: std::for_each(vList.begin(),vList.end(),[=](auto v){ - cb(v); + cb(v, callData); }); } } - -void ImageViewManager::setCurrentView(DicomImageView* view) { - currentView = view; -} diff --git a/src/src/view/ImageViewManager.h b/src/src/view/ImageViewManager.h index 10b349e..af3ce2f 100644 --- a/src/src/view/ImageViewManager.h +++ b/src/src/view/ImageViewManager.h @@ -13,13 +13,40 @@ class ImageViewManager:public QObject { Q_OBJECT public: - ImageViewManager(); - ~ImageViewManager(); + ImageViewManager(){}; + ~ImageViewManager(){ + while(this->getViewCount()>0){ + this->remove(0); + } + }; bool contains(DicomImageView* view); void add(DicomImageView* view); void remove(DicomImageView* view); - void setCurrentView(DicomImageView* view); + void remove(int idx); + void setCurrentView(DicomImageView* view){ + currentView = view; + } + void clear(){ + vList.clear(); + } + DicomImageView* getCurrentView(){ + return currentView; + } + int getViewCount(){ + return vList.size(); + } + DicomImageView* getView(int index){ + if (index >= vList.size()) return nullptr; + return vList[index]; + } + DicomImageView* getFirstView(){ + if (vList.size() == 0) return nullptr; + return vList[0]; + } + QList& getViewList(){ + return vList; + } enum DoScope{ Current, SameSeries, @@ -27,8 +54,8 @@ public: AllExceptSelf, All }; - typedef void(*SmartDoCallback)(DicomImageView*); - void smartDo(SmartDoCallback cb, DoScope scope = Current,DicomImageView* exceptView = nullptr ); + typedef void(*SmartDoCallback)(DicomImageView* view, void* callData); + void smartDo(SmartDoCallback cb, DicomImageView *sourceView = nullptr,void* callData = nullptr, DoScope scope = Current); private: QList vList; diff --git a/src/src/view/viewcontainerwidget.cpp b/src/src/view/viewcontainerwidget.cpp index cb9b67c..61553e2 100644 --- a/src/src/view/viewcontainerwidget.cpp +++ b/src/src/view/viewcontainerwidget.cpp @@ -1,4 +1,4 @@ -#include "viewcontainerwidget.h" +#include "viewcontainerwidget.h" #include "thumbnailImage.h" #include "DicomLoader.h" #include @@ -30,26 +30,26 @@ ViewContainerWidget::~ViewContainerWidget() { } //------------------------------------------------------- -QList ViewContainerWidget::getViewList() const { - return view_list_; +QList& ViewContainerWidget::getViewList() { + return manager.getViewList(); } -DicomImageView *ViewContainerWidget::getCurrentView() const { - return current_view_; +DicomImageView *ViewContainerWidget::getCurrentView() { + return manager.getCurrentView(); } -DicomImageView* ViewContainerWidget::getNextView() const +DicomImageView* ViewContainerWidget::getNextView() { bool found = false; - for (int i = 0; i < view_list_.size(); ++i) + for (int i = 0; i < manager.getViewCount(); ++i) { - DicomImageView *v = view_list_.at(i); + DicomImageView *v = manager.getView(i); if (found) { return v; } - if (current_view_ == v) + if (manager.getCurrentView() == v) { found = true; } @@ -67,53 +67,26 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo { if (SyncHelper::getSyncState() == AUTO_SYNC) { - for (auto *v : view_list_) { - //foreach(DicomImageView *v, view_list_){ - - if (v->HasSeries()) - { - if (view != v) - { - int* r = (int*)calldata; - v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY); - v->SetSlice(r[0]); -#ifdef _DEBUG - printf("Sliced, current slice number:%d \r\n", r[0]); -#endif // _DEBUG - //v->GetScrollbar()->setValue(r[0]); - v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER); - } - } - } + manager.smartDo([](auto v,auto callData){ + if (v->HasSeries()) { + int *r = (int *) callData; + v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY); + v->SetSlice(r[0]); + v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER); + } + },view, calldata,ImageViewManager::AllExceptSelf); } if (SyncHelper::getSyncState() == MANUAL_SYNC) { - - //foreach(DicomImageView *v, view_list_) { - for (auto *v : view_list_) { - if (v->HasSeries()) - { - if (v != view) - { - //disable global trigger slot - v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY); - int* r = (int*)calldata; - //r[0]:cur_value - //r[1]:view_step - //r[2]:min_value - //r[3]:max_value - //int set_value = r[0] + r[1]; - //v->GetScrollbar()->setValue(set_value); - v->AddSlice(r[1]); -#ifdef _DEBUG - printf("Sliced, current added slice number:%d \r\n", r[1]); -#endif - v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER); - - } - } - - } + manager.smartDo([](auto v,auto callData){ + if (v->HasSeries()) { + //disable global trigger slot + v->setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY); + int *r = (int *) callData; + v->AddSlice(r[1]); + v->setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER); + } + },view, calldata,ImageViewManager::AllExceptSelf); } } @@ -121,50 +94,35 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo case VTKIS_IMAGE_PAN: if (SyncHelper::getSyncItem(ZOOM_PAN)) { - //foreach(DicomImageView *v, view_list_) { - for (auto *v : view_list_) { - if (v != view) - { - double *d = (double *)calldata; - double vector[3] = { d[3] - d[0],d[4] - d[1],d[5] - d[2] }; - v->SetPanOffset(vector); -#ifdef _DEBUG - printf("EndPan, last focalpoint:%f,%f,%f;current focalpoint:%f,%f,%f \r\n", d[0], d[1], d[2], d[3], - d[4], d[5]); -#endif - } - } + manager.smartDo([](auto v,auto callData){ + if (v->HasSeries()) { + double *d = (double *)callData; + double vector[3] = { d[3] - d[0],d[4] - d[1],d[5] - d[2] }; + v->SetPanOffset(vector); + } + },view, calldata,ImageViewManager::AllExceptSelf); } break; case VTKIS_IMAGE_ZOOM: if (SyncHelper::getSyncItem(ZOOM_PAN)) { - //foreach(DicomImageView *v, view_list_) { - for (auto *v : view_list_) { - if (v != view) - { - double *d = (double *)calldata; - - v->SetZoomScale(d[1]); -#ifdef _DEBUG - printf("EndDolly, scale param:%f,%f \r\n", d[0], d[1]); -#endif - } - } + manager.smartDo([](auto v,auto callData){ + if (v->HasSeries()) { + double *d = (double *)callData; + v->SetZoomScale(d[1]); + } + },view, calldata,ImageViewManager::AllExceptSelf); } break; case VTKIS_IMAGE_WINDOWLEVEL: if (SyncHelper::getSyncItem(WIDTH_LEVEL)) { - for (auto *v : view_list_) { - //foreach(DicomImageView *v, view_list_) { - if (v != view) - { - double *d = (double *)calldata; - printf("EndWindowLevel, scale param:%f,%f \r\n", d[0], d[1]); + manager.smartDo([](auto v,auto callData){ + if (v->HasSeries()) { + double *d = (double *)callData; v->SetWindowLevel(d[1], d[0]); - } - } + } + },view, calldata,ImageViewManager::AllExceptSelf); } break; default: @@ -175,32 +133,34 @@ void ViewContainerWidget::Slot_SyncEvent(DicomImageView *view, int interactionMo void ViewContainerWidget::SetInteractionMode(int InteractionMode) { - for (auto *v : view_list_) { - if (v->getImageViewer()) - { - v->getImageViewer()->GetInteractorStyle()->SetInteractionModeFromEnum(InteractionMode); - } - } + void * data = (void *)&InteractionMode; + manager.smartDo([](auto v,auto callData){ + int* mode = (int *)callData; + if (v->getImageViewer()) + { + v->getImageViewer()->GetInteractorStyle()->SetInteractionModeFromEnum(*mode); + } + }, nullptr, data); } void ViewContainerWidget::Slot_ViewClicked(DicomImageView *view) { //set current_view - if (current_view_ != view) { - setCurrentView(view); + if (manager.getCurrentView() != view) { + manager.setCurrentView(view); } } void ViewContainerWidget::setCurrentView(DicomImageView *view) { //notify before set nullptr - if (current_view_) { - current_view_->setHighlight(false); + if (manager.getCurrentView()) { + manager.getCurrentView()->setHighlight(false); } - current_view_ = view; - if (current_view_) { - current_view_->setHighlight(true); + manager.setCurrentView(view); + if (manager.getCurrentView()) { + manager.getCurrentView()->setHighlight(true); } - emit Signal_NotifyThumbnail(current_view_); + emit Signal_NotifyThumbnail(manager.getCurrentView()); } //------------------------------------------------------- @@ -214,22 +174,13 @@ void ViewContainerWidget::Slot_ViewDoubleClicked(DicomImageView *view) { return; } if (maxed_) { - //DicomImageView::setFontRatio(_fontRatio); - //std::for_each(view_list_.begin(), view_list_.end(), [=](DicomImageView* v) { - for (auto *v : view_list_) { - v->setVisible(true); - } + manager.smartDo([](auto v,auto callData){v->setVisible(true);}); maxed_ = false; - } else { - //std::for_each(view_list_.begin(), view_list_.end(), [=](DicomImageView* v){ - for (auto *v : view_list_) { - v->setVisible(false); - } + manager.smartDo([](auto v,auto callData){v->setVisible(false);}); view->setVisible(true); maxed_ = true; - } } @@ -245,19 +196,20 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) { return; } - for (auto *v : view_list_) { + for (int i = 0; i < manager.getViewCount(); i++) { + DicomImageView *v = manager.getView(i); this->layout()->removeWidget(v); } int viewCount = col * row; - while (viewCount < view_list_.size()) { - DicomImageView *v = view_list_.takeLast(); + while (viewCount < manager.getViewCount()) { + DicomImageView *v = manager.getView(manager.getViewCount()-1); //YTC:better compare before delete - if (current_view_ == v) + if (manager.getCurrentView() == v) { - setCurrentView(view_list_.first()); + manager.setCurrentView(manager.getView(0)); } - //current_view_ = (current_view_ == v) ? nullptr : current_view_; - delete v; + + manager.remove(v); } // DicomImageView *view; @@ -271,12 +223,12 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) { for (int i = 0; i < row; ++i) { for (int j = 0; j < col; ++j) { - if (i * col + j < view_list_.size()) { - view = view_list_[i * col + j]; + if (i * col + j < manager.getViewCount()) { + view = manager.getView(i * col + j); } else { view = createImageView(this); - view_list_ << view; + manager.add(view); } if (view->IsCine()) @@ -294,8 +246,8 @@ void ViewContainerWidget::Slot_SetViewLayout(int col, int row) { } } - if ((!current_view_) && (!view_list_.isEmpty())) { - Slot_ViewClicked(view_list_.first()); + if ((!manager.getCurrentView()) && (manager.getViewCount()>0)) { + Slot_ViewClicked(manager.getView(0)); } } @@ -328,7 +280,7 @@ void ViewContainerWidget::resizeEvent(QResizeEvent *e) { void ViewContainerWidget::emptyCurrentView() { - Slot_ViewEmpty(current_view_); + Slot_ViewEmpty(manager.getCurrentView()); } @@ -349,33 +301,32 @@ void ViewContainerWidget::Slot_DragDropEvent(DicomImageView *view, thumbnailImag void ViewContainerWidget::Slot_ThumbnailClickEvent(thumbnailImage* tb) { - DicomImageView *view = getCurrentView(); + DicomImageView *view = manager.getCurrentView(); if (nullptr == view) { return; } auto serie_info = tb->getSeriesInfo(); replaceViewWithSerie(serie_info->GetUniqueID(), view); - setCurrentView(view); + manager.setCurrentView(view); } void ViewContainerWidget::resetToOneView() { Slot_SetViewLayout(1,1); - for (int i = 1; i < view_list_.size(); ++i) { - delete view_list_[i]; + while(manager.getViewCount()>1){ + manager.remove(1); } - DicomImageView* v = view_list_[0]; - view_list_.clear(); - view_list_.push_back(v); - - setCurrentView(v); + DicomImageView* v = manager.getView(0); + manager.clear(); + manager.add(v); + manager.setCurrentView(v); } void ViewContainerWidget::replaceViewWithSerie(const std::string& uniqueid, DicomImageView* curV) { if (!curV) { - curV= getCurrentView(); + curV= manager.getCurrentView(); } curV->removeViewWithFusion(); DicomLoader *helper = DicomLoader::GetInstance(); @@ -385,10 +336,10 @@ void ViewContainerWidget::replaceViewWithSerie(const std::string& uniqueid, Dico void ViewContainerWidget::toggleViewWithFusion() { - if (current_view_) + if (manager.getCurrentView()) { - if (current_view_->HasSeries() && current_view_->IsFusion()) + if (manager.getCurrentView()->HasSeries() && manager.getCurrentView()->IsFusion()) { removeCurrentViewWithFusion(); } @@ -404,13 +355,13 @@ void ViewContainerWidget::replaceViewWithFusion() { //Temporal: automatically fusion with next image DicomImageView * overlap_view = this->getNextView(); - if (checkFusionStatus(current_view_, overlap_view)) + if (checkFusionStatus(manager.getCurrentView(), overlap_view)) { connect(overlap_view, &DicomImageView::Signal_WindowLevelEventForFusion, - current_view_, &DicomImageView::Slot_WindowLevelEventForFusion); + manager.getCurrentView(), &DicomImageView::Slot_WindowLevelEventForFusion); - current_view_->SetFusionInput(overlap_view); - current_view_->Render(); + manager.getCurrentView()->SetFusionInput(overlap_view); + manager.getCurrentView()->Render(); } else { @@ -419,8 +370,8 @@ void ViewContainerWidget::replaceViewWithFusion() } void ViewContainerWidget::removeCurrentViewWithFusion() { - if (current_view_) { - current_view_->removeViewWithFusion(); + if (manager.getCurrentView()) { + manager.getCurrentView()->removeViewWithFusion(); } } diff --git a/src/src/view/viewcontainerwidget.h b/src/src/view/viewcontainerwidget.h index 5af1bfa..33386aa 100644 --- a/src/src/view/viewcontainerwidget.h +++ b/src/src/view/viewcontainerwidget.h @@ -1,9 +1,10 @@ -#pragma once +#pragma once #include #include #include "global/QGlobals.h" //#include "modalityproperty.h" #include "dicomimageview.h" +#include "ImageViewManager.h" class QGridLayout; class DicomImageView; @@ -18,14 +19,18 @@ public: ~ViewContainerWidget(); - DicomImageView* getCurrentView() const; - DicomImageView* getNextView() const; - QList getViewList() const; + DicomImageView* getCurrentView(); + DicomImageView* getNextView(); + QList& getViewList() ; void setCurrentView(DicomImageView *view); void emptyCurrentView(); + void updateCornerInfoAll(); + void updateCornerInfoPrivacy(); + void activeMeasure(); + void render(); void replaceViewWithSerie(const std::string& unique_info, DicomImageView* curV = nullptr); @@ -66,5 +71,6 @@ private: DicomImageView *createImageView(QWidget* parent); QList view_list_; DicomImageView *current_view_ = nullptr; + ImageViewManager manager; bool maxed_ = false; };