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 "prefdialog.h"
20 
21 using namespace std;
22 
PrefDialog(QWidget * parent,Qt::WindowFlags f)23 PrefDialog::PrefDialog(QWidget* parent, Qt::WindowFlags f) : QDialog(parent, f)
24 {
25     setupUi(this);
26     setSizeGripEnabled(false);
27     mSuppressSlots = false;
28     InitControls();
29 }
30 
~PrefDialog()31 PrefDialog::~PrefDialog()
32 {
33 }
34 
InitControls()35 void PrefDialog::InitControls()
36 {
37     mLevelPresetsCmb->addItem(tr("... Select from predefined level settings"), -1);
38     mLevelPresetsCmb->addItem(tr("Beginner (2 Colors, 2 Slots, Doubles)"), 0);
39     mLevelPresetsCmb->addItem(tr("Easy (4 Colors, 3 Slots, No Doubles)"), 1);
40     mLevelPresetsCmb->addItem(tr("Classic (6 Colors, 4 Slots, Doubles)"), 2);
41     mLevelPresetsCmb->addItem(tr("Challenging (8 Colors, 4 Slots, Doubles)"), 3);
42     mLevelPresetsCmb->addItem(tr("Hard (10 Colors, 5 Slots, Doubles)"), 4);
43 
44     mPegCntCmb->addItem("2 " + tr("Slots"), 2);
45     mPegCntCmb->addItem("3 " + tr("Slots"), 3);
46     mPegCntCmb->addItem("4 " + tr("Slots"), 4);
47     mPegCntCmb->addItem("5 " + tr("Slots"), 5);
48 
49     mColorCntCmb->addItem("2 " + tr("Colors"), 2);
50     mColorCntCmb->addItem("3 " + tr("Colors"), 3);
51     mColorCntCmb->addItem("4 " + tr("Colors"), 4);
52     mColorCntCmb->addItem("5 " + tr("Colors"), 5);
53     mColorCntCmb->addItem("6 " + tr("Colors"), 6);
54     mColorCntCmb->addItem("7 " + tr("Colors"), 7);
55     mColorCntCmb->addItem("8 " + tr("Colors"), 8);
56     mColorCntCmb->addItem("9 " + tr("Colors"), 9);
57     mColorCntCmb->addItem("10 " + tr("Colors"), 10);
58 
59     mGameModeCmb->addItem(tr("Human vs. Computer"), ColorCode::MODE_HVM);
60     mGameModeCmb->addItem(tr("Computer vs. Human"), ColorCode::MODE_MVH);
61 
62     mStrengthCmb->addItem(tr("Low"), CCSolver::STRENGTH_LOW);
63     mStrengthCmb->addItem(tr("Medium"), CCSolver::STRENGTH_MEDIUM);
64     mStrengthCmb->addItem(tr("High"), CCSolver::STRENGTH_HIGH);
65     mDelaySb->setMaximum(10000);
66     mDelaySb->setMinimum(0);
67     mDelaySb->setSingleStep(100);
68 
69     mUserNameLe->setMaxLength(Settings::MAX_LENGTH_USERNAME);
70 
71     connect(mCustomRowHColorCb, SIGNAL(stateChanged(int)), this, SLOT(CustomRowHColorChangedSlot(int)));
72     connect(mRowHColorFgBtn, SIGNAL(clicked()), this, SLOT(SetBtnColorSlot()));
73     connect(mRowHColorBgBtn, SIGNAL(clicked()), this, SLOT(SetBtnColorSlot()));
74 
75     mRestoreBtn = mButtonBox->button(QDialogButtonBox::RestoreDefaults);
76     mOkBtn = mButtonBox->button(QDialogButtonBox::Ok);
77     mApplyBtn = mButtonBox->button(QDialogButtonBox::Apply);
78     mCancelBtn = mButtonBox->button(QDialogButtonBox::Cancel);
79 
80     connect(mLevelPresetsCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(LevelPresetChangedSlot()));
81     connect(mColorCntCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(ColorCntChangedSlot()));
82     connect(mPegCntCmb, SIGNAL(currentIndexChanged(int)), this, SLOT(PegCntChangedSlot()));
83     connect(mDoublesCb, SIGNAL(stateChanged(int)), this, SLOT(DoublesChangedSlot()));
84     connect(mShowIndicatorsCb, SIGNAL(stateChanged(int)), this, SLOT(ShowIndicatorsChangedSlot(int)));
85     connect(mShowTimerCb, SIGNAL(stateChanged(int)), this, SLOT(ShowTimerChangedSlot(int)));
86 
87     connect(mResetColorOrderBtn, SIGNAL(clicked()), this, SLOT(ResetColorOrderSlot()));
88 
89     connect(mRestoreBtn, SIGNAL(clicked()), this, SLOT(RestoreDefSlot()));
90     connect(mApplyBtn, SIGNAL(clicked()), this, SLOT(ApplySlot()));
91     connect(mCancelBtn, SIGNAL(clicked()), this, SLOT(CancelSlot()));
92     connect(mOkBtn, SIGNAL(clicked()), this, SLOT(OkSlot()));
93 
94     connect(mUseHighscoresCb, SIGNAL(stateChanged(int)), this, SLOT(UseHighscoresChangedSlot(int)));
95 }
96 
InitSettings()97 void PrefDialog::InitSettings()
98 {
99     mSettings = GetSettings();
100     SetSettings();
101 }
102 
SetSettings()103 void PrefDialog::SetSettings()
104 {
105     bool sup = SetSuppressSlots(true);
106 
107     mMenuBarCb->setChecked(mSettings->mShowMenuBar);
108     mStatusBarCb->setChecked(mSettings->mShowStatusBar);
109     mToolBarCb->setChecked(mSettings->mShowToolBar);
110     mShowGameNoCb->setChecked(mSettings->mShowGameNo);
111 
112     mShowTimerCb->setChecked(mSettings->mShowTimer);
113     mShowTenthCb->setChecked(mSettings->mShowTenth);
114     ShowTimerChangedSlot(mShowTimerCb->checkState());
115 
116     mShowIndicatorsCb->setChecked(mSettings->mShowIndicators);
117     if (mSettings->mIndicatorType == Settings::INDICATOR_NUMBER)
118     {
119         mNumbersRb->setChecked(true);
120     }
121     else
122     {
123         mLettersRb->setChecked(true);
124     }
125     mHideColorsCb->setChecked(mSettings->mHideColors);
126 
127     int i;
128     i = mColorCntCmb->findData(mSettings->mColorCnt);
129     if (i != -1 && mColorCntCmb->currentIndex() != i)
130     {
131         mColorCntCmb->setCurrentIndex(i);
132     }
133     i = mPegCntCmb->findData(mSettings->mPegCnt);
134     if (i != -1 && mPegCntCmb->currentIndex() != i)
135     {
136         mPegCntCmb->setCurrentIndex(i);
137     }
138 
139     mDoublesCb->setChecked(mSettings->mDoubles);
140     CheckDoubles();
141     CheckLevelPresets();
142 
143     i = mGameModeCmb->findData(mSettings->mGameMode);
144     if (i != -1 && mGameModeCmb->currentIndex() != i)
145     {
146         mGameModeCmb->setCurrentIndex(i);
147     }
148 
149     i = mStrengthCmb->findData(mSettings->mSolverStrength);
150     if (i != -1 && mStrengthCmb->currentIndex() != i)
151     {
152         mStrengthCmb->setCurrentIndex(i);
153     }
154 
155     mAutoCloseCb->setChecked(mSettings->mAutoClose);
156     mAutoHintsCb->setChecked(mSettings->mAutoHints);
157 
158     mDelaySb->setValue(mSettings->mHintsDelay);
159 
160     mGamesListMaxCntSb->setValue(mSettings->mGamesListMaxCnt);
161     mUserNameLe->setText(mSettings->mHighScoreUserName);
162     if (mSettings->mHighScoreHandling == Settings::HIGHSCORE_PROMPT)
163     {
164         mUseHighscoresCb->setChecked(true);
165         mHighscorePromptRb->setChecked(true);
166     }
167     else if(mSettings->mHighScoreHandling == Settings::HIGHSCORE_AUTO)
168     {
169         mUseHighscoresCb->setChecked(true);
170         mHighscoreAutoRb->setChecked(true);
171     }
172     else if (mSettings->mHighScoreHandling == Settings::HIGHSCORE_NO)
173     {
174         mUseHighscoresCb->setChecked(false);
175     }
176 
177     mCustomRowHColorCb->setChecked(mSettings->mCustomRowHColor);
178     CustomRowHColorChangedSlot(mCustomRowHColorCb->checkState());
179 
180     if (sup)
181     {
182         SetSuppressSlots(false);
183         ShowIndicatorsChangedSlot(mShowIndicatorsCb->checkState());
184         UseHighscoresChangedSlot(mUseHighscoresCb->checkState());
185     }
186 }
187 
LevelPresetChangedSlot()188 void PrefDialog::LevelPresetChangedSlot()
189 {
190     int ix, i;
191     ix = mLevelPresetsCmb->itemData(mLevelPresetsCmb->currentIndex()).toInt();
192 
193     if (ix < 0 || ix > 4)
194     {
195         return;
196     }
197 
198     bool sup = SetSuppressSlots(true);
199 
200     i = mColorCntCmb->findData(ColorCode::LEVEL_SETTINGS[ix][0]);
201     if (i != -1 && mColorCntCmb->currentIndex() != i)
202     {
203         mColorCntCmb->setCurrentIndex(i);
204     }
205     i = mPegCntCmb->findData(ColorCode::LEVEL_SETTINGS[ix][1]);
206     if (i != -1 && mPegCntCmb->currentIndex() != i)
207     {
208         mPegCntCmb->setCurrentIndex(i);
209     }
210 
211     mDoublesCb->setChecked((ColorCode::LEVEL_SETTINGS[ix][2] == 1));
212 
213     if (sup)
214     {
215         SetSuppressSlots(false);
216     }
217 }
218 
CheckLevelPresets()219 void PrefDialog::CheckLevelPresets()
220 {
221     int ix = -1;
222     for (int i = 0; i < 5; ++i)
223     {
224         if ( ColorCode::LEVEL_SETTINGS[i][0] == mColorCntCmb->itemData(mColorCntCmb->currentIndex()).toInt()
225              && ColorCode::LEVEL_SETTINGS[i][1] == mPegCntCmb->itemData(mPegCntCmb->currentIndex()).toInt()
226              && ColorCode::LEVEL_SETTINGS[i][2] == (int) mDoublesCb->isChecked() )
227         {
228             ix = i;
229             break;
230         }
231     }
232 
233     mLevelPresetsCmb->setCurrentIndex(mLevelPresetsCmb->findData(ix));
234 }
235 
CheckDoubles()236 void PrefDialog::CheckDoubles()
237 {
238     if (mColorCntCmb->itemData(mColorCntCmb->currentIndex()).toInt() < mPegCntCmb->itemData(mPegCntCmb->currentIndex()).toInt())
239     {
240         if (!mDoublesCb->isChecked())
241         {
242             mDoublesCb->setChecked(true);
243         }
244         mDoublesCb->setEnabled(false);
245     }
246     else
247     {
248         mDoublesCb->setEnabled(true);
249     }
250 }
251 
CustomRowHColorChangedSlot(int state)252 void PrefDialog::CustomRowHColorChangedSlot(int state)
253 {
254     bool en = (state == Qt::Checked);
255     mRowHColorFgBtn->setEnabled(en);
256     mRowHColorBgBtn->setEnabled(en);
257     mFgLbl->setEnabled(en);
258     mBgLbl->setEnabled(en);
259 
260     QColor color;
261     color = GetCurBtnColor(mRowHColorFgBtn);
262     if (!en)
263     {
264         color = Desaturate(color);
265     }
266     if (color.isValid())
267     {
268         SetSwatchStyleSheet(mRowHColorFgBtn, color.name());
269     }
270 
271     color = GetCurBtnColor(mRowHColorBgBtn);
272     if (!en)
273     {
274         color = Desaturate(color);
275     }
276     if (color.isValid())
277     {
278         SetSwatchStyleSheet(mRowHColorBgBtn, color.name());
279     }
280 }
281 
Desaturate(QColor c)282 QColor PrefDialog::Desaturate(QColor c)
283 {
284     qreal h;
285     qreal s;
286     qreal v;
287     qreal a;
288     c.getHsvF(&h, &s, &v, &a);
289 
290     v = qMin((0.8 + v * 0.2), 1.0);
291     c.setHsvF(h, (s * 0.2), v, 1.0);
292     return c;
293 }
294 
SetSwatchStyleSheet(QPushButton * btn,const QString colorstr)295 void PrefDialog::SetSwatchStyleSheet(QPushButton* btn, const QString colorstr)
296 {
297     btn->setStyleSheet(QString("QPushButton { background-color: " + colorstr + "; border: 1px solid palette(dark) } QPushButton:hover { border: 1px solid palette(highlight) }"));
298     btn->update();
299 }
300 
SetBtnColorSlot()301 void PrefDialog::SetBtnColorSlot()
302 {
303     QPushButton* btn = qobject_cast<QPushButton*>(sender());
304     SetBtnColor(btn);
305 }
306 
SetBtnColor(QPushButton * btn)307 void PrefDialog::SetBtnColor(QPushButton* btn)
308 {
309     if (mSettings == NULL || btn == NULL)
310     {
311         return;
312     }
313 
314     QColor curcolor = GetCurBtnColor(btn);
315 
316     if (curcolor.isValid())
317     {
318         curcolor = QColorDialog::getColor(curcolor, this);
319     }
320 
321     if (curcolor.isValid())
322     {
323         SetSwatchStyleSheet(btn, curcolor.name());
324 
325         if (btn == mRowHColorFgBtn)
326         {
327             mSettings->mRowHColorFg = curcolor.name();
328         }
329         else if (btn == mRowHColorBgBtn)
330         {
331             mSettings->mRowHColorBg = curcolor.name();
332         }
333     }
334 }
335 
GetCurBtnColor(const QPushButton * btn)336 QColor PrefDialog::GetCurBtnColor(const QPushButton* btn)
337 {
338     QColor color;
339 
340     if (mSettings != NULL)
341     {
342         if (btn == mRowHColorBgBtn)
343         {
344             color.setNamedColor(mSettings->mRowHColorBg);
345         }
346         else
347         {
348             color.setNamedColor(mSettings->mRowHColorFg);
349         }
350     }
351     if (mSettings == NULL || !color.isValid())
352     {
353         if (btn == mRowHColorBgBtn)
354         {
355             color = QApplication::palette().color(QPalette::Active, QPalette::Button);
356         }
357         else
358         {
359             color = QApplication::palette().color(QPalette::Active, QPalette::ButtonText);
360         }
361     }
362 
363     return color;
364 }
365 
ColorCntChangedSlot()366 void PrefDialog::ColorCntChangedSlot()
367 {
368     if (!mSuppressSlots)
369     {
370         CheckDoubles();
371         CheckLevelPresets();
372     }
373 }
374 
PegCntChangedSlot()375 void PrefDialog::PegCntChangedSlot()
376 {
377     if (!mSuppressSlots)
378     {
379         CheckDoubles();
380         CheckLevelPresets();
381     }
382 }
383 
DoublesChangedSlot()384 void PrefDialog::DoublesChangedSlot()
385 {
386     if (!mSuppressSlots)
387     {
388         CheckDoubles();
389         CheckLevelPresets();
390     }
391 }
392 
UseHighscoresChangedSlot(int state)393 void PrefDialog::UseHighscoresChangedSlot(int state)
394 {
395     if (!mSuppressSlots)
396     {
397         bool en = (state != Qt::Unchecked);
398         mHighscorePromptRb->setEnabled(en);
399         mHighscoreAutoRb->setEnabled(en);
400         mUserNameLe->setEnabled(en);
401         mUserNameLbl->setEnabled(en);
402     }
403 }
404 
ShowIndicatorsChangedSlot(int state)405 void PrefDialog::ShowIndicatorsChangedSlot(int state)
406 {
407     if (!mSuppressSlots)
408     {
409         bool en = (state != Qt::Unchecked);
410         mLettersRb->setEnabled(en);
411         mNumbersRb->setEnabled(en);
412         mHideColorsCb->setEnabled(en);
413     }
414 }
415 
ShowTimerChangedSlot(int state)416 void PrefDialog::ShowTimerChangedSlot(int state)
417 {
418     bool en = (state == Qt::Checked);
419     mShowTenthCb->setEnabled(en);
420 }
421 
ResetColorOrderSlot()422 void PrefDialog::ResetColorOrderSlot()
423 {
424     emit ResetColorOrderSignal();
425 }
426 
RestoreDefSlot()427 void PrefDialog::RestoreDefSlot()
428 {
429     mSettings->RestoreDefSettings();
430     SetSettings();
431 }
432 
ApplySlot()433 void PrefDialog::ApplySlot()
434 {
435     ApplySettings();
436     setResult(QDialog::Accepted);
437     accept();
438 }
439 
OkSlot()440 void PrefDialog::OkSlot()
441 {
442     ApplySettings();
443     setResult(QDialog::Accepted);
444     accept();
445 }
446 
CancelSlot()447 void PrefDialog::CancelSlot()
448 {
449     setResult(QDialog::Rejected);
450     reject();
451 }
452 
SetSuppressSlots(bool b,bool force)453 bool PrefDialog::SetSuppressSlots(bool b, bool force)
454 {
455     if (mSuppressSlots == b && !force)
456     {
457         return false;
458     }
459     mSuppressSlots = b;
460     return true;
461 }
462 
ApplySettings()463 void PrefDialog::ApplySettings()
464 {
465     mSettings->mShowMenuBar = mMenuBarCb->isChecked();
466     mSettings->mShowStatusBar = mStatusBarCb->isChecked();
467     mSettings->mShowToolBar = mToolBarCb->isChecked();
468     mSettings->mShowTimer = mShowTimerCb->isChecked();
469     mSettings->mShowTenth = mShowTenthCb->isChecked();
470     mSettings->mShowGameNo = mShowGameNoCb->isChecked();
471 
472     mSettings->mShowIndicators = mShowIndicatorsCb->isChecked();
473 
474     if (mNumbersRb->isChecked())
475     {
476         mSettings->mIndicatorType = Settings::INDICATOR_NUMBER;
477     }
478     else
479     {
480         mSettings->mIndicatorType = Settings::INDICATOR_LETTER;
481     }
482     mSettings->mHideColors = mHideColorsCb->isChecked();
483 
484     mSettings->mColorCnt = mColorCntCmb->itemData(mColorCntCmb->currentIndex()).toInt();
485     mSettings->mPegCnt = mPegCntCmb->itemData(mPegCntCmb->currentIndex()).toInt();
486     mSettings->mDoubles = mDoublesCb->isChecked();
487 
488     mSettings->mGameMode = mGameModeCmb->itemData(mGameModeCmb->currentIndex()).toInt();
489     mSettings->mSolverStrength = mStrengthCmb->itemData(mStrengthCmb->currentIndex()).toInt();
490 
491     mSettings->mAutoClose = mAutoCloseCb->isChecked();
492     mSettings->mAutoHints = mAutoHintsCb->isChecked();
493     mSettings->mHintsDelay = mDelaySb->value();
494 
495     mSettings->mHighScoreUserName = mUserNameLe->text();
496     mSettings->mGamesListMaxCnt = mGamesListMaxCntSb->value();
497     if (mUseHighscoresCb->isChecked())
498     {
499         if (mHighscorePromptRb->isChecked())
500         {
501             mSettings->mHighScoreHandling = Settings::HIGHSCORE_PROMPT;
502         }
503         else
504         {
505             mSettings->mHighScoreHandling = Settings::HIGHSCORE_AUTO;
506         }
507     }
508     else
509     {
510         mSettings->mHighScoreHandling = Settings::HIGHSCORE_NO;
511     }
512 
513     mSettings->mCustomRowHColor = mCustomRowHColorCb->isChecked();
514     mSettings->mRowHColorFg = GetCurBtnColor(mRowHColorFgBtn).name();
515     mSettings->mRowHColorBg = GetCurBtnColor(mRowHColorBgBtn).name();
516 
517     mSettings->Validate();
518 }
519 
sizeHint() const520 QSize PrefDialog::sizeHint () const
521 {
522     return QSize(500, 400);
523 }
524