File indexing completed on 2023-05-30 10:45:28
0001 /* 0002 SPDX-FileCopyrightText: 2003-2010 Peter Hedlund <peter.hedlund@kdemail.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "qaview.h" 0008 0009 #include <QDBusInterface> 0010 #include <QUrl> 0011 0012 #include <KLocalizedString> 0013 #include <KNotification> 0014 0015 #include "prefs.h" 0016 #include "kwqquizmodel.h" 0017 #include "kwqscorewidget.h" 0018 0019 QString highlightError(const QString & c, const QString & e) 0020 { 0021 if (c == e) 0022 return c; 0023 0024 QString s = c; 0025 if (s.left(4) == QLatin1String("<qt>") && e.left(4) != QLatin1String("<qt>")) 0026 s = s.mid(4, s.length() - 9); 0027 0028 if (s == e) 0029 return s; 0030 0031 QString result = QStringLiteral("<qt>"); 0032 int i = 0; 0033 while (i < e.length() && s[i] == e[i]) 0034 result.append(e[i++]); 0035 result.append("<b>"); 0036 QString result2 = QStringLiteral("</qt>"); 0037 int j = s.length() - 1; 0038 int k = e.length() - 1; 0039 while (j >= 0 && k >= 0 && s[j] == e[k]) 0040 { 0041 result2.prepend(e[k]); 0042 j--; 0043 k--; 0044 } 0045 result2.prepend("</b>"); 0046 0047 for (int m = i; m <= k; m++) 0048 result.append(e[m]); 0049 0050 result.append(result2); 0051 return result; 0052 } 0053 0054 QAView::QAView(QWidget *parent, KActionCollection * actionCollection) : KWQQuizView(parent, actionCollection) 0055 { 0056 setupUi(this); 0057 0058 connect(txtAnswer, SIGNAL(returnPressed()), this, SLOT(slotCheck())); 0059 } 0060 0061 void QAView::init() 0062 { 0063 score->clear(); 0064 score->setQuestionCount(m_quiz->questionCount()); 0065 score->setAsPercent(Prefs::percent()); 0066 0067 m_hintUsed = false; 0068 0069 QFont f = Prefs::editorFont(); 0070 f.setWeight(QFont::Normal); 0071 lblQuestion->setFont(f); 0072 lblAnswerBlank->setFont(f); 0073 txtAnswer->setFont(f); 0074 lblPreviousQuestion->setFont(f); 0075 lblYourAnswer->setFont(f); 0076 lblCorrect->setFont(f); 0077 0078 lblPreviousQuestionHeader->clear(); 0079 lblPreviousQuestion->clear(); 0080 lblYourAnswerHeader->clear(); 0081 lblYourAnswer->clear(); 0082 lblCorrectHeader->clear(); 0083 lblCorrect->clear(); 0084 0085 picPrevious->clear(); 0086 picYourAnswer->clear(); 0087 picCorrectAnswer->clear(); 0088 0089 m_actionCollection->action(QStringLiteral("quiz_check"))->setEnabled(true); 0090 m_actionCollection->action(QStringLiteral("qa_mark_last_correct"))->setEnabled(false); 0091 m_actionCollection->action(QStringLiteral("qa_hint"))->setEnabled(true); 0092 m_actionCollection->action(QStringLiteral("quiz_repeat_errors"))->setEnabled(false); 0093 m_actionCollection->action(QStringLiteral("quiz_export_errors"))->setEnabled(false); 0094 m_actionCollection->action(QStringLiteral("quiz_audio_play"))->setEnabled(false); 0095 0096 // reset last file 0097 audioPlayFile(QUrl(), true); 0098 0099 showQuestion(); 0100 txtAnswer->show(); 0101 txtAnswer->setFocus(); 0102 } 0103 0104 void QAView::slotCheck() 0105 { 0106 if (m_actionCollection->action(QStringLiteral("quiz_check"))->isEnabled()) 0107 { 0108 bool fIsCorrect; 0109 0110 if (m_hintUsed && Prefs::hintError()) 0111 { 0112 //Force an Error 0113 fIsCorrect = m_quiz->checkAnswer(QLatin1String("")); 0114 } 0115 else 0116 { 0117 //Really check the answer 0118 fIsCorrect = m_quiz->checkAnswer(txtAnswer->text()); 0119 } 0120 //Reset for next question 0121 m_hintUsed = false; 0122 0123 if (fIsCorrect) 0124 { 0125 picYourAnswer->setPixmap(QIcon::fromTheme(QStringLiteral("answer-correct")).pixmap(32)); 0126 lblYourAnswer->setText(m_quiz->yourAnswer(txtAnswer->text())); 0127 lblCorrectHeader->clear(); 0128 picCorrectAnswer->clear(); 0129 lblCorrect->clear(); 0130 score->countIncrement(KWQScoreWidget::cdCorrect); 0131 KNotification::event(QStringLiteral("QuizCorrect"), i18n("Your answer was correct!")); 0132 m_actionCollection->action(QStringLiteral("qa_mark_last_correct"))->setEnabled(false); 0133 } 0134 else 0135 { 0136 picYourAnswer->setPixmap(QIcon::fromTheme(QStringLiteral("error")).pixmap(32)); 0137 lblYourAnswer->setText(highlightError(m_quiz->answer(), m_quiz->yourAnswer(txtAnswer->text()))); 0138 lblCorrect->setText(m_quiz->answer()); 0139 picCorrectAnswer->setPixmap(QIcon::fromTheme(QStringLiteral("answer-correct")).pixmap(32)); 0140 lblCorrectHeader->setText(i18n("Correct Answer")); 0141 score->countIncrement(KWQScoreWidget::cdError); 0142 KNotification::event(QStringLiteral("QuizError"), i18n("Your answer was incorrect.")); 0143 m_actionCollection->action(QStringLiteral("qa_mark_last_correct"))->setEnabled(true); 0144 } 0145 0146 audioPlayAnswer(); 0147 0148 lblPreviousQuestionHeader->setText(i18n("Previous Question")); 0149 lblPreviousQuestion->setText(m_quiz->question()); 0150 //lblPreviousQuestion->setFont(m_quiz->fontQuestion(m_question)); 0151 picPrevious->setPixmap(QIcon::fromTheme(QStringLiteral("question")).pixmap(32)); 0152 0153 lblYourAnswerHeader->setText(i18n("Your Answer")); 0154 0155 m_quiz->toNext(); 0156 if (!m_quiz->atEnd()) 0157 { 0158 showQuestion(); 0159 } 0160 else 0161 { 0162 m_quiz->finish(); 0163 m_actionCollection->action(QStringLiteral("quiz_check"))->setEnabled(false); 0164 m_actionCollection->action(QStringLiteral("qa_hint"))->setEnabled(false); 0165 m_actionCollection->action(QStringLiteral("quiz_repeat_errors"))->setEnabled(m_quiz->hasErrors()); 0166 m_actionCollection->action(QStringLiteral("quiz_export_errors"))->setEnabled(m_quiz->hasErrors()); 0167 m_actionCollection->action(QStringLiteral("qa_mark_last_correct"))->setEnabled(false); 0168 0169 lblQuestionLanguage->setText(i18n("Summary")); 0170 lblQuestion->clear(); 0171 lblAnswerLanguage->clear(); 0172 lblAnswerBlank->hide(); 0173 txtAnswer->hide(); 0174 picQuestion->setPixmap(QIcon::fromTheme(QStringLiteral("kwordquiz")).pixmap(32)); 0175 picAnswer->clear(); 0176 } 0177 } 0178 } 0179 0180 void QAView::slotHint() 0181 { 0182 QString answer = txtAnswer->text(); 0183 QString correctAnswer = m_quiz->hint(); 0184 if (correctAnswer.left(4) == QLatin1String("<qt>")) 0185 { 0186 correctAnswer = correctAnswer.remove(QStringLiteral("<qt>")); 0187 correctAnswer = correctAnswer.remove(QStringLiteral("</qt>")); 0188 } 0189 int minLength = qMin(answer.length(), correctAnswer.length()); 0190 0191 int correctCharCount = 1; 0192 0193 if (answer.length() > 0) 0194 { 0195 for(int i = 0; i < minLength; i++) 0196 { 0197 if (answer.at(i) == correctAnswer.at(i)) 0198 correctCharCount++; 0199 } 0200 } 0201 0202 txtAnswer->setText(correctAnswer.left(correctCharCount)); 0203 txtAnswer->setFocus(); 0204 txtAnswer->setCursorPosition(txtAnswer->text().length()); 0205 0206 m_hintUsed = true; 0207 } 0208 0209 /*! 0210 \fn QAView::showQuestion(int i) 0211 */ 0212 void QAView::showQuestion() 0213 { 0214 lblQuestionLanguage->setText(m_quiz ->langQuestion()); 0215 lblQuestion->setText(m_quiz ->question()); 0216 //audioPlayQuestion(); 0217 0218 picQuestion->setPixmap(QIcon::fromTheme(m_quiz->quizIcon(KWQQuizModel::IconLeftCol)).pixmap(32)); 0219 0220 lblAnswerLanguage->setText(m_quiz ->langAnswer()); 0221 0222 if (!QString(m_quiz->blankAnswer()).isEmpty()) 0223 { 0224 lblAnswerBlank->show(); 0225 lblAnswerBlank->setText(m_quiz->blankAnswer()); 0226 } 0227 else 0228 lblAnswerBlank->hide(); 0229 0230 txtAnswer->setText(QLatin1String("")); 0231 0232 picAnswer->setPixmap(QIcon::fromTheme(m_quiz->quizIcon(KWQQuizModel::IconRightCol)).pixmap(32)); 0233 0234 QString layout = m_quiz->kbAnswer(); 0235 if (!layout.isEmpty()) { 0236 QDBusInterface kxkb(QStringLiteral("org.kde.keyboard"), QStringLiteral("/Layouts"), QStringLiteral("org.kde.KeyboardLayouts")); 0237 if (kxkb.isValid()) 0238 kxkb.call(QStringLiteral("setLayout"), layout); 0239 } 0240 } 0241 0242 void QAView::slotApplySettings( ) 0243 { 0244 score->setAsPercent(Prefs::percent()); 0245 } 0246 0247 void QAView::slotSpecChar( const QChar & c) 0248 { 0249 if (txtAnswer->hasFocus()) 0250 { 0251 if (txtAnswer->hasSelectedText()) 0252 { 0253 QString ls = txtAnswer->text(); 0254 QString s = txtAnswer->selectedText(); 0255 int len = s.length(); 0256 int ss = txtAnswer->selectionStart(); 0257 ls = ls.replace(ss, len, c); 0258 txtAnswer->setText(ls); 0259 txtAnswer->setSelection(ss, 1); 0260 } 0261 else 0262 { 0263 QString s = txtAnswer->text(); 0264 int i = txtAnswer->cursorPosition(); 0265 s.insert(i, c); 0266 txtAnswer->setText(s); 0267 txtAnswer->setCursorPosition(i + 1); 0268 } 0269 } 0270 } 0271 0272 void QAView::slotMarkLastCorrect( ) 0273 { 0274 m_quiz->removeLastError(); 0275 score->swapCount(); 0276 m_actionCollection->action(QStringLiteral("qa_mark_last_correct"))->setEnabled(false); 0277 }