UI: Add Search Capability to Branch Selector (#814)

* Create sync-dev.yml

* Update selfdrive_tests.yaml

* Update sync-dev.yml

* Update sync-dev.yml

* Update sync-dev.yml

* add search capability in branch selector

* maybe i should remove test code

* include

* reduce needed includes

* add newline for eof

* no changes needed in upstream file

* not sure why this was here

* try to resolve merge conflicts for dev squash

* try to resolve merge conflict

* No need for this for the time being

---------

Co-authored-by: Discountchubbs <159560811+Discountchubbs@users.noreply.github.com>
Co-authored-by: Jason Wen <haibin.wen3@gmail.com>
Co-authored-by: DevTekVE <devtekve@gmail.com>
This commit is contained in:
Nayan
2025-05-30 06:06:50 -04:00
committed by GitHub
parent 31e22b0a1d
commit d9d32ebea2
4 changed files with 81 additions and 0 deletions
@@ -17,6 +17,19 @@
* @param parent Parent widget
*/
SoftwarePanelSP::SoftwarePanelSP(QWidget *parent) : SoftwarePanel(parent) {
// branch selector
QObject::disconnect(targetBranchBtn, nullptr, nullptr, nullptr);
connect(targetBranchBtn, &ButtonControlSP::clicked, [=]() {
InputDialog d(tr("Search Branch"), this, tr("Enter search keywords, or leave blank to list all branches."), false);
d.setMinLength(0);
const int ret = d.exec();
if (ret) {
searchBranches(d.text());
}
});
const auto current_model = GetActiveModelName();
currentModelLblBtn = new ButtonControlSP(tr("Current Model"), tr("SELECT"), current_model);
currentModelLblBtn->setValue(current_model);
@@ -205,3 +218,33 @@ void SoftwarePanelSP::showResetParamsDialog() {
params.remove("LiveTorqueParameters");
}
}
/**
* @brief Searches for available branches based on a query string, presents the results in a dialog,
* and updates the target branch if a selection is made.
*
* This function filters the list of branches based on the provided query, and displays the filtered branches in a selection dialog.
* If a branch is selected, the "UpdaterTargetBranch" parameter is updated and a check for updates is triggered.
* If no branches are found matching the query, an alert dialog is displayed.
*
* @param query The search query string.
*/
void SoftwarePanelSP::searchBranches(const QString &query) {
QStringList branches = QString::fromStdString(params.get("UpdaterAvailableBranches")).split(",");
QStringList results = searchFromList(query, branches);
results.sort();
if (results.isEmpty()) {
ConfirmationDialog::alert(tr("No branches found for keywords: %1").arg(query), this);
return;
}
QString selected_branch = MultiOptionDialog::getSelection(tr("Select a branch"), results, "", this);
if (!selected_branch.isEmpty()) {
params.put("UpdaterTargetBranch", selected_branch.toStdString());
targetBranchBtn->setValue(selected_branch);
checkForUpdates();
}
}
@@ -9,6 +9,7 @@
#include <QJsonObject>
#include "selfdrive/ui/sunnypilot/ui.h"
#include "selfdrive/ui/sunnypilot/qt/util.h"
#include "selfdrive/ui/qt/offroad/settings.h"
class SoftwarePanelSP final : public SoftwarePanel {
@@ -17,6 +18,9 @@ class SoftwarePanelSP final : public SoftwarePanel {
public:
explicit SoftwarePanelSP(QWidget *parent = nullptr);
private:
void searchBranches(const QString &query);
private:
QString GetActiveModelName();
void updateModelManagerState();
+32
View File
@@ -78,3 +78,35 @@ QMap<QString, QVariantMap> loadPlatformList() {
return _platforms;
}
/**
* @brief Searches a list of strings for elements containing all search terms in a query.
*
* The search is case-insensitive and normalizes both the query and the list elements
* using Unicode KD normalization before comparison. Non-alphanumeric characters are
* removed from the search terms before comparison.
*
* @param query The search query string. Multiple words can be separated by spaces.
* @param list The source list of strings to search.
* @return A list of strings from the input list that contain all of the search terms.
*/
QStringList searchFromList(const QString &query, const QStringList &list) {
if (query.isEmpty()) {
return list;
}
QStringList search_terms = query.simplified().toLower().split(" ", QString::SkipEmptyParts);
QStringList search_results;
for (const QString &element : list) {
if (std::all_of(search_terms.begin(), search_terms.end(), [&](const QString &term) {
QString normalized_term = term.normalized(QString::NormalizationForm_KD).toLower();
normalized_term.remove(QRegularExpression("[^a-zA-Z0-9\\s]"));
QString normalized_element = element.normalized(QString::NormalizationForm_KD).toLower();
return normalized_element.contains(normalized_term, Qt::CaseInsensitive);
})) {
search_results << element;
}
}
return search_results;
}
+2
View File
@@ -12,9 +12,11 @@
#include <QMap>
#include <QPainter>
#include <QRegularExpression>
#include <QWidget>
QString getUserAgent(bool sunnylink = false);
std::optional<QString> getSunnylinkDongleId();
std::optional<QString> getParamIgnoringDefault(const std::string &param_name, const std::string &default_value);
QMap<QString, QVariantMap> loadPlatformList();
QStringList searchFromList(const QString &query, const QStringList &list);