Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserved selector #34105

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 73 additions & 24 deletions tools/cabana/streams/routes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,19 @@ class RouteListWidget : public QListWidget {
RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent) {
setWindowTitle(tr("Remote routes"));

auto all_routes_widget = new QWidget;
auto all_routes_layout = new QVBoxLayout(all_routes_widget);
all_routes_layout->addWidget(period_selector_ = new QComboBox(this));
all_routes_layout->addWidget(route_list_ = new RouteListWidget());

routes_type_selector_ = new QTabWidget(this);
routes_type_selector_->addTab(all_routes_widget, tr("&All"));
routes_type_selector_->addTab(preserved_route_list_ = new RouteListWidget, tr("&Preserved"));

QFormLayout *layout = new QFormLayout(this);
layout->addRow(tr("Device"), device_list_ = new QComboBox(this));
layout->addRow(tr("Duration"), period_selector_ = new QComboBox(this));
layout->addRow(route_list_ = new RouteListWidget(this));
layout->addRow(routes_type_selector_);

auto button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
layout->addRow(button_box);

Expand All @@ -49,7 +58,9 @@ RoutesDialog::RoutesDialog(QWidget *parent) : QDialog(parent) {
// Connect signals and slots
connect(device_list_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes);
connect(period_selector_, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &RoutesDialog::fetchRoutes);
connect(routes_type_selector_, &QTabWidget::currentChanged, this, &RoutesDialog::fetchRoutes);
connect(route_list_, &QListWidget::itemDoubleClicked, this, &QDialog::accept);
connect(preserved_route_list_, &QListWidget::itemDoubleClicked, this, &QDialog::accept);
QObject::connect(button_box, &QDialogButtonBox::accepted, this, &QDialog::accept);
QObject::connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);

Expand Down Expand Up @@ -79,45 +90,83 @@ void RoutesDialog::fetchRoutes() {
if (device_list_->currentIndex() == -1 || device_list_->currentData().isNull())
return;

route_list_->clear();
route_list_->setEmptyText(tr("Loading..."));

HttpRequest *http = new HttpRequest(this, !Hardware::PC());
QObject::connect(http, &HttpRequest::requestDone, this, &RoutesDialog::parseRouteList);
currentRoutesList()->clear();
currentRoutesList()->setEmptyText(tr("Loading..."));

// Construct URL with selected device and date range
auto dongle_id = device_list_->currentData().toString();
QDateTime current = QDateTime::currentDateTime();
QString url = QString("%1/v1/devices/%2/routes_segments?start=%3&end=%4")
.arg(CommaApi::BASE_URL).arg(dongle_id)
.arg(current.addDays(-(period_selector_->currentData().toInt())).toMSecsSinceEpoch())
.arg(current.toMSecsSinceEpoch());
QString url = QString("%1/v1/devices/%2")
.arg(CommaApi::BASE_URL)
.arg(dongle_id);

if(isPreservedTabSelected()) {
url += "/routes/preserved";
} else {
QDateTime current = QDateTime::currentDateTime();
url += QString("/routes_segments?start=%2&end=%3")
.arg(current.addDays(-(period_selector_->currentData().toInt())).toMSecsSinceEpoch())
.arg(current.toMSecsSinceEpoch());
}
pbassut marked this conversation as resolved.
Show resolved Hide resolved

HttpRequest *http = new HttpRequest(this, !Hardware::PC());
QObject::connect(
http,
&HttpRequest::requestDone,
this,
isPreservedTabSelected() ? &RoutesDialog::parsePreservedRouteList : &RoutesDialog::parseRouteList
);
http->sendRequest(url);
}

void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) {
void RoutesDialog::onFinish(RouteListWidget *list, bool success, const QDateTime &from, const QDateTime &to, QJsonValue fullName) {
if (success) {
for (const QJsonValue &route : QJsonDocument::fromJson(json.toUtf8()).array()) {
uint64_t start_time = route["start_time_utc_millis"].toDouble();
uint64_t end_time = route["end_time_utc_millis"].toDouble();
auto datetime = QDateTime::fromMSecsSinceEpoch(start_time);
auto item = new QListWidgetItem(QString("%1 %2min").arg(datetime.toString()).arg((end_time - start_time) / (1000 * 60)));
item->setData(Qt::UserRole, route["fullname"].toString());
route_list_->addItem(item);
}
QListWidgetItem *item = new QListWidgetItem(QString("%1 %2min").arg(from.toString()).arg(from.secsTo(to) / 60));
item->setData(Qt::UserRole, fullName.toString());
list->addItem(item);

// Select first route if available
if (route_list_->count() > 0) route_list_->setCurrentRow(0);
if (list->count() > 0) list->setCurrentRow(0);
} else {
QMessageBox::warning(this, tr("Error"), tr("Failed to fetch routes. Check your network connection."));
reject();
}
route_list_->setEmptyText(tr("No items"));
list->setEmptyText(tr("No items"));
sender()->deleteLater();
}

void RoutesDialog::parsePreservedRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) {
if (success) {
for (const QJsonValue &route : QJsonDocument::fromJson(json.toUtf8()).array()) {
QDateTime from = QDateTime::fromString(route["start_time"].toString(), Qt::ISODateWithMs);
QDateTime to = QDateTime::fromString(route["end_time"].toString(), Qt::ISODateWithMs);

onFinish(preserved_route_list_, success, from, to, route["fullname"]);
}
}
}

void RoutesDialog::parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err) {
if (success) {
for (const QJsonValue &route : QJsonDocument::fromJson(json.toUtf8()).array()) {
QDateTime from = QDateTime::fromMSecsSinceEpoch(route["start_time_utc_millis"].toDouble());
QDateTime to = QDateTime::fromMSecsSinceEpoch(route["end_time_utc_millis"].toDouble());

onFinish(route_list_, success, from, to, route["fullname"]);
}
}
}

void RoutesDialog::accept() {
if (auto current_item = route_list_->currentItem()) {
if (auto current_item = currentRoutesList()->currentItem()) {
route_ = current_item->data(Qt::UserRole).toString();
}
QDialog::accept();
}
pbassut marked this conversation as resolved.
Show resolved Hide resolved

bool RoutesDialog::isPreservedTabSelected() {
return routes_type_selector_->currentIndex() == 1;
}

RouteListWidget* RoutesDialog::currentRoutesList() {
return isPreservedTabSelected() ? preserved_route_list_ : route_list_;
}
8 changes: 8 additions & 0 deletions tools/cabana/streams/routes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include <QComboBox>
#include <QDialog>
#include <QTabWidget>
#include <QVBoxLayout>

pbassut marked this conversation as resolved.
Show resolved Hide resolved
#include "selfdrive/ui/qt/api.h"

Expand All @@ -15,12 +17,18 @@ class RoutesDialog : public QDialog {

protected:
void accept() override;
void onFinish(RouteListWidget *list, bool success, const QDateTime &from, const QDateTime &to, QJsonValue fullName);
void parseDeviceList(const QString &json, bool success, QNetworkReply::NetworkError err);
void parseRouteList(const QString &json, bool success, QNetworkReply::NetworkError err);
void parsePreservedRouteList(const QString &json, bool success, QNetworkReply::NetworkError err);
void fetchRoutes();
bool isPreservedTabSelected();
RouteListWidget* currentRoutesList();

QTabWidget *routes_type_selector_;
QComboBox *device_list_;
QComboBox *period_selector_;
RouteListWidget *preserved_route_list_;
RouteListWidget *route_list_;
QString route_;
};