8 #include "ui_curvelist_panel.h"
11 #include <QLayoutItem>
16 #include <QHeaderView>
17 #include <QFontDatabase>
18 #include <QMessageBox>
19 #include <QApplication>
22 #include <QStandardItem>
23 #include <QWheelEvent>
24 #include <QItemSelectionModel>
26 #include <QTreeWidget>
36 , _plot_data(mapped_plot_data)
39 , _transforms_map(mapped_math_plots)
40 , _column_width_dirty(true)
44 setFocusPolicy(Qt::ClickFocus);
49 auto layout1 =
new QHBoxLayout();
50 ui->listPlaceholder1->setLayout(layout1);
52 layout1->setMargin(0);
54 auto layout2 =
new QHBoxLayout();
55 ui->listPlaceholder2->setLayout(layout2);
57 layout2->setMargin(0);
61 int point_size = settings.value(
"FilterableListWidget/table_point_size", 9).toInt();
64 ui->splitter->setStretchFactor(0, 5);
65 ui->splitter->setStretchFactor(1, 1);
67 connect(
_custom_view->selectionModel(), &QItemSelectionModel::selectionChanged,
this,
70 connect(
_custom_view->verticalScrollBar(), &QScrollBar::valueChanged,
this,
73 connect(
_tree_view->verticalScrollBar(), &QScrollBar::valueChanged,
this,
89 ui->labelNumberDisplayed->setText(
"0 of 0");
94 QString plot_id = QString::fromStdString(plot_name);
102 auto FindInPlotData = [&](
auto& plot_data,
const std::string& plot_name) {
103 auto it = plot_data.find(plot_name);
104 if (it != plot_data.end())
106 auto& plot = it->second;
109 group_name = QString::fromStdString(plot.group()->name());
142 QColor default_color = view->palette().color(QPalette::Text);
145 std::function<
void(QTreeWidgetItem*, QColor,
bool)> ChangeColorAndStyle;
146 ChangeColorAndStyle = [&](QTreeWidgetItem* cell, QColor
color,
bool italic) {
147 cell->setForeground(0,
color);
148 auto font = cell->font(0);
150 cell->setFont(0, font);
151 for (
int c = 0; c < cell->childCount(); c++)
153 ChangeColorAndStyle(cell->child(c),
color,
italic);
158 for (
int c = 0; c < view->invisibleRootItem()->childCount(); c++)
160 ChangeColorAndStyle(view->invisibleRootItem()->child(c), default_color,
false);
164 auto ChangeGroupVisitor = [&](QTreeWidgetItem* cell) {
173 color_var.isValid() ? color_var.value<QColor>() : default_color;
176 bool italic = (style_var.isValid() && style_var.value<
bool>());
178 ChangeColorAndStyle(cell, text_color,
italic);
181 QVariant tooltip = it->second->attribute(
TOOL_TIP);
187 view->treeVisitor(ChangeGroupVisitor);
191 auto ChangeLeavesVisitor = [&](QTreeWidgetItem* cell) {
192 if (cell->childCount() == 0)
194 const std::string& curve_name =
199 auto GetTextColor = [&](
auto& plot_data,
const std::string& curve_name) {
200 auto it = plot_data.find(curve_name);
201 if (it != plot_data.end())
203 auto& series = it->second;
205 if (color_var.isValid())
207 cell->setForeground(0, color_var.value<QColor>());
214 bool italic = (style_var.isValid() && style_var.value<
bool>());
217 QFont font = cell->font(0);
219 cell->setFont(0, font);
221 if (series.isTimeseries() ==
false)
236 view->treeVisitor(ChangeLeavesVisitor);
257 if (event->key() == Qt::Key_Delete)
269 settings.setValue(
"FilterableListWidget/table_point_size", point_size);
286 auto default_foreground =
_custom_view->palette().foreground();
288 auto FormattedNumber = [](
double value) {
290 int prec = settings.value(
"Preferences::precision", 3).toInt();
291 QString num_text = QString::number(value,
'f', prec);
292 if (num_text.contains(
'.'))
294 int idx = num_text.length() - 1;
295 while (num_text[idx] ==
'0')
300 if (num_text[idx] ==
'.')
303 return num_text +
" ";
306 auto GetValue = [&](
const std::string& name) -> QString {
311 auto& plot_data = it->second;
315 return FormattedNumber(val.value());
324 auto& plot_data = it->second;
328 auto str_view = val.value();
329 char last_byte = str_view.data()[str_view.size() - 1];
330 if (last_byte ==
'\0')
332 return QString::fromLocal8Bit(str_view.data(), str_view.size() - 1);
336 return QString::fromLocal8Bit(str_view.data(), str_view.size());
346 const int vertical_height = tree_view->visibleRegion().boundingRect().height();
348 auto DisplayValue = [&](QTreeWidgetItem* cell) {
351 if (!curve_name.isEmpty())
353 auto rect = cell->treeWidget()->visualItemRect(cell);
355 if (rect.bottom() < 0 || cell->isHidden())
359 if (rect.top() > vertical_height)
366 QString str_value = GetValue(curve_name.toStdString());
367 cell->setText(1, str_value);
372 tree_view->setViewResizeEnabled(
false);
373 tree_view->treeVisitor(DisplayValue);
380 static const QRegExp rx(
"(\\[\\d+\\])");
382 std::vector<std::pair<int, int>> index_positions;
384 while ((pos = rx.indexIn(str, pos)) != -1)
386 QString array_index = rx.cap(1);
388 std::pair<int, int> index = { pos + 1, array_index.size() - 2 };
389 index_positions.push_back(index);
390 pos += rx.matchedLength();
392 if (index_positions.empty())
397 QStringList out_list;
398 out_list.push_back(str);
400 for (
int i = index_positions.size() - 1; i >= 0; i--)
402 std::pair<int, int> index = index_positions[i];
403 str.remove(index.first, index.second);
404 out_list.push_front(str);
407 return out_list.join(
"/");
415 for (
int i = 0; i < parts.size(); i++)
418 if (i + 1 < parts.size())
434 int item_count = hc_1.second + hc_2.second;
435 int visible_count = item_count - hc_1.first - hc_2.first;
437 ui->labelNumberDisplayed->setText(QString::number(visible_count) + QString(
" of ") +
438 QString::number(item_count));
447 QMessageBox::StandardButton reply;
448 reply = QMessageBox::question(
nullptr, tr(
"Warning"),
449 tr(
"Do you really want to remove these data?\n"),
450 QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
452 if (reply == QMessageBox::Yes)
463 QString curve_name = QString::fromStdString(name);
473 std::string suggested_name;
477 if (curve_names.size() > 0)
479 suggested_name = (curve_names.front());
489 const QItemSelection&)
493 bool enabled = (selected.size() == 1);
494 ui->buttonEditCustom->setEnabled(enabled);
495 ui->buttonEditCustom->setToolTip(enabled ?
"Edit the selected custom timeserie" :
496 "Select a single custom Timeserie to Edit "
503 if (selected.size() == 1)
513 selected.insert(selected.end(), custom_select.begin(), custom_select.end());
526 ui->buttonAddCustom->setIcon(
LoadSvg(
":/resources/svg/add_tab.svg", theme));
527 ui->buttonEditCustom->setIcon(
LoadSvg(
":/resources/svg/pencil-edit.svg", theme));
528 ui->pushButtonTrash->setIcon(
LoadSvg(
":/resources/svg/trash.svg", theme));
530 auto ChangeIconVisitor = [&](QTreeWidgetItem* cell) {
531 const auto& curve_name = cell->data(0,
CustomRoles::Name).toString().toStdString();
536 auto& series = it->second;
537 if (series.isTimeseries() ==
false)
556 QMessageBox msgBox(
this);
557 msgBox.setWindowTitle(
"Warning. Can't be undone.");
558 msgBox.setText(tr(
"Delete data:\n\n"
559 "[Delete All]: remove timeseries and plots.\n"
560 "[Delete Points]: reset data points, but keep plots and "
564 QString theme = settings.value(
"StyleSheet::theme",
"light").toString();
566 QPushButton* buttonAll =
567 msgBox.addButton(tr(
"Delete All"), QMessageBox::DestructiveRole);
568 buttonAll->setIcon(
LoadSvg(
":/resources/svg/clear.svg"));
570 QPushButton* buttonPoints =
571 msgBox.addButton(tr(
"Delete Points"), QMessageBox::DestructiveRole);
572 buttonPoints->setIcon(
LoadSvg(
":/resources/svg/point_chart.svg"));
574 msgBox.addButton(QMessageBox::Cancel);
575 msgBox.setDefaultButton(QMessageBox::Cancel);
579 if (msgBox.clickedButton() == buttonAll)
583 else if (msgBox.clickedButton() == buttonPoints)