Initial stat view attempt
[scorecard] / src / main-window.cpp
1 #include <QtGui>
2 #include <QDirModel>
3 #include <QListView>
4 #include <QStandardItemModel>
5
6 #include "main-window.h"
7 #include "score-dialog.h"
8 #include "course-dialog.h"
9 #include "xml-parser.h"
10 #include "xml-dom-parser.h"
11
12 QString appName("scorecard");
13 QString topDir("/opt");
14 QString mmcDir("/media/mmc1");
15 QString dataDirName("data");
16 QString dataDir;
17 QString imgDir(topDir + "/pixmaps");
18 QString scoreFileName("score.xml");
19 QString scoreFile;
20 QString clubFileName("club.xml");
21 QString clubFile;
22 QString logFile("/tmp/scorecard.log");
23
24 bool dateLessThan(const Score *s1, const Score *s2)
25 {
26   return (*s1) < (*s2);
27 }
28
29 MainWindow::MainWindow(QMainWindow *parent): QMainWindow(parent)
30 {
31   resize(800, 480);
32
33   loadSettings();
34
35   centralWidget = new QWidget(this);
36
37   setCentralWidget(centralWidget);
38
39   loadScoreFile(scoreFile, scoreList);
40   loadClubFile(clubFile, clubList);
41
42   // Sort the scores based on dates
43   qSort(scoreList.begin(), scoreList.end(), dateLessThan); 
44
45   createActions();
46   createMenus();
47
48   createTableView(scoreList, clubList);
49   createStatusBar();
50
51   createLayout(centralWidget);
52 }
53
54 void MainWindow::loadSettings(void)
55 {
56   bool external = false;
57
58   QDir mmc(mmcDir);
59   if (mmc.exists())
60     external = true;
61
62   // TODO: make via user option, automatic will never work
63   external = false;
64
65 #ifndef Q_WS_HILDON
66   dataDir = "./" + dataDirName;
67 #else
68   if (external) {
69     dataDir = mmcDir + "/" + appName + "/" + dataDirName;
70   }
71   else {
72     dataDir = topDir + "/" + appName + "/" + dataDirName;
73   }
74 #endif
75   scoreFile = dataDir + "/" + scoreFileName;
76   clubFile = dataDir + "/" + clubFileName;
77
78   QDir dir(dataDir);
79   if (!dir.exists())
80     if (!dir.mkpath(dataDir)) {
81       qWarning() << "Unable to create: " + dataDir;
82       return;
83     }
84   qDebug() << "Data is at:" + dataDir;
85 }
86
87 void MainWindow::createLayout(QWidget *parent)
88 {
89
90   buttonLayout = new QVBoxLayout;
91   //labelLayout->addStretch();
92   buttonLayout->addWidget(nextButton);
93   buttonLayout->addWidget(prevButton);
94   buttonLayout->addWidget(lastButton);
95   buttonLayout->addWidget(firstButton);
96
97   tableLayout = new QVBoxLayout;
98   tableLayout->addWidget(table);
99
100   QHBoxLayout *mainLayout = new QHBoxLayout(parent);
101   mainLayout->addLayout(tableLayout);
102   mainLayout->addLayout(buttonLayout);
103   parent->setLayout(mainLayout);
104 }
105
106 // Setup 'score' tab view
107 void MainWindow::createTableView(QList<Score *> &scoreList, QList <Club *> &clubList)
108 {
109   table = new QTableView;
110
111   nextButton = new QPushButton(tr("Next"));
112   prevButton = new QPushButton(tr("Prev"));
113   firstButton = new QPushButton(tr("First"));
114   lastButton = new QPushButton(tr("Last"));
115
116   connect(nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked()));
117   connect(prevButton, SIGNAL(clicked()), this, SLOT(prevButtonClicked()));
118   connect(firstButton, SIGNAL(clicked()), this, SLOT(firstButtonClicked()));
119   connect(lastButton, SIGNAL(clicked()), this, SLOT(lastButtonClicked()));
120
121   scoreTableModel = new ScoreTableModel();
122
123   table->showGrid();
124
125   table->setModel(scoreTableModel);
126   QItemSelectionModel selectionModel();
127   table->setSelectionMode(QAbstractItemView::NoSelection);
128
129   scoreTableModel->setScore(scoreList);
130   scoreTableModel->setClub(clubList);
131
132   // Fill out all the space with the tables
133   table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
134   table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
135   table->verticalHeader()->setAutoFillBackground(true);
136   table->horizontalHeader()->hide();
137 }
138
139 void MainWindow::createStatusBar()
140 {
141 #if 0
142   // TODO: use toolbar or buttons. Toolbar seems not to be ready and
143   // requires more work.
144   toolbar = addToolBar(tr("foo"));
145   toolbar->addAction(firstAct);
146   toolbar->addAction(lastAct);
147   toolbar->addAction(prevAct);
148   toolbar->addAction(nextAct);
149 #endif
150   updateStatusBar();
151 }
152
153 void MainWindow::createActions()
154 {
155   newScoreAct = new QAction(tr("New Score"), this);
156   connect(newScoreAct, SIGNAL(triggered()), this, SLOT(newScore()));
157
158   newCourseAct = new QAction(tr("New Course"), this);
159   connect(newCourseAct, SIGNAL(triggered()), this, SLOT(newCourse()));
160
161   editScoreAct = new QAction(tr("Edit Score"), this);
162   connect(editScoreAct, SIGNAL(triggered()), this, SLOT(editScore()));
163
164   editCourseAct = new QAction(tr("Edit Course"), this);
165   connect(editCourseAct, SIGNAL(triggered()), this, SLOT(editCourse()));
166
167 #if 0
168   viewScoreAct = new QAction(tr("&View Scores"), this);
169   connect(viewScoreAct, SIGNAL(triggered()), this, SLOT(viewScore()));
170
171   viewCourseAct = new QAction(tr("&View Courses"), this);
172   connect(viewCourseAct, SIGNAL(triggered()), this, SLOT(viewCourse()));
173 #endif
174
175   statAct = new QAction(tr("Statistics"), this);
176   connect(statAct, SIGNAL(triggered()), this, SLOT(viewStatistics()));
177
178   nextAct = new QAction(tr( "   Next   "), this);
179   connect(nextAct, SIGNAL(triggered()), this, SLOT(nextButtonClicked()));
180
181   prevAct = new QAction("   Prev   ", this);
182   connect(prevAct, SIGNAL(triggered()), this, SLOT(prevButtonClicked()));
183
184   firstAct = new QAction(tr("   First  "), this);
185   connect(firstAct, SIGNAL(triggered()), this, SLOT(firstButtonClicked()));
186
187   lastAct = new QAction(tr( "   Last   "), this);
188   connect(lastAct, SIGNAL(triggered()), this, SLOT(lastButtonClicked()));
189 }
190
191 void MainWindow::createMenus()
192 {
193   menu = menuBar()->addMenu("");
194 #if 0
195   menu->addAction(viewScoreAct);
196   menu->addAction(viewCourseAct);
197   menu->addAction(viewStatisticAct);
198 #endif
199   menu->addAction(newScoreAct);
200   menu->addAction(newCourseAct);
201   menu->addAction(editScoreAct);
202   menu->addAction(editCourseAct);
203   menu->addAction(statAct);
204 }
205
206 void MainWindow::updateStatusBar()
207 {
208   QString title = scoreTableModel->getInfoText();
209   if (title.isEmpty())
210     title = "ScoreCard - No Scores";
211
212   setWindowTitle(title);
213 }
214
215 void MainWindow::firstButtonClicked()
216 {
217   scoreTableModel->first();
218   updateStatusBar();
219 }
220
221 void MainWindow::lastButtonClicked()
222 {
223   scoreTableModel->last();
224   updateStatusBar();
225 }
226
227 void MainWindow::nextButtonClicked()
228 {
229   scoreTableModel->next();
230   updateStatusBar();
231 }
232
233 void MainWindow::prevButtonClicked()
234 {
235   scoreTableModel->prev();
236   updateStatusBar();
237 }
238
239 // FIXME: dup code from table-model.cpp
240 Club *MainWindow::findClub(QString &name)
241 {
242   QListIterator<Club *> i(clubList);
243   Club *c;
244
245   while (i.hasNext()) {
246     c = i.next();
247     if (c->getName() == name)
248       return c;
249   }
250   return 0;
251 }
252
253 void MainWindow::newCourse()
254 {
255   CourseSelectDialog *selectDialog = new CourseSelectDialog(this);
256
257   int result = selectDialog->exec();
258   if (result) {
259     QString clubName;
260     QString courseName;
261     QString date;
262
263     selectDialog->results(clubName, courseName);
264
265     CourseDialog *courseDialog = new CourseDialog(this);
266     courseDialog->init();
267
268     QString title = "New Course: " + clubName + "," + courseName;
269     courseDialog->setWindowTitle(title);
270
271     int result = courseDialog->exec();
272     if (result) {
273       QVector<QString> par(18);
274       QVector<QString> hcp(18);
275       QVector<QString> len(18);
276
277       courseDialog->results(par, hcp, len);
278
279       Course *course = 0;
280       Club *club = findClub(clubName);
281       if (club) {
282         course = club->getCourse(courseName);
283         if (course) {
284           qDebug() << "Error: club/course already in the database";
285           return;
286         }
287         else {
288           course = new Course(courseName, par, hcp);
289           club->addCourse(course);
290         }
291       }
292       else {
293         // New club and course
294         club = new Club(clubName);
295         course = new Course(courseName, par, hcp);
296         club->addCourse(course);
297         clubList << club;
298       }
299       saveClubFile(clubFile, clubList);
300
301       // TODO: does this really work? No mem leaks?
302       scoreTableModel->setClub(clubList);
303     }
304   }
305 }
306
307 void MainWindow::editCourse()
308 {
309   Course *course = scoreTableModel->getCourse();
310
311   if (!course) {
312     qWarning() << "No course on edit";
313     return;
314   }
315
316   CourseDialog *courseDialog = new CourseDialog(this);
317   courseDialog->init(course);
318
319   QString title = "Edit Course: " + course->getName();
320   courseDialog->setWindowTitle(title);
321   
322   int result = courseDialog->exec();
323   if (result) {
324     QVector<QString> par(18);
325     QVector<QString> hcp(18);
326     QVector<QString> len(18);
327     
328     courseDialog->results(par, hcp, len);
329     
330     course->update(par, hcp, len);
331     saveClubFile(clubFile, clubList);
332   }
333 }
334
335 void MainWindow::newScore()
336 {
337   SelectDialog *selectDialog = new SelectDialog(this);
338
339   selectDialog->init(clubList);
340
341   int result = selectDialog->exec();
342   if (result) {
343     QString clubName;
344     QString courseName;
345     QString date;
346
347     selectDialog->results(clubName, courseName, date);
348
349     ScoreDialog *scoreDialog = new ScoreDialog(this);
350     QString title = "New Score: " + courseName + ", " + date;
351     scoreDialog->setWindowTitle(title);
352
353     Club *club = findClub(clubName);
354     if (!club) {
355       qWarning() << "Error: no such club:" << clubName;
356       return;
357     }
358     Course *course = club->getCourse(courseName);
359     if (!course) {
360       qWarning() << "Error: no such course:" << courseName;
361       return;
362     }
363     scoreDialog->init(course);
364     result = scoreDialog->exec();
365     if (result) {
366       QVector<QString> scores(18);
367
368       scoreDialog->results(scores);
369       Score *score = new Score(scores, clubName, courseName, date);
370       scoreList << score;
371
372       // Sort the scores based on dates
373       qSort(scoreList.begin(), scoreList.end(), dateLessThan); 
374       // Save it
375       saveScoreFile(scoreFile, scoreList);
376
377       // TODO: does this really work? No mem leaks?
378       scoreTableModel->setScore(scoreList, score);
379       updateStatusBar();
380     }
381   }
382 }
383
384 void MainWindow::editScore()
385 {
386   Course *course = scoreTableModel->getCourse();
387   Score *score = scoreTableModel->getScore();
388   QString date = score->getDate();
389
390   ScoreDialog *scoreDialog = new ScoreDialog(this);
391   
392   QString title = "Edit Score: " + course->getName() + ", " + date;
393   scoreDialog->setWindowTitle(title);
394
395   scoreDialog->init(course, score);
396
397   int result = scoreDialog->exec();
398
399   if (result) {
400     QVector<QString> scores(18);
401
402     scoreDialog->results(scores);
403     
404     score->update(scores);
405
406     // Sort the scores based on dates
407     qSort(scoreList.begin(), scoreList.end(), dateLessThan); 
408     // Save it
409     saveScoreFile(scoreFile, scoreList);
410
411     // TODO: does this really work? No mem leaks?
412     scoreTableModel->setScore(scoreList, score);
413     updateStatusBar();
414   }
415 }
416
417 void MainWindow::viewStatistics()
418 {
419   QMainWindow *statWindow = new QMainWindow(this);
420
421   //QWidget *centralWidget = new QWidget(statWindow);
422
423   //setCentralWidget(centralWidget);
424
425
426   QString foo = "some longer text is needed here : 17";
427   QTextEdit *textEdit = new QTextEdit(foo);
428   
429   QLabel *label = new QLabel;
430   label->setScaledContents(true);
431
432   QString text = "foo : bar";
433
434   text.append("Scores: 17");
435
436   label->setAlignment(Qt::AlignCenter);
437   label->setText(text);
438
439   QString title = "Statistics";
440   statWindow->setWindowTitle(title);
441
442   QVBoxLayout *layout = new QVBoxLayout;
443   //layout->addWidget(label);
444   layout->addWidget(textEdit);
445
446   //statWindow->setLayout(layout);
447
448   //setCentralWidget(statWindow);
449   statWindow->show();
450 }
451
452 void MainWindow::loadScoreFile(QString &fileName, QList<Score *> &list)
453 {
454   ScoreXmlHandler handler(list);
455
456   if (handler.parse(fileName))
457     qDebug() << "File loaded:" << fileName << " entries:" << list.size();
458 }
459
460 void MainWindow::saveScoreFile(QString &fileName, QList<Score *> &list)
461 {
462   ScoreXmlHandler handler(list);
463
464   if (handler.save(fileName))
465     // TODO: banner
466     qDebug() << "File saved:" << fileName << " entries:" << list.size();
467   else
468     qWarning() << "Unable to save:" << fileName;
469 }
470
471 void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list)
472 {
473   ClubXmlHandler handler(list);
474
475   if (handler.parse(fileName))
476     qDebug() << "File loaded:" << fileName << " entries:" << list.size();
477 }
478
479 void MainWindow::saveClubFile(QString &fileName, QList<Club *> &list)
480 {
481   ClubXmlHandler handler(list);
482
483   if (handler.save(fileName))
484     // TODO: banner
485     qDebug() << "File saved:" << fileName << " entries:" << list.size();
486   else
487     qWarning() << "Unable to save:" << fileName;
488
489 }