14 #include <QTreeWidget>
15 #include <QTreeWidgetItem>
16 #include <QStringList>
17 #include <QVBoxLayout>
28 RegistrationHistoryWidget::RegistrationHistoryWidget(
RegServicesPtr servicesPtr, QWidget* parent,
bool compact) :
29 BaseWidget(parent,
"registration_history_widget",
"Registration History"),
30 mServices(servicesPtr)
38 QVBoxLayout* toptopLayout =
new QVBoxLayout(
this);
39 QHBoxLayout* topLayout =
new QHBoxLayout;
40 this->createControls(topLayout);
42 toptopLayout->addWidget(mGroup);
43 mGroup->setLayout(topLayout);
46 mTextEdit =
new QTextEdit;
47 mTextEdit->setLineWrapMode(QTextEdit::NoWrap);
49 toptopLayout->addWidget(mTextEdit, 1);
50 toptopLayout->addStretch();
51 topLayout->addStretch();
54 toptopLayout->setContentsMargins(QMargins(0,0,0,0));
55 topLayout->setContentsMargins(QMargins(0,0,0,0));
67 "<h3>Registration history.</h3>"
69 "Use the registration history to rewind the system to previous time. When history is rewinded, "
70 "all registrations performed after the active time is ignored by the system."
73 "<b>NB:</b> While a previous time is active, <em>no new registrations or adding of data</em> should be performed. "
74 "This will lead to undefined behaviour!</b>"
79 void RegistrationHistoryWidget::createControls(QHBoxLayout* layout)
81 mRemoveAction = this->createAction(layout,
":/icons/open_icon_library/dialog-close.png",
"Remove",
82 "Delete all registrations after the active time", SLOT(
removeSlot()));
84 mBehindLabel =
new QLabel(
this);
85 mBehindLabel->setToolTip(
"Number of registrations before the active time");
86 layout->addWidget(mBehindLabel);
88 mRewindAction = this->createAction(layout,
":/icons/open_icon_library/arrow-left-3.png",
"Rewind",
89 "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.",
92 mForwardAction = this->createAction(layout,
":/icons/open_icon_library/arrow-right-3.png",
93 "Rewind",
"One step forward in registration history", SLOT(
forwardSlot()));
95 mInFrontLabel =
new QLabel(
this);
96 mInFrontLabel->setToolTip(
"Number of registrations after active time");
97 layout->addWidget(mInFrontLabel);
99 mFastForwardAction = this->createAction(layout,
100 ":/icons/open_icon_library/arrow-right-double-3.png",
"Fast Forward",
106 QWidget::showEvent(event);
117 QWidget::closeEvent(event);
119 for (
unsigned i = 0; i < mHistories.size(); ++i)
129 for (
unsigned i = 0; i < mHistories.size(); ++i)
134 mHistories = this->getAllRegistrationHistories();
136 for (
unsigned i = 0; i < mHistories.size(); ++i)
145 RegistrationHistoryWidget::TimeMap RegistrationHistoryWidget::generateRegistrationTimes()
149 std::vector<RegistrationHistoryPtr> allHistories = this->getAllRegistrationHistories();
151 retval.insert(TimeMapPair(QDateTime(QDate(2000, 1, 1)),
"initial"));
153 for (
unsigned i = 0; i < allHistories.size(); ++i)
155 std::vector<RegistrationTransform> current = allHistories[i]->getData();
156 for (
unsigned j = 0; j < current.size(); ++j)
158 retval.insert(TimeMapPair(current[j].mTimestamp, QString(
"%1 [fixed=%2, moving=%3]").arg(current[j].mType).arg(current[j].mFixed).arg(
159 current[j].mMoving)));
161 std::vector<ParentSpace> frames = allHistories[i]->getParentSpaces();
162 for (
unsigned j = 0; j < frames.size(); ++j)
164 if(retval.find(frames[j].mTimestamp) == retval.end())
165 retval.insert(TimeMapPair(frames[j].mTimestamp, QString(
"%1 [spaceUid=%2]").arg(frames[j].mType).arg(frames[j].mUid)));
169 retval.erase(QDateTime());
174 RegistrationHistoryWidget::TimeMap::iterator RegistrationHistoryWidget::findActiveRegistration(TimeMap& times)
176 QDateTime activeTime = this->getActiveTime();
178 if (!activeTime.isValid())
181 RegistrationHistoryWidget::TimeMapIterators activeRegistrations = findActiveRegistrations(times);
182 if (!activeRegistrations.empty())
183 return activeRegistrations.back();
187 RegistrationHistoryWidget::TimeMapIterators RegistrationHistoryWidget::findActiveRegistrations(TimeMap& times)
189 RegistrationHistoryWidget::TimeMapIterators retval;
191 QDateTime activeTime = this->getActiveTime();
193 if (!activeTime.isValid())
195 retval.push_back(times.end());
199 for (TimeMap::iterator iter = times.begin(); iter != times.end(); ++iter)
201 if(!retval.empty() && iter->first == retval[0]->first)
202 retval.push_back(iter);
203 else if (retval.empty() && iter->first >= activeTime)
204 retval.push_back(iter);
208 retval.push_back(times.end());
212 QDateTime RegistrationHistoryWidget::getActiveTime()
214 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
216 for (
unsigned i = 0; i < raw.size(); ++i)
218 if (raw[i]->isNull())
220 return raw[i]->getActiveTime();
226 void RegistrationHistoryWidget::setActiveTime(QDateTime active)
228 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
229 for (
unsigned i = 0; i < raw.size(); ++i)
231 raw[i]->setActiveTime(active);
238 std::vector<RegistrationHistoryPtr> RegistrationHistoryWidget::getAllRegistrationHistories()
240 std::vector<RegistrationHistoryPtr> retval;
241 retval.push_back(mServices->patient()->get_rMpr_History());
243 std::map<QString, DataPtr> data = mServices->patient()->getDatas();
244 for (std::map<QString, DataPtr>::iterator iter = data.begin(); iter != data.end(); ++iter)
246 retval.push_back(iter->second->get_rMd_History());
258 QDateTime active = this->getActiveTime();
259 if (!active.isValid())
265 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
266 for (
unsigned i = 0; i < raw.size(); ++i)
268 raw[i]->removeNewerThan(active);
274 std::vector<RegistrationTransform> RegistrationHistoryWidget::mergeHistory(
const std::vector<RegistrationHistoryPtr>& allHistories)
276 std::vector<RegistrationTransform> history;
277 for (
unsigned i = 0; i < allHistories.size(); ++i)
279 std::vector<RegistrationTransform> current = allHistories[i]->getData();
280 std::copy(current.begin(), current.end(), std::back_inserter(history));
282 std::sort(history.begin(), history.end());
293 TimeMap registrationTimes = this->generateRegistrationTimes();
295 if (registrationTimes.size() <= 1)
300 TimeMapIterators activeRegistrations = this->findActiveRegistrations(registrationTimes);
301 TimeMap::iterator activeRegistration = registrationTimes.end();
302 if (!activeRegistrations.empty())
303 activeRegistration = activeRegistrations.front();
305 if (activeRegistration == registrationTimes.begin())
308 if (activeRegistration == registrationTimes.end())
309 --activeRegistration;
311 --activeRegistration;
314 + activeRegistration->second +
"]");
315 this->setActiveTime(activeRegistration->first);
318 QString RegistrationHistoryWidget::debugDump()
320 TimeMap times = this->generateRegistrationTimes();
321 bool addedBreak =
false;
322 std::stringstream ss;
325 if (!this->getActiveTime().isValid())
326 ss <<
"Active time: Current \n";
331 ss <<
"<p><span style=\"color:blue\">";
332 for (TimeMap::iterator iter = times.begin(); iter != times.end(); ++iter)
334 if (iter->first > this->getActiveTime() && !addedBreak && this->getActiveTime().isValid())
336 ss <<
"</span> <span style=\"color:gray\">";
351 QAction* RegistrationHistoryWidget::createAction(QLayout* layout, QString iconName, QString text, QString tip, T slot)
353 QAction* action =
new QAction(QIcon(iconName), text,
this);
354 action->setToolTip(tip);
355 connect(action, SIGNAL(triggered()),
this, slot);
357 QToolButton* button =
new QToolButton();
358 button->setDefaultAction(action);
359 layout->addWidget(button);
368 TimeMap registrationTimes = this->generateRegistrationTimes();
370 if (registrationTimes.empty())
374 TimeMapIterators activeRegistrations = this->findActiveRegistrations(registrationTimes);
375 TimeMap::iterator activeRegistration = registrationTimes.end();
376 if (!activeRegistrations.empty())
377 activeRegistration = activeRegistrations.back();
379 if (activeRegistration == registrationTimes.end())
381 ++activeRegistration;
383 if (activeRegistration == registrationTimes.end() || registrationTimes.rbegin()->first == activeRegistration->first)
385 report(
"Forward: Setting registration time to current, [" + registrationTimes.rbegin()->second +
"]");
386 this->setActiveTime(QDateTime());
390 report(
"Forward: Setting registration time to " + activeRegistration->first.toString(
timestampSecondsFormatNice()) +
", ["+ activeRegistration->second +
"]");
391 this->setActiveTime(activeRegistration->first);
400 std::vector<RegistrationHistoryPtr> raw = getAllRegistrationHistories();
401 report(
"Fast Forward: Setting registration time to current.");
403 for (
unsigned i = 0; i < raw.size(); ++i)
405 raw[i]->setActiveTime(QDateTime());
411 TimeMap times = this->generateRegistrationTimes();
412 std::map<QDateTime, QString>::iterator current = this->findActiveRegistration(times);
413 size_t behind = std::min<int>(distance(times.begin(), current), times.size() - 1);
414 size_t infront = times.size() - 1 - behind;
416 mRewindAction->setText(
"Rewind (" +
qstring_cast(behind) +
")");
417 mForwardAction->setText(
"Forward (" +
qstring_cast(infront) +
")");
419 mBehindLabel->setText(
"(" +
qstring_cast(behind) +
")");
420 mInFrontLabel->setText(
"(" +
qstring_cast(infront) +
")");
422 mRewindAction->setEnabled(behind > 0);
423 mRemoveAction->setEnabled(infront != 0);
424 mForwardAction->setEnabled(infront != 0);
425 mFastForwardAction->setEnabled(infront != 0);
434 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) }");
435 color += QString(
"QLabel {background-color: transparent }");
438 mGroup->setStyleSheet(color);
441 mTextEdit->setText(debugDump());