File indexing completed on 2024-04-21 03:41:47
0001 /* 0002 SPDX-FileCopyrightText: 2004 Sebastian Stein <seb.kde@hpfsc.de> 0003 SPDX-FileCopyrightText: 2008 Tadeu Araujo <tadeu.araujo@ltia.fc.unesp.br> 0004 SPDX-FileCopyrightText: 2008 Danilo Balzaque <danilo.balzaque@ltia.fc.unesp.br> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "ExerciseCompare.h" 0010 0011 /* these includes are needed for KDE support */ 0012 #include <KLocalizedString> 0013 0014 /* these includes are needed for Qt support */ 0015 #include <QApplication> 0016 #include <QPushButton> 0017 #include <QRandomGenerator> 0018 0019 #ifdef DEBUG 0020 #include <QDebug> 0021 #endif 0022 0023 /* standard C++ library includes */ 0024 #include <cstdlib> 0025 0026 #include "settingsclass.h" 0027 0028 /* ----- public member functions ----- */ 0029 0030 /* constructor */ 0031 ExerciseCompare::ExerciseCompare(QWidget * parent) : 0032 ExerciseBase(parent) 0033 { 0034 #ifdef DEBUG 0035 qDebug() << QStringLiteral("constructor ExerciseCompare()"); 0036 #endif 0037 0038 QApplication::setOverrideCursor(Qt::WaitCursor); /* show the sand clock */ 0039 createTask(); 0040 QApplication::restoreOverrideCursor(); /* show the normal cursor */ 0041 0042 m_currentState = _CHECK_TASK; 0043 0044 QFont defaultFont = SettingsClass::taskFont(); 0045 defaultFont.setBold(true); 0046 defaultFont.setPointSize(12); 0047 0048 // Create layout 0049 taskWidget = new QWidget(this); 0050 taskWidget->setObjectName(QStringLiteral("taskWidget")); 0051 checkWidget = new QWidget(this); 0052 checkWidget->setObjectName(QStringLiteral("checkWidget")); 0053 0054 baseGrid = new QGridLayout(this); 0055 baseGrid->setObjectName(QStringLiteral("baseGrid")); 0056 baseGrid->setColumnStretch(0, 1); 0057 0058 baseGrid->addWidget(taskWidget, 0, 0); 0059 baseGrid->addWidget(checkWidget, 0, 1); 0060 0061 taskLayout = new QGridLayout(taskWidget); 0062 taskLayout->setObjectName(QStringLiteral("taskLayout")); 0063 taskLayout->setRowStretch(0, 1); 0064 taskLayout->setRowStretch(4, 1); 0065 taskLayout->setColumnStretch(0, 1); 0066 taskLayout->setColumnStretch(4, 1); 0067 0068 checkLayout = new QGridLayout(checkWidget); 0069 checkLayout->setObjectName(QStringLiteral("checkLayout")); 0070 0071 // first the first ratio widget 0072 m_firstRatioWidget = new RatioWidget(taskWidget, m_firstRatio); 0073 m_firstRatioWidget->setObjectName(QStringLiteral("m_firstRatioWidget")); 0074 taskLayout->addWidget(m_firstRatioWidget, 1, 1, 3, 1); 0075 0076 // now the second ratio widget 0077 m_secondRatioWidget = new RatioWidget(taskWidget, m_secondRatio); 0078 m_secondRatioWidget->setObjectName(QStringLiteral("m_secondRatioWidget")); 0079 taskLayout->addWidget(m_secondRatioWidget, 1, 3, 3, 1); 0080 0081 // Create compare buttons 0082 m_moreButton = new QPushButton(taskWidget); 0083 m_moreButton->setObjectName(QStringLiteral("m_moreButton")); 0084 m_moreButton->setText(i18n(">")); 0085 m_moreButton->setFixedSize(74, 30); 0086 m_moreButton->setFont(defaultFont); 0087 QObject::connect(m_moreButton, &QPushButton::clicked, this, &ExerciseCompare::slotMoreButtonClicked); 0088 m_moreButton->setToolTip(i18n("Click on this button to select the 'greater than' sign.")); 0089 taskLayout->addWidget(m_moreButton, 1, 2); 0090 0091 m_minorButton = new QPushButton(taskWidget); 0092 m_minorButton->setObjectName(QStringLiteral("m_minorButton")); 0093 m_minorButton->setText(i18n("<")); 0094 m_minorButton->setFixedSize(74, 30); 0095 m_minorButton->setFont(defaultFont); 0096 QObject::connect(m_minorButton, &QPushButton::clicked, this, &ExerciseCompare::slotMinorButtonClicked); 0097 m_minorButton->setToolTip(i18n("Click on this button to select the 'less than' sign.")); 0098 taskLayout->addWidget(m_minorButton, 2, 2); 0099 0100 m_equalButton = new QPushButton(taskWidget); 0101 m_equalButton->setObjectName(QStringLiteral("m_equalButton")); 0102 m_equalButton->setText(i18n("=")); 0103 m_equalButton->setFixedSize(74, 30); 0104 m_equalButton->setFont(defaultFont); 0105 QObject::connect(m_equalButton, &QPushButton::clicked, this, &ExerciseCompare::slotEqualButtonClicked); 0106 m_equalButton->setToolTip(i18n("Click on this button to select the 'equals' sign.")); 0107 taskLayout->addWidget(m_equalButton, 3, 2); 0108 0109 // Create Skip and Check buttons 0110 m_resultWidget = new ResultWidget(checkWidget); 0111 m_resultWidget->setObjectName(QStringLiteral("m_resultWidget")); 0112 checkLayout->addWidget(m_resultWidget, 0, 0); 0113 0114 defaultFont.setPointSize(10); 0115 0116 m_skipButton = new QPushButton(checkWidget); 0117 m_skipButton->setObjectName(QStringLiteral("m_skipButton")); 0118 m_skipButton->setText(i18n("&Skip")); 0119 m_skipButton->setToolTip(i18n("Click on this button to skip this question.")); 0120 m_skipButton->setFont(defaultFont); 0121 QObject::connect(m_skipButton, &QPushButton::clicked, this, &ExerciseCompare::slotSkipButtonClicked); 0122 checkLayout->addWidget(m_skipButton, 1, 0); 0123 0124 m_equalButton->setFocusPolicy(Qt::NoFocus); 0125 m_moreButton->setFocusPolicy(Qt::NoFocus); 0126 m_minorButton->setFocusPolicy(Qt::NoFocus); 0127 m_skipButton->setFocusPolicy(Qt::NoFocus); 0128 0129 setLayout(baseGrid); 0130 taskWidget->setLayout(taskLayout); 0131 checkWidget->setLayout(checkLayout); 0132 0133 // add tooltip and qwhatsthis help to the widget 0134 setToolTip(i18n("In this exercise you have to compare two given fractions.")); 0135 setWhatsThis(i18n("In this exercise you have to compare two given fractions and choose the correct comparison sign.")); 0136 0137 // that the user can start typing without moving the focus 0138 m_equalButton->setFocus(); 0139 } 0140 0141 /* destructor */ 0142 ExerciseCompare::~ExerciseCompare() 0143 { 0144 #ifdef DEBUG 0145 qDebug() << QStringLiteral("destructor ExerciseCompare()"); 0146 #endif 0147 0148 /* no need to delete any child widgets, Qt does it by itself */ 0149 } 0150 0151 /** resets the current state, creates a new task and count the last task as 0152 * wrong, if it wasn't solved (in _NEXT_TASK state) yet 0153 * mainly used after changing the task parameters */ 0154 void ExerciseCompare::forceNewTask() 0155 { 0156 #ifdef DEBUG 0157 qDebug() << QStringLiteral("forceNewTask ExerciseCompare()"); 0158 #endif 0159 0160 if (m_currentState == _CHECK_TASK) { 0161 // emit the signal for skipped 0162 Q_EMIT signalExerciseSkipped(); 0163 } 0164 m_currentState = _CHECK_TASK; 0165 0166 // generate next task 0167 (void) nextTask(); 0168 } 0169 0170 void ExerciseCompare::setQuestionMixed(bool value) 0171 { 0172 m_firstRatioWidget->setQuestionMixed(value); 0173 m_secondRatioWidget->setQuestionMixed(value); 0174 } 0175 0176 /* ------ public slots ------ */ 0177 0178 void ExerciseCompare::update() 0179 { 0180 // call update of components 0181 m_firstRatioWidget->updateAndRepaint(); 0182 m_secondRatioWidget->updateAndRepaint(); 0183 0184 // update for itself 0185 ((QWidget *) this)->update(); 0186 } 0187 0188 0189 /* ------ private member functions ------ */ 0190 0191 void ExerciseCompare::createTask() 0192 { 0193 // generate the first ratio 0194 m_firstRatio = Ratio(QRandomGenerator::global()->bounded(10) + 1, QRandomGenerator::global()->bounded(10) + 1); 0195 0196 // now the second ratio, but make sure, the second ratio is different from 0197 // the first one 0198 do { 0199 m_secondRatio = Ratio(QRandomGenerator::global()->bounded(10) + 1, QRandomGenerator::global()->bounded(10) + 1); 0200 } while (m_firstRatio == m_secondRatio); 0201 0202 return; 0203 } 0204 0205 /** - checks, if the user solved the task correctly 0206 - emits signals if task was solved correctly or wrong */ 0207 void ExerciseCompare::showResult() 0208 { 0209 SignButtonState result; 0210 0211 if (m_firstRatio < m_secondRatio) 0212 result = lessThen; 0213 else if (m_firstRatio > m_secondRatio) 0214 result = greaterThen; 0215 else 0216 result = equalTo; 0217 0218 0219 // disable sign button 0220 m_minorButton->setEnabled(false); 0221 m_moreButton->setEnabled(false); 0222 m_equalButton->setEnabled(false); 0223 0224 if (m_signButtonState == result) { 0225 // emit the signal for correct 0226 Q_EMIT signalExerciseSolvedCorrect(); 0227 0228 /* yes, the user entered the correct result */ 0229 m_resultWidget->setResult(1); 0230 } else { 0231 // emit the signal for wrong 0232 Q_EMIT signalExerciseSolvedWrong(); 0233 0234 /* no, the user entered the wrong result */ 0235 0236 m_resultWidget->setResult(2); 0237 } /* if (entered_result == result) */ 0238 0239 return; 0240 } 0241 0242 /** generate the next task and show it to the user */ 0243 void ExerciseCompare::nextTask() 0244 { 0245 // change the tooltip of the check button 0246 m_equalButton->setToolTip(i18n("Click on this button to check your result.")); 0247 m_moreButton->setToolTip(i18n("Click on this button to check your result.")); 0248 m_minorButton->setToolTip(i18n("Click on this button to check your result.")); 0249 // enable sign button 0250 m_equalButton->setEnabled(true); 0251 m_minorButton->setEnabled(true); 0252 m_moreButton->setEnabled(true); 0253 0254 // reset the signButton 0255 m_signButtonState = lessThen; 0256 0257 /* create a new task */ 0258 QApplication::setOverrideCursor(Qt::WaitCursor); /* show the sand clock */ 0259 createTask(); 0260 QApplication::restoreOverrideCursor(); /* show the normal cursor */ 0261 0262 // set the ratio widgets with the new ratios 0263 m_firstRatioWidget->setRatio(m_firstRatio); 0264 m_secondRatioWidget->setRatio(m_secondRatio); 0265 0266 return; 0267 } 0268 0269 /* ------ private slots ------ */ 0270 0271 void ExerciseCompare::slotSkipButtonClicked() 0272 { 0273 #ifdef DEBUG 0274 qDebug() << "ExerciseCompare::slotSkipButtonClicked()"; 0275 #endif 0276 if (m_currentState == _CHECK_TASK) { 0277 forceNewTask(); 0278 } else { 0279 m_currentState = _CHECK_TASK; 0280 m_skipButton->setText(i18n("&Skip")); 0281 m_resultWidget->setResult(m_firstRatio, -1); 0282 nextTask(); 0283 } 0284 0285 return; 0286 } 0287 0288 void ExerciseCompare::slotMinorButtonClicked() 0289 { 0290 #ifdef DEBUG 0291 qDebug() << QStringLiteral("ExerciseCompare::slotMinorButtonClicked()"); 0292 #endif 0293 0294 m_currentState = _NEXT_TASK; 0295 m_skipButton->setText(i18n("&Next")); 0296 m_signButtonState = lessThen; 0297 showResult(); 0298 0299 return; 0300 } 0301 0302 void ExerciseCompare::slotMoreButtonClicked() 0303 { 0304 #ifdef DEBUG 0305 qDebug() << QStringLiteral("ExerciseCompare::slotMoreButtonClicked()"); 0306 #endif 0307 0308 m_currentState = _NEXT_TASK; 0309 m_skipButton->setText(i18n("&Next")); 0310 m_signButtonState = greaterThen; 0311 showResult(); 0312 0313 return; 0314 } 0315 0316 void ExerciseCompare::slotEqualButtonClicked() 0317 { 0318 #ifdef DEBUG 0319 qDebug() << QStringLiteral("ExerciseCompare::slotEqualButtonClicked()"); 0320 #endif 0321 0322 m_currentState = _NEXT_TASK; 0323 m_skipButton->setText(i18n("&Next")); 0324 m_signButtonState = equalTo; 0325 showResult(); 0326 0327 return; 0328 } 0329 0330 #include "moc_ExerciseCompare.cpp"