#include "main_window.h"
PrintQuestionsDialogue::PrintQuestionsDialogue(MainWindow * parent):
QWidget(parent, Qt::Dialog )
{
printq_parent = parent;
this->setWindowModality(Qt::WindowModal);
this->setAttribute(Qt::WA_DeleteOnClose);
#ifdef Q_WS_MAC
this->setWindowTitle(tr("%1 - Print questions").arg(printq_parent->current_db_name));
#else
this->setWindowTitle(tr("%1 - Print questions - iTest").arg(printq_parent->current_db_name));
#endif
this->setMinimumSize(QSize(640, 480));
rbtngrpPrintqSelect = new QButtonGroup(this);
QObject::connect(rbtngrpPrintqSelect, SIGNAL(buttonReleased(QAbstractButton *)), this, SLOT(togglePrintSelection(QAbstractButton *)));
QGridLayout * printq_glayout = new QGridLayout(this);
QHBoxLayout * printq_hlayout0 = new QHBoxLayout(this);
printq_hlayout0->setMargin(0); printq_hlayout0->setSpacing(6);
QLabel * printq_label = new QLabel(this);
printq_label->setText(tr("Select:"));
printq_hlayout0->addWidget(printq_label);
QRadioButton * printq_rbtn_flags = new QRadioButton(this);
printq_rbtn_flags->setText(tr("Flags"));
printq_rbtn_flags->setChecked(true);
rbtngrpPrintqSelect->addButton(printq_rbtn_flags);
printq_hlayout0->addWidget(printq_rbtn_flags);
QRadioButton * printq_rbtn_questions = new QRadioButton(this);
printq_rbtn_questions->setText(tr("Questions"));
printq_rbtn_flags->setChecked(false);
rbtngrpPrintqSelect->addButton(printq_rbtn_questions);
printq_hlayout0->addWidget(printq_rbtn_questions);
printq_hlayout0->addStretch();
QLabel * printq_label_hidden = new QLabel(this);
printq_label_hidden->setForegroundRole(QPalette::Mid);
printq_hlayout0->addWidget(printq_label_hidden);
printq_glayout->addLayout(printq_hlayout0, 0, 0);
QHBoxLayout * printq_hlayout1 = new QHBoxLayout(this);
printq_hlayout1->setMargin(0); printq_hlayout1->setSpacing(6);
QVBoxLayout * printq_vlayout1 = new QVBoxLayout(this);
QLabel * printq_label_do_not_print = new QLabel(this);
printq_label_do_not_print->setText(tr("<b>Do not print:</b>"));
printq_vlayout1->addWidget(printq_label_do_not_print);
QHBoxLayout * printq_hlayout1_1 = new QHBoxLayout(this);
QLabel * printq_label_search_excluded = new QLabel(this);
printq_label_search_excluded->setText(tr("Search:"));
printq_hlayout1_1->addWidget(printq_label_search_excluded);
ExtendedLineEdit * printq_search_excluded = new ExtendedLineEdit(this);
printq_hlayout1_1->addWidget(printq_search_excluded);
printq_vlayout1->addLayout(printq_hlayout1_1);
printq_excludelist = new MTListWidget(this);
printq_excludelist->setDragDropMode(QAbstractItemView::InternalMove);
QObject::connect(printq_excludelist, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(addQuestionToPrint()));
QObject::connect(printq_search_excluded, SIGNAL(textChanged(QLineEdit *, const QString &)), printq_excludelist, SLOT(filterItems(QLineEdit *, const QString &)));
printq_vlayout1->addWidget(printq_excludelist);
printq_hlayout1->addLayout(printq_vlayout1);
QVBoxLayout * printq_vlayout2 = new QVBoxLayout(this);
printq_vlayout2->addStretch();
QPushButton * printq_add = new QPushButton(this);
printq_add->setEnabled(false);
printq_add->setIcon(QIcon(QString::fromUtf8(":/images/images/forward.png")));
QObject::connect(printq_add, SIGNAL(released()), this, SLOT(addQuestionToPrint()));
QObject::connect(printq_excludelist, SIGNAL(currentIndexAvailabilityChanged(bool)), printq_add, SLOT(setEnabled(bool)));
printq_vlayout2->addWidget(printq_add);
QPushButton * printq_remove = new QPushButton(this);
printq_remove->setEnabled(false);
printq_remove->setIcon(QIcon(QString::fromUtf8(":/images/images/back.png")));
QObject::connect(printq_remove, SIGNAL(released()), this, SLOT(removeQuestionToPrint()));
printq_vlayout2->addWidget(printq_remove);
printq_vlayout2->addStretch();
printq_hlayout1->addLayout(printq_vlayout2);
QVBoxLayout * printq_vlayout3 = new QVBoxLayout(this);
QLabel * printq_label_print = new QLabel(this);
printq_label_print->setText(tr("<b>Print:</b>"));
printq_vlayout3->addWidget(printq_label_print);
QHBoxLayout * printq_hlayout1_2 = new QHBoxLayout(this);
QLabel * printq_label_search_included = new QLabel(this);
printq_label_search_included->setText(tr("Search:"));
printq_hlayout1_2->addWidget(printq_label_search_included);
ExtendedLineEdit * printq_search_included = new ExtendedLineEdit(this);
printq_hlayout1_2->addWidget(printq_search_included);
printq_vlayout3->addLayout(printq_hlayout1_2);
printq_includelist = new MTTableWidget(this);
printq_includelist->setShowGrid(false);
printq_includelist->setColumnCount(2);
printq_includelist->verticalHeader()->hide();
printq_includelist->horizontalHeader()->hide();
printq_includelist->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
printq_includelist->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
QObject::connect(printq_includelist, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(removeQuestionToPrint()));
QObject::connect(printq_includelist, SIGNAL(currentIndexAvailabilityChanged(bool)), printq_remove, SLOT(setEnabled(bool)));
QObject::connect(printq_search_included, SIGNAL(textChanged(QLineEdit *, const QString &)), printq_includelist, SLOT(filterItems(QLineEdit *, const QString &)));
printq_vlayout3->addWidget(printq_includelist);
printq_hlayout1->addLayout(printq_vlayout3);
printq_glayout->addLayout(printq_hlayout1, 1, 0);
QHBoxLayout * printq_hlayout2 = new QHBoxLayout(this);
printq_hlayout2->setMargin(0); printq_hlayout2->setSpacing(6);
QPushButton * printq_btn_add_all = new QPushButton(this);
printq_btn_add_all->setText(tr("&Add all"));
QObject::connect(printq_btn_add_all, SIGNAL(released()), this, SLOT(addAllQuestionsToPrint()));
printq_hlayout2->addWidget(printq_btn_add_all);
printq_hlayout2->addStretch();
printq_btn_print = new QPushButton(tr("&Print"), this);
QObject::connect(printq_btn_print, SIGNAL(released()), this, SLOT(printQuestions()));
printq_btn_print->setEnabled(false);
printq_hlayout2->addWidget(printq_btn_print);
QPushButton * printq_btn_close = new QPushButton(tr("&Close"), this);
QObject::connect(printq_btn_close, SIGNAL(released()), this, SLOT(close()));
printq_hlayout2->addWidget(printq_btn_close);
printq_glayout->addLayout(printq_hlayout2, 2, 0);
MTAdvancedGroupBox * printq_advanced = new MTAdvancedGroupBox(this);
printq_advanced_statistics = new QCheckBox(tr("Print statistics"), this);
printq_advanced_statistics->setChecked(true);
printq_advanced->addWidget(printq_advanced_statistics, 0, 0, 1, 2);
printq_advanced_formatting = new QCheckBox(tr("Print formatted questions"), this);
printq_advanced_formatting->setChecked(true);
printq_advanced->addWidget(printq_advanced_formatting, 1, 0, 1, 2);
printq_advanced_graphics = new QCheckBox(tr("Print graphics"), this);
printq_advanced_graphics->setChecked(false);
printq_advanced->addWidget(printq_advanced_graphics, 2, 0, 1, 2);
printq_advanced_test = new QCheckBox(tr("Print a test (do not highlight the correct answers)"), this);
printq_advanced_test->setChecked(false);
QObject::connect(printq_advanced_test, SIGNAL(toggled(bool)), this, SLOT(resetDefaultValues()));
QObject::connect(printq_advanced_test, SIGNAL(toggled(bool)), printq_advanced_statistics, SLOT(setDisabled(bool)));
QObject::connect(printq_advanced_test, SIGNAL(toggled(bool)), printq_advanced_formatting, SLOT(setDisabled(bool)));
printq_advanced->addWidget(printq_advanced_test, 3, 0, 1, 2);
printq_advanced_key = new QCheckBox(tr("Print a key to the test (a separate printout with correct answers)"), this);
printq_advanced_key->setChecked(false);
printq_advanced_key->setEnabled(false);
QObject::connect(printq_advanced_test, SIGNAL(toggled(bool)), printq_advanced_key, SLOT(setEnabled(bool)));
printq_advanced->addWidget(printq_advanced_key, 4, 0, 1, 2);
printq_advanced_usegroups = new QCheckBox(tr("Allow one question per group only"), this);
printq_advanced_usegroups->setChecked(false);
printq_advanced_usegroups->setEnabled(false);
QObject::connect(printq_advanced_test, SIGNAL(toggled(bool)), printq_advanced_usegroups, SLOT(setEnabled(bool)));
QObject::connect(printq_advanced_usegroups, SIGNAL(toggled(bool)), this, SLOT(updateTestQnum()));
printq_advanced->addWidget(printq_advanced_usegroups, 5, 0, 1, 2);
printq_advanced_randomise = new QCheckBox(tr("Randomise question order in each printout"), this);
printq_advanced_randomise->setChecked(false);
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), this, SLOT(resetDefaultValues()));
printq_advanced->addWidget(printq_advanced_randomise, 6, 0, 1, 2);
QLabel * printq_label_numprintouts = new QLabel(this);
printq_label_numprintouts->setText(tr("Number of different printouts:"));
printq_label_numprintouts->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
printq_label_numprintouts->setEnabled(false);
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), printq_label_numprintouts, SLOT(setEnabled(bool)));
printq_advanced->addWidget(printq_label_numprintouts, 7, 0, 1, 1);
printq_advanced_numprintouts = new QSpinBox(this);
printq_advanced_numprintouts->setMinimum(1);
printq_advanced_numprintouts->setMaximum(9999);
printq_advanced_numprintouts->setValue(1);
printq_advanced_numprintouts->setMaximumSize(printq_advanced_numprintouts->sizeHint());
printq_advanced_numprintouts->setEnabled(false);
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), printq_advanced_numprintouts, SLOT(setEnabled(bool)));
printq_advanced->addWidget(printq_advanced_numprintouts, 7, 1, 1, 1);
QLabel * printq_label_numquestions = new QLabel(this);
printq_label_numquestions->setText(tr("Number of questions:"));
printq_label_numquestions->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
printq_label_numquestions->setEnabled(false);
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), printq_label_numquestions, SLOT(setEnabled(bool)));
printq_advanced->addWidget(printq_label_numquestions, 8, 0, 1, 1);
printq_advanced_numquestions = new MTSpinBox(this);
printq_advanced_numquestions->setMinimum(0);
printq_advanced_numquestions->setMaximum(9999);
printq_advanced_numquestions->setValue(0);
printq_advanced_numquestions->setMaximumSize(printq_advanced_numquestions->sizeHint());
printq_advanced_numquestions->setEnabled(false);
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), printq_advanced_numquestions, SLOT(setEnabled(bool)));
QObject::connect(printq_advanced_randomise, SIGNAL(toggled(bool)), printq_advanced_numquestions, SLOT(setMaximumValue()));
QObject::connect(printq_advanced_numquestions, SIGNAL(valueChanged(int)), this, SLOT(togglePrintEnabled()));
printq_advanced->addWidget(printq_advanced_numquestions, 8, 1, 1, 1);
printq_advanced->gridLayout()->setColumnStretch(2, 1);
printq_glayout->addWidget(printq_advanced, 3, 0);
printq_glayout->setMargin(6); printq_glayout->setSpacing(6);
int num_hidden = 0;
for (int i = 0; i < printq_parent->LQListWidget->count(); ++i) {
if (printq_parent->current_db_questions.value(printq_parent->LQListWidget->item(i))->isHidden()) { num_hidden++; }
}
printq_label_hidden->setText(printq_parent->actionShow_hidden->isChecked() ?
tr("%n hidden question(s) listed", "", num_hidden) : tr("%n hidden question(s) not listed", "", num_hidden));
togglePrintSelection(printq_rbtn_flags);
updateTestQnum();
this->show();
}
void PrintQuestionsDialogue::togglePrintSelection(QAbstractButton * rbtn)
{
if (rbtn->text() == tr("Flags")) {
printq_excludelist->clear();
printq_includelist->clearContents();
printq_includelist->setRowCount(0);
printq_includelist->setColumnCount(2);
printq_includelist->setHorizontalHeaderLabels(QStringList() << tr("Flag name") << tr("Number of questions"));
printq_includelist->horizontalHeader()->setResizeMode(1, QHeaderView::ResizeToContents);
printq_includelist->horizontalHeader()->show();
QListWidgetItem * item;
for (int i = 0; i < 20; ++i) {
if (printq_parent->current_db_fe[i]) {
item = new QListWidgetItem(QString("%1 - %2").arg(i+1).arg(printq_parent->current_db_f[i]), printq_excludelist);
item->setData(Qt::UserRole, i);
MainWindow::setQuestionItemColour(item, i);
}
}
} else if (rbtn->text() == tr("Questions")) {
printq_excludelist->clear();
printq_includelist->clearContents();
printq_includelist->setRowCount(0);
printq_includelist->setColumnCount(1);
printq_includelist->horizontalHeader()->hide();
QListWidgetItem * item;
for (int i = 0; i < printq_parent->LQListWidget->count(); ++i) {
if (!printq_parent->current_db_questions.value(printq_parent->LQListWidget->item(i))->isHidden() || printq_parent->actionShow_hidden->isChecked()) {
item = new QListWidgetItem(*printq_parent->LQListWidget->item(i));
item->setData(Qt::UserRole, i);
printq_excludelist->addItem(item);
}
}
}
updateTestQnum();
}
void PrintQuestionsDialogue::addQuestionToPrint()
{
if (printq_excludelist->currentIndex().isValid()) {
addQuestionToPrint(printq_excludelist->currentRow());
updateTestQnum();
}
}
void PrintQuestionsDialogue::addQuestionToPrint(int row)
{
printq_includelist->setRowCount(printq_includelist->rowCount() + 1);
QTableWidgetItem * item = MainWindow::toTableItem(printq_excludelist->takeItem(row), true);
printq_includelist->setItem(printq_includelist->rowCount() - 1, 0, item);
if (rbtngrpPrintqSelect->checkedButton()->text() == tr("Flags")) {
int max = printq_parent->qnumForFlag(item->data(Qt::UserRole).toInt(), useGroups());
MTSpinBox * spb_qnum = new MTSpinBox(this);
printq_includelist->setCellWidget(printq_includelist->rowCount() - 1, 1, spb_qnum);
spb_qnum->setMaximum(max);
spb_qnum->setMaximumValue();
spb_qnum->setFixedHeight(20);
spb_qnum->setEnabled(randomise());
QObject::connect(spb_qnum, SIGNAL(valueChanged(int)), this, SLOT(updateTestQnum()));
printq_includelist->setRowHeight(printq_includelist->rowCount() - 1, 20);
} else {
printq_includelist->setRowHeight(printq_includelist->rowCount() - 1, 16);
}
}
void PrintQuestionsDialogue::removeQuestionToPrint()
{
if (printq_includelist->currentRow() >= 0) {
printq_excludelist->addItem(MainWindow::toListItem(printq_includelist->item(printq_includelist->currentRow(), 0)));
printq_includelist->removeRow(printq_includelist->currentRow());
updateTestQnum();
}
}
void PrintQuestionsDialogue::addAllQuestionsToPrint()
{
for (int i = 0; i < printq_excludelist->count();) {
addQuestionToPrint(i);
}
updateTestQnum();
}
void PrintQuestionsDialogue::togglePrintEnabled()
{
printq_btn_print->setEnabled(printq_advanced_numquestions->value() > 0);
}
void PrintQuestionsDialogue::resetDefaultValues()
{
if (printTest()) {
printq_advanced_statistics->setChecked(false);
printq_advanced_formatting->setChecked(true);
} else {
printq_advanced_key->setChecked(false);
printq_advanced_usegroups->setChecked(false);
}
if (!randomise()) {
printq_advanced_numprintouts->setValue(1);
}
if (rbtngrpPrintqSelect->checkedButton()->text() == tr("Flags")) {
for (int i = 0; i < printq_includelist->rowCount(); ++i) {
printq_includelist->cellWidget(i, 1)->setEnabled(randomise());
if (!randomise()) { ((MTSpinBox *)printq_includelist->cellWidget(i, 1))->setMaximumValue(); }
}
}
}
void PrintQuestionsDialogue::updateTestQnum()
{
printq_parent->updateTestQnum(true, useGroups(), flagsSelected(), printq_advanced_numquestions, printq_includelist);
}
void PrintQuestionsDialogue::printQuestions()
{
printq_parent->printQuestions(this);
}
int percentageFromValues(float, float, float);
QString htmlForProgressBar(int, bool);
bool MainWindow::loadPrinterSettings()
{
QSettings settings("Michal Tomlein", "iTest");
printer_configured = settings.value("printer/configured", false).toBool();
printer_colorMode = settings.value("printer/colorMode").toInt();
printer_doubleSidedPrinting = settings.value("printer/doubleSidedPrinting").toBool();
printer_fontEmbeddingEnabled = settings.value("printer/fontEmbeddingEnabled").toBool();
printer_numCopies = settings.value("printer/numCopies").toInt();
printer_orientation = settings.value("printer/orientation").toInt();
printer_outputFileName = settings.value("printer/outputFileName").toString();
printer_outputFormat = settings.value("printer/outputFormat").toInt();
printer_pageOrder = settings.value("printer/pageOrder").toInt();
printer_pageSize = settings.value("printer/pageSize").toInt();
printer_paperSource = settings.value("printer/paperSource").toInt();
printer_printRange = settings.value("printer/printRange").toInt();
printer_printerName = settings.value("printer/printerName").toString();
printer_resolution = settings.value("printer/resolution").toInt();
return printer_configured;
}
void MainWindow::savePrinterSettings()
{
QSettings settings("Michal Tomlein", "iTest");
settings.remove("printer");
settings.setValue("printer/configured", printer_configured);
if (!printer_configured) return;
settings.setValue("printer/colorMode", printer_colorMode);
settings.setValue("printer/doubleSidedPrinting", printer_doubleSidedPrinting);
settings.setValue("printer/fontEmbeddingEnabled", printer_fontEmbeddingEnabled);
settings.setValue("printer/numCopies", printer_numCopies);
settings.setValue("printer/orientation", printer_orientation);
settings.setValue("printer/outputFileName", printer_outputFileName);
settings.setValue("printer/outputFormat", printer_outputFormat);
settings.setValue("printer/pageOrder", printer_pageOrder);
settings.setValue("printer/pageSize", printer_pageSize);
settings.setValue("printer/paperSource", printer_paperSource);
settings.setValue("printer/printRange", printer_printRange);
settings.setValue("printer/printerName", printer_printerName);
settings.setValue("printer/resolution", printer_resolution);
}
bool MainWindow::printerConfiguration(QString & printer_config)
{
QTextStream conf(&printer_config);
conf << "<br><br>\n<b>" << tr("Colour mode:") << "</b>" << " ";
switch (printer_colorMode) {
case QPrinter::Color: conf << tr("Colour") << endl; break;
case QPrinter::GrayScale: conf << tr("GrayScale") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
conf << "<br><b>" << tr("Double-sided printing:") << "</b>" << " ";
if (printer_doubleSidedPrinting) { conf << tr("Yes") << endl; }
else { conf << tr("No") << endl; }
conf << "<br><b>" << tr("Font embedding:") << "</b>" << " ";
if (printer_fontEmbeddingEnabled) { conf << tr("Yes") << endl; }
else { conf << tr("No") << endl; }
conf << "<br><b>" << tr("Number of copies:") << "</b>" << " ";
conf << printer_numCopies << endl;
#ifndef Q_WS_X11
conf << "<br>" << tr("Note: On Windows and Mac OS X, the number above is always 1<br>\nas these operating systems handle the number of copies internally.<br>\nTo print more copies, click 'Review configuration' and set the<br>\nnumber of copies each time you start the server.") << endl;
#endif
conf << "<br><b>" << tr("Orientation:") << "</b>" << " ";
switch (printer_orientation) {
case QPrinter::Portrait: conf << tr("Portrait") << endl; break;
case QPrinter::Landscape: conf << tr("Landscape") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
if (!printer_outputFileName.isEmpty()) {
conf << "<br><b>" << tr("Output file name:") << "</b>" << " ";
conf << printer_outputFileName << endl;
}
conf << "<br><b>" << tr("Output format:") << "</b>" << " ";
switch (printer_outputFormat) {
case QPrinter::NativeFormat: conf << tr("Native") << endl; break;
case QPrinter::PdfFormat: conf << tr("PDF") << endl; break;
case QPrinter::PostScriptFormat: conf << tr("PostScript") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
conf << "<br><b>" << tr("Page order:") << "</b>" << " ";
switch (printer_pageOrder) {
case QPrinter::FirstPageFirst: conf << tr("First page first") << endl; break;
case QPrinter::LastPageFirst: conf << tr("Last page first") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
conf << "<br><b>" << tr("Paper format:") << "</b>" << " ";
switch (printer_pageSize) {
case QPrinter::A0: conf << "A0" << endl; break;
case QPrinter::A1: conf << "A1" << endl; break;
case QPrinter::A2: conf << "A2" << endl; break;
case QPrinter::A3: conf << "A3" << endl; break;
case QPrinter::A4: conf << "A4" << endl; break;
case QPrinter::A5: conf << "A5" << endl; break;
case QPrinter::A6: conf << "A6" << endl; break;
case QPrinter::A7: conf << "A7" << endl; break;
case QPrinter::A8: conf << "A8" << endl; break;
case QPrinter::A9: conf << "A9" << endl; break;
case QPrinter::B0: conf << "B0" << endl; break;
case QPrinter::B1: conf << "B1" << endl; break;
case QPrinter::B10: conf << "B10" << endl; break;
case QPrinter::B2: conf << "B2" << endl; break;
case QPrinter::B3: conf << "B3" << endl; break;
case QPrinter::B4: conf << "B4" << endl; break;
case QPrinter::B5: conf << "B5" << endl; break;
case QPrinter::B6: conf << "B6" << endl; break;
case QPrinter::B7: conf << "B7" << endl; break;
case QPrinter::B8: conf << "B8" << endl; break;
case QPrinter::B9: conf << "B9" << endl; break;
case QPrinter::C5E: conf << "C5E" << endl; break;
case QPrinter::Comm10E: conf << "U.S. Common 10 Envelope" << endl; break;
case QPrinter::DLE: conf << "DLE" << endl; break;
case QPrinter::Executive: conf << "Executive" << endl; break;
case QPrinter::Folio: conf << "Folio" << endl; break;
case QPrinter::Ledger: conf << "Ledger" << endl; break;
case QPrinter::Legal: conf << "Legal" << endl; break;
case QPrinter::Letter: conf << "Letter" << endl; break;
case QPrinter::Tabloid: conf << "Tabloid" << endl; break;
case QPrinter::Custom: conf << tr("Custom") << endl; break;
default: conf << tr("Custom") << endl; break;
}
conf << "<br><b>" << tr("Paper source:") << "</b>" << " ";
switch (printer_paperSource) {
case QPrinter::OnlyOne: conf << tr("Only one") << endl; break;
case QPrinter::Lower: conf << tr("Lower") << endl; break;
case QPrinter::Middle: conf << tr("Middle") << endl; break;
case QPrinter::Manual: conf << tr("Manual") << endl; break;
case QPrinter::Envelope: conf << tr("Envelope") << endl; break;
case QPrinter::EnvelopeManual: conf << tr("Envelope (manual)") << endl; break;
case QPrinter::Auto: conf << tr("Auto") << endl; break;
case QPrinter::Tractor: conf << tr("Tractor") << endl; break;
case QPrinter::SmallFormat: conf << tr("Small format") << endl; break;
case QPrinter::LargeFormat: conf << tr("Large format") << endl; break;
case QPrinter::LargeCapacity: conf << tr("Large capacity") << endl; break;
case QPrinter::Cassette: conf << tr("Cassette") << endl; break;
case QPrinter::FormSource: conf << tr("Form source") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
conf << "<br><b>" << tr("Print range:") << "</b>" << " ";
switch (printer_printRange) {
case QPrinter::AllPages: conf << tr("All pages") << endl; break;
case QPrinter::Selection: conf << tr("Selection") << endl; break;
case QPrinter::PageRange: conf << tr("Page range") << endl; break;
default: conf << tr("Unknown") << endl; break;
}
if (printer_outputFileName.isEmpty()) {
conf << "<br><b>" << tr("Printer name:") << "</b>" << " ";
conf << printer_printerName << endl;
}
conf << "<br><b>" << tr("Resolution:") << "</b>" << " ";
conf << printer_resolution << endl;
conf << "<br><br>" << endl;
return true;
}
bool MainWindow::configurePrinter(bool review_config)
{
if (!review_config) {
if (default_printer != NULL) delete default_printer;
default_printer = new QPrinter(QPrinter::HighResolution);
} else {
if (!loadPrinterConfiguration()) return false;
default_printer->setOutputFileName("");
}
QPrintDialog * dialogue = new QPrintDialog(default_printer, this);
dialogue->setWindowTitle(tr("Configure printer"));
if (dialogue->exec() != QDialog::Accepted) return false;
printer_configured = true;
printer_colorMode = default_printer->colorMode();
printer_doubleSidedPrinting = default_printer->doubleSidedPrinting();
printer_fontEmbeddingEnabled = default_printer->fontEmbeddingEnabled();
printer_numCopies = default_printer->numCopies();
printer_orientation = default_printer->orientation();
printer_outputFileName = default_printer->outputFileName();
printer_outputFormat = default_printer->outputFormat();
printer_pageOrder = default_printer->pageOrder();
printer_pageSize = default_printer->pageSize();
printer_paperSource = default_printer->paperSource();
printer_printRange = default_printer->printRange();
printer_printerName = default_printer->printerName();
printer_resolution = default_printer->resolution();
savePrinterSettings();
return true;
}
bool MainWindow::loadPrinterConfiguration()
{
if (default_printer != NULL) delete default_printer;
default_printer = new QPrinter(QPrinter::HighResolution);
default_printer->setColorMode((QPrinter::ColorMode)printer_colorMode);
default_printer->setDoubleSidedPrinting(printer_doubleSidedPrinting);
default_printer->setFontEmbeddingEnabled(printer_fontEmbeddingEnabled);
default_printer->setNumCopies(printer_numCopies);
default_printer->setOrientation((QPrinter::Orientation)printer_orientation);
default_printer->setOutputFileName(printer_outputFileName);
default_printer->setOutputFormat((QPrinter::OutputFormat)printer_outputFormat);
default_printer->setPageOrder((QPrinter::PageOrder)printer_pageOrder);
default_printer->setPageSize((QPrinter::PageSize)printer_pageSize);
default_printer->setPaperSource((QPrinter::PaperSource)printer_paperSource);
default_printer->setPrintRange((QPrinter::PrintRange)printer_printRange);
default_printer->setPrinterName(printer_printerName);
default_printer->setResolution(printer_resolution);
return true;
}
bool MainWindow::printClientResults(Client * client, QPrinter * printer)
{
Student * student = new Student(client);
bool ok = printStudentResults(student, printer, current_db_testname, current_db_scoringsystem);
delete student;
return ok;
}
bool MainWindow::printStudentResults(Student * student, QPrinter * printer, QString session_name, ScoringSystem sys)
{
if (!student->isReady()) return false;
QTextDocument doc; QString html; QTextStream out(&html);
QuestionItem * item; QTextDocument qdoc;
QString header = tr("Exam results"); header.append(QString(" - %1 - %2 - %3").arg(Qt::escape(session_name)).arg(Qt::escape(student->name())).arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm")));
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << header << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: medium; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: 7pt; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: 7pt; color: black; font-weight: bold; }" << endl;
out << ".correct_qname { font-family: sans-serif; font-size: 7pt; font-weight: bold; color: rgb(69, 110, 14); }" << endl;
out << ".incorrect_qname { font-family: sans-serif; font-size: 7pt; font-weight: bold; color: rgb(204, 109, 0); }" << endl;
out << ".question { font-family: sans-serif; font-size: 7pt; color: black; }" << endl;
out << ".answer { font-family: sans-serif; font-size: 7pt; font-style: italic; color: black; }" << endl;
out << ".answered { text-decoration: underline; }" << endl;
out << ".correct { font-weight: bold; }" << endl;
out << "</style></head><body>" << endl;
out << "<p class=\"heading\" align=\"center\">" << endl << header << endl << "</p>" << endl;
QMapIterator<QString, QuestionAnswer> i(*(student->results())); QuestionAnswer qans;
while (i.hasNext()) {
i.next(); qans = i.value();
out << "<p><table border=\"0\" width=\"100%\" padding=\"0\" spacing=\"0\"><tr><td>" << endl;
if (qans.score(sys) > 0.0) {
out << "<div class=\"correct_qname\">" << endl;
} else {
out << "<div class=\"incorrect_qname\">" << endl;
}
item = NULL;
QMapIterator<QListWidgetItem *, QuestionItem *> q(current_db_questions);
while (q.hasNext()) { q.next();
if (q.value()->name() == i.key()) { item = q.value(); break; }
}
if (item != NULL) {
if (item->flag() >= 0 && item->flag() < 20) {
out << "<div class=\"bold_text\">";
out << Qt::escape(current_db_f[item->flag()]) << ": </div>";
}
if (!item->group().isEmpty()) {
out << "[" << Qt::escape(item->group()) << "] ";
}
out << Qt::escape(item->name()) << endl << "</div></td><td align=\"right\" class=\"default_text\">" << endl;
out << tr("%1 out of %2").arg(qans.score(sys)).arg(qans.maximumScore(sys)) << "</td></table>" << endl;
out << "<div class=\"question\">" << endl;
qdoc.setHtml(item->text());
out << Qt::escape(qdoc.toPlainText()) << endl << "</div>" << endl;
for (int a = 1; a <= item->numAnswers(); ++a) {
out << "<div class=\"answer";
if ((qans.answered() & Question::indexToAnswer(a)) == Question::indexToAnswer(a)) { out << " answered"; }
if (item->isAnswerAtIndexCorrect(a)) { out << " correct"; }
out << "\">\n" << Question::indexToLabel(a) << " " << Qt::escape(item->answerAtIndex(a)) << endl << "</div>" << endl;
}
} else {
out << Qt::escape(i.key()) << endl << "</div></td><td align=\"right\" class=\"default_text\">" << endl;
out << tr("%1 out of %2").arg(qans.score(sys)).arg(qans.maximumScore(sys)) << "</td></table>" << endl;
out << "<div class=\"question\">" << endl;
out << tr("Not available") << endl << "</div>" << endl;
out << "<div class=\"answer\">" << endl;
out << tr("Answered:") << " " << Question::answerToString(qans.answered()) << "; ";
out << tr("Correct answer:") << " " << Question::answerToString(qans.correctAnswer());
out << endl << "</div>" << endl;
}
out << "</p>" << endl;
}
out << "<p class=\"default_text\" align=\"right\">" << endl;
out << "<b>" << tr("Total score:") << "</b> ";
out << tr("%1 out of %2").arg(student->score()).arg(student->maximumScore());
out << QString(" (%3)").arg(student->passed() ? tr("PASSED") : tr("FAILED"));
out << endl << "</p></body></html>" << endl;
doc.setHtml(html); printer->setDocName(header); doc.print(printer);
return true;
}
void MainWindow::quickPrint()
{
if (!SMLCListWidget->currentIndex().isValid()) return;
Client * client = current_db_clients.value(SMLCListWidget->currentItem());
if (client == NULL) return;
if (!printClientResults(client, default_printer)) {
QListWidgetItem * log_entry = new QListWidgetItem(tr("%1 > Client #%2 (%3) > failed to print the client's results (Server QuickPrint call)").arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm:ss")).arg(client->number()).arg(client->name()));
SMSLListWidget->insertItem(0, log_entry);
log_entry->setBackground(QBrush::QBrush(QColor::QColor(200, 0, 0)));
log_entry->setForeground(QBrush::QBrush(QColor::QColor(0, 0, 0)));
} else {
QListWidgetItem * log_entry = new QListWidgetItem(tr("%1 > Client #%2 (%3) > results printed successfully (Server QuickPrint call)").arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm:ss")).arg(client->number()).arg(client->name()));
SMSLListWidget->insertItem(0, log_entry);
log_entry->setBackground(QBrush::QBrush(QColor::QColor(180, 255, 0)));
log_entry->setForeground(QBrush::QBrush(QColor::QColor(0, 0, 0)));
}
}
void MainWindow::print()
{
if (mainStackedWidget->currentIndex() == 5 || mainStackedWidget->currentIndex() == 6) {
Student * student; QString printdialogue_caption; QString session_name; ScoringSystem sys;
if (mainStackedWidget->currentIndex() == 5) {
if (!SMLCListWidget->currentIndex().isValid()) return;
student = new Student(current_db_clients.value(SMLCListWidget->currentItem()));
printdialogue_caption = tr("Print client's results");
session_name = current_db_testname;
sys = current_db_scoringsystem;
} else if (mainStackedWidget->currentIndex() == 6) {
if (!SVLCListWidget->currentIndex().isValid()) return;
student = current_db_students.value(SVLCListWidget->currentItem());
printdialogue_caption = tr("Print student's results");
if (current_db_session != NULL) {
session_name = current_db_session->name();
sys = current_db_session->scoringSystem();
} else { session_name = current_db_name; }
} else { return; }
if (student == NULL) return;
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(printdialogue_caption);
if (dialogue->exec() != QDialog::Accepted) return;
if (!printStudentResults(student, printer, session_name, sys)) {
if (mainStackedWidget->currentIndex() == 5) {
QListWidgetItem * log_entry = new QListWidgetItem(tr("%1 > Client #%2 (%3) > failed to print the client's results (Server Print call)").arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm:ss")).arg(student->number()).arg(student->name()));
SMSLListWidget->insertItem(0, log_entry);
log_entry->setBackground(QBrush::QBrush(QColor::QColor(200, 0, 0)));
log_entry->setForeground(QBrush::QBrush(QColor::QColor(0, 0, 0)));
} else {
statusBar()->showMessage(tr("Failed to print the results"), 10000);
}
} else {
if (mainStackedWidget->currentIndex() == 5) {
QListWidgetItem * log_entry = new QListWidgetItem(tr("%1 > Client #%2 (%3) > results printed successfully (Server Print call)").arg(QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm:ss")).arg(student->number()).arg(student->name()));
SMSLListWidget->insertItem(0, log_entry);
log_entry->setBackground(QBrush::QBrush(QColor::QColor(180, 255, 0)));
log_entry->setForeground(QBrush::QBrush(QColor::QColor(0, 0, 0)));
} else {
statusBar()->showMessage(tr("Results printed successfully"), 10000);
}
}
delete printer;
if (mainStackedWidget->currentIndex() == 5) { delete student; }
} else if (mainStackedWidget->currentIndex() == 7) {
if (current_db_class == NULL) { return; }
if (CLLSListWidget->highlightedRow() < 0) { return; }
ClassMember * mem = current_db_class->member(CLLSListWidget->highlightedRow());
if (mem == NULL) { return; }
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(tr("Print statistics for the selected student"));
if (dialogue->exec() != QDialog::Accepted) return;
QTextDocument doc; doc.setHtml(htmlForClassMember(mem));
printer->setDocName(tr("Statistics for %1").arg(mem->name())); doc.print(printer);
statusBar()->showMessage(tr("Statistics printed successfully"), 10000);
delete printer;
}
}
void MainWindow::printAll()
{
if (mainStackedWidget->currentIndex() == 5 || mainStackedWidget->currentIndex() == 6) {
if (current_db_session == NULL) { return; }
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(tr("Print the results of all students"));
if (dialogue->exec() != QDialog::Accepted) return;
if (printSessionSummary(current_db_session, printer)) {
statusBar()->showMessage(tr("Summary printed successfully"), 10000);
} else {
statusBar()->showMessage(tr("Failed to print the summary"), 10000);
}
int numfailed = 0, numsuccessful = 0;
for (int i = 0; i < current_db_session->numStudents(); ++i) {
if (printStudentResults(current_db_session->student(i), printer, current_db_session->name(), current_db_session->scoringSystem()))
{ numsuccessful++; } else { numfailed++; }
}
statusBar()->showMessage(tr("%1 results printed successfully; %2 failed").arg(numsuccessful).arg(numfailed), 10000);
delete printer;
} else if (mainStackedWidget->currentIndex() == 7) {
if (current_db_class == NULL) { return; }
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(tr("Print the results of all students"));
if (dialogue->exec() != QDialog::Accepted) return;
if (printClassSummary(current_db_class, printer)) {
statusBar()->showMessage(tr("Summary printed successfully"), 10000);
} else {
statusBar()->showMessage(tr("Failed to print the summary"), 10000);
}
for (int i = 0; i < current_db_class->numMembers(); ++i) {
QTextDocument doc; doc.setHtml(htmlForClassMember(current_db_class->member(i)));
printer->setDocName(tr("Statistics for %1").arg(current_db_class->member(i)->name())); doc.print(printer);
}
statusBar()->showMessage(tr("Results printed successfully"), 10000);
delete printer;
}
}
void MainWindow::printSessionSummary()
{
if (current_db_session == NULL) { return; }
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(tr("Print session summary"));
if (dialogue->exec() != QDialog::Accepted) return;
if (printSessionSummary(current_db_session, printer)) {
statusBar()->showMessage(tr("Summary printed successfully"), 10000);
} else {
statusBar()->showMessage(tr("Failed to print the summary"), 10000);
}
delete printer;
}
bool MainWindow::printSessionSummary(Session * session, QPrinter * printer)
{
if (session == NULL) { return false; }
if (printer == NULL) { return false; }
QTextDocument doc; QString html; QTextStream out(&html);
QString header = tr("Session statistics and summary");
header.append(QString(" - %1 - %2").arg(Qt::escape(session->name())).arg(session->dateTimeToString()));
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << header << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: medium; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: small; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".student_passed { font-family: sans-serif; font-size: small; font-weight: bold; color: rgb(69, 110, 14); }" << endl;
out << ".student_failed { font-family: sans-serif; font-size: small; font-weight: bold; color: rgb(204, 109, 0); }" << endl;
out << "</style></head><body>" << endl;
out << "<p class=\"heading\" align=\"center\">" << endl << header << endl << "</p>" << endl;
out << "<p>\n<div class=\"bold_text\">" << endl << tr("Pass mark:");
out << "</div><br><table border=\"0\" width=\"100%\">" << endl;
out << "<tr><td width=\"30%\"><div class=\"bold_text\">" << endl;
out << tr("Total") << endl << "</div></td><td><div class=\"bold_text\">";
out << session->passMark().passMark() << endl << "</div></td></tr>" << endl;
for (int i = 0; i < session->passMark().count(); ++i) {
out << "<tr><td width=\"30%\"><div class=\"default_text\">" << endl;
out << current_db_f[session->passMark().condition(i)] << endl;
out << "</div></td><td><div class=\"default_text\">" << endl;
out << session->passMark().value(i) << endl << "</div></td></tr>" << endl;
}
out << "</table><br><table border=\"0\" width=\"100%\"><tr><td width=\"60%\" valign=\"middle\"><div class=\"bold_text\">" << endl;
out << tr("Average:") << endl;
out << "</div></td><td>" << htmlForProgressBar(session->average(), session->mostPassed());
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << session->average() << "%" << endl;
out << "</div></td></tr></table><br><div class=\"bold_text\">" << endl;
out << tr("Students:") << endl << "</div><br>" << endl;
for (int i = 0; i < session->numStudents(); ++i) {
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"30%\" valign=\"middle\"><div class=\"" << (session->student(i)->passed() ? "student_passed" : "student_failed") << "\">" << endl;
out << Qt::escape(session->student(i)->name()) << endl;
out << "</div></td><td width=\"30%\" valign=\"middle\"><div class=\"default_text\">" << endl;
if (session->student(i)->isReady()) {
out << tr("%1 out of %2 (%3)").arg(session->student(i)->score()).arg(session->student(i)->maximumScore()).arg(session->student(i)->passed() ? tr("PASSED") : tr("FAILED")) << endl;
} else {
out << tr("NOT AVAILABLE") << endl;
}
out << "</div></td><td>" << endl;
if (session->student(i)->isReady()) {
int percentage = percentageFromValues(0.0, session->student(i)->maximumScore(), session->student(i)->score());
out << htmlForProgressBar(percentage, session->student(i)->passed());
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << percentage << "%" << endl;
} else {
out << htmlForProgressBar(0, false);
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl << tr("N/A") << endl;
}
out << "</div></td></tr></table>" << endl;
}
out << "</p></body></html>" << endl;
doc.setHtml(html); printer->setDocName(header); doc.print(printer);
return true;
}
void MainWindow::printClassSummary()
{
if (current_db_class == NULL) { return; }
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, this);
dialogue->setWindowTitle(tr("Print class summary"));
if (dialogue->exec() != QDialog::Accepted) return;
if (printClassSummary(current_db_class, printer)) {
statusBar()->showMessage(tr("Summary printed successfully"), 10000);
} else {
statusBar()->showMessage(tr("Failed to print the summary"), 10000);
}
delete printer;
}
bool MainWindow::printClassSummary(Class * cl, QPrinter * printer)
{
if (cl == NULL) { return false; }
if (printer == NULL) { return false; }
QTextDocument doc; QString html; QTextStream out(&html);
QString header = tr("Class statistics and summary");
header.append(QString(" - %1").arg(Qt::escape(cl->name())));
int average = cl->average(¤t_db_sessions, ¤t_db_archivedsessions);
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << header << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: medium; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: small; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".student_passed { font-family: sans-serif; font-size: small; color: rgb(69, 110, 14); }" << endl;
out << ".student_failed { font-family: sans-serif; font-size: small; color: rgb(204, 109, 0); }" << endl;
out << "</style></head><body>" << endl;
out << "<p align=\"center\"><div class=\"heading\">" << endl;
out << header << endl << "</div><div align=\"center\" class=\"bold_text\">" << endl;
out << cl->firstYear() << " - " << cl->lastYear() << "</div></p><p>" << endl;
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"60%\" valign=\"middle\"><div class=\"bold_text\">" << endl;
out << tr("Class average:") << endl;
out << "</div></td><td>" << htmlForProgressBar(average, average >= 50);
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << average << "%" << endl << "</div></td></tr></table>" << endl;
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"60%\"><div class=\"bold_text\">" << endl;
out << tr("Students:") << endl << "</div></td><td><div class=\"bold_text\">" << endl;
out << tr("Average:") << endl << "</div></td><td></td></tr></table>" << endl;
for (int i = 0; i < cl->numMembers(); ++i) {
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"60%\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << Qt::escape(cl->member(i)->name());
average = cl->member(i)->average(¤t_db_sessions, ¤t_db_archivedsessions);
out << "</div></td><td>" << htmlForProgressBar(average, average >= 50);
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << average << "%" << endl << "</div></td></tr></table>" << endl;
}
out << "</p></body></html>" << endl;
doc.setHtml(html); printer->setDocName(header); doc.print(printer);
return true;
}
void MainWindow::printQuestions(PrintQuestionsDialogue * printq_widget)
{
QPrinter * printer = new QPrinter(QPrinter::HighResolution);
QPrintDialog * dialogue = new QPrintDialog(printer, printq_widget);
dialogue->setWindowTitle(tr("Print questions"));
if (dialogue->exec() != QDialog::Accepted) return;
bool flags_selected = printq_widget->flagsSelected();
bool questions_selected = printq_widget->questionsSelected();
bool formatted = printq_widget->printFormatting();
bool print_statistics = printq_widget->printStatistics();
bool test = printq_widget->printTest();
bool print_graphics = printq_widget->printGraphics();
bool randomise = printq_widget->randomise();
int numprintouts = printq_widget->numPrintouts();
bool use_groups = printq_widget->useGroups();
int numquestions = printq_widget->numQuestions();
QList<int> used_items; PassMark passmark; int pm_v = 0;
for (int i = 0; i < printq_widget->includeTableWidget()->rowCount(); ++i) {
used_items << printq_widget->includeTableWidget()->item(i, 0)->data(Qt::UserRole).toInt();
pm_v = ((QSpinBox *)printq_widget->includeTableWidget()->cellWidget(i, 1))->value();
if (flags_selected && pm_v > 0) {
passmark.addCondition(printq_widget->includeTableWidget()->item(i, 0)->data(Qt::UserRole).toInt(), 0, pm_v);
}
}
QList<Question *> questions;
for (int i = 0; i < LQListWidget->count(); ++i) {
if (flags_selected) {
QuestionItem * item = current_db_questions.value(LQListWidget->item(i));
if (used_items.contains(item->flag()) && (!item->isHidden() || actionShow_hidden->isChecked())) {
questions << item;
}
} else if (questions_selected) {
if (used_items.contains(i)) {
questions << current_db_questions.value(LQListWidget->item(i));
}
}
}
QFileInfo file_info; bool print_to_file = false; bool native_format = false;
int len = QString("%1").arg(numprintouts).length();
if (!printer->outputFileName().isEmpty() && (numprintouts > 1 || printq_widget->printKey())) {
file_info.setFile(printer->outputFileName());
print_to_file = true;
native_format = printer->outputFormat() == QPrinter::NativeFormat;
}
QList<int> randlist[numprintouts]; QString timestamp = QDateTime::currentDateTime().toString("yyyy.MM.dd-hh:mm");
for (int i = 0; i < numprintouts; ++i) {
if (randomise) { randlist[i] = Question::randomise(questions, passmark, use_groups, numquestions, i); }
else { for (int q = 0; q < questions.count(); ++q) { randlist[i] << q; } }
QTextDocument doc; QString html; QTextStream out(&html);
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << tr("Questions") << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: small; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".answer { font-family: sans-serif; font-size: small; font-style: italic; color: black; }" << endl;
out << ".correct { font-weight: bold; }" << endl;
out << "</style></head><body>" << endl;
if (test) { out << QString("<div class=\"heading\" align=\"center\">%1#%2</div><hr noshade=\"noshade\" size=\"1\">").arg(timestamp).arg(i + 1, len, 10, QChar('0')) << endl; }
for (int r = 0; r < randlist[i].count(); ++r) {
out << htmlForQuestion((QuestionItem *)questions.at(randlist[i].at(r)), test ? r + 1 : 0, doc, test, formatted, print_statistics, print_graphics);
}
out << "</body></html>" << endl;
if (print_to_file) {
printer->setOutputFileName(file_info.dir().absoluteFilePath(file_info.baseName() + QString("_%1.").arg(i + 1, len, 10, QChar('0')) + file_info.completeSuffix()));
if (native_format) { printer->setOutputFormat(QPrinter::NativeFormat); }
}
doc.setHtml(html); printer->setDocName(tr("Questions")); doc.print(printer);
}
if (printq_widget->printKey()) {
QTextDocument doc; QString html; QTextStream out(&html);
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << tr("Key") << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: small; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".odd_col { background-color: lightgrey; }" << endl;
out << "table { border-style: solid; border-color: lightgrey; }" << endl;
out << "</style></head><body>" << endl;
out << QString("<div class=\"heading\" align=\"center\">%1</div><hr noshade=\"noshade\" size=\"1\">").arg(timestamp) << endl;
int cols = 12;
int n = numprintouts / cols; if (numprintouts % cols > 0) { n++; }
for (int t = 0; t < n; ++t) {
out << "<table border=\"1\" width=\"100%\" cellspacing=\"0\" cellpadding=\"1\">" << endl;
out << "<tr><th></th>" << endl;
for (int i = t * cols; i < qMin(numprintouts, (t + 1) * cols); ++i) {
out << QString("<th class=\"bold_text%1\" align=\"left\">#%2</th>").arg(i % 2 == 0 && numprintouts > 1 ? " odd_col" : "").arg(i + 1, len, 10, QChar('0')) << endl;
}
out << "</tr>" << endl;
for (int i = 0; i < numquestions; ++i) {
out << "<tr><td class=\"bold_text\">(" << i + 1 << ")</td>";
for (int j = t * cols; j < qMin(numprintouts, (t + 1) * cols); ++j) {
out << QString("<td class=\"default_text%1\">").arg(j % 2 == 0 && numprintouts > 1 ? " odd_col" : "");
out << Question::answerToString(questions.at(randlist[j].at(i))->correctAnswer());
out << "</td>" << endl;
}
out << "</tr>" << endl;
}
out << "</table><br>" << endl;
}
out << "</body></html>" << endl;
if (print_to_file) {
printer->setOutputFileName(file_info.dir().absoluteFilePath(file_info.baseName() + QString("_%1.").arg(tr("key")) + file_info.completeSuffix()));
if (native_format) { printer->setOutputFormat(QPrinter::NativeFormat); }
}
doc.setHtml(html); printer->setDocName(tr("Key")); doc.print(printer);
}
delete printer;
return;
}
QString MainWindow::htmlForQuestion(QuestionItem * item, int n, QTextDocument & doc, bool test, bool formatted, bool print_statistics, bool print_graphics)
{
if (item == NULL) { return ""; }
QString html; QTextStream out(&html);
out << "<div class=\"heading\" align=\"center\">" << endl;
if (n != 0) { out << "(" << n << ") "; }
if (item->flag() >= 0 && item->flag() < 20) {
out << Qt::escape(current_db_f[item->flag()]) << ": ";
}
if (!item->group().isEmpty()) {
out << "[" << Qt::escape(item->group()) << "] ";
}
out << Qt::escape(item->name()) << endl << "</div>" << endl;
if (!test) {
out << "<table border=\"0\" width=\"100%\">" << endl;
out << "<tr><td width=\"40%\"><div class=\"bold_text\">" << endl;
out << tr("Name:") << "</div></td><td><div class=\"default_text\">" << endl;
out << Qt::escape(item->name()) << "</div></td></tr>" << endl;
if (item->flag() >= 0 && item->flag() < 20) {
out << "<tr><td width=\"40%\"><div class=\"bold_text\">" << endl;
out << tr("Flag:") << "</div></td><td><div class=\"default_text\">" << endl;
out << Qt::escape(current_db_f[item->flag()]) << "</div></td></tr>" << endl;
}
if (!item->group().isEmpty()) {
out << "<tr><td width=\"40%\"><div class=\"bold_text\">" << endl;
out << tr("Group:") << "</div></td><td><div class=\"default_text\">" << endl;
out << Qt::escape(item->group()) << "</div></td></tr>" << endl;
}
out << "<tr><td width=\"40%\"><div class=\"bold_text\">" << endl;
out << tr("Difficulty:") << "</div></td><td><div class=\"default_text\">" << endl;
switch (item->difficulty()) {
case 0: out << tr("Easy"); break;
case 1: out << tr("Medium"); break;
case 2: out << tr("Difficult"); break;
default: out << tr("Unknown"); break;
}
out << "</div></td></tr>" << endl;
if (item->numSvgItems() > 0 && !print_graphics) {
out << "<tr><td width=\"40%\"><div class=\"bold_text\">" << endl;
out << tr("Attachments (SVG):") << "</div></td><td><div class=\"default_text\">" << endl;
for (int i = 0; i < item->numSvgItems(); ++i) {
out << Qt::escape(item->svgItem(i)->text()) << "<b>; </b>";
}
out << "</div></td></tr>" << endl;
}
out << "</table>" << endl;
}
if (formatted) {
out << item->text() << endl;
} else {
QTextDocument doc; doc.setHtml(item->text());
out << Qt::escape(doc.toPlainText()) << endl;
}
if (item->numSvgItems() > 0 && print_graphics) {
out << "<table border=\"0\" width=\"100%\"><tr>" << endl;
for (int i = 0; i < item->numSvgItems(); ++i) {
QSvgRenderer svgrenderer(item->svgItem(i)->svg().toUtf8());
if (!svgrenderer.isValid()) { out << "<td></td>" << endl; continue; }
QSize svg_size = svgrenderer.defaultSize();
svg_size.scale(128, 128, Qt::KeepAspectRatio);
QPixmap pixmap(svg_size);
QPainter painter(&pixmap);
painter.save();
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(Qt::white));
painter.drawRect(QRect(0, 0, svg_size.width(), svg_size.height()));
painter.restore();
svgrenderer.render(&painter);
QUrl resource_url(QString("%1-%2-%3.qpixmap").arg(item->name()).arg(i).arg(qrand()));
doc.addResource(QTextDocument::ImageResource, resource_url, pixmap);
out << "<td align=\"center\"><img src=\"" << resource_url.toString(QUrl::None) << "\"></td>" << endl;
}
out << "</tr><tr>" << endl;
for (int i = 0; i < item->numSvgItems(); ++i) {
out << "<td align=\"center\"><div class=\"default_text\">";
out << Qt::escape(item->svgItem(i)->text()) << "</div></td>" << endl;
}
out << "</tr></table>" << endl;
}
for (int a = 1; a <= item->numAnswers(); ++a) {
if (!item->answerAtIndex(a).isEmpty() || item->isAnswerAtIndexCorrect(a)) {
out << "<div class=\"answer";
if (item->isAnswerAtIndexCorrect(a) && !test) { out << " correct"; }
out << "\">\n" << Question::indexToLabel(a) << " " << Qt::escape(item->answerAtIndex(a)) << endl << "</div>" << endl;
}
}
if (print_statistics) {
if (item->incorrectAnsCount() != 0 || item->correctAnsCount() != 0) {
out << "<br><div class=\"bold_text\">" << tr("Statistics:") << "</div>" << endl;
out << "<table border=\"0\" width=\"100%\">" << endl;
out << "<tr><td width=\"40%\"><div class=\"default_text\">" << endl;
out << tr("Number of correct answers:") << "</div></td><td><div class=\"default_text\">" << endl;
out << item->correctAnsCount() << "</div></td></tr>" << endl;
out << "<tr><td width=\"40%\"><div class=\"default_text\">" << endl;
out << tr("Number of incorrect answers:") << "</div></td><td><div class=\"default_text\">" << endl;
out << item->incorrectAnsCount() << "</div></td></tr>" << endl;
out << "<tr><td width=\"40%\"><div class=\"default_text\">" << endl;
out << tr("Calculated difficulty:") << "</div></td><td><div class=\"default_text\">" << endl;
switch (item->recommendedDifficulty()) {
case -1: out << tr("Unavailable"); break;
case 0: out << tr("Easy"); break;
case 1: out << tr("Medium"); break;
case 2: out << tr("Difficult"); break;
default: out << tr("Unavailable"); break;
}
out << "</div></td></tr></table>" << endl;
}
}
out << "</p><hr noshade=\"noshade\" size=\"1\">" << endl;
return html;
}
QString MainWindow::htmlForClassMember(ClassMember * mem)
{
QString html; QTextStream out(&html); int average = mem->average(¤t_db_sessions, ¤t_db_archivedsessions);
out << "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>" << endl;
out << tr("Statistics for %1").arg(Qt::escape(mem->name())) << endl << "</title><style type=\"text/css\">" << endl;
out << ".heading { font-family: sans-serif; font-size: medium; font-weight: bold; color: black; }" << endl;
out << ".default_text { font-family: sans-serif; font-size: small; color: black; }" << endl;
out << ".bold_text { font-family: sans-serif; font-size: small; font-weight: bold; color: black; }" << endl;
out << ".student_passed { font-family: sans-serif; font-size: small; color: rgb(69, 110, 14); }" << endl;
out << ".student_failed { font-family: sans-serif; font-size: small; color: rgb(204, 109, 0); }" << endl;
out << "</style></head><body>" << endl;
out << "<p align=\"center\"><div class=\"heading\">" << endl;
out << tr("Statistics for %1").arg(Qt::escape(mem->name())) << endl << "</div><div align=\"center\" class=\"bold_text\">" << endl;
out << current_db_class->firstYear() << " - " << current_db_class->lastYear() << ": " << Qt::escape(current_db_class->name()) << "</div></p><p>" << endl;
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"60%\" valign=\"middle\"><div class=\"bold_text\">" << endl;
out << tr("Average:") << endl;
out << "</div></td><td>" << htmlForProgressBar(average, average >= 50);
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << average << "%" << endl << "</div></td></tr></table>" << endl;
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"35%\"><div class=\"bold_text\">" << endl;
out << tr("Test sessions attended:") << endl << "</div></td><td width=\"25%\"><div class=\"bold_text\">" << endl;
out << tr("Under the name:") << endl << "</div></td><td><div class=\"bold_text\">" << endl;
out << tr("With a score of:") << endl << "</div></td><td></td></tr></table>" << endl;
QMap<QDateTime, int> sessions_map;
for (int i = 0; i < mem->numSessionEntries(); ++i) {
sessions_map.insert(mem->sessionEntry(i).session, i);
}
QMapIterator<QDateTime, int> i(sessions_map);
while (i.hasNext()) { i.next();
Session * session = current_db_sessions.value(i.key(), current_db_archivedsessions.value(i.key(), NULL));
out << "<table border=\"0\" width=\"100%\"><tr><td width=\"35%\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << mem->sessionToString(i.value());
if (session != NULL) { out << " - " << Qt::escape(session->name()); }
out << "</div></td><td width=\"25%\" valign=\"middle\"><div class=\"";
out << (session != NULL ? (session->student(mem->sessionEntry(i.value()).member_num)->passed() ? "student_passed" : "student_failed") : "student_passed");
out << "\">" << endl;
if (session != NULL) { out << Qt::escape(session->student(mem->sessionEntry(i.value()).member_num)->name()); }
out << "</div></td><td>";
int percentage = 0;
if (session != NULL) {
percentage = percentageFromValues(0.0, session->student(mem->sessionEntry(i.value()).member_num)->maximumScore(), session->student(mem->sessionEntry(i.value()).member_num)->score());
out << htmlForProgressBar(percentage, session->student(mem->sessionEntry(i.value()).member_num)->passed());
}
else { out << htmlForProgressBar(0, true); }
out << "</td><td width=\"7%\" align=\"right\" valign=\"middle\"><div class=\"default_text\">" << endl;
out << percentage << "%" << endl << "</div></td></tr></table>" << endl;
}
out << "</p></body></html>" << endl;
return html;
}
int percentageFromValues(float minimum, float maximum, float value)
{
return (maximum - minimum) != 0.0 ? (int)(100 * (value - minimum) / (maximum - minimum)) : 100;
}
QString htmlForProgressBar(int percentage, bool green)
{
QString html; QTextStream out(&html);
out << "<table border=\"2\" width=\"100%\" height=\"20\"><tr>";
if (percentage > 0) {
out << "<td bgcolor=\"";
out << (green ? "yellowgreen" : "#FF9419"); out << "\" width=\"" << percentage << "%\"></td>" << endl;
}
out << (percentage >= 100 ? "</tr>" : "<td></td></tr>") << "</table>" << endl;
return html;
}