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