Migrated old visualization of the bidding round statuses with donut charts from the legacy BeetRound project.

This commit is contained in:
2026-02-16 18:48:05 +01:00
parent f8201ead71
commit 1e64dda701
11 changed files with 551 additions and 49 deletions

View File

@ -11,7 +11,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools Charts)
set(TS_FILES ${TARGET_APP}_en_US.ts) set(TS_FILES ${TARGET_APP}_en_US.ts)
@ -38,6 +38,8 @@ if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
widgets/spinboxdelegate.h widgets/spinboxdelegate.cpp widgets/spinboxdelegate.h widgets/spinboxdelegate.cpp
widgets/biddingroundcontrol.h widgets/biddingroundcontrol.cpp widgets/biddingroundcontrol.h widgets/biddingroundcontrol.cpp
widgets/summarywidget.h widgets/summarywidget.cpp widgets/summarywidget.h widgets/summarywidget.cpp
widgets/biddingroundstatuswidget.h widgets/biddingroundstatuswidget.cpp
widgets/biddingroundprogresslayout.h widgets/biddingroundprogresslayout.cpp
) )
# Define target properties for Android with Qt 6 as: # Define target properties for Android with Qt 6 as:
# set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR # set_property(TARGET ${TARGET_APP} APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
@ -64,7 +66,7 @@ endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${TARGET_APP} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) target_link_libraries(${TARGET_APP} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Charts)
target_include_directories(${TARGET_APP} PRIVATE ${CORE_LIB_DIR}/) target_include_directories(${TARGET_APP} PRIVATE ${CORE_LIB_DIR}/)
target_link_libraries(${TARGET_APP} PRIVATE BeetRoundCore) target_link_libraries(${TARGET_APP} PRIVATE BeetRoundCore)

View File

@ -0,0 +1,44 @@
#include "biddingroundprogresslayout.h"
#include <QLabel>
#include <QProgressBar>
BiddingRoundProgressLayout::BiddingRoundProgressLayout(const int nCurrentBiddings,
const int nExpectedBiddings,
QWidget* parent)
: QHBoxLayout(parent)
, m_nCurrentBiddings(nCurrentBiddings)
, m_nExpectedBiddings(nExpectedBiddings) {
QLabel* nBidsText = new QLabel("Abgegeben:");
addWidget(nBidsText);
m_nBiddings1Label = new QLabel(QString::number(m_nCurrentBiddings));
addWidget(m_nBiddings1Label);
QLabel* nExpectedText = new QLabel("Erwartet:");
addWidget(nExpectedText);
m_nExpectedBidding1Label = new QLabel(QString::number(m_nExpectedBiddings));
addWidget(m_nExpectedBidding1Label);
m_biddingRound1ProgressBar = new QProgressBar(parent);
m_biddingRound1ProgressBar->setMinimum(0);
m_biddingRound1ProgressBar->setMaximum(m_nExpectedBiddings);
m_biddingRound1ProgressBar->setValue(m_nCurrentBiddings);
addWidget(m_biddingRound1ProgressBar);
}
void BiddingRoundProgressLayout::setCurrentBiddings(const int value) {
m_nCurrentBiddings = value;
const QString bidCountString = QString::number(value);
m_nBiddings1Label->setText(bidCountString);
m_biddingRound1ProgressBar->setValue(value);
}
void BiddingRoundProgressLayout::setExpectedBiddings(const int value) {
m_nExpectedBiddings = value;
const QString expectedBiddingsString = QString::number(value);
m_nExpectedBidding1Label->setText(expectedBiddingsString);
m_biddingRound1ProgressBar->setMaximum(value);
}

View File

@ -0,0 +1,28 @@
#ifndef BIDDINGROUNDPROGRESSLAYOUT_H
#define BIDDINGROUNDPROGRESSLAYOUT_H
#include <QHBoxLayout>
class QLabel;
class QProgressBar;
class BiddingRoundProgressLayout : public QHBoxLayout {
Q_OBJECT
public:
BiddingRoundProgressLayout(const int nCurrentBiddings,
const int nExpectedBiddings,
QWidget* parent = nullptr);
void setCurrentBiddings(const int value);
void setExpectedBiddings(const int value);
private:
int m_nCurrentBiddings;
int m_nExpectedBiddings;
QLabel* m_nBiddings1Label = nullptr;
QLabel* m_nExpectedBidding1Label = nullptr;
QProgressBar* m_biddingRound1ProgressBar = nullptr;
};
#endif // BIDDINGROUNDPROGRESSLAYOUT_H

View File

@ -0,0 +1,110 @@
#include "biddingroundstatuswidget.h"
#include <QChartView>
#include <QLabel>
#include <QPieSeries>
#include <QVBoxLayout>
BiddingRoundStatusWidget::BiddingRoundStatusWidget(const QString& title,
const int placedBiddings,
const int expectedBiddings,
const int financialNeed,
const int currentSum,
const qreal currentAverage,
QWidget* parent)
: QWidget{parent}
, m_title(title)
, m_financialNeed(financialNeed)
, m_currentSum(currentSum) {
m_moneyDonutSeries = new QPieSeries();
m_moneyDonutSeries->setHoleSize(0.35);
const QString sumText = QString("Summe: %1 €").arg(currentSum);
m_sumSlice = m_moneyDonutSeries->append(sumText, currentSum);
m_sumSlice->setLabelVisible();
const int currentGap = m_financialNeed - currentSum;
const QString gapText = QString("offen: %1 €").arg(currentGap);
m_gapSlice = m_moneyDonutSeries->append(gapText, currentGap);
m_gapSlice->setLabelVisible();
m_chartView = new QChartView();
m_chartView->setMinimumWidth(100);
// m_chartView->setMaximumWidth(500);
m_chartView->setRenderHint(QPainter::Antialiasing);
m_chartView->chart()->setTitle(m_title);
m_chartView->chart()->addSeries(m_moneyDonutSeries);
m_chartView->chart()->legend()->setAlignment(Qt::AlignBottom);
m_chartView->chart()->setTheme(QChart::ChartThemeBlueCerulean);
m_chartView->chart()->legend()->setFont(QFont("Arial", 8));
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(m_chartView, 5);
QBoxLayout* progressLayout = createProgressLayout(placedBiddings, expectedBiddings);
layout->addLayout(progressLayout);
/// bidding average
QHBoxLayout* averageLayout = new QHBoxLayout();
m_biddingAverageDescription = new QLabel("Durchschnittsgebot: ");
const QString currencyString = createCurrencyString(currentAverage);
m_biddingAverageValue = new QLabel(currencyString);
averageLayout->addWidget(m_biddingAverageDescription);
averageLayout->addWidget(m_biddingAverageValue);
layout->addLayout(averageLayout);
setLayout(layout);
}
void BiddingRoundStatusWidget::onExpectedBiddingsChanged(const int nExpected) {
m_biddingRoundProgress->setExpectedBiddings(nExpected);
}
void BiddingRoundStatusWidget::onNPlacedBiddingsChanged(const int nPlaced) {
m_biddingRoundProgress->setCurrentBiddings(nPlaced);
}
void BiddingRoundStatusWidget::onBiddingSumChanged(const int sum) {
m_currentSum = sum;
updateDonutChart();
}
void BiddingRoundStatusWidget::onBiddingAverageChanged(const qreal average) {
if (m_biddingAverageValue) {
m_biddingAverageValue->setText(createCurrencyString(average));
}
}
void BiddingRoundStatusWidget::onFinancialNeedChanged(const int financialNeed) {
m_financialNeed = financialNeed;
updateDonutChart();
}
QBoxLayout* BiddingRoundStatusWidget::createProgressLayout(const int nPlaced, const int nExpected) {
QVBoxLayout* progressLayout = new QVBoxLayout();
m_biddingRoundProgress = new BiddingRoundProgressLayout(nPlaced, nExpected);
progressLayout->addLayout(m_biddingRoundProgress);
return progressLayout;
}
void BiddingRoundStatusWidget::updateDonutChart() {
int currentGap;
if (m_currentSum < m_financialNeed) {
currentGap = m_financialNeed - m_currentSum;
} else {
currentGap = 0;
}
const QString sumText = QString("Summe: %1 €").arg(m_currentSum);
m_sumSlice->setValue(m_currentSum);
m_sumSlice->setLabel(sumText);
const QString gapText = QString("offen: %1 €").arg(currentGap);
m_gapSlice->setValue(currentGap);
m_gapSlice->setLabel(gapText);
const bool gapLabelVisible = currentGap != 0;
m_gapSlice->setLabelVisible(gapLabelVisible);
}
QString BiddingRoundStatusWidget::createCurrencyString(const qreal value) const {
return QString::number(value) + "";
}

View File

@ -0,0 +1,53 @@
#ifndef BIDDINGROUNDSTATUSWIDGET_H
#define BIDDINGROUNDSTATUSWIDGET_H
#include "biddingroundprogresslayout.h"
#include <QWidget>
class QBoxLayout;
class QChartView;
class QPieSeries;
class QPieSlice;
class BiddingRoundStatusWidget : public QWidget {
Q_OBJECT
public:
explicit BiddingRoundStatusWidget(const QString& title,
const int placedBiddings,
const int expectedBiddings,
const int financialNeed,
const int currentSum,
const qreal currentAverage,
QWidget* parent = nullptr);
public slots:
void onExpectedBiddingsChanged(const int nExpected);
void onNPlacedBiddingsChanged(const int nPlaced);
void onBiddingSumChanged(const int sum);
void onBiddingAverageChanged(const qreal average);
void onFinancialNeedChanged(const int financialNeed);
signals:
private:
QString m_title;
int m_financialNeed;
int m_currentSum;
QChartView* m_chartView = nullptr;
QPieSeries* m_moneyDonutSeries = nullptr;
QPieSlice* m_sumSlice = nullptr;
QPieSlice* m_gapSlice = nullptr;
QLabel* m_biddingAverageDescription = nullptr;
QLabel* m_biddingAverageValue = nullptr;
BiddingRoundProgressLayout* m_biddingRoundProgress = nullptr;
QBoxLayout* createProgressLayout(const int nPlaced, const int nExpected);
void updateDonutChart();
QString createCurrencyString(const qreal value) const;
};
#endif // BIDDINGROUNDSTATUSWIDGET_H

View File

@ -1,5 +1,7 @@
#include "summarywidget.h" #include "summarywidget.h"
#include "biddingroundstatuswidget.h"
#include <QLabel> #include <QLabel>
#include <QProperty> #include <QProperty>
#include <QSpinBox> #include <QSpinBox>
@ -11,20 +13,7 @@ SummaryWidget::SummaryWidget(std::shared_ptr<ModelSummary> modelSummary, QWidget
: QWidget{parent} : QWidget{parent}
, m_modelSummary(modelSummary) { , m_modelSummary(modelSummary) {
/// Layouting /// Layouting
QVBoxLayout* mainLayout = new QVBoxLayout(this); QVBoxLayout* mainLayout = new QVBoxLayout(this);
QHBoxLayout* headerLayout = new QHBoxLayout();
/// bindable (proof of concept) properties
QLabel* rowCountLabel = new QLabel("Row count:");
m_rowCountValueLabel = new QLabel("");
headerLayout->addWidget(rowCountLabel);
headerLayout->addWidget(m_rowCountValueLabel);
QHBoxLayout* nExpectedBiddingsLayout = new QHBoxLayout();
QLabel* nExpectedBiddingsLabel = new QLabel("Expected biddings:");
m_nExpectedBiddingsValueLabel = new QLabel("");
nExpectedBiddingsLayout->addWidget(nExpectedBiddingsLabel);
nExpectedBiddingsLayout->addWidget(m_nExpectedBiddingsValueLabel);
/// monthly need /// monthly need
QHBoxLayout* footerLayout = new QHBoxLayout(); QHBoxLayout* footerLayout = new QHBoxLayout();
@ -39,35 +28,122 @@ SummaryWidget::SummaryWidget(std::shared_ptr<ModelSummary> modelSummary, QWidget
footerLayout->addWidget(m_financialNeedBox); footerLayout->addWidget(m_financialNeedBox);
footerLayout->addStretch(1); footerLayout->addStretch(1);
mainLayout->addLayout(headerLayout); QBoxLayout* roundsLayout = createBiddingOverviewLayout();
mainLayout->addLayout(nExpectedBiddingsLayout); mainLayout->addLayout(roundsLayout);
mainLayout->addLayout(footerLayout); mainLayout->addLayout(footerLayout);
mainLayout->setSpacing(50);
setLayout(mainLayout); setLayout(mainLayout);
setupBindableProperties(); setupConnections();
} }
void SummaryWidget::onFinancialNeedChanged(int newFinancialNeed) { void SummaryWidget::onFinancialNeedChanged(int newFinancialNeed) {
// NEXT implement reaction on financial need changes m_biddingStatus1->onFinancialNeedChanged(newFinancialNeed);
qCritical() << "Apply financial need changes!!!"; m_biddingStatus2->onFinancialNeedChanged(newFinancialNeed);
m_biddingStatus3->onFinancialNeedChanged(newFinancialNeed);
} }
void SummaryWidget::setupBindableProperties() { void SummaryWidget::onNExpectedBiddingChanged(int newNExpected) {
m_biddingStatus1->onExpectedBiddingsChanged(newNExpected);
m_biddingStatus2->onExpectedBiddingsChanged(newNExpected);
m_biddingStatus3->onExpectedBiddingsChanged(newNExpected);
}
void SummaryWidget::onNPlacedBiddingsChanged(const int roundNumber) {
switch (roundNumber) {
case 1:
m_biddingStatus1->onNPlacedBiddingsChanged(m_modelSummary->nPlacedBiddings1());
break;
case 2:
m_biddingStatus2->onNPlacedBiddingsChanged(m_modelSummary->nPlacedBiddings2());
break;
case 3:
m_biddingStatus3->onNPlacedBiddingsChanged(m_modelSummary->nPlacedBiddings3());
break;
default:
qWarning() << "Unknown round number:" << roundNumber;
break;
}
}
void SummaryWidget::onBiddingSumChanged(const int roundNumber) {
switch (roundNumber) {
case 1:
m_biddingStatus1->onBiddingSumChanged(m_modelSummary->biddingSum1());
break;
case 2:
m_biddingStatus2->onBiddingSumChanged(m_modelSummary->biddingSum2());
break;
case 3:
m_biddingStatus3->onBiddingSumChanged(m_modelSummary->biddingSum3());
break;
default:
qWarning() << "Unknown round number:" << roundNumber;
break;
}
}
void SummaryWidget::onBiddingAverageChanged(const int roundNumber) {
switch (roundNumber) {
case 1:
m_biddingStatus1->onBiddingAverageChanged(m_modelSummary->biddingAverage1());
break;
case 2:
m_biddingStatus2->onBiddingAverageChanged(m_modelSummary->biddingAverage2());
break;
case 3:
m_biddingStatus3->onBiddingAverageChanged(m_modelSummary->biddingAverage3());
break;
default:
qWarning() << "Unknown round number:" << roundNumber;
break;
}
}
QBoxLayout* SummaryWidget::createBiddingOverviewLayout() {
QHBoxLayout* layout = new QHBoxLayout();
const int expectedBiddings = m_modelSummary->nExpectedBiddings();
/// bidding round 1
const int placedBiddings1 = m_modelSummary->nPlacedBiddings1();
const int biddingSum1 = m_modelSummary->biddingSum1();
const qreal biddingAverage1 = m_modelSummary->biddingAverage1();
m_biddingStatus1 =
make_unique<BiddingRoundStatusWidget>("Bietrunde 1", placedBiddings1, expectedBiddings,
m_financialNeed, biddingSum1, biddingAverage1);
/// bidding round 2
const int placedBiddings2 = m_modelSummary->nPlacedBiddings2();
const int biddingSum2 = m_modelSummary->biddingSum2();
const qreal biddingAverage2 = m_modelSummary->biddingAverage2();
m_biddingStatus2 =
make_unique<BiddingRoundStatusWidget>("Bietrunde 2", placedBiddings2, expectedBiddings,
m_financialNeed, biddingSum2, biddingAverage2);
/// bidding round 3
const int placedBiddings3 = m_modelSummary->nPlacedBiddings3();
const int biddingSum3 = m_modelSummary->biddingSum3();
const qreal biddingAverage3 = m_modelSummary->biddingAverage3();
m_biddingStatus3 =
make_unique<BiddingRoundStatusWidget>("Bietrunde 3", placedBiddings3, expectedBiddings,
m_financialNeed, biddingSum3, biddingAverage3);
layout->addWidget(m_biddingStatus1.get());
layout->addWidget(m_biddingStatus2.get());
layout->addWidget(m_biddingStatus3.get());
return layout;
}
void SummaryWidget::setupConnections() {
// TODO figure out how to encapsulate each property binding into a dedicated function: // TODO figure out how to encapsulate each property binding into a dedicated function:
// "bindProperty(&bindable, &signal, &getter, widget)" // "bindProperty(&bindable, &signal, &getter, widget)"
/// nRows QObject::connect(m_modelSummary.get(), &ModelSummary::nExpectedBiddingsChanged,
QProperty<int> nRows(-1); [&]() { onNExpectedBiddingChanged(m_modelSummary->nExpectedBiddings()); });
QObject::connect(m_modelSummary.get(), &ModelSummary::rowCountChanged, [&]() { QObject::connect(m_modelSummary.get(), &ModelSummary::nPlacedBiddingsChanged, this,
m_rowCountValueLabel->setText(QString::number(m_modelSummary->rowCount())); &SummaryWidget::onNPlacedBiddingsChanged);
}); QObject::connect(m_modelSummary.get(), &ModelSummary::biddingSumChanged, this,
m_modelSummary->bindableRowCount().setBinding([&]() { return nRows.value(); }); &SummaryWidget::onBiddingSumChanged);
QObject::connect(m_modelSummary.get(), &ModelSummary::biddingAverageChanged, this,
/// nExpectedBiddings &SummaryWidget::onBiddingAverageChanged);
QProperty<int> nExpectedBiddings(-1);
QObject::connect(m_modelSummary.get(), &ModelSummary::nExpectedBiddingsChanged, [&]() {
m_nExpectedBiddingsValueLabel->setText(QString::number(m_modelSummary->nExpectedBiddings()));
});
m_modelSummary->bindableNExpectedBiddings().setBinding(
[&]() { return nExpectedBiddings.value(); });
} }

View File

@ -3,9 +3,11 @@
#include <QWidget> #include <QWidget>
class BiddingRoundStatusWidget;
class ModelSummary; class ModelSummary;
class QLabel; class QLabel;
class QSpinBox; class QSpinBox;
class QBoxLayout;
class SummaryWidget : public QWidget { class SummaryWidget : public QWidget {
Q_OBJECT Q_OBJECT
@ -15,10 +17,19 @@ class SummaryWidget : public QWidget {
private slots: private slots:
void onFinancialNeedChanged(int newFinancialNeed); void onFinancialNeedChanged(int newFinancialNeed);
void onNExpectedBiddingChanged(int newNExpected);
void onNPlacedBiddingsChanged(const int roundNumber);
void onBiddingSumChanged(const int roundNumber);
void onBiddingAverageChanged(const int roundNumber);
private: private:
std::shared_ptr<ModelSummary> m_modelSummary; std::shared_ptr<ModelSummary> m_modelSummary;
std::unique_ptr<BiddingRoundStatusWidget> m_biddingStatus1;
std::unique_ptr<BiddingRoundStatusWidget> m_biddingStatus2;
std::unique_ptr<BiddingRoundStatusWidget> m_biddingStatus3;
// TODO read from settings (maybe via model/core; maybe set in constructor) // TODO read from settings (maybe via model/core; maybe set in constructor)
const int m_financialNeed = 13942; const int m_financialNeed = 13942;
QSpinBox* m_financialNeedBox = nullptr; QSpinBox* m_financialNeedBox = nullptr;
@ -26,7 +37,9 @@ class SummaryWidget : public QWidget {
QLabel* m_rowCountValueLabel; QLabel* m_rowCountValueLabel;
QLabel* m_nExpectedBiddingsValueLabel; QLabel* m_nExpectedBiddingsValueLabel;
void setupBindableProperties(); /// functions
QBoxLayout* createBiddingOverviewLayout();
void setupConnections();
}; };
#endif // SUMMARYWIDGET_H #endif // SUMMARYWIDGET_H

View File

@ -10,6 +10,11 @@ ModelSummary::ModelSummary(std::shared_ptr<TableModel> model, QObject* parent)
// TODO ? use existing model signals (dataChanged(role),...) instead of special signals // TODO ? use existing model signals (dataChanged(role),...) instead of special signals
connect(m_model.get(), &TableModel::nExpectedBiddingsChanged, this, connect(m_model.get(), &TableModel::nExpectedBiddingsChanged, this,
&ModelSummary::nExpectedBiddingsChanged); &ModelSummary::nExpectedBiddingsChanged);
connect(m_model.get(), &TableModel::nPlacedBiddingsChanged, this,
&ModelSummary::nPlacedBiddingsChanged);
connect(m_model.get(), &TableModel::biddingSumChanged, this, &ModelSummary::biddingSumChanged);
connect(m_model.get(), &TableModel::biddingAverageChanged, this,
&ModelSummary::biddingAverageChanged);
} }
ModelSummary::~ModelSummary() {} ModelSummary::~ModelSummary() {}
@ -26,7 +31,14 @@ QBindable<int> ModelSummary::bindableRowCount() {
int ModelSummary::nExpectedBiddings() const { return m_model->nExpectedBiddings(); } int ModelSummary::nExpectedBiddings() const { return m_model->nExpectedBiddings(); }
QBindable<int> ModelSummary::bindableNExpectedBiddings() { int ModelSummary::nPlacedBiddings1() const { return m_model->nPlacedBiddings1(); }
m_nExpectedBiddings = m_model->nExpectedBiddings(); int ModelSummary::nPlacedBiddings2() const { return m_model->nPlacedBiddings2(); }
return &m_nExpectedBiddings; int ModelSummary::nPlacedBiddings3() const { return m_model->nPlacedBiddings3(); }
}
int ModelSummary::biddingSum1() const { return m_model->biddingSum1(); }
int ModelSummary::biddingSum2() const { return m_model->biddingSum2(); }
int ModelSummary::biddingSum3() const { return m_model->biddingSum3(); }
qreal ModelSummary::biddingAverage1() const { return m_model->biddingAverage1(); }
qreal ModelSummary::biddingAverage2() const { return m_model->biddingAverage2(); }
qreal ModelSummary::biddingAverage3() const { return m_model->biddingAverage3(); }

View File

@ -12,8 +12,6 @@ class ModelSummary : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged BINDABLE bindableRowCount) Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged BINDABLE bindableRowCount)
Q_PROPERTY(int nExpectedBiddings READ nExpectedBiddings NOTIFY nExpectedBiddingsChanged BINDABLE
bindableNExpectedBiddings)
public: public:
ModelSummary(shared_ptr<TableModel> model, QObject* parent = nullptr); ModelSummary(shared_ptr<TableModel> model, QObject* parent = nullptr);
@ -22,20 +20,30 @@ class ModelSummary : public QObject {
int rowCount() const; int rowCount() const;
QBindable<int> bindableRowCount(); QBindable<int> bindableRowCount();
int nExpectedBiddings() const; int nExpectedBiddings() const;
QBindable<int> bindableNExpectedBiddings(); int nPlacedBiddings1() const;
int nPlacedBiddings2() const;
int nPlacedBiddings3() const;
int biddingSum1() const;
int biddingSum2() const;
int biddingSum3() const;
qreal biddingAverage1() const;
qreal biddingAverage2() const;
qreal biddingAverage3() const;
signals: signals:
void rowCountChanged(); void rowCountChanged();
void nExpectedBiddingsChanged(); void nExpectedBiddingsChanged();
void nPlacedBiddingsChanged(const int roundNumber);
void biddingSumChanged(const int roundNumber);
void biddingAverageChanged(const int roundNumber);
private: private:
shared_ptr<TableModel> m_model; shared_ptr<TableModel> m_model;
Q_OBJECT_BINDABLE_PROPERTY(ModelSummary, int, m_rowCount, &ModelSummary::rowCountChanged); Q_OBJECT_BINDABLE_PROPERTY(ModelSummary, int, m_rowCount, &ModelSummary::rowCountChanged);
Q_OBJECT_BINDABLE_PROPERTY(ModelSummary,
int,
m_nExpectedBiddings,
&ModelSummary::nExpectedBiddingsChanged);
}; };
#endif // MODELSUMMARY_H #endif // MODELSUMMARY_H

View File

@ -291,6 +291,18 @@ void TableModel::onRowCountChanged(const QModelIndex& parent, int first, int las
} }
emit rowCountChanged(); emit rowCountChanged();
emit nExpectedBiddingsChanged(); emit nExpectedBiddingsChanged();
emit nPlacedBiddingsChanged(1);
emit nPlacedBiddingsChanged(2);
emit nPlacedBiddingsChanged(3);
emit biddingSumChanged(1);
emit biddingSumChanged(2);
emit biddingSumChanged(3);
emit biddingAverageChanged(1);
emit biddingAverageChanged(2);
emit biddingAverageChanged(3);
} }
int TableModel::nExpectedBiddings() const { int TableModel::nExpectedBiddings() const {
@ -303,6 +315,35 @@ int TableModel::nExpectedBiddings() const {
} }
return result; return result;
} }
int TableModel::nPlacedBiddings1() const { return nPlacedBiddings(Bidding1Role); }
int TableModel::nPlacedBiddings2() const { return nPlacedBiddings(Bidding2Role); }
int TableModel::nPlacedBiddings3() const { return nPlacedBiddings(Bidding3Role); }
int TableModel::biddingSum1() const { return biddingSum(Bidding1Role); }
int TableModel::biddingSum2() const { return biddingSum(Bidding2Role); }
int TableModel::biddingSum3() const { return biddingSum(Bidding3Role); }
qreal TableModel::biddingAverage1() const {
const UserRoles biddingRole = Bidding1Role;
const qreal averageBidding = averageBiddingAmount(biddingRole);
qInfo() << "average calculation (1):" << averageBidding;
return averageBidding;
}
qreal TableModel::biddingAverage2() const {
const UserRoles biddingRole = Bidding2Role;
const qreal averageBidding = averageBiddingAmount(biddingRole);
qInfo() << "average calculation (2):" << averageBidding;
return averageBidding;
}
qreal TableModel::biddingAverage3() const {
const UserRoles biddingRole = Bidding3Role;
const qreal averageBidding = averageBiddingAmount(biddingRole);
qInfo() << "average calculation (3):" << averageBidding;
return averageBidding;
}
void TableModel::execInsertItems(const int firstRow, const QList<ModelItemValues> valueList) { void TableModel::execInsertItems(const int firstRow, const QList<ModelItemValues> valueList) {
const int nRows = valueList.size(); const int nRows = valueList.size();
qDebug() << "Inserting" << nRows << "items..."; qDebug() << "Inserting" << nRows << "items...";
@ -339,7 +380,37 @@ void TableModel::execEditItemData(const int row, const QMap<int, QVariant>& chan
emit dataChanged(firstIndex, lastIndex, roles.toVector()); emit dataChanged(firstIndex, lastIndex, roles.toVector());
// NEXT check which roles are changed & trigger only changed properties // NEXT check which roles are changed & trigger only changed properties
emit nExpectedBiddingsChanged(); if (roles.contains(BiddingTypeRole) || roles.contains(ShareAmountRole)) {
emit nExpectedBiddingsChanged();
}
if (roles.contains(ShareAmountRole) || roles.contains(ShareTypeRole)) {
emit nPlacedBiddingsChanged(1);
emit nPlacedBiddingsChanged(2);
emit nPlacedBiddingsChanged(3);
emit biddingSumChanged(1);
emit biddingSumChanged(2);
emit biddingSumChanged(3);
emit biddingAverageChanged(1);
emit biddingAverageChanged(2);
emit biddingAverageChanged(3);
} else {
/// no changes to share amount or type, but maybe to the biddings:
if (roles.contains(Bidding1Role)) {
emit nPlacedBiddingsChanged(1);
emit biddingSumChanged(1);
emit biddingAverageChanged(1);
}
if (roles.contains(Bidding2Role)) {
emit nPlacedBiddingsChanged(2);
emit biddingSumChanged(2);
emit biddingAverageChanged(2);
}
if (roles.contains(Bidding3Role)) {
emit nPlacedBiddingsChanged(3);
emit biddingSumChanged(3);
emit biddingAverageChanged(3);
}
}
} }
} }
@ -435,3 +506,64 @@ bool TableModel::isItemEqualToItemValues(const QModelIndex& itemIndex,
return true; return true;
} }
} }
int TableModel::nPlacedBiddings(const UserRoles biddingRole) const {
int result = 0;
for (auto i = m_items.begin(), end = m_items.end(); i != end; ++i) {
int localBidding = (*i)->data(biddingRole).toInt();
if (localBidding > 0) {
result++;
}
}
return result;
}
int TableModel::biddingSum(const UserRoles biddingRole) const {
int result = 0;
for (auto i = m_items.begin(), end = m_items.end(); i != end; ++i) {
result += (*i)->data(biddingRole).toInt();
}
return result;
}
qreal TableModel::averageBiddingAmount(const UserRoles biddingRole) const {
qInfo() << "Calculating average bidding for role:" << ROLE_NAMES.value(biddingRole);
const qreal localTotalSharesWithBiddings = totalSharesWithBiddings(biddingRole);
if (localTotalSharesWithBiddings <= 0) {
qInfo() << "No biddings found. Aborting calculation...";
return 0;
}
const qreal localTotalBiddingAmount = biddingSum(biddingRole);
const qreal alternateBiddingAverage = localTotalBiddingAmount / localTotalSharesWithBiddings;
qDebug() << "Total bidding amount:" << localTotalBiddingAmount;
qDebug() << "Total bidding shares:" << localTotalSharesWithBiddings;
return alternateBiddingAverage;
}
qreal TableModel::totalSharesWithBiddings(const UserRoles biddingRole) const {
qreal result = 0;
for (auto i = m_items.begin(), end = m_items.end(); i != end; ++i) {
const qreal bidding = (*i)->data(biddingRole).toReal();
const qreal shareAmount = (*i)->data(ShareAmountRole).toReal();
const QString shareType = (*i)->data(ShareTypeRole).toString();
const bool isValid = bidding != 0 && shareAmount != 0;
if (isValid) {
// qInfo() << "Including entry in bidding average calculation. MailRole:"
// << (*i)->data(MailRole);
// qreal bidForWholeShare = 0;
if (shareType == "bezahlt") {
result += shareAmount;
} else if (shareType == "teils/teils") {
result += shareAmount / 2;
} else {
qInfo() << "Share type not 'bezahlt' nor 'teils/teils'. Will be ignored..";
qDebug() << "Share type:" << shareType;
continue;
}
}
}
qInfo() << "Biddings exist for " << result << "shares!";
return result;
}

View File

@ -56,9 +56,28 @@ class TableModel : public QAbstractTableModel {
const QList<ModelItemValues>& itemValuesList, const QList<ModelItemValues>& itemValuesList,
const QModelIndex& parentIndex = QModelIndex()); const QModelIndex& parentIndex = QModelIndex());
/// property functions
int nExpectedBiddings() const;
int nPlacedBiddings1() const;
int nPlacedBiddings2() const;
int nPlacedBiddings3() const;
int biddingSum1() const;
int biddingSum2() const;
int biddingSum3() const;
qreal biddingAverage1() const;
qreal biddingAverage2() const;
qreal biddingAverage3() const;
signals: signals:
void rowCountChanged(); void rowCountChanged();
void nExpectedBiddingsChanged();
void nPlacedBiddingsChanged(const int roundNumber);
void biddingSumChanged(const int roundNumber);
void biddingAverageChanged(const int roundNumber);
private slots: private slots:
void onRowCountChanged(const QModelIndex& parent, int first, int last); void onRowCountChanged(const QModelIndex& parent, int first, int last);
@ -81,6 +100,11 @@ class TableModel : public QAbstractTableModel {
QModelIndex searchItemIndex(const ModelItemValues givenItemValues) const; QModelIndex searchItemIndex(const ModelItemValues givenItemValues) const;
bool isItemEqualToItemValues(const QModelIndex& itemIndex, bool isItemEqualToItemValues(const QModelIndex& itemIndex,
const ModelItemValues givenItemValues) const; const ModelItemValues givenItemValues) const;
int nPlacedBiddings(const UserRoles biddingRole) const;
int biddingSum(const UserRoles biddingRole) const;
qreal averageBiddingAmount(const UserRoles biddingRole) const;
qreal totalSharesWithBiddings(const UserRoles biddingRole) const;
}; };
#endif // TABLEMODEL_H #endif // TABLEMODEL_H