5 #include <QStandardItemModel>
7 #include "main-window.h"
8 #include "score-dialog.h"
9 #include "course-dialog.h"
10 #include "tree-widget.h"
11 #include "xml-parser.h"
12 #include "xml-dom-parser.h"
14 QString appName("scorecard");
15 QString topDir("/opt");
16 QString mmcDir("/media/mmc1");
17 QString dataDirName("data");
19 QString imgDir(topDir + "/pixmaps");
20 QString scoreFileName("score.xml");
22 QString clubFileName("club.xml");
24 QString logFile("/tmp/scorecard.log");
26 bool dateLessThan(const Score *s1, const Score *s2)
31 MainWindow::MainWindow(QMainWindow *parent): QMainWindow(parent)
37 QWidget *centralWidget = new QWidget(this);
39 setCentralWidget(centralWidget);
41 loadScoreFile(scoreFile, scoreList);
42 loadClubFile(clubFile, clubList);
44 // Sort the scores based on dates
45 qSort(scoreList.begin(), scoreList.end(), dateLessThan);
50 createTableView(scoreList, clubList);
51 //createTreeView(scoreList, parent);
54 createLayout(centralWidget);
57 void MainWindow::loadSettings(void)
59 bool external = false;
65 // TODO: make via user option, automatic will never work
69 dataDir = "./" + dataDirName;
72 dataDir = mmcDir + "/" + appName + "/" + dataDirName;
75 dataDir = topDir + "/" + appName + "/" + dataDirName;
78 scoreFile = dataDir + "/" + scoreFileName;
79 clubFile = dataDir + "/" + clubFileName;
83 if (!dir.mkpath(dataDir)) {
84 qWarning() << "Unable to create: " + dataDir;
87 qDebug() << "Data is at:" + dataDir;
90 void MainWindow::createLayout(QWidget *parent)
93 buttonLayout = new QVBoxLayout;
94 //labelLayout->addStretch();
95 buttonLayout->addWidget(nextButton);
96 buttonLayout->addWidget(prevButton);
97 buttonLayout->addWidget(lastButton);
98 buttonLayout->addWidget(firstButton);
100 tableLayout = new QVBoxLayout;
101 tableLayout->addWidget(table);
103 QHBoxLayout *mainLayout = new QHBoxLayout(parent);
104 mainLayout->addLayout(tableLayout);
105 mainLayout->addLayout(buttonLayout);
106 parent->setLayout(mainLayout);
109 // Setup 'score' tab view
110 void MainWindow::createTableView(QList<Score *> &scoreList, QList <Club *> &clubList)
112 table = new QTableView;
114 nextButton = new QPushButton(tr("Next"));
115 prevButton = new QPushButton(tr("Prev"));
116 firstButton = new QPushButton(tr("First"));
117 lastButton = new QPushButton(tr("Last"));
119 connect(nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked()));
120 connect(prevButton, SIGNAL(clicked()), this, SLOT(prevButtonClicked()));
121 connect(firstButton, SIGNAL(clicked()), this, SLOT(firstButtonClicked()));
122 connect(lastButton, SIGNAL(clicked()), this, SLOT(lastButtonClicked()));
124 scoreTableModel = new ScoreTableModel();
128 table->setModel(scoreTableModel);
129 QItemSelectionModel selectionModel();
130 table->setSelectionMode(QAbstractItemView::NoSelection);
132 scoreTableModel->setScore(scoreList);
133 scoreTableModel->setClub(clubList);
135 // Fill out all the space with the tables
136 table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
137 table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
138 table->verticalHeader()->setAutoFillBackground(true);
139 table->horizontalHeader()->hide();
142 // When selection down in 'stat' view, this is called.
143 void MainWindow::updateTreeView(const QModelIndex & index)
145 QString scope("Scope");
146 QString count("Rounds");
147 QString scoreAvg("Score (avg.)");
148 QString scoreBest("Score (best)");
149 QString score("Total");
150 QString scoreIn("Total in");
151 QString scoreOut("Total out");
153 QVariant str = scoreTreeModel->data(index, Qt::DisplayRole);
154 QVariant type = scoreTreeModel->data(index, ScoreTreeModel::Type);
156 qDebug() << "update(" << index.row() << "/" << index.column() << "):" << str << type;
158 tableModel->setData(tableModel->index(0, 0, QModelIndex()), scope);
159 tableModel->setData(tableModel->index(0, 1, QModelIndex()), str);
161 if (type == TreeItem::TypeDate) {
162 tableModel->setData(tableModel->index(1, 0, QModelIndex()), count);
163 tableModel->setData(tableModel->index(2, 0, QModelIndex()), scoreAvg);
164 tableModel->setData(tableModel->index(3, 0, QModelIndex()), scoreBest);
166 else if (type == TreeItem::TypeScore) {
167 QVariant value = scoreTreeModel->data(index, ScoreTreeModel::Total);
168 tableModel->setData(tableModel->index(1, 0, QModelIndex()), score);
169 tableModel->setData(tableModel->index(1, 1, QModelIndex()), value);
171 value = scoreTreeModel->data(index, ScoreTreeModel::TotalOut);
172 tableModel->setData(tableModel->index(2, 0, QModelIndex()), scoreOut);
173 tableModel->setData(tableModel->index(2, 1, QModelIndex()), value);
175 value = scoreTreeModel->data(index, ScoreTreeModel::TotalIn);
176 tableModel->setData(tableModel->index(3, 0, QModelIndex()), scoreIn);
177 tableModel->setData(tableModel->index(3, 1, QModelIndex()), value);
181 void MainWindow::createStatusBar()
184 // TODO: use toolbar or buttons. Toolbar seems not to be ready and
185 // requires more work.
186 toolbar = addToolBar(tr("foo"));
187 toolbar->addAction(firstAct);
188 toolbar->addAction(lastAct);
189 toolbar->addAction(prevAct);
190 toolbar->addAction(nextAct);
195 void MainWindow::createActions()
197 newScoreAct = new QAction(tr("New Score"), this);
198 connect(newScoreAct, SIGNAL(triggered()), this, SLOT(newScore()));
200 newCourseAct = new QAction(tr("New Course"), this);
201 connect(newCourseAct, SIGNAL(triggered()), this, SLOT(newCourse()));
203 editScoreAct = new QAction(tr("Edit Score"), this);
204 connect(editScoreAct, SIGNAL(triggered()), this, SLOT(editScore()));
206 editCourseAct = new QAction(tr("Edit Course"), this);
207 connect(editCourseAct, SIGNAL(triggered()), this, SLOT(editCourse()));
210 viewScoreAct = new QAction(tr("&View Scores"), this);
211 connect(viewScoreAct, SIGNAL(triggered()), this, SLOT(viewScore()));
213 viewCourseAct = new QAction(tr("&View Courses"), this);
214 connect(viewCourseAct, SIGNAL(triggered()), this, SLOT(viewCourse()));
216 viewStatisticAct = new QAction(tr("&View Statistics"), this);
217 connect(viewStatisticAct, SIGNAL(triggered()), this, SLOT(viewStatistic()));
220 nextAct = new QAction(tr( " Next "), this);
221 connect(nextAct, SIGNAL(triggered()), this, SLOT(nextButtonClicked()));
223 prevAct = new QAction(" Prev ", this);
224 connect(prevAct, SIGNAL(triggered()), this, SLOT(prevButtonClicked()));
226 firstAct = new QAction(tr(" First "), this);
227 connect(firstAct, SIGNAL(triggered()), this, SLOT(firstButtonClicked()));
229 lastAct = new QAction(tr( " Last "), this);
230 connect(lastAct, SIGNAL(triggered()), this, SLOT(lastButtonClicked()));
233 void MainWindow::createMenus()
235 menu = menuBar()->addMenu("");
237 menu->addAction(viewScoreAct);
238 menu->addAction(viewCourseAct);
239 menu->addAction(viewStatisticAct);
241 menu->addAction(newScoreAct);
242 menu->addAction(newCourseAct);
243 menu->addAction(editScoreAct);
244 menu->addAction(editCourseAct);
247 void MainWindow::updateStatusBar()
249 setWindowTitle(scoreTableModel->getInfoText());
252 void MainWindow::firstButtonClicked()
254 scoreTableModel->first();
258 void MainWindow::lastButtonClicked()
260 scoreTableModel->last();
264 void MainWindow::nextButtonClicked()
266 scoreTableModel->next();
270 void MainWindow::prevButtonClicked()
272 scoreTableModel->prev();
276 // FIXME: dup code from table-model.cpp
277 Club *MainWindow::findClub(QString &name)
279 QListIterator<Club *> i(clubList);
282 while (i.hasNext()) {
284 if (c->getName() == name)
290 void MainWindow::newCourse()
292 CourseSelectDialog *selectDialog = new CourseSelectDialog(this);
294 int result = selectDialog->exec();
300 selectDialog->results(clubName, courseName);
302 CourseDialog *courseDialog = new CourseDialog(this);
303 courseDialog->init();
305 QString title = "New Course: " + clubName + "," + courseName;
306 courseDialog->setWindowTitle(title);
308 int result = courseDialog->exec();
310 QVector<QString> par(18);
311 QVector<QString> hcp(18);
312 QVector<QString> len(18);
314 courseDialog->results(par, hcp, len);
317 Club *club = findClub(clubName);
319 course = club->getCourse(courseName);
321 qDebug() << "Error: club/course already in the database";
325 course = new Course(courseName, par, hcp);
326 club->addCourse(course);
330 // New club and course
331 club = new Club(clubName);
332 course = new Course(courseName, par, hcp);
333 club->addCourse(course);
336 saveClubFile(clubFile, clubList);
338 // TODO: does this really work? No mem leaks?
339 scoreTableModel->setClub(clubList);
344 void MainWindow::editCourse()
346 Course *course = scoreTableModel->getCourse();
349 qWarning() << "No course on edit";
353 CourseDialog *courseDialog = new CourseDialog(this);
354 courseDialog->init(course);
356 QString title = "Edit Course: " + course->getName();
357 courseDialog->setWindowTitle(title);
359 int result = courseDialog->exec();
361 QVector<QString> par(18);
362 QVector<QString> hcp(18);
363 QVector<QString> len(18);
365 courseDialog->results(par, hcp, len);
367 course->update(par, hcp, len);
368 saveClubFile(clubFile, clubList);
372 void MainWindow::newScore()
374 SelectDialog *selectDialog = new SelectDialog(this);
376 selectDialog->init(clubList);
378 int result = selectDialog->exec();
384 selectDialog->results(clubName, courseName, date);
386 ScoreDialog *scoreDialog = new ScoreDialog(this);
387 QString title = "New Score: " + courseName + ", " + date;
388 scoreDialog->setWindowTitle(title);
390 Club *club = findClub(clubName);
392 qWarning() << "Error: no such club:" << clubName;
395 Course *course = club->getCourse(courseName);
397 qWarning() << "Error: no such course:" << courseName;
400 scoreDialog->init(course);
401 result = scoreDialog->exec();
403 QVector<QString> scores(18);
405 scoreDialog->results(scores);
406 Score *score = new Score(scores, clubName, courseName, date);
409 // Sort the scores based on dates
410 qSort(scoreList.begin(), scoreList.end(), dateLessThan);
412 saveScoreFile(scoreFile, scoreList);
414 // TODO: does this really work? No mem leaks?
415 scoreTableModel->setScore(scoreList, score);
421 void MainWindow::editScore()
423 Course *course = scoreTableModel->getCourse();
424 Score *score = scoreTableModel->getScore();
425 QString date = score->getDate();
427 ScoreDialog *scoreDialog = new ScoreDialog(this);
429 QString title = "Edit Score: " + course->getName() + ", " + date;
430 scoreDialog->setWindowTitle(title);
432 scoreDialog->init(course, score);
434 int result = scoreDialog->exec();
437 QVector<QString> scores(18);
439 scoreDialog->results(scores);
441 score->update(scores);
443 // Sort the scores based on dates
444 qSort(scoreList.begin(), scoreList.end(), dateLessThan);
446 saveScoreFile(scoreFile, scoreList);
448 // TODO: does this really work? No mem leaks?
449 scoreTableModel->setScore(scoreList, score);
454 void MainWindow::loadScoreFile(QString &fileName, QList<Score *> &list)
456 ScoreXmlHandler handler(list);
458 if (handler.parse(fileName))
459 qDebug() << "File loaded:" << fileName << " entries:" << list.size();
462 void MainWindow::saveScoreFile(QString &fileName, QList<Score *> &list)
464 ScoreXmlHandler handler(list);
466 if (handler.save(fileName))
468 qDebug() << "File saved:" << fileName << " entries:" << list.size();
470 qWarning() << "Unable to save:" << fileName;
473 void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list)
475 ClubXmlHandler handler(list);
477 if (handler.parse(fileName))
478 qDebug() << "File loaded:" << fileName << " entries:" << list.size();
481 void MainWindow::saveClubFile(QString &fileName, QList<Club *> &list)
483 ClubXmlHandler handler(list);
485 if (handler.save(fileName))
487 qDebug() << "File saved:" << fileName << " entries:" << list.size();
489 qWarning() << "Unable to save:" << fileName;