Fix a crash when viewing statistics including a score on a course which is not found.
[scorecard] / src / main-window.cpp
index 12f774a..1ace27b 100644 (file)
@@ -24,6 +24,7 @@ QString topDir("/opt");
 QString mmcDir("/media/mmc1");
 QString dataDirName("data");
 QString dataDir;
+QString userDataDir;
 QString imgDir(topDir + "/pixmaps");
 QString scoreFileName("score.xml");
 QString scoreFile;
@@ -34,20 +35,27 @@ QString masterFile;
 QString logFile("/tmp/scorecard.log");
 QString titleScores("ScoreCard - Scores");
 QString titleCourses("ScoreCard - Courses");
-QString settingsGroup("Settings");
-QString settingsHcp("hcp");
-QString settingsHomeClub("home-club");
-QString settingsDefaultCourses("default-courses");
 
 bool dateLessThan(const Score *s1, const Score *s2)
 {
-  return (*s1) < (*s2);
+    return (*s1) < (*s2);
 }
 
 bool dateMoreThan(const Score *s1, const Score *s2)
 {
-  return (*s1) > (*s2);
+    return (*s1) > (*s2);
 }
+
+bool scoreMoreThan(const Score *s1, const Score *s2)
+{
+    return s1->getTotal(Total).toInt() > s2->getTotal(Total).toInt();
+}
+
+bool scoreLessThan(const Score *s1, const Score *s2)
+{
+    return s1->getTotal(Total).toInt() < s2->getTotal(Total).toInt();
+}
+
 // Find score based on club and course name
 Score *MainWindow::findScore(QString & clubName, QString & courseName)
 {
@@ -145,84 +153,140 @@ void MainWindow::flushReadOnlyItems()
     }
 }
 
+void MainWindow::markHomeClub()
+{
+    TRACE;
+    QListIterator<Club *> i(clubList);
+    Club *c;
+
+    while (i.hasNext()) {
+        c = i.next();
+        if (c->getName() == conf.homeClub)
+            c->setHomeClub(true);
+        else
+            c->setHomeClub(false);
+    }
+}
+
+void MainWindow::sortScoreList()
+{
+    if (conf.sortOrder == "Date")
+        qSort(scoreList.begin(), scoreList.end(), dateMoreThan); 
+    else if (conf.sortOrder == "Score")
+        qSort(scoreList.begin(), scoreList.end(), scoreLessThan); 
+}
 
 MainWindow::MainWindow(QMainWindow *parent): QMainWindow(parent)
 {
-  resize(800, 480);
+    resize(800, 480);
 
 #ifdef Q_WS_MAEMO_5
-  setAttribute(Qt::WA_Maemo5StackedWindow);
+    setAttribute(Qt::WA_Maemo5StackedWindow);
 #endif
 
-  loadSettings();
+    loadSettings();
+
+    centralWidget = new QWidget(this);
 
-  centralWidget = new QWidget(this);
+    setCentralWidget(centralWidget);
 
-  setCentralWidget(centralWidget);
+    loadScoreFile(scoreFile, scoreList);
+    if (conf.defaultCourses == "Yes")
+        loadClubFile(masterFile, clubList, true);
+    loadClubFile(clubFile, clubList);
+    markHomeClub();
 
-  loadScoreFile(scoreFile, scoreList);
-  if (conf.defaultCourses == "Yes")
-      loadClubFile(masterFile, clubList, true);
-  loadClubFile(clubFile, clubList);
+    // Sort the scores based on settings
+    sortScoreList();
 
-  // Sort the scores based on dates
-  qSort(scoreList.begin(), scoreList.end(), dateMoreThan); 
-  createActions();
-  createMenus();
+    createActions();
+    createMenus();
 
-  createListView(scoreList, clubList);
+    createListView(scoreList, clubList);
 
-  createLayoutList(centralWidget);
+    createLayoutList(centralWidget);
 
-  scoreWindow = new ScoreWindow(this);
-  courseWindow = new CourseWindow(this);
+    scoreWindow = new ScoreWindow(this);
+    courseWindow = new CourseWindow(this);
 }
 
 void MainWindow::loadSettings(void)
 {
     TRACE;
-  bool external = false;
+    bool external = false;
 
-  QDir mmc(mmcDir);
-  if (mmc.exists())
-    external = true;
+    QDir mmc(mmcDir);
+    if (mmc.exists())
+        external = true;
 
-  // TODO: make via user option, automatic will never work
-  external = false;
+    // TODO: make via user option, automatic will never work
+    external = false;
 
 #ifndef Q_WS_MAEMO_5
-  dataDir = "./" + dataDirName;
+    dataDir = "./" + dataDirName;
 #else
-  if (external) {
-    dataDir = mmcDir + "/" + appName + "/" + dataDirName;
-  }
-  else {
-    dataDir = topDir + "/" + appName + "/" + dataDirName;
-  }
+    if (external) {
+        dataDir = mmcDir + "/" + appName + "/" + dataDirName;
+    }
+    else {
+        dataDir = topDir + "/" + appName + "/" + dataDirName;
+    }
 #endif
-  scoreFile = dataDir + "/" + scoreFileName;
-  clubFile = dataDir + "/" + clubFileName;
-  masterFile = dataDir + "/" + masterFileName;
-
-  QDir dir(dataDir);
-  if (!dir.exists())
-    if (!dir.mkpath(dataDir)) {
-      qWarning() << "Unable to create: " + dataDir;
-      return;
+
+    // Use MyDoc directory to get automatic backup/restore 
+    userDataDir = QDir::homePath() + "/MyDocs/." + appName;
+    QDir dir(userDataDir);
+    if (!dir.exists())
+        if (!dir.mkpath(userDataDir)) {
+            qWarning() << "Unable to create: " + userDataDir;
+            return;
+        }
+
+    masterFile = dataDir + "/" + masterFileName;
+
+    // Store user data files under $HOME so they are not lost in
+    // re-flash
+    scoreFile = userDataDir + "/" + scoreFileName;
+    clubFile = userDataDir + "/" + clubFileName;
+
+    // Start of 0.19 migration
+    // Copy existing user data to new location
+    // 0.18 and earlier: score.xml and club.xml are in /opt/scorecard/data
+    // 0.19 and later: score.xml and club.xml are in /home/user/.scorecard
+    QString scoreFileOld = dataDir + "/" + scoreFileName;
+    QString clubFileOld = dataDir + "/" + clubFileName;
+
+    QFile file1(scoreFileOld);
+    QFile file2(clubFileOld);
+    QDir move;
+    if (file1.exists()) {
+        move.rename(scoreFileOld, scoreFile);
+        qDebug() << "Moved: " << scoreFileOld << "->" << scoreFile;
     }
-  qDebug() << "Data is at:" + dataDir;
+    if (file2.exists()) {
+        move.rename(clubFileOld, clubFile);
+        qDebug() << "Moved: " << clubFileOld << "->" << clubFile;
+    }
+    // End of 0.19 migration
+
+    qDebug() << "User data is at:" + userDataDir;
+
+    settings.beginGroup(settingsGroup);
+    conf.hcp = settings.value(settingsHcp);
+    conf.homeClub = settings.value(settingsHomeClub);
+    conf.sortOrder = settings.value(settingsSortOrder);
+    conf.defaultCourses = settings.value(settingsDefaultCourses);
+    settings.endGroup();
 
-  settings.beginGroup(settingsGroup);
-  conf.hcp = settings.value(settingsHcp);
-  conf.homeClub = settings.value(settingsHomeClub);
-  conf.defaultCourses = settings.value(settingsDefaultCourses);
-  settings.endGroup();
+    // Use default courses if no settings for that
+    if (!conf.defaultCourses.isValid())
+        conf.defaultCourses = "Yes";
 
-  // Use default courses if no settings for that
-  if (!conf.defaultCourses.isValid())
-      conf.defaultCourses = "Yes";
+    // Use date sort order if no settings for that
+    if (!conf.sortOrder.isValid())
+        conf.sortOrder = "Date";
 
-  qDebug() << "Settings: " << conf.hcp << conf.homeClub << conf.defaultCourses;
+    qDebug() << "Settings: " << conf.hcp << conf.homeClub << conf.sortOrder << conf.defaultCourses;
 }
 
 void MainWindow::saveSettings(void)
@@ -233,6 +297,8 @@ void MainWindow::saveSettings(void)
         settings.setValue(settingsHcp, conf.hcp);
     if (conf.homeClub.isValid())
         settings.setValue(settingsHomeClub, conf.homeClub);
+    if (conf.sortOrder.isValid())
+        settings.setValue(settingsSortOrder, conf.sortOrder);
     if (conf.defaultCourses.isValid())
         settings.setValue(settingsDefaultCourses, conf.defaultCourses);
     settings.endGroup();
@@ -400,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);
@@ -417,8 +483,8 @@ void MainWindow::newScore()
             Score *score = new Score(scores, clubName, courseName, date);
             scoreList << score;
 
-            // Sort the scores based on dates
-            qSort(scoreList.begin(), scoreList.end(), dateMoreThan); 
+            // Sort the scores based on settings
+            sortScoreList();
             // Save it
             saveScoreFile(scoreFile, scoreList);
             scoreListModel->update(scoreList);
@@ -437,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;
     }
 
@@ -664,8 +730,6 @@ void MainWindow::viewSettings()
         QString newValue = conf.defaultCourses.toString();
         saveSettings();
 
-        qDebug() << "Settings:" << oldValue << "->" << newValue;
-
         // Reload club list, or drop r/o courses from list
         if (oldValue == "Yes" && newValue == "No") {
             flushReadOnlyItems();
@@ -677,26 +741,31 @@ void MainWindow::viewSettings()
             courseListModel->update(clubList);
             list->update();
         }
+        // TODO: do these only if needed
+        markHomeClub();
+        sortScoreList();
+        scoreListModel->update(scoreList);
+        list->update();
     }
 }
 
 void MainWindow::loadScoreFile(QString &fileName, QList<Score *> &list)
 {
-  ScoreXmlHandler handler(list);
+    ScoreXmlHandler handler(list);
 
-  if (handler.parse(fileName))
-    qDebug() << "File loaded:" << fileName << " entries:" << list.size();
+    if (handler.parse(fileName))
+        qDebug() << "File loaded:" << fileName << " entries:" << list.size();
 }
 
 void MainWindow::saveScoreFile(QString &fileName, QList<Score *> &list)
 {
-  ScoreXmlHandler handler(list);
+    ScoreXmlHandler handler(list);
 
-  if (handler.save(fileName))
-    // TODO: banner
-    qDebug() << "File saved:" << fileName << " entries:" << list.size();
-  else
-    qWarning() << "Unable to save:" << fileName;
+    if (handler.save(fileName))
+        // TODO: banner
+        qDebug() << "File saved:" << fileName << " entries:" << list.size();
+    else
+        qWarning() << "Unable to save:" << fileName;
 }
 
 void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list, bool readOnly)
@@ -709,12 +778,11 @@ void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list, bool readO
 
 void MainWindow::saveClubFile(QString &fileName, QList<Club *> &list)
 {
-  ClubXmlHandler handler(list);
-
-  if (handler.save(fileName))
-    // TODO: banner
-    qDebug() << "File saved:" << fileName << " entries:" << list.size();
-  else
-    qWarning() << "Unable to save:" << fileName;
+    ClubXmlHandler handler(list);
 
+    if (handler.save(fileName))
+        // TODO: banner
+        qDebug() << "File saved:" << fileName << " entries:" << list.size();
+    else
+        qWarning() << "Unable to save:" << fileName;
 }