42 #include <QTreeWidget>
43 #include <QTreeWidgetItem>
44 #include <QStringList>
45 #include <QVBoxLayout>
46 #include <QHeaderView>
72 BaseWidget(parent,
"MetricWidget",
"Metrics/3D ruler"),
73 mVerticalLayout(new QVBoxLayout(this)),
74 mTable(new QTableWidget(this)),
75 mPatientModelService(patientModelService),
76 mVisualizationService(visualizationService)
80 int lowUpdateRate = 100;
81 mLocalModified =
false;
82 mDelayedUpdateTimer =
new QTimer(
this);
83 connect(mDelayedUpdateTimer, SIGNAL(timeout()),
this, SLOT(
delayedUpdate()));
84 mDelayedUpdateTimer->start(lowUpdateRate);
90 connect(mMetricManager.get(), SIGNAL(activeMetricChanged()),
this, SLOT(
setModified()));
91 connect(mMetricManager.get(), SIGNAL(metricsChanged()),
this, SLOT(
setModified()));
95 connect(mTable, SIGNAL(cellChanged(
int,
int)),
this, SLOT(
cellChangedSlot(
int,
int)));
96 connect(mTable, SIGNAL(cellClicked(
int,
int)),
this, SLOT(
cellClickedSlot(
int,
int)));
98 this->setLayout(mVerticalLayout);
100 mEditWidgets =
new QStackedWidget;
102 QActionGroup* group =
new QActionGroup(
this);
103 this->createActions(group);
108 QWidget* toolBar =
new QWidget(
this);
109 QHBoxLayout* toolLayout =
new QHBoxLayout(toolBar);
110 toolLayout->setMargin(0);
111 toolLayout->setSpacing(0);
112 QList<QAction*> actions = group->actions();
113 for (
unsigned i=0; i<actions.size(); ++i)
115 if (actions[i]->isSeparator())
117 toolLayout->addSpacing(4);
118 QFrame* frame =
new QFrame();
119 frame->setFrameStyle(QFrame::Sunken + QFrame::VLine);
120 toolLayout->addWidget(frame);
121 toolLayout->addSpacing(4);
126 button->setDefaultAction(actions[i]);
127 button->setIconSize(QSize(32,32));
128 toolLayout->addWidget(button);
132 QHBoxLayout* buttonLayout =
new QHBoxLayout;
133 buttonLayout->addWidget(toolBar);
134 buttonLayout->addStretch();
137 mVerticalLayout->addLayout(buttonLayout);
138 mVerticalLayout->addWidget(mTable, 1);
139 mVerticalLayout->addWidget(mEditWidgets, 0);
145 void MetricWidget::createActions(QActionGroup* group)
151 this->createAction(group,
":/icons/metric_angle.png",
"Angle",
"Create a new Angle Metric", SLOT(
addAngleButtonClickedSlot()));
152 this->createAction(group,
":/icons/metric_plane.png",
"Plane",
"Create a new Plane Metric", SLOT(
addPlaneButtonClickedSlot()));
153 this->createAction(group,
":/icons/metric_sphere.png",
"Sphere",
"Create a new SphereMetric", SLOT(
addSphereButtonClickedSlot()));
154 this->createAction(group,
":/icons/metric_torus.png",
"Torus",
"Create a new Torus Metric", SLOT(
addDonutButtonClickedSlot()));
156 this->createAction(group,
"",
"",
"", NULL)->setSeparator(
true);
157 mRemoveAction = this->createAction(group,
":/icons/metric_remove.png",
"Remove",
"Remove currently selected metric", SLOT(
removeButtonClickedSlot()));
158 mRemoveAction->setDisabled(
true);
159 mLoadReferencePointsAction = this->createAction(group,
":/icons/metric_reference.png",
"Import",
"Import reference points from reference tool", SLOT(
loadReferencePointsSlot()));
160 mLoadReferencePointsAction->setDisabled(
true);
161 this->createAction(group,
"",
"",
"", NULL)->setSeparator(
true);
166 QAction* MetricWidget::createAction(QActionGroup* group, QString iconName, QString text, QString tip,
const char* slot)
168 QAction* action =
new QAction(QIcon(iconName), text, group);
169 action->setStatusTip(tip);
170 action->setToolTip(tip);
173 connect(action, SIGNAL(triggered()),
this, slot);
181 "<h3>Utility for sampling points in 3D</h3>"
182 "<p>Lets you sample points in 3D and get the distance between sampled points.</p>"
191 QTableWidgetItem* item = mTable->item(row,col);
194 data->setName(item->text());
201 if (row < 0 || column < 0)
204 QTableWidgetItem* item = mTable->item(row,column);
205 QString uid = item->data(Qt::UserRole).toString();
206 mMetricManager->moveToMetric(uid);
211 QTableWidgetItem* item = mTable->currentItem();
213 mMetricManager->setActiveUid(item->data(Qt::UserRole).toString());
214 mEditWidgets->setCurrentIndex(mTable->currentRow());
216 mMetricManager->setSelection(this->getSelectedUids());
221 void MetricWidget::showEvent(QShowEvent* event)
223 QWidget::showEvent(event);
227 void MetricWidget::hideEvent(QHideEvent* event)
229 QWidget::hideEvent(event);
234 template<
class T,
class SUPER>
235 boost::shared_ptr<T> castTo(boost::shared_ptr<SUPER> data)
237 return boost::dynamic_pointer_cast<T>(data);
240 template<
class T,
class SUPER>
241 bool isType(boost::shared_ptr<SUPER> data)
243 return (castTo<T>(data) ?
true :
false);
246 template<
class WRAPPER,
class METRIC,
class SUPER>
249 return boost::shared_ptr<WRAPPER>(
new WRAPPER(visualizationService, patientModelService, castTo<METRIC>(data)));
255 if (isType<PointMetric>(data))
256 return createMetricWrapperOfType<PointMetricWrapper, PointMetric>(visualizationService, patientModelService, data);
257 if (isType<DistanceMetric>(data))
258 return createMetricWrapperOfType<DistanceMetricWrapper, DistanceMetric>(visualizationService, patientModelService, data);
259 if (isType<AngleMetric>(data))
260 return createMetricWrapperOfType<AngleMetricWrapper, AngleMetric>(visualizationService, patientModelService, data);
261 if (isType<FrameMetric>(data))
262 return createMetricWrapperOfType<FrameMetricWrapper, FrameMetric>(visualizationService, patientModelService, data);
263 if (isType<ToolMetric>(data))
264 return createMetricWrapperOfType<ToolMetricWrapper, ToolMetric>(visualizationService, patientModelService, data);
265 if (isType<PlaneMetric>(data))
266 return createMetricWrapperOfType<PlaneMetricWrapper, PlaneMetric>(visualizationService, patientModelService, data);
267 if (isType<DonutMetric>(data))
268 return createMetricWrapperOfType<DonutMetricWrapper, DonutMetric>(visualizationService, patientModelService, data);
269 if (isType<SphereMetric>(data))
270 return createMetricWrapperOfType<SphereMetricWrapper, SphereMetric>(visualizationService, patientModelService, data);
280 std::vector<MetricBasePtr> retval;
282 for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
284 MetricBasePtr wrapper = this->createMetricWrapper(visualizationService, patientModelService, iter->second);
287 retval.push_back(wrapper);
294 void MetricWidget::prePaintEvent()
301 bool rebuild = !this->checkEqual(newMetrics, mMetrics);
304 this->resetWrappersAndEditWidgets(newMetrics);
305 this->initializeTable();
308 this->updateMetricWrappers();
309 this->updateTableContents();
313 this->expensizeColumnResize();
316 this->enablebuttons();
321 void MetricWidget::expensizeColumnResize()
324 mTable->resizeColumnToContents(valueColumn);
327 void MetricWidget::initializeTable()
329 mTable->blockSignals(
true);
333 mTable->setRowCount(mMetrics.size());
334 mTable->setColumnCount(4);
335 QStringList headerItems(QStringList() <<
"Name" <<
"Value" <<
"Arguments" <<
"Type");
336 mTable->setHorizontalHeaderLabels(headerItems);
338 mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
339 mTable->verticalHeader()->hide();
341 for (
unsigned i = 0; i < mMetrics.size(); ++i)
345 for (
unsigned j = 0; j < 4; ++j)
347 QTableWidgetItem* item =
new QTableWidgetItem(
"empty");
348 item->setData(Qt::UserRole, current->getData()->getUid());
349 mTable->setItem(i, j, item);
352 mTable->blockSignals(
false);
355 void MetricWidget::updateMetricWrappers()
357 for (
unsigned i = 0; i < mMetrics.size(); ++i)
359 mMetrics[i]->update();
363 void MetricWidget::updateTableContents()
365 mTable->blockSignals(
true);
369 for (
unsigned i = 0; i < mMetrics.size(); ++i)
372 QString name = current->getData()->getName();
373 QString value = current->getValue();
374 QString arguments = current->getArguments();
375 QString type = current->getType();
378 for (
unsigned i = 0; i < mMetrics.size(); ++i)
381 if (!mTable->item(i,0))
383 std::cout <<
"no qitem for:: " << i <<
" " << current->getData()->getName() << std::endl;
386 QString name = current->getData()->getName();
387 QString value = current->getValue();
388 QString arguments = current->getArguments();
389 QString type = current->getType();
391 mTable->item(i,0)->setText(name);
392 mTable->item(i,1)->setText(value);
393 mTable->item(i,2)->setText(arguments);
394 mTable->item(i,3)->setText(type);
397 if (current->getData()->getUid() == mMetricManager->getActiveUid())
399 mTable->setCurrentCell(i,1);
400 mEditWidgets->setCurrentIndex(i);
403 mTable->blockSignals(
false);
408 mLocalModified =
true;
418 mLocalModified =
false;
422 void MetricWidget::resetWrappersAndEditWidgets(std::vector<MetricBasePtr> wrappers)
424 while (mEditWidgets->count())
426 mEditWidgets->removeWidget(mEditWidgets->widget(0));
429 for (
unsigned i=0; i<mMetrics.size(); ++i)
431 disconnect(mMetrics[i]->getData().
get(), SIGNAL(transformChanged()),
this, SLOT(
setModified()));
436 for (
unsigned i=0; i<mMetrics.size(); ++i)
438 connect(mMetrics[i]->getData().
get(), SIGNAL(transformChanged()),
this, SLOT(
setModified()));
441 for (
unsigned i=0; i<mMetrics.size(); ++i)
444 QGroupBox* groupBox =
new QGroupBox(wrapper->getData()->getName(),
this);
445 groupBox->setFlat(
true);
446 QVBoxLayout* gbLayout =
new QVBoxLayout(groupBox);
447 gbLayout->setMargin(4);
448 gbLayout->addWidget(wrapper->createWidget());
449 mEditWidgets->addWidget(groupBox);
452 mEditWidgets->setCurrentIndex(-1);
455 bool MetricWidget::checkEqual(
const std::vector<MetricBasePtr>& a,
const std::vector<MetricBasePtr>& b)
const
457 if (a.size()!=b.size())
460 for (
unsigned i=0; i<a.size(); ++i)
462 if (a[i]->getData()!=b[i]->getData())
469 void MetricWidget::enablebuttons()
471 mRemoveAction->setEnabled(!mMetricManager->getActiveUid().isEmpty());
472 mLoadReferencePointsAction->setEnabled(
trackingService()->getReferenceTool() ?
true :
false);
477 mMetricManager->loadReferencePointsSlot();
481 mMetricManager->addPointButtonClickedSlot();
485 mMetricManager->addFrameButtonClickedSlot();
489 mMetricManager->addToolButtonClickedSlot();
493 mMetricManager->addPlaneButtonClickedSlot();
497 mMetricManager->addAngleButtonClickedSlot();
501 mMetricManager->addDistanceButtonClickedSlot();
505 mMetricManager->addSphereButtonClickedSlot();
509 mMetricManager->addDonutButtonClickedSlot();
512 std::set<QString> MetricWidget::getSelectedUids()
514 QList<QTableWidgetItem*> selection = mTable->selectedItems();
516 std::set<QString> selectedUids;
517 for (
int i=0; i<selection.size(); ++i)
519 selectedUids.insert(selection[i]->data(Qt::UserRole).toString());
526 int nextIndex = mTable->currentRow() + 1;
528 if (nextIndex < mTable->rowCount())
530 QTableWidgetItem* nextItem = mTable->item(nextIndex, 0);
531 nextUid = nextItem->data(Qt::UserRole).toString();
536 if (!nextUid.isEmpty())
537 mMetricManager->setActiveUid(nextUid);
542 QString suggestion = QString(
"%1/Logs/metrics_%2.txt")
546 QString filename = QFileDialog::getSaveFileName(
this,
547 "Create/select file to export metrics to",
549 if(!filename.isEmpty())
550 mMetricManager->exportMetricsToFile(filename);
QString timestampSecondsFormat()
boost::shared_ptr< class Data > DataPtr
boost::shared_ptr< class MetricBase > MetricBasePtr
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
cxLogicManager_EXPORT PatientModelServicePtr patientService()
cxLogicManager_EXPORT TrackingServicePtr trackingService()