14 #include <QAbstractItemView> 17 #include <QDesktopServices> 18 #include <QDesktopWidget> 19 #include <QDomDocument> 20 #include <QFileDialog> 23 #include <QMessageBox> 43 , m_ConnectionSuccessful(false)
45 , m_EditorSelectAction(NULL)
46 , m_EditApplicationConfigFileAction(NULL)
47 , m_DeviceSetComboBoxMaximumSizeRatio(-1)
56 ui.lineEdit_ConfigurationDirectory->setFixedHeight(
ui.pushButton_OpenConfigurationDirectory->sizeHint().height());
57 ui.comboBox_DeviceSet->setFixedHeight(
ui.pushButton_EditConfiguration->sizeHint().height());
59 ui.pushButton_EditConfiguration->setContextMenuPolicy(Qt::CustomContextMenu);
62 connect(
ui.pushButton_Connect, SIGNAL(clicked()),
this, SLOT(
InvokeConnect()));
63 connect(
ui.pushButton_RefreshFolder, SIGNAL(clicked()),
this, SLOT(
RefreshFolder()));
64 connect(
ui.pushButton_EditConfiguration, SIGNAL(clicked()),
this, SLOT(
EditConfiguration()));
65 connect(
ui.comboBox_DeviceSet, SIGNAL(currentIndexChanged(
int)),
this, SLOT(
DeviceSetSelected(
int)));
67 ui.pushButton_ResetTracker->setVisible(
false);
69 connect(
ui.pushButton_EditConfiguration, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(
ShowEditContextMenu(QPoint)));
107 LOG_TRACE(
"DeviceSetSelectorWidget::SetConfigurationDirectory(" << aDirectory.toStdString() <<
")");
112 ui.lineEdit_ConfigurationDirectory->setText(aDirectory);
113 ui.lineEdit_ConfigurationDirectory->setToolTip(aDirectory);
127 ui.lineEdit_ConfigurationDirectory->setText(tr(
"Invalid configuration directory"));
128 ui.lineEdit_ConfigurationDirectory->setToolTip(
"No valid configuration files in directory, please select another");
130 ui.textEdit_Description->setTextColor(QColor(Qt::darkRed));
131 ui.textEdit_Description->setText(
"Selected directory does not contain valid device set configuration files!\n\nPlease select another directory");
140 QString fileName = QDir::toNativeSeparators(aFilename);
141 QFileInfo info(fileName);
146 QString fileName = QDir::toNativeSeparators(info.absoluteFilePath());
147 ui.comboBox_DeviceSet->setCurrentIndex(
ui.comboBox_DeviceSet->findData(fileName));
158 LOG_TRACE(
"DeviceSetSelectorWidget::OpenConfigurationDirectoryClicked");
161 QString dirName = QFileDialog::getExistingDirectory(NULL, QString(tr(
"Open configuration directory")),
m_ConfigurationDirectory);
162 if (dirName.isNull())
169 LOG_ERROR(
"Unable to open selected directory!");
176 LOG_TRACE(
"DeviceSetSelectorWidget::InvokeConnect");
178 if (
ui.comboBox_DeviceSet->currentIndex() < 0)
185 std::string configFile =
ui.comboBox_DeviceSet->itemData(
ui.comboBox_DeviceSet->currentIndex(),
FileNameRole).toString().toStdString();
189 ui.pushButton_Connect->setEnabled(
false);
190 QCoreApplication::processEvents();
198 LOG_TRACE(
"DeviceSetSelectorWidget::GetSelectedDeviceSetConfigFilePath");
200 return ui.comboBox_DeviceSet->itemData(
ui.comboBox_DeviceSet->currentIndex(),
FileNameRole).toString().toStdString();
206 LOG_TRACE(
"DeviceSetSelectorWidget::GetSelectedDeviceSetDescription");
208 return ui.comboBox_DeviceSet->itemData(
ui.comboBox_DeviceSet->currentIndex(),
DescriptionRole).toString().toStdString();
214 LOG_TRACE(
"DeviceSetSelectorWidget::InvokeDisconnect");
218 ui.pushButton_Connect->setEnabled(
false);
219 QCoreApplication::processEvents();
227 LOG_TRACE(
"DeviceSetSelectorWidget::DeviceSetSelected(" << aIndex <<
")");
229 if ((aIndex < 0) || (aIndex >=
ui.comboBox_DeviceSet->count()))
234 ui.textEdit_Description->setTextColor(QColor(Qt::black));
236 ui.textEdit_Description->setText(
ui.comboBox_DeviceSet->itemData(aIndex,
DescriptionRole).toString());
238 ui.comboBox_DeviceSet->setToolTip(
ui.comboBox_DeviceSet->currentText() +
"\n" +
ui.comboBox_DeviceSet->itemData(aIndex,
FileNameRole).toString());
240 QString configurationFilePath =
ui.comboBox_DeviceSet->itemData(
ui.comboBox_DeviceSet->currentIndex(),
FileNameRole).toString();
248 LOG_TRACE(
"DeviceSetSelectorWidget::SetConnectionSuccessful(" << (aConnectionSuccessful ?
"true" :
"false") <<
")");
253 if (!
ui.pushButton_Connect->property(
"connected").toBool())
257 ui.pushButton_Connect->setText(tr(
"Disconnect"));
258 ui.comboBox_DeviceSet->setEnabled(
false);
260 ui.textEdit_Description->setTextColor(QColor(Qt::black));
266 disconnect(
ui.pushButton_Connect, SIGNAL(clicked()),
this, SLOT(
InvokeConnect()));
272 ui.pushButton_Connect->setProperty(
"connected", QVariant(
true));
276 ui.textEdit_Description->setTextColor(QColor(Qt::darkRed));
287 ui.pushButton_Connect->setProperty(
"connected", QVariant(
false));
288 ui.pushButton_Connect->setText(tr(
"Connect"));
289 ui.comboBox_DeviceSet->setEnabled(
true);
291 ui.textEdit_Description->setTextColor(QColor(Qt::black));
292 if (
ui.comboBox_DeviceSet->currentIndex() >= 0)
301 connect(
ui.pushButton_Connect, SIGNAL(clicked()),
this, SLOT(
InvokeConnect()));
305 LOG_ERROR(
"Disconnect failed!");
309 ui.pushButton_Connect->setEnabled(
true);
315 LOG_TRACE(
"DeviceSetSelectorWidget::GetConnectionSuccessful");
323 LOG_TRACE(
"DeviceSetSelectorWidget::ParseDirectory(" << aDirectory.toStdString() <<
")");
325 QDir configDir(aDirectory);
326 QStringList fileList(configDir.entryList());
328 if (fileList.size() > 200)
330 if (QMessageBox::No == QMessageBox::question(
this, tr(
"Many files in the directory"), tr(
"There are more than 200 files in the selected directory. Do you really want to continue parsing the files?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes))
337 ui.comboBox_DeviceSet->blockSignals(
true);
338 ui.comboBox_DeviceSet->clear();
340 QStringListIterator filesIterator(fileList);
341 QHash<QString, int> deviceSetVersion;
343 while (filesIterator.hasNext())
345 QString fileName = QDir::toNativeSeparators(QString(configDir.absoluteFilePath(filesIterator.next())));
346 QString extension = fileName.mid(fileName.lastIndexOf(
"."));
347 if (!igsioCommon::IsEqualInsensitive(extension.toStdString(),
".xml"))
352 QFile file(fileName);
353 QFileInfo fileInfo(fileName);
357 if (!file.open(QIODevice::ReadOnly))
363 if (doc.setContent(&file))
365 QDomElement docElem = doc.documentElement();
368 if (!docElem.tagName().compare(
"PlusConfiguration", Qt::CaseInsensitive))
370 QDomNodeList list = docElem.elementsByTagName(
"DataCollection");
372 if (list.count() > 0)
375 docElem = list.at(0).toElement();
389 QDomNodeList list(doc.elementsByTagName(
"DeviceSet"));
390 if (list.size() <= 0)
396 QString calibDetails;
397 vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromFile(fileName.toStdString().c_str()));
398 if (configRootElement != NULL)
400 vtkNew<vtkIGSIOTransformRepository> tr;
401 if (tr->ReadConfiguration(configRootElement) ==
PLUS_SUCCESS)
404 pivotString =
FindCalibrationDetails(doc, tr,
"vtkPlusPivotCalibrationAlgo",
"Pivot calibration: ",
"ObjectPivotPointCoordinateFrame",
"ObjectMarkerCoordinateFrame");
405 if (!pivotString.isEmpty())
407 calibDetails += pivotString;
410 QString phantomString;
411 phantomString =
FindCalibrationDetails(doc, tr,
"vtkPlusPhantomLandmarkRegistrationAlgo",
"Phantom calibration: ",
"PhantomCoordinateFrame",
"ReferenceCoordinateFrame");
412 if (!phantomString.isEmpty())
414 calibDetails += phantomString;
418 probeString =
FindCalibrationDetails(doc, tr,
"vtkPlusProbeCalibrationAlgo",
"Probe calibration: ",
"ImageCoordinateFrame",
"ProbeCoordinateFrame");
419 if (!probeString.isEmpty())
421 calibDetails += probeString;
426 QDomElement elem = list.at(0).toElement();
428 QString name(elem.attribute(
"Name"));
429 QString description(elem.attribute(
"Description"));
432 LOG_WARNING(
"Name field is empty in device set configuration file '" << fileName.toStdString() <<
"', it is not added to the list");
436 if (!calibDetails.isEmpty())
438 description +=
"\n\n";
439 description += calibDetails;
443 int foundIndex =
ui.comboBox_DeviceSet->findText(name, Qt::MatchExactly);
446 QHash<QString, int>::iterator deviceIt = deviceSetVersion.find(name);
447 if (deviceIt == deviceSetVersion.end())
449 deviceSetVersion.insert(name, 0);
454 deviceIt.value() += 1;
455 name.append(
" [" + QString::number(deviceIt.value()) +
"]");
459 ui.comboBox_DeviceSet->addItem(name, fileName);
460 int currentIndex =
ui.comboBox_DeviceSet->findText(name, Qt::MatchExactly);
466 name.append(tr(
"</p> <p>") + fileInfo.fileName() + tr(
"</p> <p>") + description + tr(
"</p>"));
467 ui.comboBox_DeviceSet->setItemData(currentIndex, name, Qt::ToolTipRole);
471 LOG_WARNING(
"Unable to parse file '" << fileName.toStdString() <<
"' as an XML. It will not appear in the device set configuration file list!");
476 if (
ui.comboBox_DeviceSet->count() < 1)
478 LOG_ERROR(
"Selected directory (" << aDirectory.toStdString() <<
") does not contain valid device set configuration files!");
483 ui.comboBox_DeviceSet->setCurrentIndex(-1);
485 ui.comboBox_DeviceSet->model()->sort(0);
488 ui.comboBox_DeviceSet->blockSignals(
false);
491 int lastSelectedDeviceSetIndex =
ui.comboBox_DeviceSet->findData(QDir::toNativeSeparators(QString(
vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationFileName().c_str())));
492 ui.comboBox_DeviceSet->setCurrentIndex(lastSelectedDeviceSetIndex);
501 vtkSmartPointer<vtkIGSIOTransformRepository> aTransformRepository,
502 const QString& aTagName,
503 const QString& aOutputPrefix,
504 const QString& aFirstFrame,
505 const QString& aSecondFrame)
507 QDomNodeList list(aDocument.elementsByTagName(aTagName));
508 if (list.count() > 0)
510 auto elem = list.at(0).toElement();
511 QString firstFrame(elem.attribute(aFirstFrame));
512 QString secondFrame(elem.attribute(aSecondFrame));
513 if (!firstFrame.isEmpty() && !secondFrame.isEmpty())
515 igsioTransformName tName(firstFrame.toStdString(), secondFrame.toStdString());
518 if (aTransformRepository->GetTransformDate(tName,
date,
true) ==
PLUS_SUCCESS &&
519 aTransformRepository->GetTransformError(tName, error,
true) ==
PLUS_SUCCESS)
523 std::stringstream ss(
date);
524 ss >> std::get_time(&tm,
"%Y.%m.%d %H:%M:%S");
525 if (tm.tm_hour == 0 || tm.tm_mday == 0 || tm.tm_mon == 0 || tm.tm_year == 0)
527 if (
date.length() == 13)
530 std::string month(
date.substr(0, 2));
531 std::string day(
date.substr(2, 2));
532 std::string year(
date.substr(4, 2));
533 std::string hour(
date.substr(7, 2));
534 std::string minute(
date.substr(9, 2));
535 std::string second(
date.substr(11, 2));
536 std::stringstream ss;
537 ss << month <<
" " << day <<
" " << year <<
"_" << hour <<
" " << minute <<
" " << second;
538 ss >> std::get_time(&tm,
"%m %d %y_%H %M %S");
540 if (!(tm.tm_hour == 0 || tm.tm_mday == 0 || tm.tm_mon == 0 || tm.tm_year == 0))
551 QString output = aOutputPrefix;
554 std::stringstream ss;
555 ss << std::put_time(&tm,
"%b %d %Y - %H:%M");
556 output += QString::fromStdString(ss.str());
560 output += QString::fromStdString(
date);
562 return output +
", error: " + QString::number(error,
'g', 2) +
"\n";
573 if (event->mimeData()->hasUrls() &&
event->mimeData()->urls().size() == 1)
575 QString filename =
event->mimeData()->urls()[0].toLocalFile();
576 if (filename.lastIndexOf(
'.') == -1)
580 QString extension = filename.mid(filename.lastIndexOf(
'.'));
581 if (extension.contains(
"xml"))
583 event->acceptProposedAction();
591 QUrl url =
event->mimeData()->urls().first();
592 QString fileName = url.toLocalFile();
600 int scroll = cb->count() <= cb->maxVisibleItems() ? 0 :
601 QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent);
605 for (
int i = 0;
i < cb->count();
i++)
607 int width = cb->view()->fontMetrics().width(cb->itemText(
i));
611 cb->view()->setMinimumWidth(scroll + max);
617 QWidget::resizeEvent(event);
621 QDesktopWidget desktop;
622 int screenWidth = desktop.screenGeometry(desktop.screenNumber(
this)).
width();
643 ui.textEdit_Description->setText(
text);
649 LOG_TRACE(
"DeviceSetSelectorWidget::RefreshFolderClicked");
653 LOG_ERROR(
"Parsing up configuration files failed in: " <<
vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationDirectory());
660 LOG_TRACE(
"DeviceSetSelectorWidget::EditConfiguration");
662 QString configurationFilePath;
663 int deviceSetIndex =
ui.comboBox_DeviceSet->currentIndex();
664 if (deviceSetIndex >= 0)
666 configurationFilePath =
ui.comboBox_DeviceSet->itemData(deviceSetIndex).toStringList().at(0);
670 LOG_ERROR(
"Cannot edit configuration file. No configuration is selected.");
675 if (!editorApplicationExecutable.isEmpty())
677 QFileInfo fileInfo(QDir::toNativeSeparators(configurationFilePath));
678 QString file = fileInfo.absoluteFilePath();
680 QProcess::startDetached(editorApplicationExecutable, QStringList() << file);
685 if (!QDesktopServices::openUrl(QUrl(
"file:///" + configurationFilePath, QUrl::TolerantMode)))
687 LOG_ERROR(
"Failed to open file in default application: " << configurationFilePath.toStdString());
714 m_EditMenu->exec(
ui.pushButton_EditConfiguration->mapToGlobal(point));
721 QString filter = QString(tr(
"Executables ( *.exe );;"));
722 QString fileName = QFileDialog::getOpenFileName(NULL, QString(tr(
"Select XML editor application")),
"", filter);
723 if (fileName.isNull())
735 LOG_TRACE(
"DeviceSetSelectorWidget::EditConfiguration");
740 if (!editorApplicationExecutable.isEmpty())
742 QFileInfo fileInfo(QDir::toNativeSeparators(configurationFilePath));
743 QString file = fileInfo.absoluteFilePath();
745 QProcess::startDetached(editorApplicationExecutable, QStringList() << file);
750 if (!QDesktopServices::openUrl(QUrl(
"file:///" + configurationFilePath, QUrl::TolerantMode)))
752 LOG_ERROR(
"Failed to open file in default application: " << configurationFilePath.toStdString());
759 LOG_TRACE(
"DeviceSetSelectorWidget::ResetTrackerButtonClicked()");
767 ui.pushButton_ResetTracker->setVisible(aValue);
773 ui.pushButton_Connect->setText(
text);
static vtkPlusConfig * GetInstance()
PlusStatus SaveApplicationConfigurationToFile()
PhidgetLCD_Font int int const char * text
void SetDeviceSetConfigurationDirectory(const std::string &aDir)
PhidgetLCD_Font int * width
void SetDeviceSetConfigurationFileName(const std::string &aFilePath)