From: Shane Jaroch Date: Mon, 26 Jan 2026 10:37:41 +0000 (-0500) Subject: some lints & UI fixes/updates X-Git-Url: https://git.nutra.tk/v1?a=commitdiff_plain;h=31951cba2e255723bda91e31e4f5d1bfd24803b6;p=nutratech%2Fgui.git some lints & UI fixes/updates --- diff --git a/include/widgets/detailswidget.h b/include/widgets/detailswidget.h index 230cb25..139c760 100644 --- a/include/widgets/detailswidget.h +++ b/include/widgets/detailswidget.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "db/foodrepository.h" @@ -35,6 +36,12 @@ private: int currentFoodId; QString currentFoodName; + + QCheckBox* hideEmptyCheckbox; + QToolButton* copyIdBtn; + + double calculateScaleMultiplier(const std::vector& nutrients); + void addNutrientRow(const Nutrient& nut, double multiplier, const std::map& rdas); }; #endif // DETAILSWIDGET_H diff --git a/src/widgets/detailswidget.cpp b/src/widgets/detailswidget.cpp index 173f813..25201f4 100644 --- a/src/widgets/detailswidget.cpp +++ b/src/widgets/detailswidget.cpp @@ -1,10 +1,13 @@ #include "widgets/detailswidget.h" +#include +#include #include #include #include #include #include +#include #include DetailsWidget::DetailsWidget(QWidget* parent) : QWidget(parent), currentFoodId(-1) { @@ -23,6 +26,17 @@ DetailsWidget::DetailsWidget(QWidget* parent) : QWidget(parent), currentFoodId(- connect(addButton, &QPushButton::clicked, this, &DetailsWidget::onAddClicked); headerLayout->addWidget(nameLabel); + + copyIdBtn = new QToolButton(this); + copyIdBtn->setText("Copy ID"); + copyIdBtn->setVisible(false); + connect(copyIdBtn, &QToolButton::clicked, this, [this]() { + if (currentFoodId != -1) { + QApplication::clipboard()->setText(QString::number(currentFoodId)); + } + }); + headerLayout->addWidget(copyIdBtn); + headerLayout->addStretch(); headerLayout->addWidget(addButton); layout->addLayout(headerLayout); @@ -41,6 +55,12 @@ DetailsWidget::DetailsWidget(QWidget* parent) : QWidget(parent), currentFoodId(- scaleCheckbox->setChecked(false); // Default off scaleLayout->addStretch(); + + hideEmptyCheckbox = new QCheckBox("Hide Empty", this); + hideEmptyCheckbox->setChecked(false); // Default show all + connect(hideEmptyCheckbox, &QCheckBox::toggled, this, &DetailsWidget::updateTable); + scaleLayout->addWidget(hideEmptyCheckbox); + scaleLayout->addWidget(scaleCheckbox); scaleLayout->addWidget(scaleSpinBox); layout->addLayout(scaleLayout); @@ -67,6 +87,7 @@ void DetailsWidget::loadFood(int foodId, const QString& foodName) { currentFoodName = foodName; nameLabel->setText(foodName + QString(" (ID: %1)").arg(foodId)); addButton->setEnabled(true); + copyIdBtn->setVisible(true); updateTable(); } @@ -78,73 +99,84 @@ void DetailsWidget::updateTable() { std::vector nutrients = repository.getFoodNutrients(currentFoodId); auto rdas = repository.getNutrientRdas(); - // Calculate Multiplier - double multiplier = 1.0; - if (scaleCheckbox->isChecked()) { - // Find calories (ID 208) - double kcalPer100g = 0; - for (const auto& n : nutrients) { - if (n.id == 208) { - kcalPer100g = n.amount; - break; - } + double multiplier = calculateScaleMultiplier(nutrients); + bool hideEmpty = hideEmptyCheckbox->isChecked(); + + for (const auto& nut : nutrients) { + double multiplierVal = nut.amount * multiplier; + + if (hideEmpty && multiplierVal < 0.01) { + continue; } - double target = scaleSpinBox->value(); - if (kcalPer100g > 0 && target > 0) { - multiplier = target / kcalPer100g; + addNutrientRow(nut, multiplier, rdas); + } +} + +double DetailsWidget::calculateScaleMultiplier(const std::vector& nutrients) { + if (!scaleCheckbox->isChecked()) return 1.0; + + // Find calories (ID 208) + double kcalPer100g = 0; + for (const auto& n : nutrients) { + if (n.id == 208) { + kcalPer100g = n.amount; + break; } } - // Mapping for easy lookup if needed, but vector iteration is fine - // We want to show ALL nutrients returned for the food? Or all nutrients tracked by RDA? - // The previous implementation showed all nutrients returned by getFoodNutrients. - // Let's stick to that, but enhance the ones that have RDAs. + double target = scaleSpinBox->value(); + if (kcalPer100g > 0 && target > 0) { + return target / kcalPer100g; + } + return 1.0; +} - nutrientsTable->setRowCount(static_cast(nutrients.size())); - for (int i = 0; i < static_cast(nutrients.size()); ++i) { - const auto& nut = nutrients[i]; - nutrientsTable->setItem(i, 0, new QTableWidgetItem(nut.description)); +void DetailsWidget::addNutrientRow(const Nutrient& nut, double multiplier, + const std::map& rdas) { + int row = nutrientsTable->rowCount(); + nutrientsTable->insertRow(row); - double rda = 0; - if (rdas.count(nut.id) != 0U) { - rda = rdas[nut.id]; - } + nutrientsTable->setItem(row, 0, new QTableWidgetItem(nut.description)); - double val = nut.amount * multiplier; - - // Progress Bar - auto* bar = new QProgressBar(); - bar->setRange(0, 100); - int pct = 0; - if (rda > 0) pct = static_cast((val / rda) * 100.0); - bar->setValue(std::min(pct, 100)); - bar->setTextVisible(true); - bar->setFormat(QString("%1%").arg(pct)); - - // Color logic - QString color = "#bdc3c7"; // Grey if no RDA - if (rda > 0) { - color = "#3498db"; // Blue - if (pct < 50) - color = "#f1c40f"; // Yellow - else if (pct > 150) - color = "#8e44ad"; // Purple - else if (pct >= 100) - color = "#2ecc71"; // Green - } - bar->setStyleSheet(QString("QProgressBar::chunk { background-color: %1; }").arg(color)); - nutrientsTable->setCellWidget(i, 1, bar); - - // Detail - QString detail; - if (rda > 0) { - detail = QString("%1 / %2 %3").arg(val, 0, 'f', 1).arg(rda, 0, 'f', 1).arg(nut.unit); - } else { - detail = QString("%1 %2").arg(val, 0, 'f', 1).arg(nut.unit); - } - nutrientsTable->setItem(i, 2, new QTableWidgetItem(detail)); + double rda = 0; + if (rdas.count(nut.id) != 0U) { + rda = rdas.at(nut.id); + } + + double val = nut.amount * multiplier; + + // Progress Bar + auto* bar = new QProgressBar(); + bar->setRange(0, 100); + int pct = 0; + if (rda > 0) pct = static_cast((val / rda) * 100.0); + bar->setValue(std::min(pct, 100)); + bar->setTextVisible(true); + bar->setFormat(QString("%1%").arg(pct)); + + // Color logic + QString color = "#bdc3c7"; // Grey if no RDA + if (rda > 0) { + color = "#3498db"; // Blue + if (pct < 50) + color = "#f1c40f"; // Yellow + else if (pct > 150) + color = "#8e44ad"; // Purple + else if (pct >= 100) + color = "#2ecc71"; // Green + } + bar->setStyleSheet(QString("QProgressBar::chunk { background-color: %1; }").arg(color)); + nutrientsTable->setCellWidget(row, 1, bar); + + // Detail + QString detail; + if (rda > 0) { + detail = QString("%1 / %2 %3").arg(val, 0, 'f', 1).arg(rda, 0, 'f', 1).arg(nut.unit); + } else { + detail = QString("%1 %2").arg(val, 0, 'f', 1).arg(nut.unit); } + nutrientsTable->setItem(row, 2, new QTableWidgetItem(detail)); } void DetailsWidget::onAddClicked() {