mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-17 07:12:08 +08:00
cabana: imporve series selector dialog (#27266)
* imporve series selector dialog * typo old-commit-hash: f4f081c56209a2fc0669e76e881821b43830462c
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QRubberBand>
|
||||
#include <QPushButton>
|
||||
#include <QToolBar>
|
||||
#include <QToolTip>
|
||||
#include <QtConcurrent>
|
||||
@@ -251,12 +252,14 @@ void ChartsWidget::resizeEvent(QResizeEvent *event) {
|
||||
}
|
||||
|
||||
void ChartsWidget::newChart() {
|
||||
SeriesSelector dlg(this);
|
||||
SeriesSelector dlg(tr("New Chart"), this);
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
QList<QStringList> series_list = dlg.series();
|
||||
if (!series_list.isEmpty()) {
|
||||
auto items = dlg.seletedItems();
|
||||
if (!items.isEmpty()) {
|
||||
auto c = createChart();
|
||||
c->addSeries(series_list);
|
||||
for (auto it : items) {
|
||||
c->addSeries(it->msg_id, it->sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,33 +428,24 @@ void ChartView::msgRemoved(uint32_t address) {
|
||||
}
|
||||
}
|
||||
|
||||
void ChartView::addSeries(const QList<QStringList> &series_list) {
|
||||
for (auto &s : series_list) {
|
||||
if (auto m = dbc()->msg(s[0])) {
|
||||
auto it = m->sigs.find(s[2]);
|
||||
if (it != m->sigs.end() && !hasSeries(s[0], &(it->second))) {
|
||||
addSeries(s[0], &(it->second));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChartView::manageSeries() {
|
||||
SeriesSelector dlg(this);
|
||||
SeriesSelector dlg(tr("Mange Chart"), this);
|
||||
for (auto &s : sigs) {
|
||||
dlg.addSeries(s.msg_id, msgName(s.msg_id), QString::fromStdString(s.sig->name));
|
||||
dlg.addSelected(s.msg_id, s.sig);
|
||||
}
|
||||
|
||||
int ret = dlg.exec();
|
||||
if (ret == QDialog::Accepted) {
|
||||
QList<QStringList> series_list = dlg.series();
|
||||
if (series_list.isEmpty()) {
|
||||
if (dlg.exec() == QDialog::Accepted) {
|
||||
auto items = dlg.seletedItems();
|
||||
if (items.isEmpty()) {
|
||||
emit remove();
|
||||
} else {
|
||||
addSeries(series_list);
|
||||
for (auto s : items) {
|
||||
if (!hasSeries(s->msg_id, s->sig)) {
|
||||
addSeries(s->msg_id, s->sig);
|
||||
}
|
||||
}
|
||||
for (auto it = sigs.begin(); it != sigs.end(); /**/) {
|
||||
bool exists = std::any_of(series_list.cbegin(), series_list.cend(), [&](auto &s) {
|
||||
return s[0] == it->msg_id && s[2] == it->sig->name.c_str();
|
||||
bool exists = std::any_of(items.cbegin(), items.cend(), [&](auto &s) {
|
||||
return s->msg_id == it->msg_id && s->sig == it->sig;
|
||||
});
|
||||
it = exists ? ++it : removeItem(it);
|
||||
}
|
||||
@@ -737,11 +731,9 @@ void ChartView::dropEvent(QDropEvent *event) {
|
||||
event->accept();
|
||||
} else {
|
||||
ChartView *source_chart = (ChartView *)event->source();
|
||||
QList<QStringList> series;
|
||||
for (auto &s : source_chart->sigs) {
|
||||
series.push_back({s.msg_id, msgName(s.msg_id), QString::fromStdString(s.sig->name)});
|
||||
addSeries(s.msg_id, s.sig);
|
||||
}
|
||||
addSeries(series);
|
||||
emit source_chart->remove();
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
@@ -836,40 +828,37 @@ void ChartView::handleMarkerClicked() {
|
||||
|
||||
// SeriesSelector
|
||||
|
||||
SeriesSelector::SeriesSelector(QWidget *parent) {
|
||||
setWindowTitle(tr("Manage Chart Series"));
|
||||
QHBoxLayout *contents_layout = new QHBoxLayout();
|
||||
SeriesSelector::SeriesSelector(QString title, QWidget *parent) : QDialog(parent) {
|
||||
setWindowTitle(title);
|
||||
QGridLayout *main_layout = new QGridLayout(this);
|
||||
|
||||
QVBoxLayout *left_layout = new QVBoxLayout();
|
||||
left_layout->addWidget(new QLabel(tr("Select Signals:")));
|
||||
|
||||
msgs_combo = new QComboBox(this);
|
||||
// left column
|
||||
main_layout->addWidget(new QLabel(tr("Available Signals")), 0, 0);
|
||||
main_layout->addWidget(msgs_combo = new QComboBox(this), 1, 0);
|
||||
msgs_combo->setEditable(true);
|
||||
msgs_combo->lineEdit()->setPlaceholderText(tr("Select Msg"));
|
||||
msgs_combo->lineEdit()->setPlaceholderText(tr("Select a msg..."));
|
||||
msgs_combo->setInsertPolicy(QComboBox::NoInsert);
|
||||
msgs_combo->completer()->setCompletionMode(QCompleter::PopupCompletion);
|
||||
msgs_combo->completer()->setFilterMode(Qt::MatchContains);
|
||||
|
||||
left_layout->addWidget(msgs_combo);
|
||||
sig_list = new QListWidget(this);
|
||||
sig_list->setSortingEnabled(true);
|
||||
sig_list->setToolTip(tr("Double click on an item to add signal to chart"));
|
||||
left_layout->addWidget(sig_list);
|
||||
main_layout->addWidget(available_list = new QListWidget(this), 2, 0);
|
||||
|
||||
QVBoxLayout *right_layout = new QVBoxLayout();
|
||||
right_layout->addWidget(new QLabel(tr("Chart Signals:")));
|
||||
chart_series = new QListWidget(this);
|
||||
chart_series->setSortingEnabled(true);
|
||||
chart_series->setToolTip(tr("Double click on an item to remove signal from chart"));
|
||||
right_layout->addWidget(chart_series);
|
||||
contents_layout->addLayout(left_layout);
|
||||
contents_layout->addLayout(right_layout);
|
||||
// buttons
|
||||
QVBoxLayout *btn_layout = new QVBoxLayout();
|
||||
QPushButton *add_btn = new QPushButton(utils::icon("chevron-right"), "", this);
|
||||
QPushButton *remove_btn = new QPushButton(utils::icon("chevron-left"), "", this);
|
||||
btn_layout->addStretch(0);
|
||||
btn_layout->addWidget(add_btn);
|
||||
btn_layout->addWidget(remove_btn);
|
||||
btn_layout->addStretch(0);
|
||||
main_layout->addLayout(btn_layout, 0, 1, 3, 1);
|
||||
|
||||
// right column
|
||||
main_layout->addWidget(new QLabel(tr("Selected Signals")), 0, 2);
|
||||
main_layout->addWidget(selected_list = new QListWidget(this), 1, 2, 2, 1);
|
||||
|
||||
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
QVBoxLayout *main_layout = new QVBoxLayout(this);
|
||||
main_layout->addLayout(contents_layout);
|
||||
main_layout->addWidget(buttonBox);
|
||||
main_layout->addWidget(buttonBox, 3, 2);
|
||||
|
||||
for (auto it = can->can_msgs.cbegin(); it != can->can_msgs.cend(); ++it) {
|
||||
if (auto m = dbc()->msg(it.key())) {
|
||||
@@ -877,56 +866,59 @@ SeriesSelector::SeriesSelector(QWidget *parent) {
|
||||
}
|
||||
}
|
||||
msgs_combo->model()->sort(0);
|
||||
msgs_combo->setCurrentIndex(-1);
|
||||
|
||||
QObject::connect(msgs_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, &SeriesSelector::updateAvailableList);
|
||||
QObject::connect(available_list, &QListWidget::currentRowChanged, [=](int row) { add_btn->setEnabled(row != -1); });
|
||||
QObject::connect(selected_list, &QListWidget::currentRowChanged, [=](int row) { remove_btn->setEnabled(row != -1); });
|
||||
QObject::connect(available_list, &QListWidget::itemDoubleClicked, this, &SeriesSelector::add);
|
||||
QObject::connect(selected_list, &QListWidget::itemDoubleClicked, this, &SeriesSelector::remove);
|
||||
QObject::connect(add_btn, &QPushButton::clicked, [this]() { if (auto item = available_list->currentItem()) add(item); });
|
||||
QObject::connect(remove_btn, &QPushButton::clicked, [this]() { if (auto item = selected_list->currentItem()) remove(item);});
|
||||
QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
QObject::connect(msgs_combo, SIGNAL(currentIndexChanged(int)), SLOT(msgSelected(int)));
|
||||
QObject::connect(sig_list, &QListWidget::itemDoubleClicked, this, &SeriesSelector::addSignal);
|
||||
QObject::connect(chart_series, &QListWidget::itemDoubleClicked, [](QListWidgetItem *item) { delete item; });
|
||||
|
||||
if (int index = msgs_combo->currentIndex(); index >= 0) {
|
||||
msgSelected(index);
|
||||
}
|
||||
}
|
||||
|
||||
void SeriesSelector::msgSelected(int index) {
|
||||
void SeriesSelector::add(QListWidgetItem *item) {
|
||||
auto it = (ListItem *)item;
|
||||
addItemToList(selected_list, it->msg_id, it->sig, true);
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SeriesSelector::remove(QListWidgetItem *item) {
|
||||
auto it = (ListItem *)item;
|
||||
if (it->msg_id == msgs_combo->currentData().toString()) {
|
||||
addItemToList(available_list, it->msg_id, it->sig);
|
||||
}
|
||||
delete item;
|
||||
}
|
||||
|
||||
void SeriesSelector::updateAvailableList(int index) {
|
||||
if (index == -1) return;
|
||||
available_list->clear();
|
||||
QString msg_id = msgs_combo->itemData(index).toString();
|
||||
sig_list->clear();
|
||||
if (auto m = dbc()->msg(msg_id)) {
|
||||
for (auto &[name, s] : m->sigs) {
|
||||
QStringList data({msg_id, m->name, name});
|
||||
QListWidgetItem *item = new QListWidgetItem(name, sig_list);
|
||||
item->setData(Qt::UserRole, data);
|
||||
sig_list->addItem(item);
|
||||
auto selected_items = seletedItems();
|
||||
for (auto &[name, s] : dbc()->msg(msg_id)->sigs) {
|
||||
bool is_selected = std::any_of(selected_items.begin(), selected_items.end(), [=, sig=&s](auto it) { return it->msg_id == msg_id && it->sig == sig; });
|
||||
if (!is_selected) {
|
||||
addItemToList(available_list, msg_id, &s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SeriesSelector::addSignal(QListWidgetItem *item) {
|
||||
QStringList data = item->data(Qt::UserRole).toStringList();
|
||||
addSeries(data[0], data[1], data[2]);
|
||||
}
|
||||
void SeriesSelector::addItemToList(QListWidget *parent, const QString id, const Signal *sig, bool show_msg_name) {
|
||||
QString text = QString("<span style=\"color:%0;\">■ </span> %1").arg(getColor(sig).name(), sig->name.c_str());
|
||||
if (show_msg_name) text += QString(" <font color=\"gray\">%0 %1</font>").arg(msgName(id), id);
|
||||
|
||||
void SeriesSelector::addSeries(const QString &id, const QString &msg_name, const QString &sig_name) {
|
||||
QStringList data({id, msg_name, sig_name});
|
||||
for (int i = 0; i < chart_series->count(); ++i) {
|
||||
if (chart_series->item(i)->data(Qt::UserRole).toStringList() == data) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
QListWidgetItem *new_item = new QListWidgetItem(chart_series);
|
||||
new_item->setData(Qt::UserRole, data);
|
||||
chart_series->addItem(new_item);
|
||||
QLabel *label = new QLabel(QString("%0 <font color=\"gray\">%1 %2</font>").arg(data[2]).arg(data[1]).arg(data[0]), chart_series);
|
||||
QLabel *label = new QLabel(text);
|
||||
label->setContentsMargins(5, 0, 5, 0);
|
||||
auto new_item = new ListItem(id, sig, parent);
|
||||
new_item->setSizeHint(label->sizeHint());
|
||||
chart_series->setItemWidget(new_item, label);
|
||||
parent->setItemWidget(new_item, label);
|
||||
}
|
||||
|
||||
QList<QStringList> SeriesSelector::series() {
|
||||
QList<QStringList> ret;
|
||||
for (int i = 0; i < chart_series->count(); ++i) {
|
||||
ret.push_back(chart_series->item(i)->data(Qt::UserRole).toStringList());
|
||||
}
|
||||
QList<SeriesSelector::ListItem *> SeriesSelector::seletedItems() {
|
||||
QList<SeriesSelector::ListItem *> ret;
|
||||
for (int i = 0; i < selected_list->count(); ++i) ret.push_back((ListItem *)selected_list->item(i));
|
||||
return ret;
|
||||
}
|
||||
|
||||
+15
-11
@@ -28,7 +28,6 @@ class ChartView : public QChartView {
|
||||
public:
|
||||
ChartView(QWidget *parent = nullptr);
|
||||
void addSeries(const QString &msg_id, const Signal *sig);
|
||||
void addSeries(const QList<QStringList> &series_list);
|
||||
void removeSeries(const QString &msg_id, const Signal *sig);
|
||||
bool hasSeries(const QString &msg_id, const Signal *sig) const;
|
||||
void updateSeries(const Signal *sig = nullptr, const std::vector<Event*> *events = nullptr, bool clear = true);
|
||||
@@ -157,19 +156,24 @@ private:
|
||||
};
|
||||
|
||||
class SeriesSelector : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SeriesSelector(QWidget *parent);
|
||||
void addSeries(const QString &id, const QString& msg_name, const QString &sig_name);
|
||||
QList<QStringList> series();
|
||||
struct ListItem : public QListWidgetItem {
|
||||
ListItem(const QString &msg_id, const Signal *sig, QListWidget *parent) : msg_id(msg_id), sig(sig), QListWidgetItem(parent) {}
|
||||
QString msg_id;
|
||||
const Signal *sig;
|
||||
};
|
||||
|
||||
private slots:
|
||||
void msgSelected(int index);
|
||||
void addSignal(QListWidgetItem *item);
|
||||
SeriesSelector(QString title, QWidget *parent);
|
||||
QList<ListItem *> seletedItems();
|
||||
inline void addSelected(const QString &id, const Signal *sig) { addItemToList(selected_list, id, sig, true); }
|
||||
|
||||
private:
|
||||
void updateAvailableList(int index);
|
||||
void addItemToList(QListWidget *parent, const QString id, const Signal *sig, bool show_msg_name = false);
|
||||
void add(QListWidgetItem *item);
|
||||
void remove(QListWidgetItem *item);
|
||||
|
||||
QComboBox *msgs_combo;
|
||||
QListWidget *sig_list;
|
||||
QListWidget *chart_series;
|
||||
QListWidget *available_list;
|
||||
QListWidget *selected_list;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user