moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kbruch / src / exercisefactorize.cpp
blobb08ff4d940be31bc60b50b8393c7e8e43c41567c
1 /***************************************************************************
2 exerciseconvert.h
3 -------------------
4 begin : 2004/06/04
5 copyright : (C) 2004 by Sebastian Stein
6 email : seb.kde@hpfsc.de
7 ***************************************************************************/
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
18 #include "exercisefactorize.h"
19 #include "exercisefactorize.moc"
21 /* these includes are needed for KDE support */
22 #include <kapplication.h>
23 #include <klocale.h>
24 #include <kmessagebox.h>
25 #include <knumvalidator.h>
27 /* these includes are needed for Qt support */
28 #include <qlabel.h>
29 #include <qlayout.h>
30 #include <qlineedit.h>
31 #include <qpushbutton.h>
32 #include <qtooltip.h>
33 #include <qwhatsthis.h>
35 /* standard C++ library includes */
36 #include <stdlib.h>
38 #include "factorizedwidget.h"
39 #include "primenumber.h"
40 #include "rationalwidget.h"
41 #include "resultwidget.h"
42 #include "settingsclass.h"
44 /* ----- public member functions ----- */
46 /* constructor */
47 ExerciseFactorize::ExerciseFactorize(QWidget * parent, const char * name):
48 ExerciseBase(parent, name)
50 QPalette pal;
51 QColorGroup cg;
52 #ifdef DEBUG
53 kdDebug() << "constructor ExerciseFactorize()" << endl;
54 #endif
56 /* create a new task */
57 QApplication::setOverrideCursor(waitCursor); /* show the sand clock */
58 createTask();
59 QApplication::restoreOverrideCursor(); /* show the normal cursor */
61 // the next thing to do on a button click would be to check the entered
62 // result
63 m_currentState = _CHECK_TASK;
65 Form1Layout = new QVBoxLayout( this, 11, 6, "Form1Layout");
67 layout9 = new QVBoxLayout( 0, 0, 6, "layout9");
69 layout4 = new QHBoxLayout( 0, 0, 6, "layout4");
71 m_taskLabel = new QLabel( this, "m_taskLabel" );
72 layout4->addWidget( m_taskLabel );
74 m_equalSignLabel = new QLabel( this, "m_equalSignLabel" );
75 layout4->addWidget( m_equalSignLabel );
77 m_factorsEnteredEdit = new QLineEdit( this, "m_factorsEnteredEdit" );
78 layout4->addWidget( m_factorsEnteredEdit );
79 m_factorsEnteredEdit->setReadOnly(true);
80 m_factorsEnteredEdit->setEnabled(false);
81 m_factorsEnteredEdit->setPaletteForegroundColor(QColor(0, 0, 0));
83 m_factorsWidget = new FactorizedWidget( this, "m_factorsWidget", m_factorsResult);
84 layout4->addWidget( m_factorsWidget );
85 m_factorsWidget->hide();
87 result_label = new QLabel( this, "result_label" );
88 layout4->addWidget( result_label );
89 spacer1 = new QSpacerItem( 25, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
90 layout4->addItem( spacer1 );
92 layout9->addLayout( layout4 );
93 spacer2 = new QSpacerItem( 20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding );
94 layout9->addItem( spacer2 );
96 layout2 = new QVBoxLayout( 0, 0, 6, "layout2");
98 layout1 = new QGridLayout( 0, 1, 1, 0, 6, "layout1");
100 m_factor3Button = new QPushButton( this, "m_factor3Button" );
101 layout1->addWidget( m_factor3Button, 0, 1 );
103 m_factor2Button = new QPushButton( this, "m_factor2Button" );
104 layout1->addWidget( m_factor2Button, 0, 0 );
106 m_factor13Button = new QPushButton( this, "m_factor13Button" );
107 layout1->addWidget( m_factor13Button, 1, 1 );
109 m_factor7Button = new QPushButton( this, "m_factor7Button" );
110 layout1->addWidget( m_factor7Button, 0, 3 );
112 m_factor11Button = new QPushButton( this, "m_factor11Button" );
113 layout1->addWidget( m_factor11Button, 1, 0 );
115 m_factor19Button = new QPushButton( this, "m_factor19Button" );
116 layout1->addWidget( m_factor19Button, 1, 3 );
118 m_factor5Button = new QPushButton( this, "m_factor5Button" );
119 layout1->addWidget( m_factor5Button, 0, 2 );
121 m_factor17Button = new QPushButton( this, "m_factor17Button" );
122 layout1->addWidget( m_factor17Button, 1, 2 );
124 layout2->addLayout( layout1 );
126 m_removeLastFactorButton = new QPushButton( this, "m_removeLastFactorButton" );
127 layout2->addWidget( m_removeLastFactorButton );
128 layout9->addLayout( layout2 );
130 spacer4 = new QSpacerItem( 20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding );
131 layout9->addItem( spacer4 );
133 layout7 = new QHBoxLayout( 0, 0, 6, "layout7");
134 spacer3 = new QSpacerItem( 361, 20, QSizePolicy::Expanding, QSizePolicy::Minimum );
135 layout7->addItem( spacer3 );
137 m_checkButton = new QPushButton( this, "m_checkButton" );
138 layout7->addWidget( m_checkButton );
139 layout9->addLayout( layout7 );
140 Form1Layout->addLayout( layout9 );
142 // the current task
143 QString tmp_str;
144 tmp_str.setNum(m_taskNumber);
145 m_taskLabel->setText(tmp_str);
147 // now set the color for the task label
148 m_taskLabel->setPaletteForegroundColor(SettingsClass::numberColor());
150 // the equal sign
151 m_equalSignLabel->setText("=");
153 // now set the color for the equal sign
154 m_equalSignLabel->setPaletteForegroundColor(SettingsClass::operationColor());
156 // the wrong/correct label, we hide it
157 result_label->setText(i18n("WRONG"));
158 result_label->hide();
160 // the prime factor buttons
161 m_factor2Button->setText( i18n( "2" ) );
162 m_factor3Button->setText( i18n( "3" ) );
163 m_factor5Button->setText( i18n( "5" ) );
164 m_factor7Button->setText( i18n( "7" ) );
165 m_factor11Button->setText( i18n( "11" ) );
166 m_factor13Button->setText( i18n( "13" ) );
167 m_factor17Button->setText( i18n( "17" ) );
168 m_factor19Button->setText( i18n( "19" ) );
169 QObject::connect(m_factor2Button, SIGNAL(clicked()), this, SLOT(slotFactor2ButtonClicked()));
170 QObject::connect(m_factor3Button, SIGNAL(clicked()), this, SLOT(slotFactor3ButtonClicked()));
171 QObject::connect(m_factor5Button, SIGNAL(clicked()), this, SLOT(slotFactor5ButtonClicked()));
172 QObject::connect(m_factor7Button, SIGNAL(clicked()), this, SLOT(slotFactor7ButtonClicked()));
173 QObject::connect(m_factor11Button, SIGNAL(clicked()), this, SLOT(slotFactor11ButtonClicked()));
174 QObject::connect(m_factor13Button, SIGNAL(clicked()), this, SLOT(slotFactor13ButtonClicked()));
175 QObject::connect(m_factor17Button, SIGNAL(clicked()), this, SLOT(slotFactor17ButtonClicked()));
176 QObject::connect(m_factor19Button, SIGNAL(clicked()), this, SLOT(slotFactor19ButtonClicked()));
178 // add tooltips to the factor buttons
179 QToolTip::add(m_factor2Button, i18n("Add prime factor 2."));
180 QToolTip::add(m_factor3Button, i18n("Add prime factor 3."));
181 QToolTip::add(m_factor5Button, i18n("Add prime factor 5."));
182 QToolTip::add(m_factor7Button, i18n("Add prime factor 7."));
183 QToolTip::add(m_factor11Button, i18n("Add prime factor 11."));
184 QToolTip::add(m_factor13Button, i18n("Add prime factor 13."));
185 QToolTip::add(m_factor17Button, i18n("Add prime factor 17."));
186 QToolTip::add(m_factor19Button, i18n("Add prime factor 19."));
188 // the remove last factor button
189 m_removeLastFactorButton->setText( i18n( "&Remove Last Factor" ) );
190 m_removeLastFactorButton->setEnabled(false);
191 QObject::connect(m_removeLastFactorButton, SIGNAL(clicked()), this, SLOT(slotRemoveLastFactorButtonClicked()));
192 QToolTip::add(m_removeLastFactorButton, i18n("Removes the last entered prime factor."));
194 // the check task button
195 m_checkButton->setText( i18n( "&Check Task" ) );
196 QToolTip::add(m_checkButton, i18n("Click on this button to check your result. The button will not work if you have not entered a result yet."));
197 QObject::connect(m_checkButton, SIGNAL(clicked()), this, SLOT(slotCheckButtonClicked()));
198 m_checkButton->setDefault(true); // is the default button of the dialog
200 // that the user can start choosing the prime factors
201 m_factor2Button->setFocus();
203 // set the tab order
204 setTabOrder(m_factor2Button, m_factor3Button);
205 setTabOrder(m_factor3Button, m_factor5Button);
206 setTabOrder(m_factor5Button, m_factor7Button);
207 setTabOrder(m_factor7Button, m_factor11Button);
208 setTabOrder(m_factor13Button, m_factor17Button);
209 setTabOrder(m_factor17Button, m_factor19Button);
210 setTabOrder(m_factor19Button, m_removeLastFactorButton);
212 // add tooltip and qwhatsthis help to the widget
213 QToolTip::add(this, i18n("In this exercise you have to factorize a given number."));
214 QWhatsThis::add(this, i18n("In this exercise you have to factorize a given number. You have to enter all prime factors of the number. You can add a prime factor by clicking on the corresponding button. The chosen prime factors will be shown in the input field. Do not forget to enter all prime factors, even when a prime factor repeats several times!"));
217 /* destructor */
218 ExerciseFactorize::~ExerciseFactorize()
220 #ifdef DEBUG
221 kdDebug() << "destructor ExerciseFactorize()" << endl;
222 #endif
224 /* no need to delete any child widgets, Qt does it by itself */
227 /** resets the current state, creates a new task and count the last task as
228 * wrong, if it wasn't solved (in _NEXT_TASK state) yet
229 * mainly used after changing the task parameters */
230 void ExerciseFactorize::forceNewTask()
232 #ifdef DEBUG
233 kdDebug() << "forceNewTask ExerciseFactorize()" << endl;
234 #endif
236 if (m_currentState == _CHECK_TASK)
238 // emit the signal for wrong
239 signalExerciseSolvedWrong();
241 m_currentState = _CHECK_TASK;
242 m_checkButton->setText(i18n("&Check Task"));
244 // generate next task
245 (void) nextTask();
249 /* ------ public slots ------ */
251 void ExerciseFactorize::update()
253 // now set the color for the task label
254 m_taskLabel->setPaletteForegroundColor(SettingsClass::numberColor());
256 // now set the color for the equal sign
257 m_equalSignLabel->setPaletteForegroundColor(SettingsClass::operationColor());
259 // and the factors
260 m_factorsWidget->updateAndRepaint();
262 // update for itself
263 ((QWidget *) this)->update();
267 /* ------ private member functions ------ */
269 void ExerciseFactorize::createTask()
271 uint uint_number;
272 primenumber tmp_primenumber;
274 // just pick one number out of the possible numbers to factorize
275 m_taskNumber = possibleTasks[uint((double(rand()) / RAND_MAX) * numberPossibleTasks)];
277 // now get the primefactors of the taskNumber
278 m_factorsResult.clear();
279 uint_number = m_taskNumber;
280 tmp_primenumber.move_first();
283 // check if the current primenumber is a divisor
284 if (uint_number % tmp_primenumber.get_current() != 0)
286 // no, it is not a divisor, go on with next primenumber
287 tmp_primenumber.move_forward();
288 } else {
289 // current primenumber is a divisor
290 m_factorsResult.append(tmp_primenumber.get_current());
291 uint_number = uint(uint_number / tmp_primenumber.get_current());
293 } while (uint_number != 1);
295 return;
298 /** - checks, if the user solved the task correctly
299 - emits signals if task was solved correctly or wrong */
300 void ExerciseFactorize::showResult()
302 QString tmp_str, tmp_str2; /* to build a string for a label */
303 QPalette pal;
304 QColorGroup cg;
305 uint uint_result = 0;
307 // change the tooltip of the check button
308 QToolTip::add(m_checkButton, i18n("Click on this button to get to the next task."));
310 // disable prime factor buttons
311 m_factor2Button->setEnabled(false);
312 m_factor3Button->setEnabled(false);
313 m_factor5Button->setEnabled(false);
314 m_factor7Button->setEnabled(false);
315 m_factor11Button->setEnabled(false);
316 m_factor13Button->setEnabled(false);
317 m_factor17Button->setEnabled(false);
318 m_factor19Button->setEnabled(false);
320 // disable factor removal button as well
321 m_removeLastFactorButton->setEnabled(false);
323 // show the result
324 m_factorsWidget->setFactors(m_factorsResult);
325 m_factorsWidget->show();
327 // now calculate the product of the prime factors entered by the user
328 for (uint tmp_uint = 0; tmp_uint < m_factorsEntered.count(); tmp_uint++)
330 if (tmp_uint == 0)
332 uint_result = m_factorsEntered[0];
333 } else {
334 uint_result *= m_factorsEntered[tmp_uint];
338 if (uint_result == m_taskNumber)
340 // emit the signal for correct
341 signalExerciseSolvedCorrect();
343 /* yes, the user entered the correct result */
344 result_label->setText(i18n("CORRECT"));
345 pal = result_label->palette(); /* set green font color */
346 cg = pal.active();
347 cg.setColor(QColorGroup::Foreground, QColor(6, 179, 0));
348 pal.setActive(cg);
349 cg = pal.inactive();
350 cg.setColor(QColorGroup::Foreground, QColor(6, 179, 0));
351 pal.setInactive(cg);
352 result_label->setPalette(pal);
353 } else {
354 // emit the signal for wrong
355 signalExerciseSolvedWrong();
357 /* no, the user entered the wrong result */
358 result_label->setText(i18n("WRONG"));
359 pal = result_label->palette(); /* set red font color */
360 cg = pal.active();
361 cg.setColor(QColorGroup::Foreground, QColor(red));
362 pal.setActive(cg);
363 cg = pal.inactive();
364 cg.setColor(QColorGroup::Foreground, QColor(red));
365 pal.setInactive(cg);
366 result_label->setPalette(pal);
368 } /* if (entered_result == result) */
370 result_label->show(); /* show the result at the end of the task */
372 return;
375 /** generate the next task and show it to the user */
376 void ExerciseFactorize::nextTask()
378 // change the tooltip of the check button
379 QToolTip::add(m_checkButton, i18n("Click on this button to check your result. The button will not work if you have not entered a result yet."));
381 // enable prime factor buttons
382 m_factor2Button->setEnabled(true);
383 m_factor3Button->setEnabled(true);
384 m_factor5Button->setEnabled(true);
385 m_factor7Button->setEnabled(true);
386 m_factor11Button->setEnabled(true);
387 m_factor13Button->setEnabled(true);
388 m_factor17Button->setEnabled(true);
389 m_factor19Button->setEnabled(true);
391 // disable the factor removal button, there are no factors to be removed yet
392 m_removeLastFactorButton->setEnabled(false);
394 result_label->hide(); /* do not show the result at the end of the task */
395 m_factorsWidget->hide();
397 /* clear user input */
398 m_factorsEntered.clear();
399 m_factorsResult.clear();
400 m_factorsEnteredEdit->setText("");
402 m_factor2Button->setFocus();
404 /* create a new task */
405 QApplication::setOverrideCursor(waitCursor); /* show the sand clock */
406 createTask();
407 QApplication::restoreOverrideCursor(); /* show the normal cursor */
409 // update the task widget
410 QString tmp_str;
411 tmp_str.setNum(m_taskNumber);
412 m_taskLabel->setText(tmp_str);
414 return;
417 void ExerciseFactorize::addFactor(uint factor)
419 // add the new entered factor
420 m_factorsEntered.append(factor);
422 // a factor was added, so the user can can remove one again
423 m_removeLastFactorButton->setEnabled(true);
425 // update the line edit
426 updateEnteredEdit();
428 return;
431 void ExerciseFactorize::updateEnteredEdit()
433 // the string to be shown in the entered edit
434 QString str_output = "";
435 QString str_tmp;
437 // find the end of the list
438 uintList::iterator it;
441 for (it = m_factorsEntered.begin(); it != m_factorsEntered.end(); ++it)
443 // convert the factor into a string
444 str_tmp.setNum(*it);
446 // add the factor with a *
447 if (it == m_factorsEntered.begin())
449 str_output = str_tmp;
450 } else {
451 str_output += " * " + str_tmp;
455 // set the text into the line edit
456 m_factorsEnteredEdit->setText(str_output);
458 return;
461 /* ------ private slots ------ */
463 void ExerciseFactorize::slotCheckButtonClicked()
465 if (m_currentState == _CHECK_TASK)
467 // if nothing has been entered by the user, we don't check the result yet
468 if (m_factorsEntered.count() == 0)
469 return;
470 m_currentState = _NEXT_TASK;
471 m_checkButton->setText(i18n("N&ext Task"));
472 (void) showResult();
473 } else {
474 m_currentState = _CHECK_TASK;
475 m_checkButton->setText(i18n("&Check Task"));
476 (void) nextTask();
479 // update the line edit
480 updateEnteredEdit();
482 return;
485 void ExerciseFactorize::slotFactor2ButtonClicked()
487 addFactor(2);
489 return;
492 void ExerciseFactorize::slotFactor3ButtonClicked()
494 addFactor(3);
496 return;
499 void ExerciseFactorize::slotFactor5ButtonClicked()
501 addFactor(5);
503 return;
506 void ExerciseFactorize::slotFactor7ButtonClicked()
508 addFactor(7);
510 return;
513 void ExerciseFactorize::slotFactor11ButtonClicked()
515 addFactor(11);
517 return;
520 void ExerciseFactorize::slotFactor13ButtonClicked()
522 addFactor(13);
524 return;
527 void ExerciseFactorize::slotFactor17ButtonClicked()
529 addFactor(17);
531 return;
534 void ExerciseFactorize::slotFactor19ButtonClicked()
536 addFactor(19);
538 return;
541 void ExerciseFactorize::slotRemoveLastFactorButtonClicked()
543 if (m_factorsEntered.count() > 0)
545 // find the end of the list
546 uintList::iterator it = m_factorsEntered.end();
547 --it;
549 // remove last item
550 m_factorsEntered.remove(it);
553 // if the list is empty, we have to disable the delete button
554 if (m_factorsEntered.count() == 0)
555 m_removeLastFactorButton->setEnabled(false);
557 // update the line edit
558 updateEnteredEdit();
560 return;