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 mViewService(viewService)
80 int lowUpdateRate = 100;
81 mLocalModified =
false;
82 mDelayedUpdateTimer =
new QTimer(
this);
83 connect(mDelayedUpdateTimer, SIGNAL(timeout()),
this, SLOT(
delayedUpdate()));
84 mDelayedUpdateTimer->start(lowUpdateRate);
85 this->setToolTip(
"3D measurements");
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);
182 QTableWidgetItem* item = mTable->item(row,col);
185 data->setName(item->text());
192 if (row < 0 || column < 0)
195 QTableWidgetItem* item = mTable->item(row,column);
196 QString uid = item->data(Qt::UserRole).toString();
197 mMetricManager->moveToMetric(uid);
202 QTableWidgetItem* item = mTable->currentItem();
204 mMetricManager->setActiveUid(item->data(Qt::UserRole).toString());
205 mEditWidgets->setCurrentIndex(mTable->currentRow());
207 mMetricManager->setSelection(this->getSelectedUids());
212 void MetricWidget::showEvent(QShowEvent* event)
214 QWidget::showEvent(event);
218 void MetricWidget::hideEvent(QHideEvent* event)
220 QWidget::hideEvent(event);
225 template<
class T,
class SUPER>
226 boost::shared_ptr<T> castTo(boost::shared_ptr<SUPER> data)
228 return boost::dynamic_pointer_cast<T>(data);
231 template<
class T,
class SUPER>
232 bool isType(boost::shared_ptr<SUPER> data)
234 return (castTo<T>(data) ?
true :
false);
237 template<
class WRAPPER,
class METRIC,
class SUPER>
240 return boost::shared_ptr<WRAPPER>(
new WRAPPER(viewService, patientModelService, castTo<METRIC>(data)));
246 if (isType<PointMetric>(data))
247 return createMetricWrapperOfType<PointMetricWrapper, PointMetric>(
viewService, patientModelService, data);
248 if (isType<DistanceMetric>(data))
249 return createMetricWrapperOfType<DistanceMetricWrapper, DistanceMetric>(viewService, patientModelService, data);
250 if (isType<AngleMetric>(data))
251 return createMetricWrapperOfType<AngleMetricWrapper, AngleMetric>(viewService, patientModelService, data);
252 if (isType<FrameMetric>(data))
253 return createMetricWrapperOfType<FrameMetricWrapper, FrameMetric>(viewService, patientModelService, data);
254 if (isType<ToolMetric>(data))
255 return createMetricWrapperOfType<ToolMetricWrapper, ToolMetric>(viewService, patientModelService, data);
256 if (isType<PlaneMetric>(data))
257 return createMetricWrapperOfType<PlaneMetricWrapper, PlaneMetric>(viewService, patientModelService, data);
258 if (isType<DonutMetric>(data))
259 return createMetricWrapperOfType<DonutMetricWrapper, DonutMetric>(viewService, patientModelService, data);
260 if (isType<SphereMetric>(data))
261 return createMetricWrapperOfType<SphereMetricWrapper, SphereMetric>(viewService, patientModelService, data);
271 std::vector<MetricBasePtr> retval;
273 for (std::map<QString, DataPtr>::iterator iter=all.begin(); iter!=all.end(); ++iter)
275 MetricBasePtr wrapper = this->createMetricWrapper(viewService, patientModelService, iter->second);
278 retval.push_back(wrapper);
285 void MetricWidget::prePaintEvent()
292 bool rebuild = !this->checkEqual(newMetrics, mMetrics);
295 this->resetWrappersAndEditWidgets(newMetrics);
296 this->initializeTable();
299 this->updateMetricWrappers();
300 this->updateTableContents();
304 this->expensizeColumnResize();
307 this->enablebuttons();
312 void MetricWidget::expensizeColumnResize()
315 mTable->resizeColumnToContents(valueColumn);
318 void MetricWidget::initializeTable()
320 mTable->blockSignals(
true);
324 mTable->setRowCount(mMetrics.size());
325 mTable->setColumnCount(4);
326 QStringList headerItems(QStringList() <<
"Name" <<
"Value" <<
"Arguments" <<
"Type");
327 mTable->setHorizontalHeaderLabels(headerItems);
329 mTable->setSelectionBehavior(QAbstractItemView::SelectRows);
330 mTable->verticalHeader()->hide();
332 for (
unsigned i = 0; i < mMetrics.size(); ++i)
336 for (
unsigned j = 0; j < 4; ++j)
338 QTableWidgetItem* item =
new QTableWidgetItem(
"empty");
339 item->setData(Qt::UserRole, current->getData()->getUid());
340 mTable->setItem(i, j, item);
343 mTable->blockSignals(
false);
346 void MetricWidget::updateMetricWrappers()
348 for (
unsigned i = 0; i < mMetrics.size(); ++i)
350 mMetrics[i]->update();
354 void MetricWidget::updateTableContents()
356 mTable->blockSignals(
true);
360 for (
unsigned i = 0; i < mMetrics.size(); ++i)
363 QString name = current->getData()->getName();
364 QString value = current->getValue();
365 QString arguments = current->getArguments();
366 QString type = current->getType();
369 for (
unsigned i = 0; i < mMetrics.size(); ++i)
372 if (!mTable->item(i,0))
374 std::cout <<
"no qitem for:: " << i <<
" " << current->getData()->getName() << std::endl;
377 QString name = current->getData()->getName();
378 QString value = current->getValue();
379 QString arguments = current->getArguments();
380 QString type = current->getType();
382 mTable->item(i,0)->setText(name);
383 mTable->item(i,1)->setText(value);
384 mTable->item(i,2)->setText(arguments);
385 mTable->item(i,3)->setText(type);
388 if (current->getData()->getUid() == mMetricManager->getActiveUid())
390 mTable->setCurrentCell(i,1);
391 mEditWidgets->setCurrentIndex(i);
394 mTable->blockSignals(
false);
399 mLocalModified =
true;
409 mLocalModified =
false;
413 void MetricWidget::resetWrappersAndEditWidgets(std::vector<MetricBasePtr> wrappers)
415 while (mEditWidgets->count())
417 mEditWidgets->removeWidget(mEditWidgets->widget(0));
420 for (
unsigned i=0; i<mMetrics.size(); ++i)
422 disconnect(mMetrics[i]->getData().
get(), SIGNAL(transformChanged()),
this, SLOT(
setModified()));
427 for (
unsigned i=0; i<mMetrics.size(); ++i)
429 connect(mMetrics[i]->getData().
get(), SIGNAL(transformChanged()),
this, SLOT(
setModified()));
432 for (
unsigned i=0; i<mMetrics.size(); ++i)
435 QGroupBox* groupBox =
new QGroupBox(wrapper->getData()->getName(),
this);
436 groupBox->setFlat(
true);
437 QVBoxLayout* gbLayout =
new QVBoxLayout(groupBox);
438 gbLayout->setMargin(4);
439 gbLayout->addWidget(wrapper->createWidget());
440 mEditWidgets->addWidget(groupBox);
443 mEditWidgets->setCurrentIndex(-1);
446 bool MetricWidget::checkEqual(
const std::vector<MetricBasePtr>& a,
const std::vector<MetricBasePtr>& b)
const
448 if (a.size()!=b.size())
451 for (
unsigned i=0; i<a.size(); ++i)
453 if (a[i]->getData()!=b[i]->getData())
460 void MetricWidget::enablebuttons()
462 mRemoveAction->setEnabled(!mMetricManager->getActiveUid().isEmpty());
463 mLoadReferencePointsAction->setEnabled(
trackingService()->getReferenceTool() ?
true :
false);
468 mMetricManager->loadReferencePointsSlot();
472 mMetricManager->addPointButtonClickedSlot();
476 mMetricManager->addFrameButtonClickedSlot();
480 mMetricManager->addToolButtonClickedSlot();
484 mMetricManager->addPlaneButtonClickedSlot();
488 mMetricManager->addAngleButtonClickedSlot();
492 mMetricManager->addDistanceButtonClickedSlot();
496 mMetricManager->addSphereButtonClickedSlot();
500 mMetricManager->addDonutButtonClickedSlot();
503 std::set<QString> MetricWidget::getSelectedUids()
505 QList<QTableWidgetItem*> selection = mTable->selectedItems();
507 std::set<QString> selectedUids;
508 for (
int i=0; i<selection.size(); ++i)
510 selectedUids.insert(selection[i]->data(Qt::UserRole).toString());
517 int nextIndex = mTable->currentRow() + 1;
519 if (nextIndex < mTable->rowCount())
521 QTableWidgetItem* nextItem = mTable->item(nextIndex, 0);
522 nextUid = nextItem->data(Qt::UserRole).toString();
527 if (!nextUid.isEmpty())
528 mMetricManager->setActiveUid(nextUid);
533 QString suggestion = QString(
"%1/Logs/metrics_%2.txt")
537 QString filename = QFileDialog::getSaveFileName(
this,
538 "Create/select file to export metrics to",
540 if(!filename.isEmpty())
541 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 ViewServicePtr viewService()
cxLogicManager_EXPORT PatientModelServicePtr patientService()
cxLogicManager_EXPORT TrackingServicePtr trackingService()