Warning, file /education/parley/src/practice/practicesummarycomponent.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2007-2009 Frederik Gladhorn <gladhorn@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "practicesummarycomponent.h" 0007 #include "prefs.h" 0008 0009 #include "parleyactions.h" 0010 0011 #include <KActionCollection> 0012 #include <KColorScheme> 0013 #include <KConfigGroup> 0014 #include <KEduVocExpression> 0015 #include <KLocalizedString> 0016 #include <KMessageBox> 0017 #include <KToolBar> 0018 #include <QFileDialog> 0019 #include <QTableWidgetItem> 0020 #include <QTextCursor> 0021 #include <QTextDocument> 0022 #include <QTextDocumentWriter> 0023 #include <QTextTable> 0024 0025 using namespace Practice; 0026 0027 class PracticeSummaryComponent::SortedAttemptTableWidgetItem : public QTableWidgetItem 0028 { 0029 bool operator<(const QTableWidgetItem &other) const override 0030 { 0031 if (data(Qt::DisplayRole).toInt() == other.data(Qt::DisplayRole).toInt()) { 0032 return data(Qt::UserRole).toInt() < other.data(Qt::UserRole).toInt(); 0033 } 0034 return data(Qt::DisplayRole).toInt() < other.data(Qt::DisplayRole).toInt(); 0035 } 0036 }; 0037 0038 PracticeSummaryComponent::PracticeSummaryComponent(SessionManagerBase *sessionManager, QWidget *parent) 0039 : KXmlGuiWindow(parent) 0040 , m_sessionManager(sessionManager) 0041 { 0042 // KXmlGui 0043 setXMLFile(QStringLiteral("practicesummaryui.rc")); 0044 setObjectName(QStringLiteral("Statistics")); 0045 0046 QWidget *mainWidget = new QWidget(this); 0047 setupUi(mainWidget); 0048 setCentralWidget(mainWidget); 0049 0050 initActions(parent); 0051 0052 setupDetailsTable(); 0053 summaryBar->setStatistics(m_sessionManager->statisticTotalCorrectFirstAttempt(), 0054 m_sessionManager->statisticTotalWrong(), 0055 m_sessionManager->statisticTotalUnanswered()); 0056 0057 int total = m_sessionManager->statisticTotalCorrectFirstAttempt() + m_sessionManager->statisticTotalWrong(); 0058 int minutes = m_sessionManager->totalTime() / 60; 0059 int seconds = m_sessionManager->totalTime() % 60; 0060 0061 testSummaryLabel->setText(i18nc("number of words, minutes, seconds", 0062 "You practiced %1 in %2 and %3.", 0063 i18np("one word", "%1 words", total), 0064 i18np("one minute", "%1 minutes", minutes), 0065 i18np("one second", "%1 seconds", seconds))); 0066 0067 KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); 0068 applyMainWindowSettings(cfg); 0069 } 0070 0071 PracticeSummaryComponent::~PracticeSummaryComponent() 0072 { 0073 KConfigGroup cfg(KSharedConfig::openConfig(QStringLiteral("parleyrc")), objectName()); 0074 saveMainWindowSettings(cfg); 0075 } 0076 0077 void PracticeSummaryComponent::initActions(QWidget *parleyMainWindow) 0078 { 0079 ParleyActions::create(ParleyActions::EnterEditMode, parleyMainWindow, SLOT(showEditor()), actionCollection()); 0080 ParleyActions::create(ParleyActions::StartPractice, parleyMainWindow, SLOT(showPracticeConfiguration()), actionCollection()); 0081 ParleyActions::create(ParleyActions::ExportPracticeResults, this, SLOT(exportResults()), actionCollection()); 0082 actionCollection()->action(QStringLiteral("practice_start"))->setText(i18n("Practice Overview")); 0083 actionCollection()->action(QStringLiteral("practice_start"))->setToolTip(i18n("Switch to the Practice Overview page")); 0084 } 0085 0086 void PracticeSummaryComponent::setupDetailsTable() 0087 { 0088 tableWidget->setRowCount(m_sessionManager->allEntryCount()); 0089 tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); 0090 0091 Qt::ItemFlags flags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0092 0093 KColorScheme scheme(QPalette::Active); 0094 QPalette correctPalette = QApplication::palette(); 0095 correctPalette.setColor(QPalette::WindowText, scheme.foreground(KColorScheme::PositiveText).color()); 0096 correctPalette.setColor(QPalette::Text, scheme.foreground(KColorScheme::PositiveText).color()); 0097 0098 QPalette wrongPalette = QApplication::palette(); 0099 wrongPalette.setColor(QPalette::WindowText, scheme.foreground(KColorScheme::NegativeText).color()); 0100 wrongPalette.setColor(QPalette::Text, scheme.foreground(KColorScheme::NegativeText).color()); 0101 0102 int i = 0; 0103 // TODO headers with languages 0104 // TODO some colors, maybe an indicator icon whether the word was right/wrong 0105 const QList<TestEntry *> allTestEntries = m_sessionManager->allTestEntries(); 0106 for (TestEntry *entry : allTestEntries) { 0107 QTableWidgetItem *itemFrom = new QTableWidgetItem(entry->entry()->translation(entry->TestEntry::languageFrom())->text()); 0108 QTableWidgetItem *itemTo = new QTableWidgetItem(entry->entry()->translation(entry->languageTo())->text()); 0109 if (entry->statisticGoodCount() > 0) { 0110 itemTo->setForeground(correctPalette.windowText()); 0111 } 0112 0113 QTableWidgetItem *itemUserAnswer = new QTableWidgetItem(entry->userAnswers().join(QStringLiteral("; "))); 0114 itemUserAnswer->setForeground(wrongPalette.windowText()); 0115 0116 SortedAttemptTableWidgetItem *itemAttempts = new SortedAttemptTableWidgetItem(); 0117 itemAttempts->setData(Qt::DisplayRole, entry->statisticCount()); 0118 itemAttempts->setData(Qt::UserRole, entry->statisticBadCount()); 0119 itemAttempts->setTextAlignment(Qt::AlignRight); 0120 0121 itemFrom->setFlags(flags); 0122 itemTo->setFlags(flags); 0123 itemUserAnswer->setFlags(flags); 0124 itemAttempts->setFlags(flags); 0125 0126 if (entry->correctAtFirstAttempt()) { 0127 itemUserAnswer->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok-apply"))); 0128 } else if (entry->statisticGoodCount() > 0) { 0129 itemUserAnswer->setIcon(QIcon::fromTheme(QStringLiteral("task-attempt"))); 0130 } else if (entry->statisticCount() > 0) { 0131 itemUserAnswer->setIcon(QIcon::fromTheme(QStringLiteral("dialog-error"))); 0132 } else { 0133 itemUserAnswer->setIcon(QIcon::fromTheme(QStringLiteral("task-attempt"))); 0134 } 0135 0136 tableWidget->setItem(i, 0, itemAttempts); 0137 tableWidget->setItem(i, 1, itemFrom); 0138 tableWidget->setItem(i, 2, itemTo); 0139 tableWidget->setItem(i, 3, itemUserAnswer); 0140 ++i; 0141 } 0142 0143 tableWidget->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents); 0144 tableWidget->setSortingEnabled(true); 0145 tableWidget->sortItems(0, Qt::DescendingOrder); 0146 } 0147 0148 void PracticeSummaryComponent::exportResults() 0149 { 0150 QString filter = i18n("HTML Files") + " (*.html);;" + i18n("OpenDocument text files") + " (*.odt)"; 0151 QString caption; 0152 QString startingdir(QStringLiteral("kfiledialog:///practice_export")); 0153 QString fileName = QFileDialog::getSaveFileName(0, caption, startingdir, filter); 0154 0155 if (fileName.isEmpty()) { 0156 return; 0157 } 0158 0159 QTextDocument doc; 0160 doc.setHtml("<html><head><title>" + i18n("Practice results") + "</title></body></html>"); 0161 QTextCursor cursor(&doc); 0162 0163 cursor.insertHtml("<h1>" + m_sessionManager->title() + "</h1><br />"); 0164 0165 cursor.insertText(i18n("Answered questions: %1\n", m_sessionManager->allEntryCount())); 0166 cursor.insertText(i18n("Correct answers: %1\n", m_sessionManager->statisticTotalCorrectFirstAttempt())); 0167 cursor.insertText(i18n("Wrong answers: %1\n", m_sessionManager->statisticTotalWrong())); 0168 0169 QTextTableFormat tableFormat; 0170 tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid); 0171 tableFormat.setCellPadding(1); 0172 tableFormat.setAlignment(Qt::AlignLeft); 0173 QTextTable *table = cursor.insertTable(1, 4, tableFormat); 0174 table->cellAt(0, 0).firstCursorPosition().insertHtml(i18n("<b>Attempts</b>")); 0175 table->cellAt(0, 1).firstCursorPosition().insertHtml(i18n("<b>Question</b>")); 0176 table->cellAt(0, 2).firstCursorPosition().insertHtml(i18n("<b>Correct answer</b>")); 0177 table->cellAt(0, 3).firstCursorPosition().insertHtml(i18n("<b>Your errors</b>")); 0178 0179 const QList<TestEntry *> allTestEntries = m_sessionManager->allTestEntries(); 0180 for (TestEntry *entry : allTestEntries) { 0181 table->appendRows(1); 0182 int newRow = table->rows() - 1; 0183 table->cellAt(newRow, 0).firstCursorPosition().insertText(QString::number(entry->statisticCount())); 0184 table->cellAt(newRow, 1).firstCursorPosition().insertText(entry->entry()->translation(entry->languageFrom())->text()); 0185 table->cellAt(newRow, 2).firstCursorPosition().insertText(entry->entry()->translation(entry->languageTo())->text()); 0186 table->cellAt(newRow, 3).firstCursorPosition().insertText(entry->userAnswers().join(QStringLiteral("; "))); 0187 } 0188 0189 QTextDocumentWriter writer(fileName); 0190 0191 if (!writer.write(&doc)) { 0192 KMessageBox::error(this, i18n("Could not write to %1", fileName), i18n("Could not write file")); 0193 return; 0194 } 0195 }