2 * Copyright (C) 2009 Sakari Poussa
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, version 2.
11 #include <QMaemo5InformationBox>
14 #include "score-common.h"
15 #include "main-window.h"
16 #include "score-dialog.h"
17 #include "course-dialog.h"
18 #include "stat-model.h"
19 #include "xml-dom-parser.h"
21 QString appName("scorecard");
22 QString topDir("/opt");
23 QString mmcDir("/media/mmc1");
24 QString dataDirName("data");
26 QString imgDir(topDir + "/pixmaps");
27 QString scoreFileName("score.xml");
29 QString clubFileName("club.xml");
31 QString logFile("/tmp/scorecard.log");
32 QString titleScores("ScoreCard - Scores");
33 QString titleCourses("ScoreCard - Courses");
35 bool dateLessThan(const Score *s1, const Score *s2)
40 bool dateMoreThan(const Score *s1, const Score *s2)
44 // Find score based on club and course name
45 Score *MainWindow::findScore(QString & clubName, QString & courseName)
47 QListIterator<Score *> i(scoreList);
52 if ((s->getClubName() == clubName) &&
53 (s->getCourseName() == courseName))
59 // Find club based on name
60 Club *MainWindow::findClub(QString &name)
62 QListIterator<Club *> i(clubList);
67 if (c->getName() == name)
73 // Find course based on club & course name
74 Course *MainWindow::findCourse(const QString &clubName,
75 const QString &courseName)
77 QListIterator<Club *> i(clubList);
82 if (c->getName() == clubName) {
83 return c->getCourse(courseName);
89 // Find course based on current selection on the list
90 // TODO: make sure this is only called when course list is the model...
91 Course *MainWindow::findCourse()
93 QModelIndex index = selectionModel->currentIndex();
94 const QAbstractItemModel *model = selectionModel->model();
95 QString str = model->data(index, Qt::DisplayRole).toString();
97 QStringList strList = str.split(",");
98 if (strList.count() != 2) {
99 showNote(tr("Invalid course selection"));
102 return findCourse(strList[0], strList[1]);
105 MainWindow::MainWindow(QMainWindow *parent): QMainWindow(parent)
110 setAttribute(Qt::WA_Maemo5StackedWindow);
115 centralWidget = new QWidget(this);
117 setCentralWidget(centralWidget);
119 loadScoreFile(scoreFile, scoreList);
120 loadClubFile(clubFile, clubList);
122 // Sort the scores based on dates
123 qSort(scoreList.begin(), scoreList.end(), dateMoreThan);
127 createListView(scoreList, clubList);
129 createLayoutList(centralWidget);
132 void MainWindow::loadSettings(void)
134 bool external = false;
140 // TODO: make via user option, automatic will never work
144 dataDir = "./" + dataDirName;
147 dataDir = mmcDir + "/" + appName + "/" + dataDirName;
150 dataDir = topDir + "/" + appName + "/" + dataDirName;
153 scoreFile = dataDir + "/" + scoreFileName;
154 clubFile = dataDir + "/" + clubFileName;
158 if (!dir.mkpath(dataDir)) {
159 qWarning() << "Unable to create: " + dataDir;
162 qDebug() << "Data is at:" + dataDir;
165 void MainWindow::createLayoutList(QWidget *parent)
167 QVBoxLayout * tableLayout = new QVBoxLayout;
168 tableLayout->addWidget(list);
170 QHBoxLayout *mainLayout = new QHBoxLayout(parent);
171 mainLayout->addLayout(tableLayout);
172 parent->setLayout(mainLayout);
175 void MainWindow::createListView(QList<Score *> &scoreList,
176 QList <Club *> &clubList)
178 list = new QListView(this);
180 scoreListModel = new ScoreListModel(scoreList, clubList);
181 courseListModel = new CourseListModel(clubList);
183 list->setStyleSheet(ScoreStyle::style());
185 list->setSelectionMode(QAbstractItemView::SingleSelection);
186 list->setProperty("FingerScrolling", true);
191 connect(list, SIGNAL(clicked(QModelIndex)),
192 this, SLOT(clickedList(QModelIndex)));
195 void MainWindow::listScores()
197 list->setModel(scoreListModel);
198 selectionModel = list->selectionModel();
199 updateTitleBar(titleScores);
202 void MainWindow::listCourses()
204 list->setModel(courseListModel);
205 selectionModel = list->selectionModel();
206 updateTitleBar(titleCourses);
209 void MainWindow::createActions()
211 newScoreAction = new QAction(tr("New Score"), this);
212 connect(newScoreAction, SIGNAL(triggered()), this, SLOT(newScore()));
214 newCourseAction = new QAction(tr("New Course"), this);
215 connect(newCourseAction, SIGNAL(triggered()), this, SLOT(newCourse()));
217 statAction = new QAction(tr("Statistics"), this);
218 connect(statAction, SIGNAL(triggered()), this, SLOT(viewStatistics()));
220 // Maemo5 style menu filters
221 filterGroup = new QActionGroup(this);
222 filterGroup->setExclusive(true);
224 listScoreAction = new QAction(tr("Scores"), filterGroup);
225 listScoreAction->setCheckable(true);
226 listScoreAction->setChecked(true);
227 connect(listScoreAction, SIGNAL(triggered()), this, SLOT(listScores()));
229 listCourseAction = new QAction(tr("Courses"), filterGroup);
230 listCourseAction->setCheckable(true);
231 connect(listCourseAction, SIGNAL(triggered()), this, SLOT(listCourses()));
234 void MainWindow::createMenus()
237 menu = menuBar()->addMenu("");
239 menu = menuBar()->addMenu("Menu");
242 menu->addAction(newScoreAction);
243 menu->addAction(newCourseAction);
244 menu->addAction(statAction);
245 menu->addActions(filterGroup->actions());
248 void MainWindow::updateTitleBar(QString & msg)
253 void MainWindow::showNote(QString msg)
256 QMaemo5InformationBox::information(this,
258 QMaemo5InformationBox::DefaultTimeout);
262 void MainWindow::clickedList(const QModelIndex &index)
264 int row = index.row();
266 const QAbstractItemModel *m = index.model();
267 if (m == scoreListModel) {
268 if (row < scoreList.count()) {
269 Score * score = scoreList.at(row);
270 Course * course = findCourse(score->getClubName(), score->getCourseName());
271 viewScore(score, course);
274 else if (m == courseListModel) {
275 QString str = courseListModel->data(index, Qt::DisplayRole).toString();
276 QStringList strList = str.split(",");
278 if (strList.count() != 2) {
279 showNote(QString("Invalid course selection"));
282 Course * course = findCourse(strList.at(0), strList.at(1));
288 void MainWindow::newCourse()
290 CourseSelectDialog *selectDialog = new CourseSelectDialog(this);
292 int result = selectDialog->exec();
298 selectDialog->results(clubName, courseName);
300 CourseDialog *courseDialog = new CourseDialog(this);
301 courseDialog->init();
302 QString title = "New Course: " + clubName + "," + courseName;
303 courseDialog->setWindowTitle(title);
305 int result = courseDialog->exec();
307 QVector<QString> par(18);
308 QVector<QString> hcp(18);
309 QVector<QString> len(18);
311 courseDialog->results(par, hcp, len);
314 Club *club = findClub(clubName);
316 course = club->getCourse(courseName);
318 qDebug() << "Error: club/course already in the database";
322 course = new Course(courseName, par, hcp);
323 club->addCourse(course);
327 // New club and course
328 club = new Club(clubName);
329 course = new Course(courseName, par, hcp);
330 club->addCourse(course);
334 saveClubFile(clubFile, clubList);
335 courseListModel->update(clubList);
341 void MainWindow::deleteCourse()
343 Course * course = findCourse();
344 Club * club = course->parent();
346 // Can not delete course if it has scores -- check
347 if (findScore(club->getName(), course->getName()) != 0) {
348 showNote(tr("Can not delete course, delete scores on the course first"));
355 club->delCourse(course);
357 if (club->isEmpty()) {
358 int index = clubList.indexOf(club);
360 clubList.removeAt(index);
364 saveClubFile(clubFile, clubList);
365 courseListModel->update(clubList);
369 void MainWindow::editCourse()
371 Course *course = findCourse();
374 showNote(tr("No course on edit"));
378 CourseDialog *courseDialog = new CourseDialog(this);
379 courseDialog->init(course);
381 QString title = "Edit Course: " + course->getName();
382 courseDialog->setWindowTitle(title);
384 int result = courseDialog->exec();
386 QVector<QString> par(18);
387 QVector<QString> hcp(18);
388 QVector<QString> len(18);
390 courseDialog->results(par, hcp, len);
392 course->update(par, hcp, len);
393 saveClubFile(clubFile, clubList);
397 void MainWindow::newScore()
399 SelectDialog *selectDialog = new SelectDialog(this);
401 selectDialog->init(clubList);
403 int result = selectDialog->exec();
409 selectDialog->results(clubName, courseName, date);
411 ScoreDialog *scoreDialog = new ScoreDialog(this);
412 QString title = "New Score: " + courseName + ", " + date;
413 scoreDialog->setWindowTitle(title);
415 Club *club = findClub(clubName);
417 showNote(tr("Error: no such club"));
420 Course *course = club->getCourse(courseName);
422 showNote(tr("Error: no such course:"));
425 scoreDialog->init(course);
426 result = scoreDialog->exec();
428 QVector<QString> scores(18);
430 scoreDialog->results(scores);
431 Score *score = new Score(scores, clubName, courseName, date);
434 // Sort the scores based on dates
435 qSort(scoreList.begin(), scoreList.end(), dateMoreThan);
437 saveScoreFile(scoreFile, scoreList);
438 scoreListModel->update(scoreList);
444 void MainWindow::deleteScore()
449 QModelIndex index = selectionModel->currentIndex();
450 scoreList.removeAt(index.row());
452 saveScoreFile(scoreFile, scoreList);
453 scoreListModel->update(scoreList);
457 void MainWindow::editScore()
459 QModelIndex index = selectionModel->currentIndex();
460 Score * score = scoreList.at(index.row());
463 course = findCourse(score->getClubName(), score->getCourseName());
465 if (!course || !score) {
466 qDebug() << "No score/course to edit";
470 QString date = score->getDate();
472 ScoreDialog *scoreDialog = new ScoreDialog;
474 QString title = "Edit Score: " + course->getName() + ", " + date;
475 scoreDialog->setWindowTitle(title);
477 scoreDialog->init(course, score);
479 int result = scoreDialog->exec();
482 QVector<QString> scores(18);
484 scoreDialog->results(scores);
486 score->update(scores);
488 // Sort the scores based on dates
489 qSort(scoreList.begin(), scoreList.end(), dateMoreThan);
491 saveScoreFile(scoreFile, scoreList);
493 scoreListModel->update(scoreList);
497 void MainWindow::viewScore(Score * score, Course * course)
499 scoreWin = new QMainWindow(this);
500 QString title = QString("Score: %1, %2 - %3").arg(score->getClubName()).arg(score->getCourseName()).arg(score->getDate());
501 scoreWin->setWindowTitle(title);
503 scoreWin->setAttribute(Qt::WA_Maemo5StackedWindow);
506 QAction *editAction = new QAction(tr("Edit"), scoreWin);
507 connect(editAction, SIGNAL(triggered()), this, SLOT(editScore()));
508 scoreWin->menuBar()->addAction(editAction);
510 QAction *delAction = new QAction(tr("Delete"), scoreWin);
511 connect(delAction, SIGNAL(triggered()), this, SLOT(deleteScore()));
512 scoreWin->menuBar()->addAction(delAction);
514 ScoreTableModel *model = new ScoreTableModel(score, course);
516 QTableView * table = new QTableView;
518 table->setSelectionMode(QAbstractItemView::NoSelection);
519 //table->setStyleSheet(ScoreStyle::headerView());
520 table->setStyleSheet(ScoreStyle::style());
521 table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
522 table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
523 table->horizontalHeader()->hide();
524 table->setModel(model);
526 QWidget *central = new QWidget(scoreWin);
527 scoreWin->setCentralWidget(central);
529 QVBoxLayout *layout = new QVBoxLayout;
530 layout->addWidget(table);
532 central->setLayout(layout);
536 void MainWindow::viewCourse(Course * course)
538 courseWin = new QMainWindow(this);
539 QString title = QString("Course: %1, Par - %2").arg(course->getName()).arg(course->getTotal(Total));
540 courseWin->setWindowTitle(title);
542 courseWin->setAttribute(Qt::WA_Maemo5StackedWindow);
545 QAction *editAction = new QAction(tr("Edit"), courseWin);
546 connect(editAction, SIGNAL(triggered()), this, SLOT(editCourse()));
547 courseWin->menuBar()->addAction(editAction);
549 QAction *delAction = new QAction(tr("Delete"), courseWin);
550 connect(delAction, SIGNAL(triggered()), this, SLOT(deleteCourse()));
551 courseWin->menuBar()->addAction(delAction);
553 CourseTableModel *model = new CourseTableModel(course);
555 QTableView * table = new QTableView;
557 table->setSelectionMode(QAbstractItemView::NoSelection);
558 //table->setStyleSheet(ScoreStyle::headerView());
559 table->setStyleSheet(ScoreStyle::style());
560 table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
561 table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
562 table->horizontalHeader()->hide();
563 table->setModel(model);
565 QWidget *central = new QWidget(courseWin);
566 courseWin->setCentralWidget(central);
568 QVBoxLayout *layout = new QVBoxLayout;
569 layout->addWidget(table);
571 central->setLayout(layout);
575 void MainWindow::viewStatistics()
577 QMainWindow *win = new QMainWindow(this);
578 QString title = "Statistics";
579 win->setWindowTitle(title);
581 win->setAttribute(Qt::WA_Maemo5StackedWindow);
584 StatModel *model = new StatModel(clubList, scoreList);
586 QTableView *table = new QTableView;
588 table->setSelectionMode(QAbstractItemView::NoSelection);
589 table->setStyleSheet(ScoreStyle::headerView());
590 table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
591 table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
592 table->verticalHeader()->setAutoFillBackground(true);
593 table->setModel(model);
595 QWidget *central = new QWidget(win);
596 win->setCentralWidget(central);
598 QTextEdit *textEdit = new QTextEdit;
600 textEdit->setReadOnly(true);
602 QVBoxLayout *infoLayout = new QVBoxLayout;
603 infoLayout->addWidget(table);
605 QHBoxLayout *mainLayout = new QHBoxLayout(central);
606 mainLayout->addLayout(infoLayout);
607 central->setLayout(mainLayout);
612 void MainWindow::loadScoreFile(QString &fileName, QList<Score *> &list)
614 ScoreXmlHandler handler(list);
616 if (handler.parse(fileName))
617 qDebug() << "File loaded:" << fileName << " entries:" << list.size();
620 void MainWindow::saveScoreFile(QString &fileName, QList<Score *> &list)
622 ScoreXmlHandler handler(list);
624 if (handler.save(fileName))
626 qDebug() << "File saved:" << fileName << " entries:" << list.size();
628 qWarning() << "Unable to save:" << fileName;
631 void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list)
633 ClubXmlHandler handler(list);
635 if (handler.parse(fileName))
636 qDebug() << "File loaded:" << fileName << " entries:" << list.size();
639 void MainWindow::saveClubFile(QString &fileName, QList<Club *> &list)
641 ClubXmlHandler handler(list);
643 if (handler.save(fileName))
645 qDebug() << "File saved:" << fileName << " entries:" << list.size();
647 qWarning() << "Unable to save:" << fileName;