/*************************************************************************** exercisecompare.cpp ------------------- begin : 2004/06/03 copyright : (C) 2004 by Sebastian Stein email : seb.kde@hpfsc.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "exercisecompare.h" #include "exercisecompare.moc" /* these includes are needed for KDE support */ #include #include /* these includes are needed for Qt support */ #include #include #include #include #include /* standard C++ library includes */ #include /* ----- public member functions ----- */ /* constructor */ ExerciseCompare::ExerciseCompare(QWidget * parent, const char * name): ExerciseBase(parent, name) { #ifdef DEBUG kdDebug() << "constructor ExerciseCompare()" << endl; #endif /* create a new task */ QApplication::setOverrideCursor(waitCursor); /* show the sand clock */ createTask(); QApplication::restoreOverrideCursor(); /* show the normal cursor */ // the next thing to do on a button click would be to check the entered // result m_currentState = _CHECK_TASK; baseWidget = new QWidget(this, "baseWidget"); baseGrid = new QGridLayout(this, 1, 1, 0, -1, "baseGrid"); baseGrid->addWidget(baseWidget, 0, 0); // this is a VBox realLayout = new QVBoxLayout(baseWidget, 5, 5, "realLayout"); // add a spacer at the top of the VBox QSpacerItem * v_spacer = new QSpacerItem(1, 1); realLayout->addItem(v_spacer); // now a line holding the task, input fields and result QHBoxLayout * taskLineHBoxLayout = new QHBoxLayout(5, "taskLineHBoxLayout"); realLayout->addLayout(taskLineHBoxLayout); // spacer v_spacer = new QSpacerItem(1, 1); taskLineHBoxLayout->addItem(v_spacer); // first the first ratio widget m_firstRatioWidget = new RatioWidget(baseWidget, "m_firstRatioWidget", m_firstRatio); taskLineHBoxLayout->addWidget(m_firstRatioWidget); // spacer v_spacer = new QSpacerItem(1, 1); taskLineHBoxLayout->addItem(v_spacer); // now the button where the user has to choose the comparison sign m_signButton = new QPushButton(baseWidget, "m_signButton"); // RTL BUG, see slotSignButtonClicked() for more information m_signButton->setText( QApplication::reverseLayout()?">":"<"); m_signButtonState = lessThen; taskLineHBoxLayout->addWidget(m_signButton); QObject::connect(m_signButton, SIGNAL(clicked()), this, SLOT(slotSignButtonClicked())); QToolTip::add(m_signButton, i18n("Click on this button to change the comparison sign.")); // spacer v_spacer = new QSpacerItem(1, 1); taskLineHBoxLayout->addItem(v_spacer); // now the second ratio widget m_secondRatioWidget = new RatioWidget(baseWidget, "m_secondRatioWidget", m_secondRatio); taskLineHBoxLayout->addWidget(m_secondRatioWidget); // spacer v_spacer = new QSpacerItem(1, 1); taskLineHBoxLayout->addItem(v_spacer); // at the right end we have a label just showing CORRECT or WRONG result_label = new QLabel(baseWidget, "result_label"); result_label->setText(i18n("WRONG")); taskLineHBoxLayout->addWidget(result_label); result_label->hide(); // --- that is the end of the horizontal line --- // add another spacer in the middle of the VBox v_spacer = new QSpacerItem(1, 1); realLayout->addItem(v_spacer); // the lower part of the VBox holds just a right aligned button QHBoxLayout * lowerHBox = new QHBoxLayout(1, "lowerHBox"); realLayout->addLayout(lowerHBox); lowerHBox->addStretch(100); // the right aligned button m_checkButton = new QPushButton( baseWidget, "m_checkButton" ); m_checkButton->setText(i18n("&Check Task")); m_checkButton->setDefault(true); // is the default button of the dialog QToolTip::add(m_checkButton, i18n("Click on this button to check your result.")); lowerHBox->addWidget(m_checkButton, 1, Qt::AlignRight); QObject::connect(m_checkButton, SIGNAL(clicked()), this, SLOT(slotCheckButtonClicked())); // that the user can start typing without moving the focus m_signButton->setFocus(); // show the whole layout baseWidget->show(); // add tooltip and qwhatsthis help to the widget QToolTip::add(this, i18n("In this exercise you have to compare 2 given fractions.")); QWhatsThis::add(this, i18n("In this exercise you have to compare 2 given fractions by choosing the correct comparison sign. You can change the comparison sign by just clicking on the button showing the sign.")); } /* destructor */ ExerciseCompare::~ExerciseCompare() { #ifdef DEBUG kdDebug() << "destructor ExerciseCompare()" << endl; #endif /* no need to delete any child widgets, Qt does it by itself */ } /** resets the current state, creates a new task and count the last task as * wrong, if it wasn't solved (in _NEXT_TASK state) yet * mainly used after changing the task parameters */ void ExerciseCompare::forceNewTask() { #ifdef DEBUG kdDebug() << "forceNewTask ExerciseCompare()" << endl; #endif if (m_currentState == _CHECK_TASK) { // emit the signal for wrong signalExerciseSolvedWrong(); } m_currentState = _CHECK_TASK; m_checkButton->setText(i18n("&Check Task")); // generate next task (void) nextTask(); } /* ------ public slots ------ */ void ExerciseCompare::update() { // call update of components m_firstRatioWidget->updateAndRepaint(); m_secondRatioWidget->updateAndRepaint(); // update for itself ((QWidget *) this)->update(); } /* ------ private member functions ------ */ void ExerciseCompare::createTask() { // generate the first ratio m_firstRatio = ratio(int((double(rand()) / RAND_MAX) * 10 + 1), int((double(rand()) / RAND_MAX) * 10 + 1)); // now the second ratio, but make sure, the second ratio is different from // the first one do { m_secondRatio = ratio(int((double(rand()) / RAND_MAX) * 10 + 1), int((double(rand()) / RAND_MAX) * 10 + 1)); } while (m_firstRatio == m_secondRatio); return; } /** - checks, if the user solved the task correctly - emits signals if task was solved correctly or wrong */ void ExerciseCompare::showResult() { QPalette pal; QColorGroup cg; bool result = m_firstRatio < m_secondRatio; // change the tooltip of the check button QToolTip::add(m_checkButton, i18n("Click on this button to get to the next task.")); // disable sign button m_signButton->setEnabled(false); if ((m_signButtonState == lessThen && result == true) || (m_signButtonState == greaterThen && result == false)) { // emit the signal for correct signalExerciseSolvedCorrect(); /* yes, the user entered the correct result */ result_label->setText(i18n("CORRECT")); pal = result_label->palette(); /* set green font color */ cg = pal.active(); cg.setColor(QColorGroup::Foreground, QColor(6, 179, 0)); pal.setActive(cg); cg = pal.inactive(); cg.setColor(QColorGroup::Foreground, QColor(6, 179, 0)); pal.setInactive(cg); result_label->setPalette(pal); result_label->show(); /* show the result at the end of the task */ } else { // emit the signal for wrong signalExerciseSolvedWrong(); /* no, the user entered the wrong result */ result_label->setText(i18n("WRONG")); pal = result_label->palette(); /* set red font color */ cg = pal.active(); cg.setColor(QColorGroup::Foreground, QColor(red)); pal.setActive(cg); cg = pal.inactive(); cg.setColor(QColorGroup::Foreground, QColor(red)); pal.setInactive(cg); result_label->setPalette(pal); result_label->show(); /* show the result at the end of the task */ } /* if (entered_result == result) */ return; } /** generate the next task and show it to the user */ void ExerciseCompare::nextTask() { // change the tooltip of the check button QToolTip::add(m_checkButton, i18n("Click on this button to check your result.")); // enable sign button m_signButton->setEnabled(true); result_label->hide(); /* do not show the result at the end of the task */ // reset the signButton // RTL BUG, see slotSignButtonClicked() for more information m_signButton->setText( QApplication::reverseLayout()?">":"<"); m_signButtonState = lessThen; /* create a new task */ QApplication::setOverrideCursor(waitCursor); /* show the sand clock */ createTask(); QApplication::restoreOverrideCursor(); /* show the normal cursor */ // set the ratio widgets with the new ratios m_firstRatioWidget->setRatio(m_firstRatio); m_secondRatioWidget->setRatio(m_secondRatio); return; } /* ------ private slots ------ */ void ExerciseCompare::slotCheckButtonClicked() { if (m_currentState == _CHECK_TASK) { m_currentState = _NEXT_TASK; m_checkButton->setText(i18n("N&ext Task")); (void) showResult(); } else { m_currentState = _CHECK_TASK; m_checkButton->setText(i18n("&Check Task")); (void) nextTask(); } return; } void ExerciseCompare::slotSignButtonClicked() { // in RTL desktops, we still need to allign the // execise to the left. On Qt4, you can set the direction // of the layout to LTR (instead of inherit), but on Qt3 // the only way of fixing it is inserting the widgets in reversed // order to the layout. // // But... as an ugly hack, we can also display the "other" operation // thats damm ugly, but will work as well :) // // See also taskview.cpp for the same bug. // // (if you need help with this feel free to contact // (me - Diego ) // This shuold fix parts of bug #116831, if (m_signButtonState == lessThen) { m_signButton->setText( QApplication::reverseLayout()?"<":">"); m_signButtonState = greaterThen; } else { m_signButton->setText( QApplication::reverseLayout()?">":"<"); m_signButtonState = lessThen; } return; }