diff --git a/Modules/QtWidgetsExt/src/QmitkPointListView.cpp b/Modules/QtWidgetsExt/src/QmitkPointListView.cpp index 5e42b28d20..0480ab1361 100644 --- a/Modules/QtWidgetsExt/src/QmitkPointListView.cpp +++ b/Modules/QtWidgetsExt/src/QmitkPointListView.cpp @@ -1,326 +1,334 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkPointListView.h" #include "QmitkEditPointDialog.h" #include "QmitkPointListModel.h" #include "QmitkStdMultiWidget.h" #include "mitkRenderingManager.h" #include #include #include #include #include QmitkPointListView::QmitkPointListView(QWidget *parent) : QListView(parent), m_PointListModel(new QmitkPointListModel()), m_SelfCall(false), m_showFading(false), m_MultiWidget(nullptr) { QListView::setAlternatingRowColors(true); - QListView::setSelectionBehavior(QAbstractItemView::SelectRows); + QListView::setSelectionBehavior(QAbstractItemView::SelectItems); QListView::setSelectionMode(QAbstractItemView::SingleSelection); QListView::setModel(m_PointListModel); QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse " "wheel to change the timestep.\n\nTimeStep:\t%1") .arg(0); QListView::setToolTip(tooltip); this->setContextMenuPolicy(Qt::CustomContextMenu); this->setMinimumHeight(40); this->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); connect(m_PointListModel, SIGNAL(SignalUpdateSelection()), this, SLOT(OnPointSetSelectionChanged())); connect(this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(OnPointDoubleClicked(const QModelIndex &))); connect(QListView::selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(OnListViewSelectionChanged(const QItemSelection &, const QItemSelection &))); connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ctxMenu(const QPoint &))); } QmitkPointListView::~QmitkPointListView() { delete m_PointListModel; } void QmitkPointListView::SetPointSetNode(mitk::DataNode *pointSetNode) { m_PointListModel->SetPointSetNode(pointSetNode); } const mitk::PointSet *QmitkPointListView::GetPointSet() const { return m_PointListModel->GetPointSet(); } void QmitkPointListView::SetMultiWidget(QmitkStdMultiWidget *multiWidget) { m_MultiWidget = multiWidget; this->AddSliceNavigationController(multiWidget->mitkWidget1->GetSliceNavigationController()); this->AddSliceNavigationController(multiWidget->mitkWidget2->GetSliceNavigationController()); this->AddSliceNavigationController(multiWidget->mitkWidget3->GetSliceNavigationController()); } QmitkStdMultiWidget *QmitkPointListView::GetMultiWidget() const { return m_MultiWidget; } void QmitkPointListView::OnPointDoubleClicked(const QModelIndex &index) { mitk::PointSet::PointType p; mitk::PointSet::PointIdentifier id; m_PointListModel->GetPointForModelIndex(index, p, id); QmitkEditPointDialog _EditPointDialog(this); _EditPointDialog.SetPoint(m_PointListModel->GetPointSet(), id, m_PointListModel->GetTimeStep()); _EditPointDialog.exec(); } void QmitkPointListView::OnPointSetSelectionChanged() { const mitk::PointSet *pointSet = m_PointListModel->GetPointSet(); if (pointSet == nullptr) return; // update this view's selection status as a result to changes in the point set data structure m_SelfCall = true; int timeStep = m_PointListModel->GetTimeStep(); if (pointSet->GetNumberOfSelected(timeStep) > 1) { MITK_ERROR << "Point set has multiple selected points. This view is not designed for more than one selected point."; } int selectedIndex = pointSet->SearchSelectedPoint(timeStep); if (selectedIndex == -1) // no selected point is found { m_SelfCall = false; return; } QModelIndex index; bool modelIndexOkay = m_PointListModel->GetModelIndexForPointID(selectedIndex, index); if (modelIndexOkay == true) QListView::selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); emit SignalPointSelectionChanged(); m_SelfCall = false; } void QmitkPointListView::OnListViewSelectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/) { if (m_SelfCall) return; mitk::PointSet *pointSet = const_cast(m_PointListModel->GetPointSet()); if (pointSet == nullptr) return; // (take care that this widget doesn't react to self-induced changes by setting m_SelfCall) m_SelfCall = true; // update selection of all points in pointset: select the one(s) that are selected in the view, deselect all others QModelIndexList selectedIndexes = selected.indexes(); + // only call setSelectInfo on a point set with 'selected = true' if you deselcted the other entries + int indexToSelect = -1; + for (mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->Begin(); it != pointSet->GetPointSet(m_PointListModel->GetTimeStep())->GetPoints()->End(); ++it) { QModelIndex index; if (m_PointListModel->GetModelIndexForPointID(it->Index(), index)) { if (selectedIndexes.indexOf(index) != -1) // index is found in the selected indices list { - pointSet->SetSelectInfo(it->Index(), true, m_PointListModel->GetTimeStep()); - - mitk::Point3D p = pointSet->GetPoint(it->Index(), m_PointListModel->GetTimeStep()); - - for (auto snc : m_Sncs) - snc->SelectSliceByPoint(p); + indexToSelect = it->Index(); } else { pointSet->SetSelectInfo(it->Index(), false, m_PointListModel->GetTimeStep()); } } } + // force selection of only one index after deselecting the others + if (indexToSelect > -1) { + pointSet->SetSelectInfo(indexToSelect, true, m_PointListModel->GetTimeStep()); + + mitk::Point3D p = pointSet->GetPoint(indexToSelect, m_PointListModel->GetTimeStep()); + + for (auto snc : m_Sncs) + snc->SelectSliceByPoint(p); + } + m_SelfCall = false; emit SignalPointSelectionChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointListView::keyPressEvent(QKeyEvent *e) { if (m_PointListModel == nullptr) return; int key = e->key(); switch (key) { case Qt::Key_F2: m_PointListModel->MoveSelectedPointUp(); break; case Qt::Key_F3: m_PointListModel->MoveSelectedPointDown(); break; case Qt::Key_Delete: m_PointListModel->RemoveSelectedPoint(); break; default: break; } } void QmitkPointListView::wheelEvent(QWheelEvent *event) { if (!m_PointListModel || !m_PointListModel->GetPointSet() || (int)(m_PointListModel->GetPointSet()->GetTimeSteps()) == 1) return; int whe = event->delta(); mitk::PointSet::Pointer ps = dynamic_cast(m_PointListModel->GetPointSet()); unsigned int numberOfTS = ps->GetTimeSteps(); if (numberOfTS == 1) return; int currentTS = this->m_PointListModel->GetTimeStep(); if (whe > 0) { if ((currentTS + 1 >= (int)numberOfTS)) return; this->m_PointListModel->SetTimeStep(++currentTS); } else { if ((currentTS <= 0)) return; this->m_PointListModel->SetTimeStep(--currentTS); } QString tooltip = QString("Use the F2/F3 keys to move a point up/down, the Del key to remove a point\nand the mouse " "wheel to change the timestep.\n\nTimeStep:\t%1") .arg(currentTS); this->setToolTip(tooltip); emit SignalTimeStepChanged(currentTS); } void QmitkPointListView::ctxMenu(const QPoint &pos) { QMenu *menu = new QMenu; // add Fading check QAction *showFading = new QAction(this); showFading->setCheckable(false); // TODO: reset when fading is working showFading->setEnabled(false); // TODO: reset when fading is working showFading->setText("Fade TimeStep"); connect(showFading, SIGNAL(triggered(bool)), this, SLOT(SetFading(bool))); menu->addAction(showFading); // add Clear action QAction *clearList = new QAction(this); clearList->setText("Clear List"); connect(clearList, SIGNAL(triggered()), this, SLOT(ClearPointList())); menu->addAction(clearList); // add Clear TimeStep action QAction *clearTS = new QAction(this); clearTS->setText("Clear current time step"); connect(clearTS, SIGNAL(triggered()), this, SLOT(ClearPointListTS())); menu->addAction(clearTS); menu->exec(this->mapToGlobal(pos)); } void QmitkPointListView::SetFading(bool onOff) { m_showFading = onOff; } void QmitkPointListView::ClearPointList() { if (!m_PointListModel->GetPointSet()) return; mitk::PointSet::Pointer curPS = m_PointListModel->GetPointSet(); if (curPS->GetSize() == 0) return; switch (QMessageBox::question(this, tr("Clear Points"), tr("Remove all points from the displayed list?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)) { case QMessageBox::Yes: { mitk::PointSet::PointsIterator it; mitk::PointSet::PointsContainer *curPsPoints; while (!curPS->IsEmptyTimeStep(0)) { curPsPoints = curPS->GetPointSet()->GetPoints(); it = curPsPoints->Begin(); curPS->SetSelectInfo(it->Index(), true); m_PointListModel->RemoveSelectedPoint(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); break; } case QMessageBox::No: default: break; } } void QmitkPointListView::ClearPointListTS() { } void QmitkPointListView::AddSliceNavigationController(mitk::SliceNavigationController *snc) { if (snc == nullptr) return; m_Sncs.insert(snc); } void QmitkPointListView::RemoveSliceNavigationController(mitk::SliceNavigationController *snc) { if (snc == nullptr) return; m_Sncs.erase(snc); } diff --git a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/QmitkPointSetInteractionView.cpp b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/QmitkPointSetInteractionView.cpp index 741d400124..83e9bf97a5 100755 --- a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/QmitkPointSetInteractionView.cpp +++ b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/QmitkPointSetInteractionView.cpp @@ -1,143 +1,142 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Qmitk related includes #include "QmitkPointSetInteractionView.h" #include "ui_QmitkPointSetInteractionViewControls.h" #include #include #include #include #include #include #include #include const std::string QmitkPointSetInteractionView::VIEW_ID = "org.mitk.views.pointsetinteraction"; QmitkPointSetInteractionView::QmitkPointSetInteractionView( QObject* /*parent*/ ) : m_Controls(0) { - } QmitkPointSetInteractionView::~QmitkPointSetInteractionView() { } void QmitkPointSetInteractionView::CreateQtPartControl( QWidget *parent ) { m_Controls = new Ui::QmitkPointSetInteractionControls; m_Controls->setupUi(parent); m_Controls->m_PbAddPointSet->connect( m_Controls->m_PbAddPointSet, SIGNAL( clicked() ) , this, SLOT( OnAddPointSetClicked() ) ); } void QmitkPointSetInteractionView::SetFocus() { m_Controls->m_PbAddPointSet->setFocus(); } void QmitkPointSetInteractionView::OnAddPointSetClicked() { //Ask for the name of the point set bool ok = false; QString name = QInputDialog::getText( QApplication::activeWindow() , tr("Add point set..."), tr("Enter name for the new point set"), QLineEdit::Normal, tr("PointSet"), &ok ); if ( ! ok || name.isEmpty() ) return; // //Create a new empty pointset // mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); // // Create a new data tree node // mitk::DataNode::Pointer pointSetNode = mitk::DataNode::New(); // // fill the data tree node with the appropriate information // pointSetNode->SetData( pointSet ); pointSetNode->SetProperty( "name", mitk::StringProperty::New( name.toStdString() ) ); pointSetNode->SetProperty( "opacity", mitk::FloatProperty::New( 1 ) ); pointSetNode->SetColor( 1.0, 1.0, 0.0 ); // // add the node to the ds // this->GetDataStorage()->Add(pointSetNode); // make new selection and emulate selection for this berry::IWorkbenchPart::Pointer nullPart; QList selection; selection.push_back(pointSetNode); this->OnSelectionChanged(nullPart, selection); } void QmitkPointSetInteractionView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& nodes) { mitk::DataNode::Pointer selectedNode; if(!nodes.empty()) selectedNode = nodes.front(); mitk::PointSet::Pointer pointSet; if(selectedNode.IsNotNull()) pointSet = dynamic_cast(selectedNode->GetData()); if (pointSet.IsNotNull()) { m_SelectedPointSetNode = selectedNode; m_Controls->m_CurrentPointSetLabel->setText(QString::fromStdString(selectedNode->GetName())); m_Controls->m_PointListWidget->SetPointSetNode(selectedNode); } else { m_Controls->m_CurrentPointSetLabel->setText(tr("None")); m_Controls->m_PointListWidget->SetPointSetNode(nullptr); } } void QmitkPointSetInteractionView::NodeChanged( const mitk::DataNode* node ) { if(node == m_SelectedPointSetNode && m_Controls->m_CurrentPointSetLabel->text().toStdString() != node->GetName()) { m_Controls->m_CurrentPointSetLabel->setText(QString::fromStdString(node->GetName())); } } void QmitkPointSetInteractionView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { if(m_Controls) { m_Controls->m_PointListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); m_Controls->m_PointListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); m_Controls->m_PointListWidget->AddSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); } } void QmitkPointSetInteractionView::RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) { if(m_Controls) { m_Controls->m_PointListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("axial")->GetSliceNavigationController()); m_Controls->m_PointListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()); m_Controls->m_PointListWidget->RemoveSliceNavigationController(renderWindowPart->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()); } }