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"