add regex search

This commit is contained in:
oleg 2026-04-13 07:08:38 +03:00
parent a9b4e4e7db
commit 22172309e1
5 changed files with 75 additions and 17 deletions

View File

@ -15,6 +15,7 @@ option(BUILD_SHARED_LIBS "Build using shared libraries" OFF)
include(cmake/dependencies.cmake)
project(canscope)
find_package(Boost REQUIRED COMPONENTS regex)
file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_executable(${CMAKE_PROJECT_NAME} ${SOURCES})
@ -30,5 +31,5 @@ target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${clipp_SOURCE_DIR}/include
)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ftxui::component ftxui::screen ftxui::dom tiny-process-library xlnt sqlite3_lib z ${Boost_LIBRARIES})
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ftxui::component ftxui::screen ftxui::dom tiny-process-library xlnt sqlite3_lib z Boost::regex ${Boost_LIBRARIES})

View File

@ -72,6 +72,7 @@ install_static: ## Install static binary to PREFIX/bin
docker-run: ## Build and run in Docker (works on Linux/Mac/Windows)
docker build -t $(DEV_IMAGE) -f docker/Dockerfile.dev .
docker run --rm -it \
-e TERM=xterm-256color \
-v $(CURDIR):/app \
-v $(SSH_DIR):/host_ssh:ro \
-v /etc/hosts:/etc/hosts:ro \

View File

@ -19,14 +19,25 @@
class CanIDUnit : public ftxui::ComponentBase {
public:
CanIDUnit(const std::string &iface, const std::string &canid, const std::string &protocol, size_t &spn_count, const std::vector<uint8_t> &data, ftxui::ScreenInteractive *screen,
signals_map_t &smap, ftxui::Component content, ftxui::Component container, ftxui::Component spn_settings_dialog, ftxui::Component cansettings_dialog, bool is_deployed,
bool is_verbose, bool is_brief, bool is_manual, std::string &, bool &, bool &canbus_parameters_export_shown, bool &filedialog_shown,
CanIDUnit(const std::string &iface, const std::string &canid, const std::string &protocol, size_t &spn_count,
const std::vector<uint8_t> &data, ftxui::ScreenInteractive *screen, signals_map_t &smap,
ftxui::Component content, ftxui::Component container, ftxui::Component spn_settings_dialog,
ftxui::Component cansettings_dialog, bool is_deployed, bool is_verbose, bool is_brief, bool is_manual,
std::string &, bool &, bool &canbus_parameters_export_shown, bool &filedialog_shown,
std::map<std::string, std::map<int32_t, ftxui::Component>> &spnSettingsFormMap,
spn_settings_map_t &spnSettingsMap);
inline const std::string &getIfaceName() const { return m_iface_; }
inline const std::string &getCanID() const { return m_canid_; }
inline std::string getLabel() const {
if (m_data_verbose_ && !m_data_verbose_->is_null() && m_data_verbose_->contains("Label")) {
return (*m_data_verbose_)["Label"].get<std::string>();
}
return {};
}
inline size_t getDataSize() const { return m_data_.size(); }
inline const std::vector<uint8_t> &getData() const { return m_data_; }
@ -37,8 +48,8 @@ public:
inline ftxui::Component getSpnSettingsForm() { return m_spnSettingsForm_; }
inline const auto &getParametersExportMap() const { return s_canbus_parameters_export_map_; }
void update(const can_frame_data_s &data, const can_frame_diff_s &diff,
std::shared_ptr<nlohmann::json> verbose, std::shared_ptr<nlohmann::json> brief);
void update(const can_frame_data_s &data, const can_frame_diff_s &diff, std::shared_ptr<nlohmann::json> verbose,
std::shared_ptr<nlohmann::json> brief);
bool OnEvent(ftxui::Event event) override;
@ -64,6 +75,8 @@ private:
static inline std::map<
/* canid */ std::string,
std::tuple</* deployed flag */ bool, /* has data flag */ bool,
/* Selected spns to export */ std::map</* spn name */ std::string, std::tuple</* deployed */ bool, /* selected */ bool, /* data */ nlohmann::json>>>>
/* Selected spns to export */
std::map</* spn name */ std::string,
std::tuple</* deployed */ bool, /* selected */ bool, /* data */ nlohmann::json>>>>
s_canbus_parameters_export_map_ = {};
};

View File

@ -392,6 +392,7 @@ int32_t main(int32_t argc, char *argv[]) {
source->request_stop();
}
}
if (candump_fd >= 0) {
::close(candump_fd);
candump_fd = -1;

View File

@ -3,6 +3,7 @@
#include "tagsettingrow.hpp"
#include "tagsettings.hpp"
#include <atomic>
#include <boost/regex.hpp>
#include <cstdint>
#include <ftxui/component/component.hpp>
#include <ftxui/component/component_base.hpp>
@ -24,10 +25,11 @@ ftxui::Component makeMainForm(ftxui::ScreenInteractive *screen, signals_map_t &s
explicit Impl(ftxui::ScreenInteractive *screen, signals_map_t &smap) {
static bool canbus_params_export_dialog_shown = false, file_dialog_shown = false,
canbus_player_dialog_shown = false, canplayer_is_ready = false;
;
static float focus_relative = 0.15f;
static float canbus_params_focus_relative = 0;
static std::string canid_active;
static std::string filter_text;
static size_t tags_count = 0u;
static std::unordered_map<std::string, std::shared_ptr<CanIDUnit>> canid_lookup;
static std::atomic<sqlite::database *> database_atomic{nullptr};
@ -129,10 +131,24 @@ ftxui::Component makeMainForm(ftxui::ScreenInteractive *screen, signals_map_t &s
canidsCont, ftxui::Container::Vertical({}), canbus_params_export_dialog, false, false, true,
false, canid_active, file_dialog_shown, canbus_params_export_dialog_shown,
file_dialog_shown, spnSettingsFormMap, tagSettingsMap);
auto unit = std::static_pointer_cast<CanIDUnit>(new_cmp);
unit->update(entry.data, entry.diff, entry.verbose, entry.brief);
canid_lookup[entry.canid] = unit;
canidsCont->Add(new_cmp);
canidsCont->Add(ftxui::Maybe(new_cmp, [unit]() -> bool {
if (filter_text.empty()) {
return true;
}
try {
boost::regex re(filter_text, boost::regex_constants::icase);
std::string subject = unit->getCanID() + " " + unit->getLabel();
return boost::regex_search(subject, re);
} catch (...) {
return true;
}
}));
}
}
});
@ -170,14 +186,40 @@ ftxui::Component makeMainForm(ftxui::ScreenInteractive *screen, signals_map_t &s
fmt::format(" Uptime: {} ", fmt::format("{:02}:{:02}:{:02}", hours, minutes, seconds)))});
}),
ftxui::Renderer([]() {
ftxui::Renderer([]() { return ftxui::separator(); }),
ftxui::Container::Horizontal({
ftxui::Input({
.content = &filter_text,
.placeholder = "regex filter ...",
.transform = [](ftxui::InputState state) -> ftxui::Element {
bool valid = true;
if (!filter_text.empty()) {
try {
boost::regex(filter_text, boost::regex_constants::icase);
} catch (...) {
valid = false;
}
}
state.element |= (!valid ? ftxui::color(ftxui::Color::Red) : ftxui::nothing) |
(state.focused ? ftxui::color(ftxui::Color::Cyan) : ftxui::nothing) |
(state.hovered ? ftxui::bold : ftxui::nothing);
return ftxui::hbox({
ftxui::separator(),
ftxui::filler(),
ftxui::separator(),
ftxui::text(" Search: [ "),
state.element |
(state.hovered || state.focused ? ftxui::bgcolor(ftxui::Color::Grey11)
: ftxui::nothing) |
ftxui::flex,
ftxui::text(" ]"),
}) |
ftxui::xflex;
ftxui::flex;
},
}),
}) | ftxui::flex,
ftxui::Renderer([]() { return ftxui::separator(); }),
ftxui::Checkbox({
.transform = [this](const ftxui::EntryState &state) -> ftxui::Element {