From a76429062140038c0bee13774c55e9e8fad82171 Mon Sep 17 00:00:00 2001 From: Sakari Poussa Date: Mon, 19 Jul 2010 18:37:50 +0300 Subject: [PATCH] Fix a crash when viewing statistics including a score on a course which is not found. --- scorecard.pro | 2 +- src/main-window.cpp | 4 +- src/score-dialog.cpp | 2 + src/stat-model.cpp | 321 +++++++++++++++++++++++++------------------------- 4 files changed, 168 insertions(+), 161 deletions(-) diff --git a/scorecard.pro b/scorecard.pro index a28297b..9c84851 100644 --- a/scorecard.pro +++ b/scorecard.pro @@ -10,7 +10,7 @@ CONFIG += qt debug TEMPLATE = app QT += xml maemo5 -#DEFINES += WANT_DEBUG +DEFINES += WANT_DEBUG RESOURCES = scorecard.qrc diff --git a/src/main-window.cpp b/src/main-window.cpp index 6cd05d3..1ace27b 100644 --- a/src/main-window.cpp +++ b/src/main-window.cpp @@ -466,7 +466,7 @@ void MainWindow::newScore() Club *club = findClub(clubName); if (!club) { - showNote(tr("Error: no such club")); + showNote(tr("No club")); return; } Course *course = club->getCourse(courseName); @@ -503,7 +503,7 @@ void MainWindow::editScore() course = findCourse(score->getClubName(), score->getCourseName()); if (!course || !score) { - qDebug() << "No score/course to edit"; + showNote(tr("No score or course to edit")); return; } diff --git a/src/score-dialog.cpp b/src/score-dialog.cpp index 20b839b..867c373 100644 --- a/src/score-dialog.cpp +++ b/src/score-dialog.cpp @@ -326,6 +326,8 @@ void ScoreDialog::init(Course *course, Score *score) table->setItem(ROW_SCORE_2, i-9, scoreItem); } } + // This - for some unknown reason - does not work ... + table->setInputMethodHints(Qt::ImhDigitsOnly); // Set focus to 1st cell table->setCurrentCell(ROW_SCORE, 0); diff --git a/src/stat-model.cpp b/src/stat-model.cpp index 9ce9526..c834717 100644 --- a/src/stat-model.cpp +++ b/src/stat-model.cpp @@ -14,199 +14,204 @@ StatModel::StatModel(QList &cList, QList &sList) : clubList(cList), scoreList(sList) { - update(); + TRACE; + update(); } int StatModel::rowCount(const QModelIndex & parent) const { - Q_UNUSED(parent); - return ROWS; + Q_UNUSED(parent); + return ROWS; } int StatModel::columnCount(const QModelIndex & parent) const { - Q_UNUSED(parent); - return COLS; + Q_UNUSED(parent); + return COLS; } QVariant StatModel::data(const QModelIndex & index, int role) const { - if (!index.isValid()) - return QVariant(); + if (!index.isValid()) + return QVariant(); - int row = index.row(); - int col = index.column(); + int row = index.row(); + int col = index.column(); - if (col >= stat.size()) - return QVariant(); + if (col >= stat.size()) + return QVariant(); - // - // ALIGNMENT - // - if (role == Qt::TextAlignmentRole ) { - return Qt::AlignCenter; - } - - // - // FONT - // - if (role == Qt::FontRole) { - QFont font; - font.setPointSize(fontSize); - return font; - } - // - // NUMBERS - // - if (role == Qt::DisplayRole) { - switch (row) { - case ROW_ROUNDS: - return stat.at(col)->rounds(); - case ROW_AVERAGE: - return stat.at(col)->average(); - case ROW_MIN: - return stat.at(col)->min(); - case ROW_MAX: - return stat.at(col)->max(); - case ROW_BIRDIE: - return stat.at(col)->birdies(); - case ROW_PAR: - return stat.at(col)->pars(); - case ROW_BOGEY: - return stat.at(col)->bogeys(); - case ROW_MORE: - return stat.at(col)->more(); + // + // ALIGNMENT + // + if (role == Qt::TextAlignmentRole ) { + return Qt::AlignCenter; + } + + // + // FONT + // + if (role == Qt::FontRole) { + QFont font; + font.setPointSize(fontSize); + return font; } - } - return QVariant(); + // + // NUMBERS + // + if (role == Qt::DisplayRole) { + switch (row) { + case ROW_ROUNDS: + return stat.at(col)->rounds(); + case ROW_AVERAGE: + return stat.at(col)->average(); + case ROW_MIN: + return stat.at(col)->min(); + case ROW_MAX: + return stat.at(col)->max(); + case ROW_BIRDIE: + return stat.at(col)->birdies(); + case ROW_PAR: + return stat.at(col)->pars(); + case ROW_BOGEY: + return stat.at(col)->bogeys(); + case ROW_MORE: + return stat.at(col)->more(); + } + } + return QVariant(); } QVariant StatModel::headerData(int section, Qt::Orientation orientation, int role) const { - // Only vertical header -- horizontal is hidden - if (role != Qt::DisplayRole) - return QVariant(); + // Only vertical header -- horizontal is hidden + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + // TODO: check when no or less data than cols + // HERE CRASH - if (orientation == Qt::Horizontal) { - // TODO: check when no or less data than cols - // HERE CRASH - - if (section < stat.size()) - return stat.at(section)->year(); - } - - if (orientation == Qt::Vertical) { - switch(section) { - case ROW_ROUNDS: - return QString("Rounds"); - case ROW_AVERAGE: - return QString("Average"); - case ROW_MIN: - return QString("Best"); - case ROW_MAX: - return QString("Worst"); - case ROW_BIRDIE: - return QString("Birdies"); - case ROW_PAR: - return QString("Pars"); - case ROW_BOGEY: - return QString("Bogeys"); - case ROW_MORE: - return QString("Double+"); + if (section < stat.size()) + return stat.at(section)->year(); } - } - return QVariant(); + if (orientation == Qt::Vertical) { + switch(section) { + case ROW_ROUNDS: + return QString("Rounds"); + case ROW_AVERAGE: + return QString("Average"); + case ROW_MIN: + return QString("Best"); + case ROW_MAX: + return QString("Worst"); + case ROW_BIRDIE: + return QString("Birdies"); + case ROW_PAR: + return QString("Pars"); + case ROW_BOGEY: + return QString("Bogeys"); + case ROW_MORE: + return QString("Double+"); + } + } + + return QVariant(); } // TODO: dup code from table-model.cpp Course *StatModel::findCourse(const QString &clubName, const QString &courseName) { - QListIterator i(clubList); - Club *c; - - while (i.hasNext()) { - c = i.next(); - if (c->getName() == clubName) { - return c->getCourse(courseName); + QListIterator i(clubList); + Club *c; + + while (i.hasNext()) { + c = i.next(); + if (c->getName() == clubName) { + return c->getCourse(courseName); + } } - } - return 0; + return 0; } void StatModel::update(void) { - QListIterator iScore(scoreList); - QMultiMap yearMap; - - // Create multi map with years as keys, scores as values - while (iScore.hasNext()) { - Score *score = iScore.next(); - QString year = score->getDate().split("-").at(0); - yearMap.insert(year, score); - } - // Create uniq list of years - QList yearList = yearMap.uniqueKeys(); - - // For each year collect the statistics - QListIterator iYear(yearList); - while (iYear.hasNext()) { - QString year = iYear.next(); - - StatItem *item = new StatItem; - item->setYear(year); - - QList scoresPerYear = yearMap.values(year); - QListIterator iScoresPerYear(scoresPerYear); + TRACE; + QListIterator iScore(scoreList); + QMultiMap yearMap; + + // Create multi map with years as keys, scores as values + while (iScore.hasNext()) { + Score *score = iScore.next(); + QString year = score->getDate().split("-").at(0); + yearMap.insert(year, score); + } + // Create uniq list of years + QList yearList = yearMap.uniqueKeys(); + + // For each year collect the statistics + QListIterator iYear(yearList); + while (iYear.hasNext()) { + QString year = iYear.next(); + + StatItem *item = new StatItem; + item->setYear(year); + + QList scoresPerYear = yearMap.values(year); + QListIterator iScoresPerYear(scoresPerYear); - item->setRounds(scoresPerYear.count()); - - // for each year, add score - int sum = 0; - int min = 200; - int max = 0; - int pars = 0; - int birdies = 0; - int bogeys = 0; - int more = 0; - while (iScoresPerYear.hasNext()) { - Score *s = iScoresPerYear.next(); - int tot = s->getTotal(Total).toInt(); - sum += tot; - - if (tot > max) - max = tot; - - if (tot < min) - min = tot; - - Course *c = findCourse(s->getClubName(), s->getCourseName()); - - for (int i = 0; i < 18; i++) { - int par = c->getPar(i).toInt(); - int shots = s->getScore(i).toInt(); + item->setRounds(scoresPerYear.count()); + + // for each year, add score + int sum = 0; + int min = 200; + int max = 0; + int pars = 0; + int birdies = 0; + int bogeys = 0; + int more = 0; + while (iScoresPerYear.hasNext()) { + Score *s = iScoresPerYear.next(); + int tot = s->getTotal(Total).toInt(); + sum += tot; + + if (tot > max) + max = tot; + + if (tot < min) + min = tot; + + Course *c = findCourse(s->getClubName(), s->getCourseName()); + if (!c) + // We have a score on a course which we don't have... + continue; + + for (int i = 0; i < 18; i++) { + int par = c->getPar(i).toInt(); + int shots = s->getScore(i).toInt(); - if (shots == (par - 1)) - birdies++; - else if (shots == par) - pars++; - else if (shots == (par + 1)) - bogeys++; - else if (shots >= (par + 2)) - more++; - } + if (shots == (par - 1)) + birdies++; + else if (shots == par) + pars++; + else if (shots == (par + 1)) + bogeys++; + else if (shots >= (par + 2)) + more++; + } + } + item->setBirdies(birdies); + item->setPars(pars); + item->setBogeys(bogeys); + item->setMore(more); + + int avg = sum / scoresPerYear.count(); + item->setAverage(avg); + item->setMin(min); + item->setMax(max); + + stat << item; } - item->setBirdies(birdies); - item->setPars(pars); - item->setBogeys(bogeys); - item->setMore(more); - - int avg = sum / scoresPerYear.count(); - item->setAverage(avg); - item->setMin(min); - item->setMax(max); - - stat << item; - } } -- 1.7.9.5