35 #include <QTreeWidget> 36 #include <QTreeWidgetItem> 37 #include <QStringList> 38 #include <QVBoxLayout> 49 RegistrationHistoryWidget::RegistrationHistoryWidget(
RegServicesPtr servicesPtr, QWidget* parent,
bool compact) :
50 BaseWidget(parent,
"registration_history_widget",
"Registration History"),
51 mServices(servicesPtr)
59 QVBoxLayout* toptopLayout =
new QVBoxLayout(
this);
60 QHBoxLayout* topLayout =
new QHBoxLayout;
61 this->createControls(topLayout);
63 toptopLayout->addWidget(mGroup);
64 mGroup->setLayout(topLayout);
67 mTextEdit =
new QTextEdit;
68 mTextEdit->setLineWrapMode(QTextEdit::NoWrap);
70 toptopLayout->addWidget(mTextEdit, 1);
71 toptopLayout->addStretch();
72 topLayout->addStretch();
75 toptopLayout->setContentsMargins(QMargins(0,0,0,0));
76 topLayout->setContentsMargins(QMargins(0,0,0,0));
88 "<h3>Registration history.</h3>" 90 "Use the registration history to rewind the system to previous time. When history is rewinded, " 91 "all registrations performed after the active time is ignored by the system." 94 "<b>NB:</b> While a previous time is active, <em>no new registrations or adding of data</em> should be performed. " 95 "This will lead to undefined behaviour!</b>" 100 void RegistrationHistoryWidget::createControls(QHBoxLayout* layout)
102 mRemoveAction = this->createAction(layout,
":/icons/open_icon_library/dialog-close.png",
"Remove",
103 "Delete all registrations after the active time", SLOT(
removeSlot()));
105 mBehindLabel =
new QLabel(
this);
106 mBehindLabel->setToolTip(
"Number of registrations before the active time");
107 layout->addWidget(mBehindLabel);
109 mRewindAction = this->createAction(layout,
":/icons/open_icon_library/arrow-left-3.png",
"Rewind",
110 "One step back in registration history, changing active time.\nThis enables looking at a previous system state,\nbut take care to not add more registrations while this state.",
113 mForwardAction = this->createAction(layout,
":/icons/open_icon_library/arrow-right-3.png",
114 "Rewind",
"One step forward in registration history", SLOT(
forwardSlot()));
116 mInFrontLabel =
new QLabel(
this);
117 mInFrontLabel->setToolTip(
"Number of registrations after active time");
118 layout->addWidget(mInFrontLabel);
120 mFastForwardAction = this->createAction(layout,
121 ":/icons/open_icon_library/arrow-right-double-3.png",
"Fast Forward",
127 QWidget::showEvent(event);
138 QWidget::closeEvent(event);
140 for (
unsigned i = 0; i < mHistories.size(); ++i)
150 for (
unsigned i = 0; i < mHistories.size(); ++i)
155 mHistories = this->getAllRegistrationHistories();
157 for (
unsigned i = 0; i < mHistories.size(); ++i)
166 RegistrationHistoryWidget::TimeMap RegistrationHistoryWidget::generateRegistrationTimes()
170 std::vector<RegistrationHistoryPtr> allHistories = this->getAllRegistrationHistories();
172 retval.insert(TimeMapPair(QDateTime(QDate(2000, 1, 1)),
"initial"));
174 for (
unsigned i = 0; i < allHistories.size(); ++i)
176 std::vector<RegistrationTransform> current = allHistories[i]->getData();
177 for (
unsigned j = 0; j < current.size(); ++j)
179 retval.insert(TimeMapPair(current[j].mTimestamp, QString(
"%1 [fixed=%2, moving=%3]").arg(current[j].mType).arg(current[j].mFixed).arg(
180 current[j].mMoving)));
182 std::vector<ParentSpace> frames = allHistories[i]->getParentSpaces();
183 for (
unsigned j = 0; j < frames.size(); ++j)
185 if(retval.find(frames[j].mTimestamp) == retval.end())
186 retval.insert(TimeMapPair(frames[j].mTimestamp, QString(
"%1 [spaceUid=%2]").arg(frames[j].mType).arg(frames[j].mUid)));
190 retval.erase(QDateTime());
195 RegistrationHistoryWidget::TimeMap::iterator RegistrationHistoryWidget::findActiveRegistration(TimeMap& times)
197 QDateTime activeTime = this->getActiveTime();
199 if (!activeTime.isValid())
202 RegistrationHistoryWidget::TimeMapIterators activeRegistrations = findActiveRegistrations(times);
203 if (!activeRegistrations.empty())
204 return activeRegistrations.back();
208 RegistrationHistoryWidget::TimeMapIterators RegistrationHistoryWidget::findActiveRegistrations(TimeMap& times)
210 RegistrationHistoryWidget::TimeMapIterators retval;
212 QDateTime activeTime = this->getActiveTime();
214 if (!activeTime.isValid())
216 retval.push_back(times.end());
220 for (TimeMap::iterator iter = times.begin(); iter != times.end(); ++iter)
222 if(!retval.empty() && iter->first == retval[0]->first)
223 retval.push_back(iter);
224 else if (retval.empty() && iter->first >= activeTime)
225 retval.push_back(iter);
229 retval.push_back(times.end());
233 QDateTime RegistrationHistoryWidget::getActiveTime()
235 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
237 for (
unsigned i = 0; i < raw.size(); ++i)
239 if (raw[i]->isNull())
241 return raw[i]->getActiveTime();
247 void RegistrationHistoryWidget::setActiveTime(QDateTime active)
249 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
250 for (
unsigned i = 0; i < raw.size(); ++i)
252 raw[i]->setActiveTime(active);
259 std::vector<RegistrationHistoryPtr> RegistrationHistoryWidget::getAllRegistrationHistories()
261 std::vector<RegistrationHistoryPtr> retval;
262 retval.push_back(mServices->patient()->get_rMpr_History());
264 std::map<QString, DataPtr> data = mServices->patient()->getDatas();
265 for (std::map<QString, DataPtr>::iterator iter = data.begin(); iter != data.end(); ++iter)
267 retval.push_back(iter->second->get_rMd_History());
279 QDateTime active = this->getActiveTime();
280 if (!active.isValid())
286 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
287 for (
unsigned i = 0; i < raw.size(); ++i)
289 raw[i]->removeNewerThan(active);
295 std::vector<RegistrationTransform> RegistrationHistoryWidget::mergeHistory(
const std::vector<RegistrationHistoryPtr>& allHistories)
297 std::vector<RegistrationTransform> history;
298 for (
unsigned i = 0; i < allHistories.size(); ++i)
300 std::vector<RegistrationTransform> current = allHistories[i]->getData();
301 std::copy(current.begin(), current.end(), std::back_inserter(history));
303 std::sort(history.begin(), history.end());
314 TimeMap registrationTimes = this->generateRegistrationTimes();
316 if (registrationTimes.size() <= 1)
321 TimeMapIterators activeRegistrations = this->findActiveRegistrations(registrationTimes);
322 TimeMap::iterator activeRegistration = registrationTimes.end();
323 if (!activeRegistrations.empty())
324 activeRegistration = activeRegistrations.front();
326 if (activeRegistration == registrationTimes.begin())
329 if (activeRegistration == registrationTimes.end())
330 --activeRegistration;
332 --activeRegistration;
335 + activeRegistration->second +
"]");
336 this->setActiveTime(activeRegistration->first);
339 QString RegistrationHistoryWidget::debugDump()
341 TimeMap times = this->generateRegistrationTimes();
342 bool addedBreak =
false;
343 std::stringstream ss;
346 if (!this->getActiveTime().isValid())
347 ss <<
"Active time: Current \n";
352 ss <<
"<p><span style=\"color:blue\">";
353 for (TimeMap::iterator iter = times.begin(); iter != times.end(); ++iter)
355 if (iter->first > this->getActiveTime() && !addedBreak && this->getActiveTime().isValid())
357 ss <<
"</span> <span style=\"color:gray\">";
372 QAction* RegistrationHistoryWidget::createAction(QLayout* layout, QString iconName, QString text, QString tip, T slot)
374 QAction* action =
new QAction(QIcon(iconName), text,
this);
375 action->setToolTip(tip);
376 connect(action, SIGNAL(triggered()),
this, slot);
378 QToolButton* button =
new QToolButton();
379 button->setDefaultAction(action);
380 layout->addWidget(button);
389 TimeMap registrationTimes = this->generateRegistrationTimes();
391 if (registrationTimes.empty())
395 TimeMapIterators activeRegistrations = this->findActiveRegistrations(registrationTimes);
396 TimeMap::iterator activeRegistration = registrationTimes.end();
397 if (!activeRegistrations.empty())
398 activeRegistration = activeRegistrations.back();
400 if (activeRegistration == registrationTimes.end())
402 ++activeRegistration;
404 if (activeRegistration == registrationTimes.end() || registrationTimes.rbegin()->first == activeRegistration->first)
406 report(
"Forward: Setting registration time to current, [" + registrationTimes.rbegin()->second +
"]");
407 this->setActiveTime(QDateTime());
411 report(
"Forward: Setting registration time to " + activeRegistration->first.toString(
timestampSecondsFormatNice()) +
", ["+ activeRegistration->second +
"]");
412 this->setActiveTime(activeRegistration->first);
421 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
422 report(
"Fast Forward: Setting registration time to current.");
424 for (
unsigned i = 0; i < raw.size(); ++i)
426 raw[i]->setActiveTime(QDateTime());
432 TimeMap times = this->generateRegistrationTimes();
433 std::map<QDateTime, QString>::iterator current = this->findActiveRegistration(times);
434 size_t behind = std::min<int>(distance(times.begin(), current), times.size() - 1);
435 size_t infront = times.size() - 1 - behind;
437 mRewindAction->setText(
"Rewind (" +
qstring_cast(behind) +
")");
438 mForwardAction->setText(
"Forward (" +
qstring_cast(infront) +
")");
440 mBehindLabel->setText(
"(" +
qstring_cast(behind) +
")");
441 mInFrontLabel->setText(
"(" +
qstring_cast(infront) +
")");
443 mRewindAction->setEnabled(behind > 0);
444 mRemoveAction->setEnabled(infront != 0);
445 mForwardAction->setEnabled(infront != 0);
446 mFastForwardAction->setEnabled(infront != 0);
455 color = QString(
"QFrame {background: qradialgradient(cx:0.5, cy:0.5, radius: 0.5, fx:0.5, fy:0.5, stop:0 rgb(255,30,0), stop:0.8 rgb(255,50,0), stop:1 transparent) }");
456 color += QString(
"QLabel {background-color: transparent }");
459 mGroup->setStyleSheet(color);
462 mTextEdit->setText(debugDump());
QString qstring_cast(const T &val)
void dataAddedOrRemoved()
virtual QString defaultWhatsThis() const
QString timestampSecondsFormatNice()
virtual void hideEvent(QCloseEvent *event)
disconnects stuff
virtual ~RegistrationHistoryWidget()
virtual void prePaintEvent()
boost::shared_ptr< class RegServices > RegServicesPtr
virtual void showEvent(QShowEvent *event)
updates internal info before showing the widget
Namespace for all CustusX production code.