moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kwordquiz / src / wqquiz.cpp
blob95277464bddad098f102e9de85e82f8bf512472d
1 /* This file is part of KWordQuiz
2 Copyright (C) 2003 Peter Hedlund <peter@peterandlinda.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
19 #include <krandomsequence.h>
21 #include <qregexp.h>
23 #include "wqquiz.h"
24 #include "prefs.h"
26 QPtrList<WQListItem> *WQQuiz::m_list = 0L;
27 QPtrList<WQListItem> *WQQuiz::m_errorList = 0L;
28 QPtrList<WQListItem> *WQQuiz::m_quizList = 0L;
30 WQQuiz::WQQuiz(KWordQuizView * parent, const char *name) : QObject(parent, name)
32 m_table = parent;
34 m_list = new QPtrList<WQListItem>();
35 m_errorList = new QPtrList<WQListItem>();
36 m_quizList = new QPtrList<WQListItem>();
39 WQQuiz::~WQQuiz()
43 void WQQuiz::activateErrorList()
45 m_list->clear();
47 WQListItem *l;
48 for (l = m_errorList->first(); l; l = m_errorList->next())
50 m_list->append(l);
53 m_errorList->clear();
54 m_questionCount = m_list->count();
58 void WQQuiz::activateBaseList()
60 m_list->clear();
62 if (m_quizMode > 2)
64 listRandom();
67 WQListItem *l;
68 for (l = m_quizList->first(); l; l = m_quizList->next())
69 m_list->append(l);
71 m_questionCount = m_list->count();
75 void WQQuiz::addToList(int aCol, int bCol)
77 //build a list of row numbers containing text in both columns
79 typedef QValueList<int> IntList;
80 IntList tempList;
81 for (int current = 0; current < m_table ->numRows(); ++current)
83 if (!m_table->text(current, 0).isEmpty() && !m_table->text(current, 1).isEmpty())
85 tempList.append(current);
89 KRandomSequence *rs = new KRandomSequence(0);
91 int count = tempList.count();
93 IntList::ConstIterator it;
94 for ( it = tempList.begin(); it != tempList.end(); ++it )
96 WQListItem *li;
97 li = new WQListItem();
98 li->setQuestion(aCol);
99 li->setCorrect(1);
100 li->setOneOp(*it);
102 if (count > 2)
105 int a, b;
107 a = rs->getLong(count); //rand() % count;
108 while(a==*it);
110 li->setTwoOp(a);
113 b = rs->getLong(count); //rand() % count;
114 while(b == *it || b == a /*|| b < 0*/);
116 li->setThreeOp(b);
119 m_quizList->append(li);
125 bool WQQuiz::init()
128 bool result = false;
129 if (Prefs::enableBlanks())
131 result = m_table->checkSyntax(true, true);
133 else
135 result = true;
138 if (!result)
140 return false;
143 int aCol;
144 int bCol;
146 switch (m_quizMode)
148 case 1:
149 aCol = 0;
150 bCol = 1;
151 break;
152 case 2:
153 aCol = 1;
154 bCol = 0;
155 break;
156 case 3:
157 aCol = 0;
158 bCol = 1;
159 break;
160 case 4:
161 aCol = 1;
162 bCol = 0;
163 break;
164 case 5:
165 default:
166 aCol = 0;
167 bCol = 1;
168 break;
171 addToList(aCol, bCol);
173 //check if enough in list
174 switch (m_quizType)
176 case qtEditor:
178 break;
179 case qtFlash:
180 result = (m_quizList -> count() > 0);
181 break;
182 case qtQA:
183 result = (m_quizList -> count() > 0);
184 break;
185 case qtMultiple:
186 result = (m_quizList -> count() > 2);
187 break;
190 if (!result)
192 return false;
195 if (m_quizMode == 5)
197 aCol = 1;
198 bCol = 0;
199 addToList(aCol, bCol);
202 //Prepare final lists
203 activateBaseList();
204 return true;
207 void WQQuiz::listRandom()
209 KRandomSequence *rs = new KRandomSequence(0);
210 rs->randomize(m_quizList);
213 bool WQQuiz::checkAnswer(int i, const QString & a)
215 bool result = false;
216 WQListItem *li = m_list->at(i);
217 int j;
218 if (li->question() == 0)
220 j = 1;
222 else
224 j= 0;
226 QString ans = a;
227 QString tTemp = m_table -> text(li->oneOp(), j);
228 tTemp = tTemp.stripWhiteSpace();
229 ans = ans.stripWhiteSpace();
231 if (m_quizType == qtQA)
233 if (QString(m_correctBlank).length() > 0)
235 QStringList la, ls;
236 if (ans.find(";") > 0)
237 ls = QStringList::split(";", ans);
238 else
239 ls.append(ans);
241 if (m_correctBlank.find(";") > 0)
242 la = QStringList::split(";", m_correctBlank);
243 else
244 la.append(m_correctBlank);
246 result = (ls.count() == la.count());
247 if (result)
249 for (uint counter = 0; counter < la.count(); counter++)
251 result = (ls[counter].stripWhiteSpace() == la[counter].stripWhiteSpace());
252 if (!result)
253 break;
257 else
259 result = (ans == tTemp);
262 else
264 if (m_quizType == qtMultiple)
266 if (Prefs::enableBlanks())
268 tTemp.remove("[");
269 tTemp.remove("]");
271 result = (ans == tTemp);
274 else
276 result = (ans == tTemp);
281 if (!result)
283 m_errorList -> append(li);
286 return result;
289 QStringList WQQuiz::multiOptions(int i)
291 QString *s;
292 QStringList Result;
293 WQListItem *li = m_list->at(i);
295 typedef QPtrList<QString> LS;
296 LS *ls;
297 ls = new QPtrList<QString>();
299 int j;
300 if (li->question() == 0)
302 j = 1;
304 else
306 j= 0;
309 s= new QString(m_table->text(li->oneOp(), j));
310 if (Prefs::enableBlanks())
312 s->remove("[");
313 s->remove("]");
315 ls->append(s);
317 s = new QString(m_table->text(li->twoOp(), j));
318 if (Prefs::enableBlanks())
320 s->remove("[");
321 s->remove("]");
323 ls->append(s);
325 s = new QString(m_table->text(li->threeOp(), j));
326 if (Prefs::enableBlanks())
328 s->remove("[");
329 s->remove("]");
331 ls->append(s);
333 KRandomSequence *rs = new KRandomSequence(0);
334 rs->randomize(ls);
336 while (ls->count())
338 Result.append(*ls->first());
339 ls->removeFirst();
341 return Result;
344 QString WQQuiz::quizIcon(int i, QuizIcon ico)
346 QString s;
347 WQListItem *li = m_list->at(i);
348 if (ico == qiLeftCol)
350 if (li->question() == 0)
351 s = "question";
352 else
353 s = "answer";
356 if (ico == qiRightCol)
358 if (li->question() == 0)
359 s = "answer";
360 else
361 s = "question";
363 return s;
366 QString WQQuiz::yourAnswer(int i, const QString & s)
368 QString result ="";
370 if (QString(m_answerBlank).length() > 0)
372 QStringList ls;
374 if (s.find(";") > 0)
375 ls = QStringList::split(";", s, true);
376 else
377 ls.append(s);
379 result = m_answerBlank.replace("..........", "<u></u>");
381 int offset = 0, counter = 0;
382 while (offset >= 0)
384 offset = result.find("<u>", offset);
385 if (offset >= 0)
387 result.insert(offset + 3, ls[counter]);
388 offset++;
389 counter++;
392 result.append("</qt>");
393 result.prepend("<qt>");
395 else
397 result = s;
399 return result;
402 QString WQQuiz::hint(int i)
404 if (QString(m_correctBlank).length() > 0)
406 return m_correctBlank;
408 else
410 return answer(i);
414 void WQQuiz::setQuizType(QuizType qt)
416 m_quizType = qt;
419 void WQQuiz::setQuizMode(int qm)
421 m_quizMode = qm;
425 QString WQQuiz::question(int i)
427 WQListItem *li = m_list->at(i);
428 QString s = m_table->text(li->oneOp(), li->question());
429 if (Prefs::enableBlanks())
431 s.remove("[");
432 s.remove("]");
434 if (m_quizType != qtFlash && i > 0)
436 WQListItem *li2 = m_list->at(i - 1);
437 emit checkingAnswer(li2->oneOp());
439 else
440 emit checkingAnswer(li->oneOp());
442 return s;
445 QString WQQuiz::blankAnswer(int i)
448 QString r = "";
449 m_correctBlank = "";
450 m_answerBlank = "";
451 QString tTemp;
453 if (m_quizType == qtQA && Prefs::enableBlanks())
455 WQListItem *li = m_list->at(i);
456 int j;
457 if (li->question() == 0)
459 j = 1;
461 else
463 j= 0;
465 tTemp = m_table->text(li->oneOp(), j);
466 r = tTemp;
467 QRegExp rx;
468 rx.setMinimal(true);
469 rx.setPattern("\\[.*\\]");
471 r.replace(rx, "..........");
473 if (r != tTemp)
475 m_answerBlank = r;
476 int offset = 0;
477 while (offset >= 0)
479 offset = rx.search(tTemp, offset);
480 if (offset >= 0)
482 if (m_correctBlank.length() > 0)
483 m_correctBlank = m_correctBlank + ";" + " " + tTemp.mid(offset + 1, tTemp.find(']', offset) - offset - 1);
484 else
485 m_correctBlank = tTemp.mid(offset + 1, tTemp.find(']', offset) - offset - 1);
486 offset++;
491 return m_answerBlank;
494 QString WQQuiz::answer(int i)
496 QString s;
497 WQListItem *li = m_list->at(i);
498 int j;
499 if (li->question() == 0)
501 j = 1;
503 else
505 j= 0;
509 if (m_quizType == qtQA)
511 s = m_table->text(li->oneOp(), j);
512 if (Prefs::enableBlanks())
514 s.replace("[", "<u>");
515 s.replace("]", "</u>");
516 s.prepend("<qt>");
517 s.append("</qt>");
520 else
522 s = m_table->text(li->oneOp(), j);
523 if (Prefs::enableBlanks())
525 s.remove("[");
526 s.remove("]");
529 return s;
532 QString WQQuiz::langQuestion(int i)
534 WQListItem *li = m_list->at(i);
535 return m_table->horizontalHeader()->label(li->question());
538 QString WQQuiz::langAnswer(int i)
541 WQListItem *li = m_list->at(i);
543 int j;
544 if (li->question() == 0)
546 j = 1;
548 else
550 j= 0;
553 return m_table->horizontalHeader()->label(j);
556 int WQQuiz::kbAnswer(int i)
558 /* WQListItem *li = m_list->at(i);
559 if (li->question() == 0)
561 //@todo return m_table ->layoutLeft();
563 else
565 //@todo return m_table -> layoutRight();
567 return 0;
570 int WQQuiz::questionCount()
572 return m_questionCount;
575 void WQQuiz::finish()
577 emit checkingAnswer(-1);
580 #include "wqquiz.moc"