1 /* ColorCode, a free MasterMind clone with built in solver
2 * Copyright (C) 2009 Dirk Laebisch
3 * http://www.laebisch.com/
4 *
5 * ColorCode is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * ColorCode is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with ColorCode. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "gametablesdialog.h"
20 #include "ui_gametablesdialog.h"
21 #include "gametableview.h"
22 #include "highscoresmodel.h"
23 #include "prevgamesmodel.h"
24 #include "savedgamesmodel.h"
25 #include "buttondelegate.h"
26 #include "ccsolver.h"
27 #include "ccgame.h"
28 #include "settings.h"
29
30 const int GameTablesDialog::TABIX_INPUT = 0;
31 const int GameTablesDialog::TABIX_PREVIOUS = 1;
32 const int GameTablesDialog::TABIX_BOOKMARKS = 2;
33 const int GameTablesDialog::TABIX_HIGHSCORES = 3;
34
35
GameTablesDialog(QWidget * parent,Qt::WindowFlags f)36 GameTablesDialog::GameTablesDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f), ui(new Ui::GameTablesDialog)
37 {
38 ui->setupUi(this);
39 Init();
40 }
41
~GameTablesDialog()42 GameTablesDialog::~GameTablesDialog()
43 {
44 delete ui;
45 }
46
Init()47 void GameTablesDialog::Init()
48 {
49 setModal(true);
50 setMouseTracking(true);
51 setAttribute(Qt::WA_Hover, true);
52 setAttribute(Qt::WA_AlwaysShowToolTips, true);
53
54 mLastGameProperties = NULL;
55
56 ui->mDescriptionTe->setFocusPolicy(Qt::NoFocus);
57 ui->mDescriptionTe->setAttribute(Qt::WA_TransparentForMouseEvents);
58 ui->mDescriptionTe->setText(tr("Insert an arbitrary game number greater than 0 in the input field above. <br><br>"
59 "The game properties like color count, slot count etc. will be displayed in the corresponding area above.<br><br>"
60 "Click the Play button or press key Enter, to play the game. If a game is currently running, it will be aborted."));
61
62 ui->mGameNoLe->setValidator(new QIntValidator(1, INT_MAX, this));
63
64 connect(ui->mGameNoLe, SIGNAL(textChanged(const QString)), this, SLOT(GameNoInpChangedSlot(const QString)));
65
66
67 mPrevTableView = new GameTableView();
68 mPrevTableView->SetGamesListModel(GetPrevGamesModel());
69 mPrevTableView->setColumnWidth(GetPrevGamesModel()->GetColIx(GamesListModel::COL_RANKING), 20);
70 mPrevTableView->setColumnWidth(GetPrevGamesModel()->GetColIx(GamesListModel::COL_DATE), 90);
71 mPrevTableView->setColumnWidth(GetPrevGamesModel()->GetColIx(GamesListModel::COL_TIME), 90);
72 mPrevTableView->setColumnWidth(GetPrevGamesModel()->GetColIx(GamesListModel::COL_DELETE), 40);
73
74 mPrevTableView->setItemDelegateForColumn(GetPrevGamesModel()->GetColIx(GamesListModel::COL_RANKING), new ButtonDelegate());
75 mPrevTableView->setItemDelegateForColumn(GetPrevGamesModel()->GetColIx(GamesListModel::COL_DATE), new ButtonDelegate());
76 mPrevTableView->setItemDelegateForColumn(GetPrevGamesModel()->GetColIx(GamesListModel::COL_TIME), new ButtonDelegate());
77 mPrevTableView->setItemDelegateForColumn(GetPrevGamesModel()->GetColIx(GamesListModel::COL_DELETE), new ButtonDelegate());
78
79 GetPrevGamesModel()->SetView(mPrevTableView);
80
81 ui->mPrevTab->layout()->addWidget(mPrevTableView);
82
83 connect(mPrevTableView, SIGNAL(HoverRowSignal(int)), this, SLOT(HoverRowSlot(int)));
84 connect(GetPrevGamesModel(), SIGNAL(CloseEditorSignal(QModelIndex)), mPrevTableView, SLOT(CloseEditorSlot(QModelIndex)));
85 connect(GetPrevGamesModel(), SIGNAL(NewGameInputSignal(CCGame*)), this, SLOT(NewGameInputSlot(CCGame*)));
86
87
88 mSavedTableView = new GameTableView();
89 mSavedTableView->SetGamesListModel(GetSavedGamesModel());
90 mSavedTableView->setColumnWidth(GetSavedGamesModel()->GetColIx(GamesListModel::COL_GAMENO), 70);
91 mSavedTableView->setColumnWidth(GetSavedGamesModel()->GetColIx(GamesListModel::COL_CCNT), 50);
92 mSavedTableView->setColumnWidth(GetSavedGamesModel()->GetColIx(GamesListModel::COL_PCNT), 50);
93 mSavedTableView->setColumnWidth(GetSavedGamesModel()->GetColIx(GamesListModel::COL_DOUBLES), 30);
94 mSavedTableView->setColumnWidth(GetSavedGamesModel()->GetColIx(GamesListModel::COL_DELETE), 40);
95
96 mSavedTableView->setItemDelegateForColumn(GetSavedGamesModel()->GetColIx(GamesListModel::COL_GAMENO), new ButtonDelegate());
97 mSavedTableView->setItemDelegateForColumn(GetSavedGamesModel()->GetColIx(GamesListModel::COL_CCNT), new ButtonDelegate());
98 mSavedTableView->setItemDelegateForColumn(GetSavedGamesModel()->GetColIx(GamesListModel::COL_PCNT), new ButtonDelegate());
99 mSavedTableView->setItemDelegateForColumn(GetSavedGamesModel()->GetColIx(GamesListModel::COL_DOUBLES), new ButtonDelegate());
100 mSavedTableView->setItemDelegateForColumn(GetSavedGamesModel()->GetColIx(GamesListModel::COL_DELETE), new ButtonDelegate());
101
102 GetSavedGamesModel()->SetView(mSavedTableView);
103
104 ui->mSavedTab->layout()->addWidget(mSavedTableView);
105
106 connect(mSavedTableView, SIGNAL(HoverRowSignal(int)), this, SLOT(HoverRowSlot(int)));
107 connect(GetSavedGamesModel(), SIGNAL(CloseEditorSignal(QModelIndex)), mSavedTableView, SLOT(CloseEditorSlot(QModelIndex)));
108 connect(GetSavedGamesModel(), SIGNAL(NewGameInputSignal(CCGame*)), this, SLOT(NewGameInputSlot(CCGame*)));
109
110
111 mHighTableView = new GameTableView();
112 mHighTableView->SetGamesListModel(GetHighScoresModel());
113 mHighTableView->setColumnWidth(GetHighScoresModel()->GetColIx(GamesListModel::COL_RANKING), 20);
114 mHighTableView->setColumnWidth(GetHighScoresModel()->GetColIx(GamesListModel::COL_SCORE), 60);
115 mHighTableView->setColumnWidth(GetHighScoresModel()->GetColIx(GamesListModel::COL_USERNAME), 120);
116 mHighTableView->setColumnWidth(GetHighScoresModel()->GetColIx(GamesListModel::COL_DELETE), 40);
117
118 mHighTableView->setItemDelegateForColumn(GetHighScoresModel()->GetColIx(GamesListModel::COL_RANKING), new ButtonDelegate());
119 mHighTableView->setItemDelegateForColumn(GetHighScoresModel()->GetColIx(GamesListModel::COL_SCORE), new ButtonDelegate());
120 mHighTableView->setItemDelegateForColumn(GetHighScoresModel()->GetColIx(GamesListModel::COL_USERNAME), new ButtonDelegate());
121 mHighTableView->setItemDelegateForColumn(GetHighScoresModel()->GetColIx(GamesListModel::COL_DELETE), new ButtonDelegate());
122
123 GetHighScoresModel()->SetView(mHighTableView);
124
125 ui->mHighTab->layout()->addWidget(mHighTableView);
126
127 connect(mHighTableView, SIGNAL(HoverRowSignal(int)), this, SLOT(HoverRowSlot(int)));
128 connect(GetHighScoresModel(), SIGNAL(CloseEditorSignal(QModelIndex)), mHighTableView, SLOT(CloseEditorSlot(QModelIndex)));
129 connect(GetHighScoresModel(), SIGNAL(NewGameInputSignal(CCGame*)), this, SLOT(NewGameInputSlot(CCGame*)));
130 connect(GetHighScoresModel(), SIGNAL(ValidNameCommitSignal()), this, SLOT(ValidNameCommitSlot()));
131
132
133 connect(GetPrevGamesModel(), SIGNAL(SaveListGameSignal(CCGame*)), this, SLOT(InsertSavedGameSlot(CCGame*)));
134 connect(GetHighScoresModel(), SIGNAL(SaveListGameSignal(CCGame*)), this, SLOT(InsertSavedGameSlot(CCGame*)));
135
136
137 connect(ui->mTabsWidget, SIGNAL(currentChanged(int)), this, SLOT(CurrentTabChanged(int)));
138
139 connect(ui->mCloseBtn, SIGNAL(clicked()), this, SLOT(OkBtnSlot()));
140 connect(ui->mClearBtn, SIGNAL(clicked()), this, SLOT(ClearListSlot()));
141 connect(ui->mPlayBtn, SIGNAL(clicked()), this, SLOT(PlayInputSlot()));
142 }
143
ShowTab(int tabix)144 void GameTablesDialog::ShowTab(int tabix)
145 {
146 if (ui->mTabsWidget->currentIndex() != tabix)
147 {
148 ui->mTabsWidget->setCurrentIndex(tabix);
149 }
150 else
151 {
152 CurrentTabChanged(tabix);
153 }
154 show();
155 }
156
ShowInputSlot()157 void GameTablesDialog::ShowInputSlot()
158 {
159 ShowTab(TABIX_INPUT);
160 }
161
ShowPrevSlot()162 void GameTablesDialog::ShowPrevSlot()
163 {
164 ShowTab(TABIX_PREVIOUS);
165 }
166
ShowSavedSlot()167 void GameTablesDialog::ShowSavedSlot()
168 {
169 ShowTab(TABIX_BOOKMARKS);
170 }
171
ShowHighSlot()172 void GameTablesDialog::ShowHighSlot()
173 {
174 ShowTab(TABIX_HIGHSCORES);
175 }
176
177
HoverRowSlot(const int row)178 void GameTablesDialog::HoverRowSlot(const int row)
179 {
180 if (row > -1)
181 {
182 GamesListModel* glm = GetCurModel();
183 if (glm != NULL)
184 {
185 SetGameProperties(glm->GetGameAt(row));
186 }
187 else
188 {
189 SetGameProperties(NULL);
190 }
191 }
192 else
193 {
194 SetGameProperties(NULL);
195 }
196 }
197
GetCurModel() const198 GamesListModel* GameTablesDialog::GetCurModel() const
199 {
200 GamesListModel* glm;
201
202 int ix = ui->mTabsWidget->currentIndex();
203 if (ix == TABIX_PREVIOUS)
204 {
205 glm = qobject_cast<GamesListModel*>(GetPrevGamesModel());
206 }
207 else if (ix == TABIX_BOOKMARKS)
208 {
209 glm = qobject_cast<GamesListModel*>(GetSavedGamesModel());
210 }
211 else if (ix == TABIX_HIGHSCORES)
212 {
213 glm = qobject_cast<GamesListModel*>(GetHighScoresModel());
214 }
215 else
216 {
217 glm = NULL;
218 }
219
220 return glm;
221 }
222
GetCurView() const223 GameTableView* GameTablesDialog::GetCurView() const
224 {
225 GameTableView* gtv;
226
227 int ix = ui->mTabsWidget->currentIndex();
228 if (ix == TABIX_PREVIOUS)
229 {
230 gtv = qobject_cast<GameTableView*>(mPrevTableView);
231 }
232 else if (ix == TABIX_BOOKMARKS)
233 {
234 gtv = qobject_cast<GameTableView*>(mSavedTableView);
235 }
236 else if (ix == TABIX_HIGHSCORES)
237 {
238 gtv = qobject_cast<GameTableView*>(mHighTableView);
239 }
240 else
241 {
242 gtv = NULL;
243 }
244
245 return gtv;
246 }
247
SetGameProperties(const CCGame * g)248 void GameTablesDialog::SetGameProperties(const CCGame* g)
249 {
250 if (g != NULL && g->IsValidGame())
251 {
252 if (mLastGameProperties == NULL || mLastGameProperties != g)
253 {
254 mLastGameProperties = const_cast<CCGame*>(g);
255
256 int ix = ui->mTabsWidget->currentIndex();
257 switch (ix)
258 {
259 case TABIX_PREVIOUS:
260 case TABIX_BOOKMARKS:
261 ui->mUserValLbl->setText("");
262 ui->mDurationValLbl->setText("");
263 ui->mDateValLbl->setText(g->GetDateTimeStr());
264 break;
265 case TABIX_HIGHSCORES:
266 ui->mUserValLbl->setText(g->GetUserName());
267 ui->mDurationValLbl->setText(FormatDuration(g->mDuration));
268 ui->mDateValLbl->setText(g->GetDateTimeStr());
269 break;
270 case TABIX_INPUT:
271 ui->mDateValLbl->setText("");
272 break;
273 }
274
275 ui->mColorCntValLbl->setText(QString::number(g->mColorCnt));
276 ui->mPegCntValLbl->setText(QString::number(g->mPegCnt));
277 QString str = (g->mDoubles == 1) ? tr("Yes") : tr("No");
278 ui->mDoublesValLbl->setText(str);
279 ui->mGameNoValLbl->setText(QString::number(g->mGameNo));
280 }
281 }
282 else
283 {
284 mLastGameProperties = NULL;
285
286 ui->mUserValLbl->setText("");
287 ui->mColorCntValLbl->setText("");
288 ui->mPegCntValLbl->setText("");
289 ui->mDoublesValLbl->setText("");
290 ui->mGameNoValLbl->setText("");
291 ui->mDateValLbl->setText("");
292 ui->mDurationValLbl->setText("");
293 }
294 }
295
FormatDuration(const uint dur) const296 QString GameTablesDialog::FormatDuration(const uint dur) const
297 {
298 QTime t(0, 0, 0, 0);
299 t = t.addMSecs(int(dur));
300 QString tstr = QString("%1 : %2 : %3 : %4").arg( t.toString("hh"), t.toString("mm"), t.toString("ss"), t.toString("zzz"));
301 return tstr;
302 }
303
ReadSettingsGamesSlot()304 void GameTablesDialog::ReadSettingsGamesSlot()
305 {
306 SetSettingsSlot();
307
308 GetPrevGamesModel()->ReadList(GetSettings()->mPrevGamesStr);
309 GetSavedGamesModel()->ReadList(GetSettings()->mSavedGamesStr);
310 GetHighScoresModel()->ReadList(GetSettings()->mHighGamesStr);
311 clearFocus();
312 }
313
SetSettingsSlot()314 void GameTablesDialog::SetSettingsSlot()
315 {
316 GetPrevGamesModel()->SetMaxSize(GetSettings()->mGamesListMaxCnt);
317 GetSavedGamesModel()->SetMaxSize(GetSettings()->mGamesListMaxCnt);
318 GetHighScoresModel()->SetMaxSize(GetSettings()->mGamesListMaxCnt);
319 GetPrevGamesModel()->SetRowHColors(GetSettings()->GetActiveRowHFg(), GetSettings()->GetActiveRowHBg());
320 GetSavedGamesModel()->SetRowHColors(GetSettings()->GetActiveRowHFg(), GetSettings()->GetActiveRowHBg());
321 GetHighScoresModel()->SetRowHColors(GetSettings()->GetActiveRowHFg(), GetSettings()->GetActiveRowHBg());
322 }
323
InsertHighScoreSlot(CCGame * g)324 void GameTablesDialog::InsertHighScoreSlot(CCGame* g)
325 {
326 if (GetSettings()->mHighScoreHandling == Settings::HIGHSCORE_NO)
327 {
328 return;
329 }
330
331 if (GetHighScoresModel()->IsValidHighScore(g->mScore))
332 {
333 CCGame game = *g;
334 game.SetUserName(GetSettings()->mHighScoreUserName);
335 if (GetSettings()->mHighScoreHandling != Settings::HIGHSCORE_AUTO || GetSettings()->mHighScoreUserName == "")
336 {
337 ShowTab(GameTablesDialog::TABIX_HIGHSCORES);
338 }
339 GetHighScoresModel()->InsertRow(game);
340 }
341 }
342
InsertPrevGameSlot(CCGame * g)343 void GameTablesDialog::InsertPrevGameSlot(CCGame* g)
344 {
345 CCGame game = *g;
346 game.Anonymize();
347 GetPrevGamesModel()->InsertRow(game);
348 }
349
InsertSavedGameSlot(CCGame * g)350 void GameTablesDialog::InsertSavedGameSlot(CCGame* g)
351 {
352 CCGame game = *g;
353 game.Anonymize();
354 game.mTime = QDateTime::currentDateTime().toTime_t();
355 GetSavedGamesModel()->InsertRow(game);
356 }
357
OkBtnSlot()358 void GameTablesDialog::OkBtnSlot()
359 {
360 close();
361 }
362
ClearListSlot()363 void GameTablesDialog::ClearListSlot()
364 {
365 GamesListModel* glm = GetCurModel();
366 if (glm == NULL)
367 {
368 return;
369 }
370
371 int rcnt = glm->rowCount();
372 if (rcnt <= 0)
373 {
374 return;
375 }
376
377 int r = QMessageBox::warning( this,
378 tr("Message"),
379 tr("This will permanently remove all entries from the List.\nDo You want to proceed?"),
380 QMessageBox::Yes | QMessageBox::No,
381 QMessageBox::Yes);
382
383 if (r == QMessageBox::Yes)
384 {
385 rcnt = glm->rowCount();
386 if (rcnt > 0)
387 {
388 glm->removeRows(0, rcnt);
389 }
390 }
391 }
392
PlayInputSlot()393 void GameTablesDialog::PlayInputSlot()
394 {
395 if (ui->mTabsWidget->currentIndex() == TABIX_INPUT
396 && ui->mGameNoLe->text() != "")
397 {
398 uint gameno = ui->mGameNoLe->text().toUInt();
399 if (gameno > 0)
400 {
401 const int* props = ColorCode::INSTANCE->GetCCSolver()->GetGameByNo(gameno);
402 CCGame* g = new CCGame("", 0, 0, gameno, 0, 0, 0, ColorCode::MODE_HVM, props[1], props[2], props[3]);
403 NewGameInputSlot(g);
404 }
405 }
406 }
407
GameNoInpChangedSlot(const QString & txt)408 void GameTablesDialog::GameNoInpChangedSlot(const QString &txt)
409 {
410 if (txt != "" && txt.toUInt() > 0)
411 {
412 const int* props = ColorCode::INSTANCE->GetCCSolver()->GetGameByNo(txt.toUInt());
413 CCGame* g = new CCGame("", 0, 0, txt.toUInt(), 0, 0, 0, ColorCode::MODE_HVM, props[1], props[2], props[3]);
414 SetGameProperties(g);
415 }
416 else
417 {
418 SetGameProperties(NULL);
419 }
420 }
421
NewGameInputSlot(CCGame * g)422 void GameTablesDialog::NewGameInputSlot(CCGame* g)
423 {
424 emit NewGameInputSignal(g);
425 close();
426 }
427
ValidNameCommitSlot()428 void GameTablesDialog::ValidNameCommitSlot()
429 {
430 if (ui->mTabsWidget->currentIndex() == TABIX_HIGHSCORES)
431 {
432 ui->mCloseBtn->setFocus();
433 }
434 }
435
SetRowHeight()436 void GameTablesDialog::SetRowHeight()
437 {
438 for (int i = 0; i < GetHighScoresModel()->rowCount(); ++i)
439 {
440 mHighTableView->setRowHeight(i, 18);
441 }
442 }
443
CurrentTabChanged(int ix)444 void GameTablesDialog::CurrentTabChanged(int ix)
445 {
446 mLastGameProperties = NULL;
447 SetGameProperties(NULL);
448
449 QString str = "";
450 QIcon ico;
451 switch (ix)
452 {
453 case TABIX_INPUT:
454 ui->mPlayBtn->setVisible(true);
455 ui->mClearBtn->setVisible(false);
456 ui->mGameNoLe->setFocus();
457 ui->mUserLbl->setEnabled(false);
458 ui->mDurationLbl->setEnabled(false);
459 ui->mDateLbl->setEnabled(false);
460 GameNoInpChangedSlot(ui->mGameNoLe->text());
461 str = tr("Game Number Input");
462 ico = QIcon(":/img/document-new.png");
463 break;
464 case TABIX_PREVIOUS:
465 ui->mPlayBtn->setVisible(false);
466 ui->mClearBtn->setVisible(true);
467 ui->mUserLbl->setEnabled(false);
468 ui->mDurationLbl->setEnabled(false);
469 ui->mDateLbl->setEnabled(true);
470 str = tr("Recent Games");
471 ico = QIcon(":/img/history.png");
472 break;
473 case TABIX_BOOKMARKS:
474 ui->mPlayBtn->setVisible(false);
475 ui->mClearBtn->setVisible(true);
476 ui->mUserLbl->setEnabled(false);
477 ui->mDurationLbl->setEnabled(false);
478 ui->mDateLbl->setEnabled(true);
479 str = tr("Bookmarked Games");
480 ico = QIcon(":/img/bookmark.png");
481 break;
482 case TABIX_HIGHSCORES:
483 ui->mPlayBtn->setVisible(false);
484 ui->mClearBtn->setVisible(true);
485 ui->mUserLbl->setEnabled(true);
486 ui->mDurationLbl->setEnabled(true);
487 ui->mDateLbl->setEnabled(true);
488 str = tr("High Score List");
489 ico = QIcon(":/img/games-highscores.png");
490 break;
491 default:
492 str = tr("Game Lists");
493 break;
494 }
495 setWindowTitle(str);
496 setWindowIcon(ico);
497 }
498
closeEvent(QCloseEvent * e)499 void GameTablesDialog::closeEvent(QCloseEvent* e)
500 {
501 GetHighScoresModel()->EditField();
502 if (GetHighScoresModel()->GetEditIndex().isValid() && GetHighScoresModel()->GetEditValue() == "")
503 {
504 e->ignore();
505
506 int r = QMessageBox::warning( this,
507 tr("Message"),
508 tr("Please provide a name!\nOtherwise your score won't be saved."),
509 QMessageBox::Ok | QMessageBox::Discard,
510 QMessageBox::Ok);
511
512 if (r == QMessageBox::Discard)
513 {
514 GetHighScoresModel()->removeRows(GetHighScoresModel()->GetEditIndex().row(), 1);
515 e->accept();
516 }
517 else
518 {
519 GetHighScoresModel()->EditField();
520 }
521 }
522 else
523 {
524 GetHighScoresModel()->SetEditIndex(QModelIndex());
525 e->accept();
526 }
527 }
528
reject()529 void GameTablesDialog::reject()
530 {
531 close();
532 }
533
changeEvent(QEvent * e)534 void GameTablesDialog::changeEvent(QEvent *e)
535 {
536 QDialog::changeEvent(e);
537 switch (e->type())
538 {
539 case QEvent::LanguageChange:
540 ui->retranslateUi(this);
541 break;
542 default:
543 break;
544 }
545 }
546