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 "gameslistmodel.h"
20 #include "gametableview.h"
21
22 const int GamesListModel::MODEL_ID_DEFAULT = 0;
23 const int GamesListModel::MODEL_ID_PREV = 1;
24 const int GamesListModel::MODEL_ID_SAVED = 2;
25 const int GamesListModel::MODEL_ID_HIGH = 3;
26
27 const int GamesListModel::COL_RANKING = 0;
28 const int GamesListModel::COL_SCORE = 1;
29 const int GamesListModel::COL_USERNAME = 2;
30 const int GamesListModel::COL_DELETE = 3;
31 const int GamesListModel::COL_GAMENO = 4;
32 const int GamesListModel::COL_DATE = 5;
33 const int GamesListModel::COL_TIME = 6;
34 const int GamesListModel::COL_CCNT = 7;
35 const int GamesListModel::COL_PCNT = 8;
36 const int GamesListModel::COL_DOUBLES = 9;
37
SortListScore(CCGame a,CCGame b)38 bool GamesListModel::SortListScore(CCGame a, CCGame b)
39 {
40 if (a.GetScore() > b.GetScore())
41 {
42 return true;
43 }
44 return false;
45 }
46
SortListTime(CCGame a,CCGame b)47 bool GamesListModel::SortListTime(CCGame a, CCGame b)
48 {
49 if (a.mTime > b.mTime)
50 {
51 return true;
52 }
53 return false;
54 }
55
GamesListModel(QObject * parent)56 GamesListModel::GamesListModel(QObject* parent) : QAbstractTableModel(parent)
57 {
58 mId = MODEL_ID_DEFAULT;
59 mEditIndex = QModelIndex();
60 mMaxSize = 20;
61 mHoverRow = -1;
62 mRowHFg = QApplication::palette().color(QPalette::Active, QPalette::ButtonText);
63 mRowHBg = QApplication::palette().color(QPalette::Active, QPalette::Button);
64 }
65
GetId()66 int GamesListModel::GetId()
67 {
68 return mId;
69 }
70
GetListStr() const71 QString GamesListModel::GetListStr() const
72 {
73 QStringList strl;
74 for (int i = 0; i < mGamesList.size(); ++i)
75 {
76 strl << mGamesList.at(i).ToString();
77 }
78 return strl.join(";");
79 }
80
SetView(GameTableView * view)81 void GamesListModel::SetView(GameTableView* view)
82 {
83 mView = view;
84 }
85
SetMaxSize(const int max)86 void GamesListModel::SetMaxSize(const int max)
87 {
88 if (max != mMaxSize)
89 {
90 mMaxSize = max;
91 LimitGamesListSize();
92 }
93 }
94
SetRowHColors(QString fg,QString bg)95 void GamesListModel::SetRowHColors(QString fg, QString bg)
96 {
97 mRowHFg.setNamedColor(fg);
98 mRowHBg.setNamedColor(bg);
99 }
100
InsertRow(CCGame g)101 void GamesListModel::InsertRow(CCGame g)
102 {
103 mView->clearSelection();
104
105 bool found = false;
106 for (int i = 0; i < mGamesList.size(); ++i)
107 {
108 if (mGamesList.at(i).mGameNo == g.mGameNo)
109 {
110 mGamesList.replace(i, g);
111 found = true;
112 break;
113 }
114 }
115
116 if (!found)
117 {
118 beginInsertRows(QModelIndex(), rowCount(), rowCount());
119 mGamesList.push_back(g);
120 endInsertRows();
121 QModelIndex mix = index(rowCount() - 1, GetColIx(COL_DELETE), QModelIndex());
122 mView->openPersistentEditor(mix);
123 }
124
125 DoSort(mGamesList);
126 LimitGamesListSize();
127 emit layoutChanged();
128 }
129
LimitGamesListSize()130 void GamesListModel::LimitGamesListSize()
131 {
132 if (!mGamesList.isEmpty() && mGamesList.size() > mMaxSize)
133 {
134 removeRows(mMaxSize, mGamesList.size() - mMaxSize);
135 }
136 }
137
EditField()138 void GamesListModel::EditField()
139 {
140 if (mView != NULL && mEditIndex.isValid())
141 {
142 mView->setCurrentIndex(mEditIndex);
143 mView->selectRow(mEditIndex.row());
144 mView->edit(mEditIndex);
145 }
146 }
147
SetEditIndex(QModelIndex ix)148 void GamesListModel::SetEditIndex(QModelIndex ix)
149 {
150 mEditIndex = ix;
151 }
152
GetEditIndex() const153 QModelIndex GamesListModel::GetEditIndex() const
154 {
155 return mEditIndex;
156 }
157
GetEditValue() const158 QString GamesListModel::GetEditValue() const
159 {
160 QString val = "";
161 const CCGame* eg;
162 if (mEditIndex.isValid())
163 {
164 eg = GetGameAt(mEditIndex.row());
165 val = eg->GetUserName();
166 }
167 return val;
168 }
169
GetGameAt(const int row) const170 const CCGame* GamesListModel::GetGameAt(const int row) const
171 {
172 if (row > -1 && mGamesList.size() > row)
173 {
174 return &mGamesList.at(row);
175 }
176 return NULL;
177 }
178
ReadList(const QString & str)179 void GamesListModel::ReadList(const QString &str)
180 {
181 mEditIndex = QModelIndex();
182 if (rowCount() > 0)
183 {
184 removeRows(0, rowCount());
185 }
186
187 QStringList games = str.split(QString(";"));
188 CCGame* g;
189 QModelIndex mix;
190 for (int i = 0; i < games.size(); ++i)
191 {
192 g = new CCGame(games.at(i));
193 if (g->IsValidGame())
194 {
195 beginInsertRows(QModelIndex(), rowCount(), rowCount());
196 mGamesList.push_back(*g);
197 endInsertRows();
198
199 mix = index(rowCount() - 1, GetColIx(COL_DELETE), QModelIndex());
200 mView->openPersistentEditor(mix);
201 }
202 }
203 DoSort(mGamesList);
204 LimitGamesListSize();
205 emit layoutChanged();
206 }
207
HoverRowSlot(int row)208 void GamesListModel::HoverRowSlot(int row)
209 {
210 if (mHoverRow == row)
211 {
212 return;
213 }
214
215 int tmprow;
216 if (row == -1)
217 {
218 tmprow = mHoverRow;
219 }
220 else
221 {
222 tmprow = row;
223 }
224
225 mHoverRow = row;
226 emit dataChanged(index(tmprow, 0), index(tmprow, columnCount() - 1));
227 }
228
removeRows(int row,int count,const QModelIndex & parent)229 bool GamesListModel::removeRows(int row, int count, const QModelIndex &parent)
230 {
231 if (row < 0 || row + count > rowCount() || count == 0)
232 {
233 return false;
234 }
235
236 if (mEditIndex.isValid())
237 {
238 if (mEditIndex.row() >= row && mEditIndex.row() < row + count)
239 {
240 mEditIndex = QModelIndex();
241 }
242 else if (mEditIndex.row() >= row + count)
243 {
244 mEditIndex = createIndex(mEditIndex.row() - count, GetColIx(COL_USERNAME));
245 }
246 }
247 beginRemoveRows(parent, row, row + count - 1);
248 for (int i = row; i < row + count; ++i)
249 {
250 mGamesList.removeAt(row);
251 }
252 endRemoveRows();
253 return true;
254 }
255
flags(const QModelIndex & index) const256 Qt::ItemFlags GamesListModel::flags(const QModelIndex &index) const
257 {
258 if (index.isValid() && index == mEditIndex)
259 {
260 return Qt::ItemIsEnabled|Qt::ItemIsEditable;
261 }
262
263 return Qt::ItemIsEnabled;
264 }
265
setData(const QModelIndex & index,const QVariant & value,int role)266 bool GamesListModel::setData(const QModelIndex &index, const QVariant &value, int role)
267 {
268 if (role == Qt::EditRole && index.isValid() && index.row() < rowCount())
269 {
270 if (index.column() == GetColIx(COL_USERNAME))
271 {
272 if (index == mEditIndex)
273 {
274 CCGame g = mGamesList.at(index.row());
275 g.SetUserName(value.toString());
276 mGamesList.replace(index.row(), g);
277 if (g.GetUserName() != "")
278 {
279 emit ValidNameCommitSignal();
280 }
281 }
282 }
283 else if (index.column() == GetColIx(COL_DELETE))
284 {
285 bool ok;
286 int aid = value.toInt(&ok);
287 if (ok)
288 {
289 if (aid == ButtonsCell::ACTIONID_DELETE)
290 {
291 removeRows(index.row(), 1);
292 }
293 else
294 {
295 CCGame g = mGamesList.at(index.row());
296
297 if (aid == ButtonsCell::ACTIONID_SAVE)
298 {
299 CCGame* gc = new CCGame(g.ToString());
300 emit SaveListGameSignal(gc);
301 }
302 else if (aid == ButtonsCell::ACTIONID_PLAY)
303 {
304 CCGame* gc = new CCGame(g.ToString());
305 emit NewGameInputSignal(gc);
306 }
307 else if (aid == ButtonsCell::ACTIONID_COPY)
308 {
309 QClipboard* cb = QApplication::clipboard();
310 cb->setText(QString::number(g.mGameNo));
311 }
312 }
313 }
314 }
315
316 return true;
317 }
318 return false;
319 }
320
rowCount(const QModelIndex &) const321 int GamesListModel::rowCount(const QModelIndex &) const
322 {
323 return mGamesList.size();
324 }
325
columnCount(const QModelIndex &) const326 int GamesListModel::columnCount(const QModelIndex &) const
327 {
328 return GetMaxColCnt();
329 }
330
data(const QModelIndex & index,int role) const331 QVariant GamesListModel::data(const QModelIndex &index, int role) const
332 {
333 if (!(index.row() < mGamesList.size()) || !index.isValid())
334 {
335 return QVariant();
336 }
337 else if (role == Qt::TextAlignmentRole)
338 {
339 if (index.column() == GetColIx(COL_USERNAME)
340 || index.column() == GetColIx(COL_DATE)
341 || index.column() == GetColIx(COL_TIME)
342 || index.column() == GetColIx(COL_DOUBLES))
343 {
344 return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
345 }
346 return QVariant(Qt::AlignRight | Qt::AlignVCenter);
347 }
348 else if (role == Qt::BackgroundRole)
349 {
350 if (index == mEditIndex)
351 {
352 return QVariant(QApplication::palette().color(QPalette::Active, QPalette::Highlight));
353 }
354 else if (index.row() == mHoverRow)
355 {
356 return QVariant(mRowHBg);
357 }
358 }
359 else if (role == Qt::ForegroundRole)
360 {
361 if (index == mEditIndex)
362 {
363 return QVariant(QApplication::palette().color(QPalette::Active, QPalette::HighlightedText));
364 }
365 else if (index.row() == mHoverRow)
366 {
367 return QVariant(mRowHFg);
368 }
369 }
370 else if (role == Qt::DisplayRole || role == Qt::EditRole)
371 {
372 CCGame g = mGamesList.at(index.row());
373 if (index.column() == GetColIx(COL_RANKING))
374 {
375 return index.row() + 1;
376 }
377 else if (index.column() == GetColIx(COL_USERNAME))
378 {
379 return g.GetUserName();
380 }
381 else if (index.column() == GetColIx(COL_SCORE))
382 {
383 return g.GetScore();
384 }
385 else if (index.column() == GetColIx(COL_DATE))
386 {
387 return g.GetDatePartStr();
388 }
389 else if (index.column() == GetColIx(COL_TIME))
390 {
391 return g.GetTimePartStr();
392 }
393 else if (index.column() == GetColIx(COL_CCNT))
394 {
395 return g.mColorCnt;
396 }
397 else if (index.column() == GetColIx(COL_PCNT))
398 {
399 return g.mPegCnt;
400 }
401 else if (index.column() == GetColIx(COL_GAMENO))
402 {
403 return g.mGameNo;
404 }
405 else if (index.column() == GetColIx(COL_DOUBLES))
406 {
407 return (g.mDoubles == 1) ? tr("Yes") : tr("No");
408 }
409 else
410 {
411 return QVariant();
412 }
413 }
414
415 return QVariant();
416 }
417
headerData(int section,Qt::Orientation orientation,int role) const418 QVariant GamesListModel::headerData(int section, Qt::Orientation orientation, int role) const
419 {
420 if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
421 {
422 return GetHHeaderLabel(section);
423 }
424 else if (role == Qt::DecorationRole && orientation == Qt::Horizontal)
425 {
426 if (section == GetColIx(COL_DOUBLES))
427 {
428 return QVariant(QIcon(":/img/same_color_header.png"));
429 }
430 }
431 else if (role == Qt::ToolTipRole && orientation == Qt::Horizontal)
432 {
433 if (section == GetColIx(COL_DOUBLES))
434 {
435 return QVariant(QString(tr("Pegs of Same Color")));
436 }
437 else if (section == GetColIx(COL_DELETE))
438 {
439 return QVariant(QString(tr("Actions")));
440 }
441 else if (section == GetColIx(COL_RANKING))
442 {
443 return QVariant(QString(tr("Rank")));
444 }
445 }
446 return QVariant();
447 }
448
GetHHeaderLabel(const int col) const449 QString GamesListModel::GetHHeaderLabel(const int col) const
450 {
451 QString str;
452 if (col == GetColIx(COL_RANKING))
453 {
454 str = "";
455 }
456 else if (col == GetColIx(COL_USERNAME))
457 {
458 str = tr("User");
459 }
460 else if (col == GetColIx(COL_SCORE))
461 {
462 str = tr("Score");
463 }
464 else if (col == GetColIx(COL_DATE))
465 {
466 str = tr("Date");
467 }
468 else if (col == GetColIx(COL_TIME))
469 {
470 str = tr("Time");
471 }
472 else if (col == GetColIx(COL_CCNT))
473 {
474 str = tr("Colors");
475 }
476 else if (col == GetColIx(COL_PCNT))
477 {
478 str = tr("Slots");
479 }
480 else if (col == GetColIx(COL_GAMENO))
481 {
482 str = tr("Game No.");
483 }
484 else
485 {
486 str = "";
487 }
488 return str;
489 }
490