From: Shane Jaroch Date: Wed, 21 Jan 2026 23:15:26 +0000 (-0500) Subject: better history X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=46ff83b60921276acff907395f3c8c9711bcd83c;p=nutratech%2Fgui.git better history --- diff --git a/include/widgets/searchwidget.h b/include/widgets/searchwidget.h index 9b109aa..2efe769 100644 --- a/include/widgets/searchwidget.h +++ b/include/widgets/searchwidget.h @@ -1,6 +1,7 @@ #ifndef SEARCHWIDGET_H #define SEARCHWIDGET_H +#include #include #include #include @@ -18,18 +19,31 @@ public: signals: void foodSelected(int foodId, const QString& foodName); void addToMealRequested(int foodId, const QString& foodName, double grams); + void searchStatus(const QString& msg); private slots: void performSearch(); void onRowDoubleClicked(int row, int column); void onCustomContextMenu(const QPoint& pos); + void showHistory(); private: + void addToHistory(int foodId, const QString& foodName); + void loadHistory(); + QLineEdit* searchInput; QPushButton* searchButton; + QPushButton* historyButton; QTableWidget* resultsTable; FoodRepository repository; QTimer* searchTimer; + + struct HistoryItem { + int id; + QString name; + QDateTime timestamp; + }; + QList recentHistory; }; #endif // SEARCHWIDGET_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4a80b85..b932814 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -91,6 +91,8 @@ void MainWindow::setupUi() { connect(searchWidget, &SearchWidget::foodSelected, this, [=](int foodId, const QString& foodName) { qDebug() << "Selected food:" << foodName << "(" << foodId << ")"; + // Determine if we are in analysis mode or just searching + // For now, simpler handling: detailsWidget->loadFood(foodId, foodName); tabs->setCurrentWidget(detailsWidget); }); @@ -101,6 +103,9 @@ void MainWindow::setupUi() { tabs->setCurrentWidget(mealWidget); }); + connect(searchWidget, &SearchWidget::searchStatus, this, + [=](const QString& msg) { dbStatusLabel->setText(msg); }); + // Analysis Tab detailsWidget = new DetailsWidget(this); tabs->addTab(detailsWidget, "Analyze"); @@ -117,8 +122,6 @@ void MainWindow::setupUi() { connect(detailsWidget, &DetailsWidget::addToMeal, this, [=](int foodId, const QString& foodName, double grams) { mealWidget->addFood(foodId, foodName, grams); - // Optional: switch tab? - // tabs->setCurrentWidget(mealWidget); }); // Connect Meal Builder -> Daily Log @@ -248,16 +251,19 @@ void MainWindow::updateRecentFileActions() { int numToShow = static_cast(qMin(static_cast(sortedFiles.size()), static_cast(MaxRecentFiles))); + QFontMetrics fontMetrics(recentFilesMenu->font()); + for (int i = 0; i < numToShow; ++i) { QVariantMap m = sortedFiles[i]; QString path = m["path"].toString(); QString type = m["type"].toString(); int version = m["version"].toInt(); - QString name = QFileInfo(path).fileName(); - // Format: "nt.sqlite3 (User v1)" - // Or per user request: "Display pragma version... for full transparency" - QString text = QString("&%1 %2 (%3 v%4)").arg(i + 1).arg(name).arg(type).arg(version); + // Elide path to ~400 pixels (roughly 50-60 chars depending on font) + QString elidedPath = fontMetrics.elidedText(path, Qt::ElideMiddle, 400); + + // Format: "/path/to/file... (User v9)" + QString text = QString("&%1 %2 (%3 v%4)").arg(i + 1).arg(elidedPath).arg(type).arg(version); recentFileActions[static_cast(i)]->setText(text); recentFileActions[static_cast(i)]->setData(path); diff --git a/src/widgets/searchwidget.cpp b/src/widgets/searchwidget.cpp index a4a0b80..7c5d19e 100644 --- a/src/widgets/searchwidget.cpp +++ b/src/widgets/searchwidget.cpp @@ -1,14 +1,16 @@ #include "widgets/searchwidget.h" #include +#include +#include #include #include #include #include +#include #include #include "widgets/weightinputdialog.h" - SearchWidget::SearchWidget(QWidget* parent) : QWidget(parent) { auto* layout = new QVBoxLayout(this); @@ -29,7 +31,14 @@ SearchWidget::SearchWidget(QWidget* parent) : QWidget(parent) { connect(searchButton, &QPushButton::clicked, this, &SearchWidget::performSearch); searchLayout->addWidget(searchInput); + searchButton = new QPushButton("Search", this); + connect(searchButton, &QPushButton::clicked, this, &SearchWidget::performSearch); searchLayout->addWidget(searchButton); + + historyButton = new QPushButton("History", this); + connect(historyButton, &QPushButton::clicked, this, &SearchWidget::showHistory); + searchLayout->addWidget(historyButton); + layout->addLayout(searchLayout); // Results table @@ -50,20 +59,29 @@ SearchWidget::SearchWidget(QWidget* parent) : QWidget(parent) { &SearchWidget::onCustomContextMenu); layout->addWidget(resultsTable); + + loadHistory(); } void SearchWidget::performSearch() { QString query = searchInput->text().trimmed(); if (query.length() < 2) return; + QElapsedTimer timer; + timer.start(); + resultsTable->setRowCount(0); std::vector results = repository.searchFoods(query); + int elapsed = timer.elapsed(); resultsTable->setRowCount(static_cast(results.size())); for (int i = 0; i < static_cast(results.size()); ++i) { const auto& item = results[i]; resultsTable->setItem(i, 0, new QTableWidgetItem(QString::number(item.id))); + resultsTable->setItem(i, 1, + new QTableWidgetItem(item.description)); // Fixed: Description Column + static const std::map groupAbbreviations = { {1100, "Vegetables"}, // Vegetables and Vegetable Products {600, "Soups/Sauces"}, // Soups, Sauces, and Gravies @@ -105,6 +123,9 @@ void SearchWidget::performSearch() { resultsTable->setItem(i, 5, new QTableWidgetItem(QString::number(item.flavCount))); resultsTable->setItem(i, 6, new QTableWidgetItem(QString::number(item.score))); } + + emit searchStatus( + QString("Search: matched %1 foods in %2 ms").arg(results.size()).arg(elapsed)); } void SearchWidget::onRowDoubleClicked(int row, int column) { @@ -113,7 +134,10 @@ void SearchWidget::onRowDoubleClicked(int row, int column) { QTableWidgetItem* descItem = resultsTable->item(row, 1); if (idItem != nullptr && descItem != nullptr) { - emit foodSelected(idItem->text().toInt(), descItem->text()); + int id = idItem->text().toInt(); + QString name = descItem->text(); + addToHistory(id, name); + emit foodSelected(id, name); } } @@ -136,6 +160,10 @@ void SearchWidget::onCustomContextMenu(const QPoint& pos) { QAction* selectedAction = menu.exec(resultsTable->viewport()->mapToGlobal(pos)); + if (selectedAction) { + addToHistory(foodId, foodName); + } + if (selectedAction == analyzeAction) { emit foodSelected(foodId, foodName); } else if (selectedAction == addToMealAction) { @@ -146,3 +174,64 @@ void SearchWidget::onCustomContextMenu(const QPoint& pos) { } } } + +void SearchWidget::addToHistory(int foodId, const QString& foodName) { + // Remove if exists to move to top + for (int i = 0; i < recentHistory.size(); ++i) { + if (recentHistory[i].id == foodId) { + recentHistory.removeAt(i); + break; + } + } + + HistoryItem item{foodId, foodName, QDateTime::currentDateTime()}; + recentHistory.prepend(item); + + // Limit to 50 + while (recentHistory.size() > 50) { + recentHistory.removeLast(); + } + + // 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); +} + +void SearchWidget::loadHistory() { + QSettings settings("NutraTech", "Nutra"); + QList list = settings.value("recentFoods").toList(); + recentHistory.clear(); + for (const auto& v : list) { + QVariantMap m = v.toMap(); + HistoryItem item; + item.id = m["id"].toInt(); + item.name = m["name"].toString(); + item.timestamp = m["timestamp"].toDateTime(); + recentHistory.append(item); + } +} + +void SearchWidget::showHistory() { + resultsTable->setRowCount(0); + resultsTable->setRowCount(recentHistory.size()); + + for (int i = 0; i < recentHistory.size(); ++i) { + const auto& item = recentHistory[i]; + resultsTable->setItem(i, 0, new QTableWidgetItem(QString::number(item.id))); + resultsTable->setItem(i, 1, new QTableWidgetItem(item.name)); + resultsTable->setItem(i, 2, new QTableWidgetItem("History")); + // Empty cols for nutrients etc since we don't store them in history + for (int c = 3; c < 7; ++c) { + resultsTable->setItem(i, c, new QTableWidgetItem("")); + } + } + emit searchStatus(QString("Showing %1 recent items").arg(recentHistory.size())); +}