31 #include <QMessageBox> 32 #include <QMouseEvent> 33 #include <QTreeWidget> 42 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
47 _main_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
50 QHBoxLayout* title_layout =
new QHBoxLayout;
51 title_layout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
52 title_layout->setContentsMargins(5, 5, 5, 5);
53 title_layout->addWidget(
new QLabel(tr(
"Available Signals")));
71 signal_tree->viewport()->setBackgroundRole(QPalette::Background);
72 signal_tree->setAttribute(Qt::WA_MacShowFocusRect,
false);
76 signal_tree->setHeaderHidden(
true);
77 signal_tree->setIndentation(10);
78 signal_tree->setStyleSheet(
"QTreeView { border: none; }");
79 signal_tree->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
80 signal_tree->setContextMenuPolicy(Qt::CustomContextMenu);
81 signal_tree->connect(signal_tree, &QTreeWidget::customContextMenuRequested,
90 QStringList namespaces = signal_data.
namespaces;
91 namespaces.pop_back();
93 QVector<QTreeWidgetItem*> namespace_items;
95 for (
const QString& group : namespaces)
98 QTreeWidgetItem* current_item =
nullptr;
99 if (namespace_items.empty())
101 QList<QTreeWidgetItem*> items =
_signal_tree->findItems(group, Qt::MatchExactly);
102 if (!items.empty()) current_item = items.front();
107 for (
int i = 0; i < namespace_items.back()->childCount(); ++i)
109 if (namespace_items.back()->child(i)->text(0) == group)
111 current_item = namespace_items.back()->child(i);
119 QTreeWidgetItem* item =
new QTreeWidgetItem;
120 if (namespace_items.empty())
123 namespace_items.back()->addChild(item);
124 item->setText(0, group);
125 namespace_items.push_back(item);
130 namespace_items.push_back(current_item);
136 int dimension = signal_data.
signal->header.value_dimension;
138 if (dimension == 0)
return;
140 QTreeWidgetItem* item =
new QTreeWidgetItem;
141 if (namespace_items.empty())
144 namespace_items.back()->addChild(item);
156 item->setText(0, signal_data.
namespaces.back());
158 for (
int i = 0; i < dimension; ++i)
161 QTreeWidgetItem* subitem =
new QTreeWidgetItem;
162 item->addChild(subitem);
184 QString groupname =
"data_" + dtime.toString(
"yyyy_MM_dd_hh_mm_ss");
190 QVBoxLayout* layout =
new QVBoxLayout;
191 layout->setContentsMargins(15, 0, 0, 0);
192 layout->addItem(current_tree);
194 QString title = dtime.toString(
"dd.MM.yyyy hh:mm:ss");
198 group->setContextMenuPolicy(Qt::CustomContextMenu);
200 group->connect(group, &QTreeWidget::customContextMenuRequested,
203 group->
groupBox()->setLayout(layout);
219 QTreeWidget* tree =
nullptr;
230 [id](
const std::tuple<CollapsableGroupBox*, QWidget*, int> item) {
return id == std::get<2>(item); });
233 group_box = std::get<0>(*group_it);
234 tree =
static_cast<QTreeWidget*
>(std::get<1>(*group_it));
241 QStringList namespaces;
245 QTreeWidgetItem* item =
nullptr;
246 QTreeWidgetItem* candidate =
nullptr;
250 for (
int n = 0;
n < namespaces.size() + 1; ++
n)
256 no_items = tree->topLevelItemCount();
258 no_items = item->childCount();
262 for (
int i = 0; i < no_items; ++i)
264 QTreeWidgetItem* child = (
n == 0) ? tree->topLevelItem(i) : item->child(i);
270 if (signal_widget->
key().compare(key) == 0)
282 if (
n < namespaces.size() && child->text(0).compare(namespaces[
n]) == 0)
284 if (namespaces.size() == n + 1)
299 if (!candidate)
return;
302 QTreeWidgetItem* parent = candidate->parent();
303 QTreeWidgetItem* parent_candidate =
nullptr;
304 while (parent !=
nullptr)
306 if (parent->childCount() > 1)
break;
307 parent_candidate = parent;
308 parent = parent->parent();
311 if (parent_candidate)
312 delete parent_candidate;
317 if (group_box && group_it !=
_recent_signals.end() && tree->topLevelItemCount() == 0)
319 int task_id = std::get<2>(*group_it);
320 group_box->deleteLater();
331 [tree](
const std::tuple<CollapsableGroupBox*, QWidget*, int> item) {
return tree == std::get<1>(item); });
332 if (group_it !=
_recent_signals.end()) task_id = std::get<2>(*group_it);
334 if (id_out) *id_out = task_id;
339 const QTreeWidgetItem* parent = item->parent();
340 QString name = item->text(0);
341 while (parent !=
nullptr)
344 parent = parent->parent();
355 [tree](
const std::tuple<CollapsableGroupBox*, QWidget*, int> item) {
return tree == std::get<1>(item); });
356 if (group_it !=
_recent_signals.end()) task_id = std::get<2>(*group_it);
367 QTreeWidgetItem* parent = item->parent();
368 QString name = item->text(0);
369 while (parent !=
nullptr)
372 parent = parent->parent();
384 QAction* restore_param_action =
new QAction(tr(
"Restore Parameters"),
this);
385 connect(restore_param_action, &QAction::triggered, [
this, task_id]() {
386 if (QMessageBox::Yes ==
387 QMessageBox(QMessageBox::Information,
"Restore Parameters",
"Do you really want to restore parameters?",
388 QMessageBox::Yes | QMessageBox::No)
394 menu.addAction(restore_param_action);
399 QMenu* menu_export = menu.addMenu(tr(
"Export to ..."));
410 if (exporter_in_factory->isSupportingSignalGroup())
412 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
413 connect(export_group_action, &QAction::triggered, [
this, signal_group, exporter_in_factory]() {
415 exporter_in_factory->getInstance();
416 QString format_name = QString::fromStdString(exporter->getFormatName());
417 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
419 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
421 exporter->exportSignalGroup(filename, (*signal_group));
423 menu_export->addAction(export_group_action);
430 QAction* remove_action =
new QAction(tr(
"Remove Signals"),
this);
431 connect(remove_action, &QAction::triggered, [
this, task_id]() {
_signal_helper->clearSeries(task_id); });
432 menu.addAction(remove_action);
434 menu.exec(group->mapToGlobal(point));
444 QTreeWidgetItem* item = tree->itemAt(point);
457 QAction* remove_action =
new QAction(tr(
"Remove Signal"),
this);
458 connect(remove_action, &QAction::triggered, [
this, tree, item]() {
removeSignal(tree, item); });
459 menu.addAction(remove_action);
469 QMenu* menu_export = menu.addMenu(tr(
"Export to ..."));
481 if (exporter_in_factory->isSupportingSignalGroup())
483 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
484 connect(export_group_action, &QAction::triggered, [
this, signal_group, exporter_in_factory]() {
488 QString format_name = QString::fromStdString(exporter->getFormatName());
489 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
490 std::string
filename = QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix,
491 format_name +
" File (* " + file_suffix +
")")
493 exporter->exportSignalGroup(filename, (*signal_group));
495 menu_export->addAction(export_group_action);
516 QAction* remove_action =
new QAction(tr(
"Remove Signals"),
this);
517 connect(remove_action, &QAction::triggered, [
this, tree, item]() {
removeSignal(tree, item); });
518 menu.addAction(remove_action);
521 menu.exec(tree->mapToGlobal(point));
528 int signal_value_idx = signal_widget.
valueIdx();
529 if (!signal_data)
return;
561 if (matrix_set_signal)
593 if (!ts_signal)
return;
597 QMenu* menu_normalization = menu.addMenu(tr(
"Normalization"));
600 QAction* normalize_firstval_action =
new QAction(tr(
"Normalize by First Value"),
this);
601 connect(normalize_firstval_action, &QAction::triggered,
603 menu_normalization->addAction(normalize_firstval_action);
606 QAction* normalize_absmax_action =
new QAction(tr(
"Normalize by Absolute Maximum"),
this);
607 connect(normalize_absmax_action, &QAction::triggered, [ts_signal, signal_value_idx]() {
610 menu_normalization->addAction(normalize_absmax_action);
613 QAction* normalize_mean_action =
new QAction(tr(
"Normalize by Mean"),
this);
614 connect(normalize_mean_action, &QAction::triggered,
616 menu_normalization->addAction(normalize_mean_action);
621 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
627 if (exporter_in_factory->isSupportingTimeSeriesSignal())
629 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
630 connect(export_group_action, &QAction::triggered, [
this, ts_signal, exporter_in_factory]() {
632 exporter_in_factory->getInstance();
633 QString format_name = QString::fromStdString(exporter->getFormatName());
634 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
636 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
638 exporter->exportTimeSeriesSignal(filename, (*ts_signal));
640 menu_export_aux->addAction(export_group_action);
647 if (!ts_signal)
return;
649 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
655 if (exporter_in_factory->isSupportingTimeSeriesSignal())
657 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
658 connect(export_group_action, &QAction::triggered, [
this, ts_signal, exporter_in_factory]() {
660 exporter_in_factory->getInstance();
661 QString format_name = QString::fromStdString(exporter->getFormatName());
662 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
664 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
666 exporter->exportTimeSeriesSignal(filename, (*ts_signal));
668 menu_export_aux->addAction(export_group_action);
676 if (!ts_seq_signal)
return;
678 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
684 if (exporter_in_factory->isSupportingTimeSeriesSequenceSignal())
686 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
687 connect(export_group_action, &QAction::triggered, [
this, ts_seq_signal, exporter_in_factory]() {
689 exporter_in_factory->getInstance();
690 QString format_name = QString::fromStdString(exporter->getFormatName());
691 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
693 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
695 exporter->exportTimeSeriesSequenceSignal(filename, (*ts_seq_signal));
697 menu_export_aux->addAction(export_group_action);
704 if (!ts_seq_signal)
return;
706 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
712 if (exporter_in_factory->isSupportingTimeSeriesSequenceSignal())
714 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
715 connect(export_group_action, &QAction::triggered, [
this, ts_seq_signal, exporter_in_factory]() {
717 exporter_in_factory->getInstance();
718 QString format_name = QString::fromStdString(exporter->getFormatName());
719 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
721 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
723 exporter->exportTimeSeriesSequenceSignal(filename, (*ts_seq_signal));
725 menu_export_aux->addAction(export_group_action);
732 if (!ivs_signal)
return;
734 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
740 if (exporter_in_factory->isSupportingIndexedValuesSetSignal())
742 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
743 connect(export_group_action, &QAction::triggered, [
this, ivs_signal, exporter_in_factory]() {
745 exporter_in_factory->getInstance();
746 QString format_name = QString::fromStdString(exporter->getFormatName());
747 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
749 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
751 exporter->exportIndexedValuesSetSignal(filename, (*ivs_signal));
753 menu_export_aux->addAction(export_group_action);
760 if (!mat_signal)
return;
762 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
768 if (exporter_in_factory->isSupportingMatrixSignal())
770 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
771 connect(export_group_action, &QAction::triggered, [
this, mat_signal, exporter_in_factory]() {
773 exporter_in_factory->getInstance();
774 QString format_name = QString::fromStdString(exporter->getFormatName());
775 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
777 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
779 exporter->exportMatrixSignal(filename, (*mat_signal));
781 menu_export_aux->addAction(export_group_action);
788 if (!mat_set_signal)
return;
790 QMenu* menu_export_aux = menu_export ? menu_export : menu.addMenu(tr(
"Export to ..."));
796 if (exporter_in_factory->isSupportingMatrixSetSignal())
798 QAction* export_group_action =
new QAction(QString::fromStdString(exporter_in_factory->getFormatName()),
this);
799 connect(export_group_action, &QAction::triggered, [
this, mat_set_signal, exporter_in_factory]() {
801 exporter_in_factory->getInstance();
802 QString format_name = QString::fromStdString(exporter->getFormatName());
803 QString file_suffix = QString::fromStdString(exporter->getFileSuffix());
805 QFileDialog::getSaveFileName(
this,
"Save " + format_name,
"data" + file_suffix, format_name +
" File (* " + file_suffix +
")")
807 exporter->exportMatrixSetSignal(filename, (*mat_set_signal));
809 menu_export_aux->addAction(export_group_action);
#define PRINT_ERROR_NAMED(msg)
Signal for a sequence of time series objects.
QFrame * create_horizontal_line()
std::shared_ptr< TimeSeriesSignal > Ptr
std::shared_ptr< MatrixSetSignal > Ptr
static void extractNamespace(const QString &name, QStringList &namespaces)
std::shared_ptr< TimeSeriesSequenceSignal > Ptr
SignalInterface::Ptr signal
Signal containing a set of matrices.
QSet< int > active_indices
static Factory< DataExporterInterface > & getFactory()
Get access to the associated factory.
std::shared_ptr< SignalInterface > Ptr
static constexpr const int ALL_VALUES
std::shared_ptr< SignalHelper > Ptr
std::shared_ptr< MatrixSignal > Ptr
Time Series signal (trajectory resp. sequence of values w.r.t. time)
Signal containing a simple matrix.
static bool key2Name(const QString &key, QString &name, int &id)
constexpr const char SIGNAL_NAMESPACE_DELIMITER
Tree node containing a group of signals and a set of child tree nodes.
std::shared_ptr< IndexedValuesSetSignal > Ptr
std::shared_ptr< DataExporterInterface > Ptr
Signal containing values indexed by an integer (int to double[] map)
Tuple< Args... > make_tuple(Args... args)
Creates a tuple object, deducing the target type from the types of arguments.