faa8d8225aa552b658edf35f7c7b5a06b195a640
[scorecard] / src / score-dialog.cpp
1 /*
2  * Copyright (C) 2009 Sakari Poussa
3  *
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.
7  */
8
9 #include <QtGui>
10 #include <QInputContext>
11 #ifdef Q_WS_MAEMO_5
12 #include <QMaemo5InformationBox>
13 #endif
14
15 #include "score-dialog.h"
16 #include "score-common.h"
17 #include "table-model.h"
18
19 ////////////////////////////////////////////////////////////////////////////////
20 // ScoreWindow based on QMainWindow
21 ////////////////////////////////////////////////////////////////////////////////
22 ScoreWindow::ScoreWindow(QWidget *parent) : QMainWindow(parent)
23 {
24 #ifdef Q_WS_MAEMO_5
25     setAttribute(Qt::WA_Maemo5StackedWindow);
26 #endif
27
28     QAction *editAction = new QAction(tr("Edit"), this);
29     connect(editAction, SIGNAL(triggered()), parent, SLOT(editScore()));
30     menuBar()->addAction(editAction);
31
32     QAction *delAction = new QAction(tr("Delete"), this);
33     connect(delAction, SIGNAL(triggered()), parent, SLOT(deleteScore()));
34     menuBar()->addAction(delAction);
35
36     model = new ScoreTableModel;
37     
38     QTableView * table = new QTableView;
39     table->showGrid();
40     table->setSelectionMode(QAbstractItemView::NoSelection);
41     table->setStyleSheet(defaultStyleSheet);
42     table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
43     table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
44     table->horizontalHeader()->hide();
45     table->setModel(model);
46     
47     QWidget *central = new QWidget(this);
48     setCentralWidget(central);
49     
50     QVBoxLayout *layout = new QVBoxLayout;
51     layout->addWidget(table);
52     
53     central->setLayout(layout);
54 }
55
56 ScoreWindow::~ScoreWindow()
57 {
58     TRACE;
59 }
60
61 void ScoreWindow::setup(Score *score, Course *course)
62 {
63     TRACE;
64     QString title = QString("Score: %1, %2 - %3").arg(score->getClubName()).arg(score->getCourseName()).arg(score->getDate());
65     setWindowTitle(title);
66     model->set(score, course);
67 }
68
69
70 ////////////////////////////////////////////////////////////////////////////////
71 // SelectDialog based on QDialog
72 ////////////////////////////////////////////////////////////////////////////////
73 SelectDialog::SelectDialog(QWidget *parent) : QDialog(parent)
74 {
75   resize(800, 350);
76
77   QWidget *centralWidget = new QWidget(this);
78   createLayout(centralWidget);
79
80   setWindowTitle(tr("ScoreCard: Select Course and Date"));
81 }
82
83 void SelectDialog::createLayout(QWidget *parent)
84 {
85   listClub = new QListWidget(parent);
86   pushButtonNext = new QPushButton(tr("Next"));
87
88   connect(pushButtonNext, SIGNAL(clicked()), this, SLOT(next()));
89
90   QDialogButtonBox * buttonBox = new QDialogButtonBox(Qt::Vertical);
91   buttonBox->addButton(pushButtonNext, QDialogButtonBox::ActionRole);
92
93   leftLayout = new QVBoxLayout;
94   leftLayout->addWidget(listClub);
95
96 #ifdef Q_WS_MAEMO_5
97   dateButton = new QMaemo5ValueButton();
98   dateButton->setValueLayout(QMaemo5ValueButton::ValueUnderText);
99   dateButton->setPickSelector(new QMaemo5DatePickSelector());
100   dateButton->setText(QString::fromUtf8("Date"));
101   leftLayout->addWidget(dateButton);
102 #else
103   QDate today(QDate::currentDate());
104   lineEditDate = new QLineEdit;
105   lineEditDate->setText(today.toString("yyyy-MM-dd"));
106   date = new QDateEdit;
107   leftLayout->addWidget(date);
108   leftLayout->addWidget(lineEditDate);
109 #endif
110
111   rightLayout = new QVBoxLayout;
112   rightLayout->addStretch();
113   rightLayout->addWidget(buttonBox);
114
115   QHBoxLayout *mainLayout = new QHBoxLayout(parent);
116   mainLayout->addLayout(leftLayout);
117   mainLayout->addLayout(rightLayout);
118
119   setLayout(mainLayout);
120 }
121
122 void SelectDialog::init(QList<Club *> &list)
123 {
124   clubList = list;
125
126   QListIterator<Club *> i(clubList);
127   int index = 0;
128
129   while (i.hasNext()) {
130     Club *club = i.next();
131
132     QList<Course *> courseList = club->getCourseList();
133
134     QListIterator<Course *> j(courseList);
135     while (j.hasNext()) {
136       Course *course = j.next();
137
138       QListWidgetItem *newItem = new QListWidgetItem;
139
140       QString entry = club->getName() + ", " + course->getName();
141
142       newItem->setText(entry);
143       listClub->insertItem(index, newItem);
144
145       index++;
146     }
147   }
148 }
149
150 void SelectDialog::results(QString &club, 
151                            QString &course, 
152                            QString &date)
153 {  
154   QListWidgetItem *current = listClub->currentItem();
155
156   if (current) {
157     QString tmp = current->text();
158
159     QStringList stringList = tmp.split(", ");
160     club = stringList[0];
161     course = stringList[1];
162 #ifdef Q_WS_MAEMO_5
163     QMaemo5DatePickSelector *sel = (QMaemo5DatePickSelector *)dateButton->pickSelector();
164     QDate d = sel->currentDate();
165     // TODO: change to QDate
166     date = d.toString(Qt::ISODate);
167 #else
168     date = lineEditDate->text();
169 #endif
170   }
171 }
172
173 bool SelectDialog::validate(void)
174 {
175   return true;
176 }
177
178 void SelectDialog::next(void)
179 {
180   if (validate())
181     done(1);
182   else {
183     qDebug() << "SelectDialog: invalid data, cancel or correct";
184   }
185 }
186
187 void SelectDialog::reject(void)
188 {
189   done(0);
190 }
191
192 ////////////////////////////////////////////////////////////////////////////////
193 // ScoreDialog based on QDialog
194 ////////////////////////////////////////////////////////////////////////////////
195 ScoreDialog::ScoreDialog(QWidget *parent) : QDialog(parent)
196 {
197     TRACE;
198     resize(800, 400);
199     QFont font;
200     font.setPointSize(fontSize);
201     setFont(font);
202
203     QWidget *centralWidget = new QWidget(this);
204
205     createTable();
206     createButton();
207     
208     createLayout(centralWidget);
209 }
210
211 ScoreDialog::~ScoreDialog()
212 {
213     //if (centralWidget)
214     //  delete centralWidget;
215     if (leftLayout)
216         delete leftLayout;
217     if (rightLayout)
218         delete rightLayout;
219     //if (mainLayout)
220     //  delete mainLayout;
221     if (table)
222         delete table;
223 }
224
225 void ScoreDialog::createLayout(QWidget *parent)
226 {
227     TRACE;
228     leftLayout = new QVBoxLayout;
229     leftLayout->addWidget(table);
230
231     QDialogButtonBox * buttonBoxUp = new QDialogButtonBox(Qt::Vertical);
232     buttonBoxUp->addButton(pushButtonUp, QDialogButtonBox::ActionRole);
233     buttonBoxUp->addButton(pushButtonDown, QDialogButtonBox::ActionRole);
234     buttonBoxUp->addButton(pushButtonNext, QDialogButtonBox::ActionRole);
235
236     QDialogButtonBox * buttonBoxDown = new QDialogButtonBox(Qt::Vertical);
237     buttonBoxDown->addButton(pushButtonFinish, QDialogButtonBox::ActionRole);
238
239     rightLayout = new QVBoxLayout;
240     rightLayout->addWidget(buttonBoxUp);
241     rightLayout->addStretch();
242     rightLayout->addWidget(buttonBoxDown);
243
244     QHBoxLayout *mainLayout = new QHBoxLayout(parent);
245     mainLayout->addLayout(leftLayout);
246     mainLayout->addLayout(rightLayout);
247     setLayout(mainLayout);
248 }
249
250 void ScoreDialog::createTable(QWidget *parent)
251 {
252     TRACE;
253     table = new QTableWidget(ROWS, COLS, parent);
254
255     table->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
256     table->verticalHeader()->setResizeMode(QHeaderView::Stretch);
257     table->horizontalHeader()->hide();
258
259     table->setStyleSheet(defaultStyleSheet);
260
261     QStringList headers;
262     headers << "" << "Par" << "HCP" << "Score" << "" << "Par" << "HCP" << "Score";
263     table->setVerticalHeaderLabels(headers);
264 }
265
266 void ScoreDialog::createButton(QWidget *parent)
267 {
268     TRACE;
269     Q_UNUSED(parent);
270     pushButtonUp = new QPushButton(tr("+"));
271     connect(pushButtonUp, SIGNAL(clicked()), this, SLOT(up()));
272     
273     pushButtonDown = new QPushButton(tr("-"));
274     connect(pushButtonDown, SIGNAL(clicked()), this, SLOT(down()));
275   
276     pushButtonNext = new QPushButton(tr("Next"));
277     connect(pushButtonNext, SIGNAL(clicked()), this, SLOT(next()));
278
279     pushButtonFinish = new QPushButton(tr("Finish"));
280     connect(pushButtonFinish, SIGNAL(clicked()), this, SLOT(finish()));
281 }
282
283 void ScoreDialog::init(Course *course, Score *score)
284 {
285     TRACE;
286     QTableWidgetItem *par, *hcp, *scoreItem, *holeNum;
287
288     for (int i = 0; i < 18; i++) {
289         par = new QTableWidgetItem(course->getPar(i));
290         hcp = new QTableWidgetItem(course->getHcp(i));
291         if (score)
292             scoreItem = new QTableWidgetItem(score->getScore(i));
293         else
294             scoreItem = new QTableWidgetItem("");
295         holeNum = new QTableWidgetItem(QString::number(i+1));
296
297         holeNum->setTextAlignment(Qt::AlignCenter);
298         holeNum->setFlags(Qt::NoItemFlags);
299         holeNum->setForeground(ScoreColor::holeBg());
300         
301         par->setTextAlignment(Qt::AlignCenter);
302         par->setFlags(Qt::NoItemFlags);
303
304         hcp->setTextAlignment(Qt::AlignCenter);
305         hcp->setFlags(Qt::NoItemFlags);
306         
307         scoreItem->setTextAlignment(Qt::AlignCenter);
308
309         if (i < 9) {
310             table->setItem(ROW_HOLE, i, holeNum);
311             table->setItem(ROW_PAR, i, par);
312             table->setItem(ROW_HCP, i, hcp);
313             table->setItem(ROW_SCORE, i, scoreItem);
314         }
315         else {
316             table->setItem(ROW_HOLE_2, i-9, holeNum);
317             table->setItem(ROW_PAR_2, i-9, par);
318             table->setItem(ROW_HCP_2, i-9, hcp);
319             table->setItem(ROW_SCORE_2, i-9, scoreItem);
320         }
321     }
322
323     // Set focus to 1st cell
324     table->setCurrentCell(ROW_SCORE, 0);
325     if (!score)
326         setDefaultScore(table);
327 }
328
329 // Set default score to par if not set
330 void ScoreDialog::setDefaultScore(QTableWidget *table)
331 {
332   int row = table->currentRow();
333   int col = table->currentColumn();
334   
335   if (row == ROW_SCORE)
336     row = ROW_PAR;
337   else if (row == ROW_SCORE_2)
338     row = ROW_PAR_2;
339   else {
340     qDebug() << "ERROR: unknown row in default score";
341     return;
342   }
343   QTableWidgetItem *par = table->item(row, col);
344   QTableWidgetItem *score = table->item(row + 2, col);
345
346   if (par && score && score->text() == "") {
347     QVariant value(par->text());
348     score->setData(Qt::DisplayRole, value);
349   }
350 }
351
352 void ScoreDialog::up(void)
353 {
354   QTableWidgetItem *item = table->currentItem();
355
356   if (!item) {
357     qWarning() << "ERROR: no current item";
358     return;
359   }
360
361   int i = (item->text()).toInt();
362   QVariant value(i+1);
363   item->setData(Qt::DisplayRole, value);
364 }
365
366 void ScoreDialog::down(void)
367 {
368   QTableWidgetItem *item = table->currentItem();
369
370   if (!item)
371     return;
372
373   int i = (item->text()).toInt();
374   QVariant value(i-1);
375   item->setData(Qt::DisplayRole, value);
376 }
377
378 void ScoreDialog::next(void)
379 {
380   if (table) {
381     QTableWidgetItem *item = table->currentItem();
382     moveToNextCell(item);
383     setDefaultScore(table);
384   }
385 }
386
387 void ScoreDialog::moveToNextCell(QTableWidgetItem *item)
388 {
389   if (!item)
390     return;
391
392   QTableWidget *table = item->tableWidget();
393
394   if (!table)
395     return;
396
397   int row = table->currentRow();
398   int col = table->currentColumn();
399
400   if (col < (COLS-1)) {
401     col++;
402   }
403   else if (col == (COLS-1)) {
404     col = 0;
405     row = (row == ROW_SCORE_2) ? ROW_SCORE : ROW_SCORE_2;
406   }
407   table->setCurrentCell(row, col);
408 }
409
410 void ScoreDialog::results(QVector<QString> &scores)
411 {
412     TRACE;
413     for (int i = 0; i < 9; i++) {
414         QTableWidgetItem *frontItem = table->item(ROW_SCORE, i);
415         QTableWidgetItem *backItem = table->item(ROW_SCORE_2, i);
416
417         if (frontItem)
418             scores[i] = frontItem->text();
419
420         if (backItem)
421             scores[i+9] = backItem->text();
422     }
423 }
424
425 bool ScoreDialog::validate(void)
426 {
427   for (int i=0; i<9; i++) {
428     QTableWidgetItem *frontItem = table->item(ROW_SCORE, i);
429     QTableWidgetItem *backItem = table->item(ROW_SCORE_2, i);
430     
431     if (!frontItem || !backItem)
432       return false;
433     
434     QString str1 = frontItem->text();
435     QString str2 = backItem->text();
436     
437     if (str1.isEmpty() || str2.isEmpty())
438       return false;
439   }
440   return true;
441 }
442
443 void ScoreDialog::finish(void)
444 {
445     if (validate())
446         done(1);
447     else {
448         showNote("Invalid data - cancel or correct");
449     }
450 }
451
452 void ScoreDialog::reject(void)
453 {
454   done(0);
455 }
456
457 void ScoreDialog::showNote(QString msg)
458 {
459 #ifdef Q_WS_MAEMO_5
460     QMaemo5InformationBox::information(this, 
461                                        msg,
462                                        QMaemo5InformationBox::DefaultTimeout);
463 #endif
464 }