Use QListWidget instead of comboboxes
[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 scoreFile("data/score.xml");
15 QString scoreFileWr("data/score-save.xml");
16 QString clubFile("data/club.xml");
17 QString clubFileWr("data/club-save.xml");
18
19 MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent)
20 {
21   resize(800, 480);
22
23   QWidget *centralWidget = new QWidget(this);
24
25   // TODO: move to proper function
26   tableViewFront = new QTableView(centralWidget);
27   tableViewBack = new QTableView(centralWidget);
28
29   setCentralWidget(centralWidget);
30
31   loadScoreFile(scoreFile, scoreList);
32   loadClubFile(clubFile, clubList);
33
34 #ifdef TEST
35   saveScoreFile(scoreFileWr, scoreList);
36   saveClubFile(clubFileWr, clubList);
37 #endif
38
39   createTableView(scoreList, clubList);
40   //createTreeView(scoreList, parent);
41   createStatusBar();
42
43   createLayout(centralWidget);
44
45   createActions();
46   createMenus();
47 }
48
49 void MainWindow::createLayout(QWidget *parent)
50 {
51   buttonLayout = new QVBoxLayout;
52   //labelLayout->addStretch();
53   buttonLayout->addWidget(nextButton);
54   buttonLayout->addWidget(prevButton);
55   buttonLayout->addWidget(lastButton);
56   buttonLayout->addWidget(firstButton);
57
58   tableLayout = new QVBoxLayout;
59   tableLayout->addWidget(tableViewFront);
60   tableLayout->addWidget(tableViewBack);
61
62   QHBoxLayout *mainLayout = new QHBoxLayout(parent);
63   mainLayout->addLayout(tableLayout);
64   mainLayout->addLayout(buttonLayout);
65   setLayout(mainLayout);
66 }
67
68 // Setup 'score' tab view
69 void MainWindow::createTableView(QList<Score *> &scoreList, QList <Club *> &clubList)
70 {
71   nextButton = new QPushButton(tr(">"));
72   prevButton = new QPushButton(tr("<"));
73   firstButton = new QPushButton(tr("<<"));
74   lastButton = new QPushButton(tr(">>"));
75
76   connect(nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked()));
77   connect(prevButton, SIGNAL(clicked()), this, SLOT(prevButtonClicked()));
78   connect(firstButton, SIGNAL(clicked()), this, SLOT(firstButtonClicked()));
79   connect(lastButton, SIGNAL(clicked()), this, SLOT(lastButtonClicked()));
80
81   scoreTableModel = new ScoreTableModel();
82   scoreTableModel->setScore(scoreList);
83   scoreTableModel->setClub(clubList);
84
85   tableViewFront->showGrid();
86   tableViewBack->showGrid();
87
88   tableViewFront->setModel(scoreTableModel);
89   tableViewBack->setModel(scoreTableModel);
90
91   // Flag model items which one belongs to front and back nines
92   tableViewFront->setRootIndex(scoreTableModel->index(0, 0));
93   tableViewBack->setRootIndex(scoreTableModel->index(0, 1));
94
95   // Fill out all the space with the tables
96   tableViewFront->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
97   tableViewFront->verticalHeader()->setResizeMode(QHeaderView::Stretch);
98   tableViewBack->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
99   tableViewBack->verticalHeader()->setResizeMode(QHeaderView::Stretch);
100 }
101
102 // When selection down in 'stat' view, this is called.
103 void MainWindow::updateTreeView(const QModelIndex & index)
104 {
105   QString scope("Scope");
106   QString count("Rounds");
107   QString scoreAvg("Score (avg.)");
108   QString scoreBest("Score (best)");
109   QString score("Total");
110   QString scoreIn("Total in");
111   QString scoreOut("Total out");
112
113   QVariant str = scoreTreeModel->data(index, Qt::DisplayRole);
114   QVariant type = scoreTreeModel->data(index, ScoreTreeModel::Type);
115
116   qDebug() << "update(" << index.row() << "/" << index.column() << "):" << str << type;
117
118   tableModel->setData(tableModel->index(0, 0, QModelIndex()), scope);
119   tableModel->setData(tableModel->index(0, 1, QModelIndex()), str);
120
121   if (type == TreeItem::TypeDate) {
122     tableModel->setData(tableModel->index(1, 0, QModelIndex()), count);
123     tableModel->setData(tableModel->index(2, 0, QModelIndex()), scoreAvg);
124     tableModel->setData(tableModel->index(3, 0, QModelIndex()), scoreBest);
125   }    
126   else if (type == TreeItem::TypeScore) {
127     QVariant value = scoreTreeModel->data(index, ScoreTreeModel::Total);
128     tableModel->setData(tableModel->index(1, 0, QModelIndex()), score);
129     tableModel->setData(tableModel->index(1, 1, QModelIndex()), value);
130
131     value = scoreTreeModel->data(index, ScoreTreeModel::TotalOut);
132     tableModel->setData(tableModel->index(2, 0, QModelIndex()), scoreOut);
133     tableModel->setData(tableModel->index(2, 1, QModelIndex()), value);
134
135     value = scoreTreeModel->data(index, ScoreTreeModel::TotalIn);
136     tableModel->setData(tableModel->index(3, 0, QModelIndex()), scoreIn);
137     tableModel->setData(tableModel->index(3, 1, QModelIndex()), value);
138   }
139 }
140
141 void MainWindow::createStatusBar()
142 {
143   updateStatusBar();
144 }
145
146 void MainWindow::createActions()
147 {
148   newScoreAct = new QAction(tr("&New Score"), this);
149   connect(newScoreAct, SIGNAL(triggered()), this, SLOT(newScore()));
150
151   newCourseAct = new QAction(tr("&New Course"), this);
152   connect(newCourseAct, SIGNAL(triggered()), this, SLOT(newCourse()));
153
154 #if 0
155   viewScoreAct = new QAction(tr("&View Scores"), this);
156   connect(viewScoreAct, SIGNAL(triggered()), this, SLOT(viewScore()));
157
158   viewCourseAct = new QAction(tr("&View Courses"), this);
159   connect(viewCourseAct, SIGNAL(triggered()), this, SLOT(viewCourse()));
160
161   viewStatisticAct = new QAction(tr("&View Statistics"), this);
162   connect(viewStatisticAct, SIGNAL(triggered()), this, SLOT(viewStatistic()));
163 #endif
164 }
165
166 void MainWindow::createMenus()
167 {
168   menu = menuBar()->addMenu(tr("fremantle"));
169 #if 0
170   menu->addAction(viewScoreAct);
171   menu->addAction(viewCourseAct);
172   menu->addAction(viewStatisticAct);
173 #endif
174   menu->addAction(newScoreAct);
175   menu->addAction(newCourseAct);
176 }
177
178 void MainWindow::updateStatusBar()
179 {
180   setWindowTitle(scoreTableModel->getInfoText());
181 }
182
183 void MainWindow::firstButtonClicked()
184 {
185   scoreTableModel->first();
186   updateStatusBar();
187 }
188
189 void MainWindow::lastButtonClicked()
190 {
191   scoreTableModel->last();
192   updateStatusBar();
193 }
194
195 void MainWindow::nextButtonClicked()
196 {
197   scoreTableModel->next();
198   updateStatusBar();
199 }
200
201 void MainWindow::prevButtonClicked()
202 {
203   scoreTableModel->prev();
204   updateStatusBar();
205 }
206
207 // FIXME: dup code from table-model.cpp
208 Club *MainWindow::findClub(QString &name)
209 {
210   QListIterator<Club *> i(clubList);
211   Club *c;
212
213   while (i.hasNext()) {
214     c = i.next();
215     if (c->getName() == name)
216       return c;
217   }
218   return 0;
219 }
220
221 void MainWindow::newCourse()
222 {
223   CourseSelectDialog *selectDialog = new CourseSelectDialog(this);
224
225   int result = selectDialog->exec();
226   if (result) {
227     QString clubName;
228     QString courseName;
229     QString date;
230
231     selectDialog->results(clubName, courseName);
232     qDebug() << "club=" << clubName;
233     qDebug() << "course=" << courseName;
234
235     CourseDialog *courseDialog = new CourseDialog(this);
236
237     QString title = "New Course : " + clubName + "," + courseName;
238     courseDialog->setWindowTitle(title);
239
240     int result = courseDialog->exec();
241     if (result) {
242       QVector<QString> par(18);
243       QVector<QString> hcp(18);
244       QVector<QString> len(18);
245
246       courseDialog->results(par, hcp, len);
247
248       Course *course = 0;
249       Club *club = findClub(clubName);
250       if (club) {
251         course = club->getCourse(courseName);
252         if (course) {
253           qDebug() << "Error: club/course already in the database";
254           return;
255         }
256         else {
257           course = new Course(courseName, par, hcp);
258           club->addCourse(course);
259         }
260       }
261       else {
262         club = new Club(clubName);
263         course = new Course(courseName, par, hcp);
264         club->addCourse(course);
265         clubList << club;
266       }
267       saveClubFile(clubFile, clubList);
268     }
269   }
270 }
271
272 void MainWindow::newScore()
273 {
274   SelectDialog *selectDialog = new SelectDialog(this);
275
276   selectDialog->init(clubList);
277
278   int result = selectDialog->exec();
279   if (result) {
280     QString clubName;
281     QString courseName;
282     QString date;
283
284     selectDialog->results(clubName, courseName, date);
285
286     ScoreDialog *scoreDialog = new ScoreDialog(this);
287     QString title = "New Score : " + courseName + ", " + date;
288     scoreDialog->setWindowTitle(title);
289
290     Club *club = findClub(clubName);
291     if (!club) {
292       qDebug() << "Error: no such club: " << clubName;
293       return;
294     }
295     Course *course = club->getCourse(courseName);
296     if (!course) {
297       qDebug() << "Error: no such course: " << courseName;
298       return;
299     }
300
301     scoreDialog->init(course);
302
303     result = scoreDialog->exec();
304
305     if (result) {
306       QVector<QString> scores(18);
307
308       scoreDialog->results(scores);
309       Score *score = new Score(scores, clubName, courseName, date);
310       scoreList << score;
311
312       saveScoreFile(scoreFile, scoreList);
313
314       // TODO: does this really work? No mem leaks?
315       scoreTableModel->setScore(scoreList);
316       lastButtonClicked();
317     }
318   }
319 }
320
321 void MainWindow::loadScoreFile(QString &fileName, QList<Score *> &list)
322 {
323   ScoreXmlHandler handler(list);
324
325   if (handler.parse(fileName))
326     qDebug() << "Score loaded : " << fileName << 
327       " entries : " << list.size();
328 }
329
330 void MainWindow::saveScoreFile(QString &fileName, QList<Score *> &list)
331 {
332   ScoreXmlHandler handler(list);
333
334   if (handler.save(fileName))
335     qDebug() << "Score saved : " << fileName << 
336       " entries : " << list.size();
337 }
338
339 void MainWindow::loadClubFile(QString &fileName, QList<Club *> &list)
340 {
341   ClubXmlHandler handler(list);
342
343   if (handler.parse(fileName))
344     qDebug() << "Club loaded: " << fileName << 
345       " entries : " << list.size();
346 }
347
348 void MainWindow::saveClubFile(QString &fileName, QList<Club *> &list)
349 {
350   ClubXmlHandler handler(list);
351
352   if (handler.save(fileName))
353     qDebug() << "Club saved : " << fileName << 
354       " entries : " << list.size();
355 }