From: Shane Jaroch Date: Mon, 26 Jan 2026 04:54:32 +0000 (-0500) Subject: allow deleting search history items, lint/format. X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=8d362c8ed0dfc1d91ecaddb4a4f56ff618cdf335;p=nutratech%2Fgui.git allow deleting search history items, lint/format. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b80074..f523a11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,8 @@ find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED) # Dynamic Test Discovery file(GLOB TEST_SOURCES "tests/test_*.cpp") +add_custom_target(build_tests) + foreach(TEST_SOURCE ${TEST_SOURCES}) get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE) @@ -61,6 +63,7 @@ foreach(TEST_SOURCE ${TEST_SOURCES}) target_link_libraries(${TEST_NAME} PRIVATE nutra_lib Qt${QT_VERSION_MAJOR}::Test) add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME}) + add_dependencies(build_tests ${TEST_NAME}) endforeach() diff --git a/Makefile b/Makefile index dc5d837..e0f41e2 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ clean: .PHONY: test test: release - $(CMAKE) --build $(BUILD_DIR) --target test_nutra --config Release + $(CMAKE) --build $(BUILD_DIR) --target build_tests --config Release cd $(BUILD_DIR) && $(CTEST) --output-on-failure -C Release .PHONY: run @@ -61,7 +61,7 @@ format: lint: config @echo "Linting..." @# Build test target first to generate MOC files for tests - @$(CMAKE) --build $(BUILD_DIR) --target test_nutra --config Debug 2>/dev/null || true + @$(CMAKE) --build $(BUILD_DIR) --target build_tests --config Debug 2>/dev/null || true @echo "Running cppcheck..." cppcheck --enable=warning,performance,portability \ --language=c++ --std=c++17 \ diff --git a/include/widgets/searchwidget.h b/include/widgets/searchwidget.h index 1088fa3..530533c 100644 --- a/include/widgets/searchwidget.h +++ b/include/widgets/searchwidget.h @@ -17,6 +17,7 @@ class SearchWidget : public QWidget { public: explicit SearchWidget(QWidget* parent = nullptr); + bool eventFilter(QObject* obj, QEvent* event) override; void reloadSettings(); @@ -29,10 +30,12 @@ private slots: void performSearch(); void onRowDoubleClicked(int row, int column); void onCustomContextMenu(const QPoint& pos); + void onHistoryContextMenu(const QPoint& pos); void onCompleterActivated(const QString& text); private: void addToHistory(int foodId, const QString& foodName); + void removeFromHistory(int index); void loadHistory(); void updateCompleterModel(); diff --git a/src/widgets/searchwidget.cpp b/src/widgets/searchwidget.cpp index 738f394..2b31aa3 100644 --- a/src/widgets/searchwidget.cpp +++ b/src/widgets/searchwidget.cpp @@ -1,10 +1,13 @@ #include "widgets/searchwidget.h" +#include #include #include #include +#include #include #include +#include #include #include #include @@ -33,6 +36,13 @@ SearchWidget::SearchWidget(QWidget* parent) : QWidget(parent) { historyCompleter->setCompletionMode(QCompleter::PopupCompletion); searchInput->setCompleter(historyCompleter); + QAbstractItemView* popup = historyCompleter->popup(); + popup->setContextMenuPolicy(Qt::CustomContextMenu); + popup->installEventFilter(this); + + connect(popup, &QAbstractItemView::customContextMenuRequested, this, + &SearchWidget::onHistoryContextMenu); + connect(historyCompleter, QOverload::of(&QCompleter::activated), this, &SearchWidget::onCompleterActivated); @@ -256,3 +266,51 @@ void SearchWidget::reloadSettings() { debounce = std::max(debounce, 250); searchTimer->setInterval(debounce); } + +bool SearchWidget::eventFilter(QObject* obj, QEvent* event) { + if (obj == historyCompleter->popup() && event->type() == QEvent::KeyPress) { + auto* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Delete) { + QModelIndex index = historyCompleter->popup()->currentIndex(); + if (index.isValid()) { + removeFromHistory(index.row()); + return true; + } + } + } + return QWidget::eventFilter(obj, event); +} + +void SearchWidget::onHistoryContextMenu(const QPoint& pos) { + QAbstractItemView* popup = historyCompleter->popup(); + QModelIndex index = popup->indexAt(pos); + if (!index.isValid()) return; + + QMenu menu(this); + QAction* deleteAction = menu.addAction("Remove from history"); + QAction* selectedAction = menu.exec(popup->viewport()->mapToGlobal(pos)); + + if (selectedAction == deleteAction) { + removeFromHistory(index.row()); + } +} + +void SearchWidget::removeFromHistory(int index) { + if (index < 0 || index >= recentHistory.size()) return; + + recentHistory.removeAt(index); + + // Save to settings + QSettings settings("NutraTech", "Nutra"); + QList list; + for (const auto& h : recentHistory) { + QVariantMap m; + m["id"] = h.id; + m["name"] = h.name; + m["timestamp"] = h.timestamp; + list.append(m); + } + settings.setValue("recentFoods", list); + + updateCompleterModel(); +}