Convert CRLF to Unix newlines

This commit is contained in:
Sebastian Lohff 2022-06-30 23:13:43 +02:00
parent 9898b3404a
commit 1010914f41
47 changed files with 8916 additions and 8916 deletions

View File

@ -1,119 +1,119 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "answer.h" #include "answer.h"
#include <qcoreapplication.h> #include <qcoreapplication.h>
CAnswer::CAnswer(const QString& strText, const bool bCorrect) CAnswer::CAnswer(const QString& strText, const bool bCorrect)
{ {
m_strText = strText; m_strText = strText;
m_bIsCorrect = bCorrect; m_bIsCorrect = bCorrect;
} }
void CAnswer::clear() void CAnswer::clear()
{ {
m_strText.clear(); m_strText.clear();
m_bIsCorrect = false; m_bIsCorrect = false;
} }
QString CAnswerClicked::tr (const char *sourceText, const char *comment) QString CAnswerClicked::tr (const char *sourceText, const char *comment)
{ {
return QCoreApplication::translate("CAnswerClicked", sourceText, comment); return QCoreApplication::translate("CAnswerClicked", sourceText, comment);
} }
void CAnswerClicked::clear() void CAnswerClicked::clear()
{ {
m_dt = QDateTime::currentDateTime(); m_dt = QDateTime::currentDateTime();
m_uAnswer=0; m_uAnswer=0;
m_uNeededTime=0; m_uNeededTime=0;
} }
bool CAnswerClicked::operator < (const CAnswerClicked& ac) const bool CAnswerClicked::operator < (const CAnswerClicked& ac) const
{ {
return m_dt < ac.m_dt; return m_dt < ac.m_dt;
} }
QString CAnswerClicked::answerText(const unsigned uAnswer) QString CAnswerClicked::answerText(const unsigned uAnswer)
{ {
QString strRet; QString strRet;
for (int i=0; i<32; i++) for (int i=0; i<32; i++)
{ {
if (uAnswer & (1<<i)) if (uAnswer & (1<<i))
{ {
if (!strRet.isEmpty()) if (!strRet.isEmpty())
strRet += ", "; strRet += ", ";
strRet += QChar('A' + i); strRet += QChar('A' + i);
} }
} }
return strRet; return strRet;
} }
QString CAnswerClicked::answerText() const QString CAnswerClicked::answerText() const
{ {
return answerText(m_uAnswer); return answerText(m_uAnswer);
} }
QString CAnswerClicked::neededTimeText() const QString CAnswerClicked::neededTimeText() const
{ {
if (m_uNeededTime < 1000) if (m_uNeededTime < 1000)
return tr("&lt; 1 sec"); return tr("&lt; 1 sec");
else if (m_uNeededTime < 60000) else if (m_uNeededTime < 60000)
return tr("%1 sec").arg(m_uNeededTime / 1000); return tr("%1 sec").arg(m_uNeededTime / 1000);
else else
return tr("%1:%2 min").arg(m_uNeededTime / 60000).arg((m_uNeededTime / 1000) % 60, 2, 10, QChar('0')); return tr("%1:%2 min").arg(m_uNeededTime / 60000).arg((m_uNeededTime / 1000) % 60, 2, 10, QChar('0'));
} }
bool CAnswerClicked::isCorrect(const QList<CAnswer>& listAnswer) const bool CAnswerClicked::isCorrect(const QList<CAnswer>& listAnswer) const
{ {
unsigned uMask=0; unsigned uMask=0;
for (int i=0; i<listAnswer.size(); i++) for (int i=0; i<listAnswer.size(); i++)
{ {
if (listAnswer.at(i).isCorrect()) if (listAnswer.at(i).isCorrect())
uMask |= (1<<i); uMask |= (1<<i);
} }
return (m_uAnswer == uMask); return (m_uAnswer == uMask);
} }
bool CAnswerClicked::load (QDomElement elem) bool CAnswerClicked::load (QDomElement elem)
{ {
bool bOk=false; bool bOk=false;
if (elem.tagName() != "answer_clicked") return false; if (elem.tagName() != "answer_clicked") return false;
m_dt = QDateTime::fromString (elem.attribute("datetime"), Qt::ISODate); m_dt = QDateTime::fromString (elem.attribute("datetime"), Qt::ISODate);
if (!m_dt.isValid()) return false; if (!m_dt.isValid()) return false;
m_uAnswer = elem.attribute("answer_code").toUInt(&bOk); m_uAnswer = elem.attribute("answer_code").toUInt(&bOk);
if (!bOk) return false; if (!bOk) return false;
m_uNeededTime = elem.attribute("needed_time").toUInt(&bOk); m_uNeededTime = elem.attribute("needed_time").toUInt(&bOk);
if (!bOk) return false; if (!bOk) return false;
return true; return true;
} }
void CAnswerClicked::save (QDomElement& parent, QDomDocument& doc) const void CAnswerClicked::save (QDomElement& parent, QDomDocument& doc) const
{ {
QDomElement elem = doc.createElement("answer_clicked"); QDomElement elem = doc.createElement("answer_clicked");
elem.setAttribute("datetime", m_dt.toString(Qt::ISODate)); elem.setAttribute("datetime", m_dt.toString(Qt::ISODate));
elem.setAttribute("answer_code", QString("%1").arg(m_uAnswer)); elem.setAttribute("answer_code", QString("%1").arg(m_uAnswer));
elem.setAttribute("needed_time", QString("%1").arg(m_uNeededTime)); elem.setAttribute("needed_time", QString("%1").arg(m_uNeededTime));
parent.appendChild(elem); parent.appendChild(elem);
} }

284
answer.h
View File

@ -1,142 +1,142 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ANSWER_H #ifndef ANSWER_H
#define ANSWER_H #define ANSWER_H
#include <qstring.h> #include <qstring.h>
#include <qdom.h> #include <qdom.h>
#include <qlist.h> #include <qlist.h>
#include <qdatetime.h> #include <qdatetime.h>
//! Die Klasse CAnswer speichert eine einzelne Antwort auf eine Frage //! Die Klasse CAnswer speichert eine einzelne Antwort auf eine Frage
/*! /*!
Das Schreiben und Lesen von XML-Daten wird von der Klasse CQuestion übernommen Das Schreiben und Lesen von XML-Daten wird von der Klasse CQuestion übernommen
*/ */
class CAnswer class CAnswer
{ {
public: public:
//! Standard-Konstruktor //! Standard-Konstruktor
/*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */ /*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */
CAnswer() { clear(); } CAnswer() { clear(); }
//! Konstruktor inkl. setzen eines Textes und ob die Antwort richtig ist //! Konstruktor inkl. setzen eines Textes und ob die Antwort richtig ist
/*! /*!
\param strText Antworttext \param strText Antworttext
\param bCorrect true: Die Antwort ist korrekt \param bCorrect true: Die Antwort ist korrekt
\sa m_strText, m_bIsCorrect \sa m_strText, m_bIsCorrect
*/ */
CAnswer(const QString& strText, const bool bCorrect); CAnswer(const QString& strText, const bool bCorrect);
//! Standard-Destruktor //! Standard-Destruktor
/*! In der Standard-Implementierung tut der Destruktor nichts. */ /*! In der Standard-Implementierung tut der Destruktor nichts. */
~CAnswer() {} ~CAnswer() {}
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Daten der Antwort gelöscht. */ /*! Es werden alle Daten der Antwort gelöscht. */
void clear(); void clear();
//! Überprüfen, ob die Klasse eine Antwort enthält //! Überprüfen, ob die Klasse eine Antwort enthält
/*! \return true: Die Klasse ist leer und enthält keine Antwort */ /*! \return true: Die Klasse ist leer und enthält keine Antwort */
inline bool isEmpty() const { return m_strText.isEmpty(); } inline bool isEmpty() const { return m_strText.isEmpty(); }
//! Auslesen, ob diese Antwort richtig ist //! Auslesen, ob diese Antwort richtig ist
/*! \return true: Die Antwort ist richtig */ /*! \return true: Die Antwort ist richtig */
inline bool isCorrect() const { return m_bIsCorrect; } inline bool isCorrect() const { return m_bIsCorrect; }
//! Auslesen des Antworttextes //! Auslesen des Antworttextes
/*! \return Antworttext */ /*! \return Antworttext */
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
//! Setzen, ob diese Antwort richtig ist //! Setzen, ob diese Antwort richtig ist
/*! /*!
\param bCorrect true: Die Antwort ist korrekt \param bCorrect true: Die Antwort ist korrekt
\sa m_bIsCorrect \sa m_bIsCorrect
*/ */
inline void setCorrect (const bool bCorrect) { m_bIsCorrect = bCorrect; } inline void setCorrect (const bool bCorrect) { m_bIsCorrect = bCorrect; }
//! Setzen des Antworttextes //! Setzen des Antworttextes
/*! /*!
\param strText Antworttext \param strText Antworttext
\sa m_strText \sa m_strText
*/ */
inline void setText(const QString& strText) { m_strText = strText; } inline void setText(const QString& strText) { m_strText = strText; }
//! Anhängen eines Textes an den Antworttext //! Anhängen eines Textes an den Antworttext
/*! /*!
\param strText Anzuhängender Text \param strText Anzuhängender Text
\sa m_strText \sa m_strText
*/ */
inline void appendText(const QString& strText) { m_strText += strText; } inline void appendText(const QString& strText) { m_strText += strText; }
protected: protected:
//! Antworttext //! Antworttext
/*! /*!
Der Antworttext darf HTML-Code und HTML-Verweise auf Grafiken/Bilder enthalten. Bei Verweisen ist zu achten, dass kein Verzeichnis angegeben werden darf! Der Antworttext darf HTML-Code und HTML-Verweise auf Grafiken/Bilder enthalten. Bei Verweisen ist zu achten, dass kein Verzeichnis angegeben werden darf!
Default: leer Default: leer
*/ */
QString m_strText; QString m_strText;
//! Richtige oder falsche Antwort //! Richtige oder falsche Antwort
/*! Default: false */ /*! Default: false */
bool m_bIsCorrect; bool m_bIsCorrect;
}; };
//! Die Klasse CAnswerClicked speichert eine einzelne Beantwortung des Benutzers //! Die Klasse CAnswerClicked speichert eine einzelne Beantwortung des Benutzers
/*! /*!
*/ */
class CAnswerClicked class CAnswerClicked
{ {
public: public:
//! Standard-Konstruktor //! Standard-Konstruktor
/*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */ /*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */
CAnswerClicked () { clear(); } CAnswerClicked () { clear(); }
CAnswerClicked (const unsigned uAnswer, const unsigned uNeededTime) CAnswerClicked (const unsigned uAnswer, const unsigned uNeededTime)
{ m_uAnswer = uAnswer; m_dt = QDateTime::currentDateTime(); m_uNeededTime = uNeededTime; } { m_uAnswer = uAnswer; m_dt = QDateTime::currentDateTime(); m_uNeededTime = uNeededTime; }
//! Standard-Destruktor //! Standard-Destruktor
/*! In der Standard-Implementierung tut der Destruktor nichts. */ /*! In der Standard-Implementierung tut der Destruktor nichts. */
~CAnswerClicked () {} ~CAnswerClicked () {}
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Daten auf Default-Werte zurückgesetzt. */ /*! Es werden alle Daten auf Default-Werte zurückgesetzt. */
void clear(); void clear();
inline QDateTime dateTime() const { return m_dt; } inline QDateTime dateTime() const { return m_dt; }
inline unsigned neededTime() const { return m_uNeededTime; } inline unsigned neededTime() const { return m_uNeededTime; }
inline unsigned answer() const { return m_uAnswer; } inline unsigned answer() const { return m_uAnswer; }
static QString answerText(const unsigned uAnswer); static QString answerText(const unsigned uAnswer);
QString answerText() const; QString answerText() const;
QString neededTimeText() const; QString neededTimeText() const;
bool isCorrect(const QList<CAnswer>& listAnswer) const; bool isCorrect(const QList<CAnswer>& listAnswer) const;
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc) const; void save (QDomElement& parent, QDomDocument& doc) const;
static QString tr (const char *sourceText, const char *comment=0); static QString tr (const char *sourceText, const char *comment=0);
bool operator < (const CAnswerClicked& ac) const; bool operator < (const CAnswerClicked& ac) const;
protected: protected:
QDateTime m_dt; //!< Zeitstempel der Antwort QDateTime m_dt; //!< Zeitstempel der Antwort
unsigned m_uAnswer; //!< Antwort-Bitmaske unsigned m_uAnswer; //!< Antwort-Bitmaske
unsigned m_uNeededTime; //!< Benötigte Zeit in ms unsigned m_uNeededTime; //!< Benötigte Zeit in ms
}; };
#endif #endif

View File

@ -1,433 +1,433 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "catalog.h" #include "catalog.h"
#include "osziparchive.h" #include "osziparchive.h"
#include "tools.h" #include "tools.h"
#include <qdir.h> #include <qdir.h>
#include <qfile.h> #include <qfile.h>
#include <qmessagebox.h> #include <qmessagebox.h>
#include <qtextstream.h> #include <qtextstream.h>
#include <qvariant.h> #include <qvariant.h>
CCatalog::~CCatalog() CCatalog::~CCatalog()
{ {
qDeleteAll(m_listFiles); qDeleteAll(m_listFiles);
} }
void CCatalog::clear() void CCatalog::clear()
{ {
CChapter::clear(); CChapter::clear();
m_bMixAnswers = true; m_bMixAnswers = true;
m_bSort = false; m_bSort = false;
m_strFileName.clear(); m_strFileName.clear();
m_listHint.clear(); m_listHint.clear();
m_strUniqueName.clear(); m_strUniqueName.clear();
qDeleteAll(m_listFiles); qDeleteAll(m_listFiles);
m_strPublisher.clear(); m_strPublisher.clear();
m_strContact.clear(); m_strContact.clear();
m_dateValidFrom = QDate(); m_dateValidFrom = QDate();
m_dateValidUntil = QDate(); m_dateValidUntil = QDate();
m_dateCreated = QDate(); m_dateCreated = QDate();
m_datePublished = QDate(); m_datePublished = QDate();
m_strVersion.clear(); m_strVersion.clear();
m_listExam.clear(); m_listExam.clear();
m_listExamStat.clear(); m_listExamStat.clear();
} }
bool CCatalog::isEmpty() bool CCatalog::isEmpty()
{ {
return m_strText.isEmpty(); return m_strText.isEmpty();
} }
bool CCatalog::isValid() const bool CCatalog::isValid() const
{ {
if (m_dateValidFrom.isValid() && QDate::currentDate() < m_dateValidFrom) return false; if (m_dateValidFrom.isValid() && QDate::currentDate() < m_dateValidFrom) return false;
if (m_dateValidUntil.isValid() && QDate::currentDate() > m_dateValidUntil) return false; if (m_dateValidUntil.isValid() && QDate::currentDate() > m_dateValidUntil) return false;
return true; return true;
} }
bool CCatalog::hasHints (const QString& strQuestionId) const bool CCatalog::hasHints (const QString& strQuestionId) const
{ {
for (int i=0; i<m_listHint.size(); i++) for (int i=0; i<m_listHint.size(); i++)
{ {
if (m_listHint.at(i).hasQuestion(strQuestionId)) return true; if (m_listHint.at(i).hasQuestion(strQuestionId)) return true;
} }
return false; return false;
} }
QString CCatalog::hintText (const QString& strQuestionId) const QString CCatalog::hintText (const QString& strQuestionId) const
{ {
QString str; QString str;
if (strQuestionId.isEmpty()) return QString(); if (strQuestionId.isEmpty()) return QString();
for (int i=0; i<m_listHint.size(); i++) for (int i=0; i<m_listHint.size(); i++)
{ {
if (m_listHint.at(i).hasQuestion(strQuestionId)) if (m_listHint.at(i).hasQuestion(strQuestionId))
str += m_listHint[i].showText(); str += m_listHint[i].showText();
} }
return str; return str;
} }
bool CCatalog::load (const QString& strFileName, QWidget *pParent) bool CCatalog::load (const QString& strFileName, QWidget *pParent)
{ {
QDomDocument doc; QDomDocument doc;
QDomElement elemRoot, e; QDomElement elemRoot, e;
QDomNode n; QDomNode n;
QString str, strXML; QString str, strXML;
int iErrLine, iErrCol; int iErrLine, iErrCol;
double dVersion=0.0; double dVersion=0.0;
CChapter *pChapter=0; CChapter *pChapter=0;
if (strFileName.right(3).toLower() != "aqz") return false; if (strFileName.right(3).toLower() != "aqz") return false;
CZipArchive zip; CZipArchive zip;
if (!zip.open(strFileName, CZipArchive::OpenReadOnly)) if (!zip.open(strFileName, CZipArchive::OpenReadOnly))
{ {
QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n%1").arg(strFileName)); QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n%1").arg(strFileName));
return false; return false;
} }
// Fragen entpacken // Fragen entpacken
CZipFile *pzfQuestions = zip.findFile("questions.xml"); CZipFile *pzfQuestions = zip.findFile("questions.xml");
if (pzfQuestions == 0) if (pzfQuestions == 0)
{ {
QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Konnte in der Datei '%1' keine Fragen finden.").arg(strFileName)); QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Konnte in der Datei '%1' keine Fragen finden.").arg(strFileName));
return false; return false;
} }
strXML = QString::fromUtf8(pzfQuestions->deflateToByteArray()); strXML = QString::fromUtf8(pzfQuestions->deflateToByteArray());
clear(); clear();
// Alle Grafiken in temp. Dateien entpacken // Alle Grafiken in temp. Dateien entpacken
// pParent->setCursor(Qt::WaitCursor); // pParent->setCursor(Qt::WaitCursor);
for (int i=0; i<zip.fileCount(); i++) for (int i=0; i<zip.fileCount(); i++)
{ {
CZipFile *pzf = zip.fileAt(i); CZipFile *pzf = zip.fileAt(i);
str = pzf->fileName().right(3); str = pzf->fileName().right(3);
if (str == "png" || str == "jpg" || str == "gif" || str == "bmp") if (str == "png" || str == "jpg" || str == "gif" || str == "bmp")
{ // Datei entpacken und Pfade im XML anpassen { // Datei entpacken und Pfade im XML anpassen
str = QDir::temp().absoluteFilePath(pzf->fileName()+".XXXXXX"); str = QDir::temp().absoluteFilePath(pzf->fileName()+".XXXXXX");
QTemporaryFile *ptf = new QTemporaryFile(str); QTemporaryFile *ptf = new QTemporaryFile(str);
ptf->open(); ptf->open();
str = ptf->fileName(); str = ptf->fileName();
pzf->deflateToFile(*ptf); pzf->deflateToFile(*ptf);
ptf->close(); ptf->close();
m_listFiles.append(ptf); m_listFiles.append(ptf);
strXML.replace(pzf->fileName(), str); strXML.replace(pzf->fileName(), str);
//qDebug ("Deflating %s to %s", qPrintable(pzf->fileName()), qPrintable(str)); //qDebug ("Deflating %s to %s", qPrintable(pzf->fileName()), qPrintable(str));
} }
} }
// pParent->setCursor(Qt::ArrowCursor); // pParent->setCursor(Qt::ArrowCursor);
if (!doc.setContent(strXML, true, &str, &iErrLine, &iErrCol)) if (!doc.setContent(strXML, true, &str, &iErrLine, &iErrCol))
{ {
QMessageBox::critical(pParent, pParent->tr("XML-Fehler"), pParent->tr("Fragenkatalog: ") + strFileName + "\n" + str + "\n" + QString (pParent->tr("Zeile: %1 Spalte %2")).arg(iErrLine).arg(iErrCol)); QMessageBox::critical(pParent, pParent->tr("XML-Fehler"), pParent->tr("Fragenkatalog: ") + strFileName + "\n" + str + "\n" + QString (pParent->tr("Zeile: %1 Spalte %2")).arg(iErrLine).arg(iErrCol));
return false; return false;
} }
elemRoot = doc.documentElement (); elemRoot = doc.documentElement ();
if (elemRoot.tagName() != "aqdf") if (elemRoot.tagName() != "aqdf")
{ {
QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Unbekanntes XML-Datenformat '%1'.").arg(elemRoot.tagName())); QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Unbekanntes XML-Datenformat '%1'.").arg(elemRoot.tagName()));
return false; return false;
} }
//m_strText = elemRoot.attribute ("name"); //m_strText = elemRoot.attribute ("name");
m_dateCreated = QDate::fromString(elemRoot.attribute("created"), Qt::ISODate); m_dateCreated = QDate::fromString(elemRoot.attribute("created"), Qt::ISODate);
dVersion = elemRoot.attribute("version").toDouble(); dVersion = elemRoot.attribute("version").toDouble();
if (dVersion != 1.0) if (dVersion != 1.0)
{ {
QMessageBox::information(pParent, pParent->tr("Information"), pParent->tr("Kann die Dateiversion %1 des Fragenkatalogs '%2' nicht lesen.").arg(dVersion).arg(strFileName)); QMessageBox::information(pParent, pParent->tr("Information"), pParent->tr("Kann die Dateiversion %1 des Fragenkatalogs '%2' nicht lesen.").arg(dVersion).arg(strFileName));
return false; return false;
} }
n = elemRoot.firstChild(); n = elemRoot.firstChild();
while (!n.isNull()) while (!n.isNull())
{ {
if (n.isElement ()) if (n.isElement ())
{ {
e = n.toElement (); e = n.toElement ();
if (e.tagName() == QString ("chapter")) if (e.tagName() == QString ("chapter"))
{ {
pChapter = new CChapter(); pChapter = new CChapter();
if (pChapter->load (e)) if (pChapter->load (e))
appendChapter(pChapter); appendChapter(pChapter);
else else
delete pChapter; delete pChapter;
} }
else if (e.tagName() == QString ("exam")) else if (e.tagName() == QString ("exam"))
{ {
CExam exam; CExam exam;
if (exam.load(e)) m_listExam.append(exam); if (exam.load(e)) m_listExam.append(exam);
} }
else if (e.tagName () == "hint") else if (e.tagName () == "hint")
{ {
CHint hint; CHint hint;
if (hint.load (e)) if (hint.load (e))
m_listHint.append (hint); m_listHint.append (hint);
} }
else if (e.tagName () == "title") else if (e.tagName () == "title")
{ {
m_strText = e.text(); m_strText = e.text();
m_strUniqueName = e.attribute("unique"); m_strUniqueName = e.attribute("unique");
} }
else if (e.tagName () == "comment") else if (e.tagName () == "comment")
m_strComment = e.text(); m_strComment = e.text();
else if (e.tagName () == "contact") else if (e.tagName () == "contact")
m_strContact = e.text(); m_strContact = e.text();
else if (e.tagName () == "publisher") else if (e.tagName () == "publisher")
m_strPublisher = e.text(); m_strPublisher = e.text();
else if (e.tagName() == "valid") else if (e.tagName() == "valid")
{ {
m_dateValidFrom = QDate::fromString(e.attribute("from"), Qt::ISODate); m_dateValidFrom = QDate::fromString(e.attribute("from"), Qt::ISODate);
m_dateValidUntil = QDate::fromString(e.attribute("until"), Qt::ISODate); m_dateValidUntil = QDate::fromString(e.attribute("until"), Qt::ISODate);
} }
else if (e.tagName() == "version") else if (e.tagName() == "version")
{ {
m_datePublished = QDate::fromString(e.attribute("published"), Qt::ISODate); m_datePublished = QDate::fromString(e.attribute("published"), Qt::ISODate);
m_strVersion = e.text(); m_strVersion = e.text();
} }
else if (e.tagName() == "options") else if (e.tagName() == "options")
{ {
m_bMixAnswers = QVariant(e.attribute("mixanswers", "true")).toBool(); m_bMixAnswers = QVariant(e.attribute("mixanswers", "true")).toBool();
m_bSort = QVariant(e.attribute("sort", "false")).toBool(); m_bSort = QVariant(e.attribute("sort", "false")).toBool();
} }
} }
n = n.nextSibling(); n = n.nextSibling();
} }
if (m_strUniqueName.isEmpty()) if (m_strUniqueName.isEmpty())
m_strUniqueName = QDir(strFileName).dirName(); m_strUniqueName = QDir(strFileName).dirName();
if (m_bSort) sortAll(); if (m_bSort) sortAll();
loadStatistic (pParent); loadStatistic (pParent);
updateStatistic(); updateStatistic();
m_strFileName = strFileName; m_strFileName = strFileName;
return true; return true;
} }
bool CCatalog::save (const QString& strFileName, QWidget *pParent) bool CCatalog::save (const QString& strFileName, QWidget *pParent)
{ {
QFile file (strFileName); QFile file (strFileName);
if (strFileName.isEmpty()) return false; if (strFileName.isEmpty()) return false;
if (!file.open(QIODevice::WriteOnly)) if (!file.open(QIODevice::WriteOnly))
{ {
QMessageBox::critical(pParent, QString(pParent->tr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen:\n")+strFileName); QMessageBox::critical(pParent, QString(pParent->tr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen:\n")+strFileName);
return false; return false;
} }
QTextStream out(&file); QTextStream out(&file);
QDomDocument doc("afutrainer"); QDomDocument doc("afutrainer");
QDomElement elemRoot = doc.createElement("afutrainer"); QDomElement elemRoot = doc.createElement("afutrainer");
//elemRoot.setAttribute("name", name()); //elemRoot.setAttribute("name", name());
elemRoot.setAttribute("version", 3.0); elemRoot.setAttribute("version", 3.0);
elemRoot.setAttribute("created", QDate::currentDate().toString(Qt::ISODate)); elemRoot.setAttribute("created", QDate::currentDate().toString(Qt::ISODate));
doc.appendChild(elemRoot); doc.appendChild(elemRoot);
// save unique name // save unique name
QDomElement elemTitle = createXmlTextElement("title", name(), doc); QDomElement elemTitle = createXmlTextElement("title", name(), doc);
elemTitle.setAttribute("unique", m_strUniqueName); elemTitle.setAttribute("unique", m_strUniqueName);
elemRoot.appendChild (elemTitle); elemRoot.appendChild (elemTitle);
// save comment // save comment
if (!m_strComment.isEmpty()) if (!m_strComment.isEmpty())
elemRoot.appendChild (createXmlTextElement("comment", m_strComment, doc)); elemRoot.appendChild (createXmlTextElement("comment", m_strComment, doc));
// save contact // save contact
if (!m_strContact.isEmpty()) if (!m_strContact.isEmpty())
elemRoot.appendChild (createXmlTextElement("contact", m_strContact, doc)); elemRoot.appendChild (createXmlTextElement("contact", m_strContact, doc));
// save publisher // save publisher
if (!m_strPublisher.isEmpty()) if (!m_strPublisher.isEmpty())
elemRoot.appendChild (createXmlTextElement("publisher", m_strPublisher, doc)); elemRoot.appendChild (createXmlTextElement("publisher", m_strPublisher, doc));
// save version // save version
QDomElement elemVersion = createXmlTextElement("version", m_strVersion, doc); QDomElement elemVersion = createXmlTextElement("version", m_strVersion, doc);
elemVersion.setAttribute("published", m_datePublished.toString(Qt::ISODate)); elemVersion.setAttribute("published", m_datePublished.toString(Qt::ISODate));
elemRoot.appendChild(elemVersion); elemRoot.appendChild(elemVersion);
// save dates // save dates
if (m_dateValidFrom.isValid() || m_dateValidUntil.isValid()) if (m_dateValidFrom.isValid() || m_dateValidUntil.isValid())
{ {
QDomElement elemValid = doc.createElement("valid"); QDomElement elemValid = doc.createElement("valid");
elemValid.setAttribute("from", m_dateValidFrom.toString(Qt::ISODate)); elemValid.setAttribute("from", m_dateValidFrom.toString(Qt::ISODate));
elemValid.setAttribute("until", m_dateValidUntil.toString(Qt::ISODate)); elemValid.setAttribute("until", m_dateValidUntil.toString(Qt::ISODate));
elemRoot.appendChild(elemValid); elemRoot.appendChild(elemValid);
} }
// TODO: save tests // TODO: save tests
// save chapters // save chapters
for (int i=0; i<m_listChapter.size(); i++) for (int i=0; i<m_listChapter.size(); i++)
m_listChapter[i]->save(elemRoot, doc); m_listChapter[i]->save(elemRoot, doc);
// save helpers // save helpers
for (int i=0; i<m_listHint.size(); i++) for (int i=0; i<m_listHint.size(); i++)
m_listHint[i].save(elemRoot, doc); m_listHint[i].save(elemRoot, doc);
out << doc.toString(); out << doc.toString();
m_strFileName = strFileName; m_strFileName = strFileName;
return true; return true;
} }
QString CCatalog::statisticFileName() const QString CCatalog::statisticFileName() const
{ {
QDir dir; QDir dir;
QString str = dir.homePath()+QString("/.afutrainer/") + m_strUniqueName + QString(".stat.xml"); QString str = dir.homePath()+QString("/.afutrainer/") + m_strUniqueName + QString(".stat.xml");
Q_ASSERT(!m_strUniqueName.isEmpty()); Q_ASSERT(!m_strUniqueName.isEmpty());
return (str); return (str);
} }
bool CCatalog::loadStatistic(QWidget *pParent) bool CCatalog::loadStatistic(QWidget *pParent)
{ {
QDomDocument doc; QDomDocument doc;
QDomElement elemRoot, e; QDomElement elemRoot, e;
QDomNode n; QDomNode n;
QFile file (statisticFileName()); QFile file (statisticFileName());
QString strVerzeichnis, str, strXML; QString strVerzeichnis, str, strXML;
int iErrLine, iErrCol; int iErrLine, iErrCol;
if (!file.exists()) return true; if (!file.exists()) return true;
if (!file.open (QIODevice::ReadOnly)) if (!file.open (QIODevice::ReadOnly))
{ {
QMessageBox::critical(pParent, QString(pParent->tr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n")+statisticFileName()); QMessageBox::critical(pParent, QString(pParent->tr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n")+statisticFileName());
return false; return false;
} }
QTextStream in (&file); QTextStream in (&file);
strXML = in.readAll(); strXML = in.readAll();
if (!doc.setContent(strXML, true, &str, &iErrLine, &iErrCol)) if (!doc.setContent(strXML, true, &str, &iErrLine, &iErrCol))
{ {
QMessageBox::critical(pParent, pParent->tr("XML-Fehler"), pParent->tr("Statistik zum Fragenkatalog: ") + statisticFileName() + "\n" + str + "\n" + QString (pParent->tr("Zeile: %1 Spalte %2")).arg(iErrLine).arg(iErrCol)); QMessageBox::critical(pParent, pParent->tr("XML-Fehler"), pParent->tr("Statistik zum Fragenkatalog: ") + statisticFileName() + "\n" + str + "\n" + QString (pParent->tr("Zeile: %1 Spalte %2")).arg(iErrLine).arg(iErrCol));
return false; return false;
} }
file.close (); file.close ();
elemRoot = doc.documentElement (); elemRoot = doc.documentElement ();
if (doc.doctype().name() != "AFUTrainerStatistics") return false; if (doc.doctype().name() != "AFUTrainerStatistics") return false;
if (elemRoot.tagName() != "statistic") return false; if (elemRoot.tagName() != "statistic") return false;
n = elemRoot.firstChild(); n = elemRoot.firstChild();
while (!n.isNull()) while (!n.isNull())
{ {
if (n.isElement ()) if (n.isElement ())
{ {
e = n.toElement (); e = n.toElement ();
if (e.tagName() == QString ("learning")) if (e.tagName() == QString ("learning"))
{ {
loadLearnStatistic(e); loadLearnStatistic(e);
} }
else if (e.tagName() == QString("exams")) else if (e.tagName() == QString("exams"))
loadExamStatistic(e); loadExamStatistic(e);
} }
n = n.nextSibling(); n = n.nextSibling();
} }
return true; return true;
} }
bool CCatalog::saveStatistic(QWidget *pParent) bool CCatalog::saveStatistic(QWidget *pParent)
{ {
QDomDocument doc ("AFUTrainerStatistics"); QDomDocument doc ("AFUTrainerStatistics");
QString strFileName = statisticFileName(); QString strFileName = statisticFileName();
QFile file (strFileName); QFile file (strFileName);
if (m_strUniqueName.isEmpty()) return false; if (m_strUniqueName.isEmpty()) return false;
QDomElement elemRoot = doc.createElement ("statistic"); QDomElement elemRoot = doc.createElement ("statistic");
elemRoot.setAttribute ("name", name()); elemRoot.setAttribute ("name", name());
elemRoot.setAttribute("version", 2); elemRoot.setAttribute("version", 2);
elemRoot.setAttribute("date", QDate::currentDate().toString(Qt::ISODate)); elemRoot.setAttribute("date", QDate::currentDate().toString(Qt::ISODate));
doc.appendChild (elemRoot); doc.appendChild (elemRoot);
QDomElement elemLearn = doc.createElement ("learning"); QDomElement elemLearn = doc.createElement ("learning");
elemRoot.appendChild (elemLearn); elemRoot.appendChild (elemLearn);
saveLearnStatistic(elemLearn, doc); saveLearnStatistic(elemLearn, doc);
QDomElement elemExams = doc.createElement ("exams"); QDomElement elemExams = doc.createElement ("exams");
elemRoot.appendChild (elemExams); elemRoot.appendChild (elemExams);
saveExamStatistic(elemExams, doc); saveExamStatistic(elemExams, doc);
if (!file.open (QIODevice::WriteOnly)) if (!file.open (QIODevice::WriteOnly))
{ {
QMessageBox::critical (pParent, pParent->tr("Fehler"), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen.\n")+strFileName); QMessageBox::critical (pParent, pParent->tr("Fehler"), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen.\n")+strFileName);
return false; return false;
} }
QTextStream out(&file); QTextStream out(&file);
out << doc.toString (); out << doc.toString ();
return true; return true;
} }
bool CCatalog::loadExamStatistic (QDomElement& elemRoot) bool CCatalog::loadExamStatistic (QDomElement& elemRoot)
{ {
QDomNode n; QDomNode n;
QDomElement e; QDomElement e;
n = elemRoot.firstChild(); n = elemRoot.firstChild();
while (!n.isNull()) while (!n.isNull())
{ {
if (n.isElement ()) if (n.isElement ())
{ {
e = n.toElement (); e = n.toElement ();
if (e.tagName() == QString ("exam")) if (e.tagName() == QString ("exam"))
{ {
CExamStat es; CExamStat es;
if (es.load(e)) m_listExamStat.append(es); if (es.load(e)) m_listExamStat.append(es);
} }
} }
n = n.nextSibling(); n = n.nextSibling();
} }
return true; return true;
} }
void CCatalog::saveExamStatistic (QDomElement& parent, QDomDocument& doc) void CCatalog::saveExamStatistic (QDomElement& parent, QDomDocument& doc)
{ {
for (int i=0; i<m_listExamStat.size(); i++) for (int i=0; i<m_listExamStat.size(); i++)
{ {
m_listExamStat.at(i).save (parent, doc); m_listExamStat.at(i).save (parent, doc);
} }
} }
QList<CChapter*> CCatalog::chapters() QList<CChapter*> CCatalog::chapters()
{ {
QList<CChapter*> list; QList<CChapter*> list;
list.append(this); list.append(this);
list << subChapters(); list << subChapters();
return list; return list;
} }
CExam CCatalog::examById(const QString& strId) const CExam CCatalog::examById(const QString& strId) const
{ {
for (int i=0; i<m_listExam.size(); i++) for (int i=0; i<m_listExam.size(); i++)
{ {
if (m_listExam.at(i).id() == strId) if (m_listExam.at(i).id() == strId)
return m_listExam.at(i); return m_listExam.at(i);
} }
return CExam(); return CExam();
} }

240
catalog.h
View File

@ -1,120 +1,120 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CATALOG_H #ifndef CATALOG_H
#define CATALOG_H #define CATALOG_H
#include "chapter.h" #include "chapter.h"
#include "exam.h" #include "exam.h"
#include <qlist.h> #include <qlist.h>
#include <qtemporaryfile.h> #include <qtemporaryfile.h>
class CCatalog : public CChapter class CCatalog : public CChapter
{ {
public: public:
CCatalog() : CChapter() { clear(); } CCatalog() : CChapter() { clear(); }
~CCatalog(); ~CCatalog();
void clear(); void clear();
bool isEmpty(); bool isEmpty();
inline QString name() const { return m_strText; } inline QString name() const { return m_strText; }
inline void setName(const QString& strName) { m_strText = strName; } inline void setName(const QString& strName) { m_strText = strName; }
inline QString contact() const { return m_strContact; } inline QString contact() const { return m_strContact; }
inline void setContact(const QString& strContact) { m_strContact = strContact; } inline void setContact(const QString& strContact) { m_strContact = strContact; }
inline QString publisher() const { return m_strPublisher; } inline QString publisher() const { return m_strPublisher; }
inline void setPublisher(const QString& strPublisher) { m_strPublisher = strPublisher; } inline void setPublisher(const QString& strPublisher) { m_strPublisher = strPublisher; }
// Validation // Validation
inline QDate validFrom() const { return m_dateValidFrom; } inline QDate validFrom() const { return m_dateValidFrom; }
inline void setValidFrom(const QDate& date) { m_dateValidFrom = date; } inline void setValidFrom(const QDate& date) { m_dateValidFrom = date; }
inline QDate validUntil() const { return m_dateValidUntil; } inline QDate validUntil() const { return m_dateValidUntil; }
inline void setValidUntil(const QDate& date) { m_dateValidUntil = date; } inline void setValidUntil(const QDate& date) { m_dateValidUntil = date; }
bool isValid() const; bool isValid() const;
inline QDate created() const { return m_dateCreated; } inline QDate created() const { return m_dateCreated; }
inline void setCreated(const QDate& date) { m_dateCreated = date; } inline void setCreated(const QDate& date) { m_dateCreated = date; }
inline QDate published() const { return m_datePublished; } inline QDate published() const { return m_datePublished; }
inline void setPublished(const QDate& date) { m_datePublished = date; } inline void setPublished(const QDate& date) { m_datePublished = date; }
inline QString versionText() const { return m_strVersion; } inline QString versionText() const { return m_strVersion; }
inline void setVersionText(const QString& str) { m_strVersion = str; } inline void setVersionText(const QString& str) { m_strVersion = str; }
// file operations // file operations
inline QString fileName() const { return m_strFileName; } inline QString fileName() const { return m_strFileName; }
bool load (const QString& strFileName, QWidget *pParent); bool load (const QString& strFileName, QWidget *pParent);
bool save (const QString& strFileName, QWidget *pParent); bool save (const QString& strFileName, QWidget *pParent);
bool loadStatistic(QWidget *pParent); bool loadStatistic(QWidget *pParent);
bool saveStatistic(QWidget *pParent); bool saveStatistic(QWidget *pParent);
// hints // hints
inline int countHint() const { return m_listHint.size(); } inline int countHint() const { return m_listHint.size(); }
inline const CHint& hintAt(int i) const { return m_listHint.at(i); } inline const CHint& hintAt(int i) const { return m_listHint.at(i); }
inline CHint& hintAt(int i) { return m_listHint[i]; } inline CHint& hintAt(int i) { return m_listHint[i]; }
inline void appendHint(const CHint& a) { m_listHint.append(a); } inline void appendHint(const CHint& a) { m_listHint.append(a); }
bool hasHints (const QString& strQuestionId) const; bool hasHints (const QString& strQuestionId) const;
QString hintText (const QString& strQuestionId) const; QString hintText (const QString& strQuestionId) const;
// exams // exams
inline int countExam() const { return m_listExam.size(); } inline int countExam() const { return m_listExam.size(); }
inline const CExam& examAt(int i) const { return m_listExam.at(i); } inline const CExam& examAt(int i) const { return m_listExam.at(i); }
inline CExam& examAt(int i) { return m_listExam[i]; } inline CExam& examAt(int i) { return m_listExam[i]; }
inline void appendExam(const CExam& a) { m_listExam.append(a); } inline void appendExam(const CExam& a) { m_listExam.append(a); }
CExam examById(const QString& strId) const; CExam examById(const QString& strId) const;
inline void appendExamStat(const CExamStat& a) { m_listExamStat.append(a); } inline void appendExamStat(const CExamStat& a) { m_listExamStat.append(a); }
inline int countExamStat() const { return m_listExamStat.size(); } inline int countExamStat() const { return m_listExamStat.size(); }
inline const CExamStat& examStatAt(int i) const { return m_listExamStat.at(i); } inline const CExamStat& examStatAt(int i) const { return m_listExamStat.at(i); }
// options // options
inline bool useMixedAnswers() const { return m_bMixAnswers; } inline bool useMixedAnswers() const { return m_bMixAnswers; }
// others // others
QList<CChapter*> chapters(); QList<CChapter*> chapters();
protected: protected:
QString statisticFileName() const; QString statisticFileName() const;
bool loadExamStatistic (QDomElement& elemRoot); bool loadExamStatistic (QDomElement& elemRoot);
void saveExamStatistic (QDomElement& parent, QDomDocument& doc); void saveExamStatistic (QDomElement& parent, QDomDocument& doc);
protected: protected:
QString m_strFileName; QString m_strFileName;
QString m_strUniqueName; QString m_strUniqueName;
QList<QTemporaryFile*> m_listFiles; QList<QTemporaryFile*> m_listFiles;
QList<CHint> m_listHint; QList<CHint> m_listHint;
QString m_strContact; QString m_strContact;
QString m_strPublisher; QString m_strPublisher;
QDate m_dateValidFrom; QDate m_dateValidFrom;
QDate m_dateValidUntil; QDate m_dateValidUntil;
QDate m_dateCreated; QDate m_dateCreated;
QDate m_datePublished; QDate m_datePublished;
QString m_strVersion; QString m_strVersion;
QList<CExam> m_listExam; QList<CExam> m_listExam;
QList<CExamStat> m_listExamStat; QList<CExamStat> m_listExamStat;
// Optionen // Optionen
bool m_bMixAnswers; bool m_bMixAnswers;
bool m_bSort; bool m_bSort;
}; };
#endif #endif

View File

@ -1,205 +1,205 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "catalogmodel.h" #include "catalogmodel.h"
#include "catalog.h" #include "catalog.h"
#define COL_CHAPTER 0 #define COL_CHAPTER 0
#define COL_QUESTION 1 #define COL_QUESTION 1
#define COL_ASSIST 2 #define COL_ASSIST 2
#define COL_AVG 3 #define COL_AVG 3
CCatalogModel::CCatalogModel (QObject *pParent) : QAbstractItemModel (pParent) CCatalogModel::CCatalogModel (QObject *pParent) : QAbstractItemModel (pParent)
{ {
m_pCatalog = 0; m_pCatalog = 0;
} }
CCatalogModel::~CCatalogModel() CCatalogModel::~CCatalogModel()
{ {
} }
void CCatalogModel::onLanguageChanged() void CCatalogModel::onLanguageChanged()
{ {
headerDataChanged(Qt::Horizontal, 0, columnCount()-1); headerDataChanged(Qt::Horizontal, 0, columnCount()-1);
} }
void CCatalogModel::setModelData (CCatalog *pCatalog) void CCatalogModel::setModelData (CCatalog *pCatalog)
{ {
reset(); reset();
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
reset(); reset();
} }
int CCatalogModel::columnCount (const QModelIndex& parent) const int CCatalogModel::columnCount (const QModelIndex& parent) const
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
return 4; return 4;
} }
QVariant CCatalogModel::headerData (int section, Qt::Orientation orientation, int role) const QVariant CCatalogModel::headerData (int section, Qt::Orientation orientation, int role) const
{ {
if (orientation == Qt::Vertical) return QVariant(); if (orientation == Qt::Vertical) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (section == COL_CHAPTER) if (section == COL_CHAPTER)
return tr("Kapitel"); return tr("Kapitel");
else if (section == COL_QUESTION) else if (section == COL_QUESTION)
return tr("Fragen"); return tr("Fragen");
else if (section == COL_AVG) else if (section == COL_AVG)
return tr("Ø"); return tr("Ø");
else if (section == COL_ASSIST) else if (section == COL_ASSIST)
return tr("Lernassistent"); return tr("Lernassistent");
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (section == COL_CHAPTER) if (section == COL_CHAPTER)
return tr("Kapitelname\nBitte markieren Sie das Kapitel, das Sie lernen möchten."); return tr("Kapitelname\nBitte markieren Sie das Kapitel, das Sie lernen möchten.");
else if (section == COL_QUESTION) else if (section == COL_QUESTION)
return tr("Anzahl d. Fragen inkl. Unterkapitel"); return tr("Anzahl d. Fragen inkl. Unterkapitel");
else if (section == COL_AVG) else if (section == COL_AVG)
return tr("Durchschnittlicher Lernfortschritt"); return tr("Durchschnittlicher Lernfortschritt");
else if (section == COL_ASSIST) else if (section == COL_ASSIST)
return tr("Empfehlung des Lernassistentes"); return tr("Empfehlung des Lernassistentes");
} }
else if (role == Qt::WhatsThisRole) else if (role == Qt::WhatsThisRole)
{ {
} }
return QVariant(); return QVariant();
} }
QVariant CCatalogModel::data (const QModelIndex& index, int role) const QVariant CCatalogModel::data (const QModelIndex& index, int role) const
{ {
CChapter *p = (CChapter*) index.internalPointer(); CChapter *p = (CChapter*) index.internalPointer();
if (m_pCatalog == 0 || !index.isValid()) return QVariant(); if (m_pCatalog == 0 || !index.isValid()) return QVariant();
if (role == Qt::TextAlignmentRole && index.column() == COL_QUESTION) return Qt::AlignRight; if (role == Qt::TextAlignmentRole && index.column() == COL_QUESTION) return Qt::AlignRight;
if (p == 0) return QVariant(); if (p == 0) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (index.column() == COL_CHAPTER) if (index.column() == COL_CHAPTER)
{ {
if (p->id().isEmpty()) if (p->id().isEmpty())
return p->text(); return p->text();
else else
return p->id() + " - " + p->text(); return p->id() + " - " + p->text();
} }
else if (index.column() == COL_QUESTION) else if (index.column() == COL_QUESTION)
return QString("%1").arg(p->countSubQuestion()); return QString("%1").arg(p->countSubQuestion());
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationText(); return p->recommendationText();
} }
} }
else if (role == Qt::DecorationRole) else if (role == Qt::DecorationRole)
{ {
if (index.column() == COL_CHAPTER) if (index.column() == COL_CHAPTER)
return QIcon(":/icons/16x16/folder.png"); return QIcon(":/icons/16x16/folder.png");
else if (index.column() == COL_AVG) else if (index.column() == COL_AVG)
{ {
return p->levelAvgIcon(); return p->levelAvgIcon();
} }
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationIcon(m_pCatalog); return p->recommendationIcon(m_pCatalog);
} }
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (index.column() == COL_AVG) if (index.column() == COL_AVG)
{ {
return QString ("%1 - Kennzahl: %2").arg(p->/*statistic().*/levelAvgText()).arg(p->/*statistic().*/levelAvg(), 4, 'f', 2); return QString ("%1 - Kennzahl: %2").arg(p->/*statistic().*/levelAvgText()).arg(p->/*statistic().*/levelAvg(), 4, 'f', 2);
} }
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationToolTip(); return p->recommendationToolTip();
} }
} }
return QVariant(); return QVariant();
} }
bool CCatalogModel::hasChildren (const QModelIndex& parent) const bool CCatalogModel::hasChildren (const QModelIndex& parent) const
{ {
CChapter *p = (CChapter*) parent.internalPointer(); CChapter *p = (CChapter*) parent.internalPointer();
if (m_pCatalog == 0) return false; if (m_pCatalog == 0) return false;
if (parent.isValid() && p) if (parent.isValid() && p)
return (p->countChapter() > 0); return (p->countChapter() > 0);
else // root item else // root item
return true; return true;
} }
QModelIndex CCatalogModel::index (int row, int column, const QModelIndex& parent) const QModelIndex CCatalogModel::index (int row, int column, const QModelIndex& parent) const
{ {
CChapter *pParent = (CChapter*) parent.internalPointer(); CChapter *pParent = (CChapter*) parent.internalPointer();
if (!parent.isValid()) if (!parent.isValid())
{ // root item { // root item
return createIndex (row, column, (void*) m_pCatalog); return createIndex (row, column, (void*) m_pCatalog);
} }
else else
{ {
// take entry from parent item // take entry from parent item
if (row > pParent->countChapter()) if (row > pParent->countChapter())
return QModelIndex(); return QModelIndex();
return createIndex (row, column, (void*)pParent->chapterAt(row)); return createIndex (row, column, (void*)pParent->chapterAt(row));
} }
return QModelIndex(); return QModelIndex();
} }
QModelIndex CCatalogModel::parent (const QModelIndex& index) const QModelIndex CCatalogModel::parent (const QModelIndex& index) const
{ {
CChapter *pIndex = (CChapter*) index.internalPointer(); CChapter *pIndex = (CChapter*) index.internalPointer();
int iRow=0; int iRow=0;
if (pIndex == 0 || pIndex->parentChapter() == 0) // root item if (pIndex == 0 || pIndex->parentChapter() == 0) // root item
return QModelIndex(); // has no parent return QModelIndex(); // has no parent
CChapter *pParent = pIndex->parentChapter(); CChapter *pParent = pIndex->parentChapter();
if (pParent->parentChapter()) if (pParent->parentChapter())
iRow = pParent->parentChapter()->indexOfChapter(pParent); iRow = pParent->parentChapter()->indexOfChapter(pParent);
else // parent is the root item (parent of the parent doesn't exist) else // parent is the root item (parent of the parent doesn't exist)
iRow = 0; iRow = 0;
return createIndex (iRow, 0 /*index.column()*/, pParent); return createIndex (iRow, 0 /*index.column()*/, pParent);
} }
int CCatalogModel::rowCount (const QModelIndex& parent) const int CCatalogModel::rowCount (const QModelIndex& parent) const
{ {
CChapter *pParent = (CChapter*) parent.internalPointer(); CChapter *pParent = (CChapter*) parent.internalPointer();
if (m_pCatalog == 0 || m_pCatalog->isEmpty()) return 0; if (m_pCatalog == 0 || m_pCatalog->isEmpty()) return 0;
if (!parent.isValid()) // root item if (!parent.isValid()) // root item
return 1; return 1;
return pParent->countChapter(); return pParent->countChapter();
} }

View File

@ -1,55 +1,55 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CATALOGMODEL_H #ifndef CATALOGMODEL_H
#define CATALOGMODEL_H #define CATALOGMODEL_H
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
class CCatalog; class CCatalog;
class CCatalogModel : public QAbstractItemModel class CCatalogModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
public: public:
CCatalogModel (QObject *pParent=0); CCatalogModel (QObject *pParent=0);
~CCatalogModel(); ~CCatalogModel();
void setModelData (CCatalog *pCatalog); void setModelData (CCatalog *pCatalog);
public: public:
virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const; virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const; virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const;
virtual QModelIndex parent ( const QModelIndex & index ) const; virtual QModelIndex parent ( const QModelIndex & index ) const;
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
public slots: public slots:
void onLanguageChanged(); void onLanguageChanged();
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

484
chapter.h
View File

@ -1,242 +1,242 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CHAPTER_H #ifndef CHAPTER_H
#define CHAPTER_H #define CHAPTER_H
#include "question.h" #include "question.h"
//#include "recommendation.h" //#include "recommendation.h"
//#include "chapterstatistic.h" //#include "chapterstatistic.h"
#include <qmap.h> #include <qmap.h>
//! Die Klasse CChapter speichert ein Kapitel mit allen Unterkapiteln und Fragen //! Die Klasse CChapter speichert ein Kapitel mit allen Unterkapiteln und Fragen
/*! /*!
*/ */
class CChapter class CChapter
{ {
public: public:
//! Empfehlung für Kapitel //! Empfehlung für Kapitel
enum Recommendation enum Recommendation
{ {
RecommendationNone=0, //!< Keine Emfehlung RecommendationNone=0, //!< Keine Emfehlung
RecommendationSubChapter=1, //!< Untergeordnetes Kapitel lernen RecommendationSubChapter=1, //!< Untergeordnetes Kapitel lernen
RecommendationParentChapter=2, //!< Übergeordnetes Kapitel lernen RecommendationParentChapter=2, //!< Übergeordnetes Kapitel lernen
RecommendationRepeatToday=3, //!< Kapitel heute wiederholen RecommendationRepeatToday=3, //!< Kapitel heute wiederholen
RecommendationLearnNew=4, //!< Neue Fragen lernen RecommendationLearnNew=4, //!< Neue Fragen lernen
RecommendationRepeatLater=5, //!< Kapitel später wiederholen RecommendationRepeatLater=5, //!< Kapitel später wiederholen
RecommendationMax=6 //!< Für for-Schleifen, etc. RecommendationMax=6 //!< Für for-Schleifen, etc.
}; };
//! Standard-Konstruktor //! Standard-Konstruktor
/*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */ /*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */
CChapter() { clear(); } CChapter() { clear(); }
//! Standard-Destruktor //! Standard-Destruktor
/*! Es werden alle Unterkapitel und Fragen dieses Kapitels aus dem Speicher gelöscht. */ /*! Es werden alle Unterkapitel und Fragen dieses Kapitels aus dem Speicher gelöscht. */
~CChapter() { qDeleteAll(m_listChapter); qDeleteAll(m_listQuestion); } ~CChapter() { qDeleteAll(m_listChapter); qDeleteAll(m_listQuestion); }
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Unterkapitel und Fragen dieses Kapitels aus dem Speicher gelöscht und alle andere Daten auf die Default-Werte zurückgesetzt. */ /*! Es werden alle Unterkapitel und Fragen dieses Kapitels aus dem Speicher gelöscht und alle andere Daten auf die Default-Werte zurückgesetzt. */
void clear(); void clear();
//! Elternkapitel auslesen //! Elternkapitel auslesen
/*! /*!
\return Elternkapitel m_pParentChapter \return Elternkapitel m_pParentChapter
\sa setParentChapter(), m_pParentChapter \sa setParentChapter(), m_pParentChapter
*/ */
inline CChapter* parentChapter() const { return m_pParentChapter; } inline CChapter* parentChapter() const { return m_pParentChapter; }
//! Elternkapitel setzen //! Elternkapitel setzen
/*! /*!
Durch diese Funktion wird lediglich die Variable m_pParentChapter gesetzt, jedoch nicht die Statistiken Durch diese Funktion wird lediglich die Variable m_pParentChapter gesetzt, jedoch nicht die Statistiken
des Eltern-Kapitels aktualisiert. des Eltern-Kapitels aktualisiert.
\param pChapter Das zu setzende Elternkapitel dieses Kapitels \param pChapter Das zu setzende Elternkapitel dieses Kapitels
\sa parentChapter(), m_pParentChapter \sa parentChapter(), m_pParentChapter
*/ */
inline void setParentChapter(CChapter *pChapter) { m_pParentChapter = pChapter; } inline void setParentChapter(CChapter *pChapter) { m_pParentChapter = pChapter; }
//! ID dieses Kapitels auslesen //! ID dieses Kapitels auslesen
inline QString id() const { return m_strId; } inline QString id() const { return m_strId; }
//! ID dieses Kapitels zusammengesetzt mit allen IDs der Eltern-Kapitel auslesen //! ID dieses Kapitels zusammengesetzt mit allen IDs der Eltern-Kapitel auslesen
QString idWithParents() const; QString idWithParents() const;
//! Kapitelbeschreibung auslesen //! Kapitelbeschreibung auslesen
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
//! Kommentar //! Kommentar
inline QString comment() const { return m_strComment; } inline QString comment() const { return m_strComment; }
//! ID setzen //! ID setzen
inline void setId (const QString& strId) { m_strId = strId; } inline void setId (const QString& strId) { m_strId = strId; }
//! Kapitelbeschreibung setzen //! Kapitelbeschreibung setzen
inline void setText (const QString& strText) { m_strText = strText; } inline void setText (const QString& strText) { m_strText = strText; }
//! Kommentar setzen //! Kommentar setzen
inline void setComment (const QString& strComment) { m_strComment = strComment; } inline void setComment (const QString& strComment) { m_strComment = strComment; }
//! Anhängen eines Textes an die Kapitelbeschreibung //! Anhängen eines Textes an die Kapitelbeschreibung
/*! /*!
\param strText Anzuhängender Text \param strText Anzuhängender Text
\sa m_strText \sa m_strText
*/ */
inline void appendText(const QString& strText) { m_strText += strText; } inline void appendText(const QString& strText) { m_strText += strText; }
//! Anzahl der Unterkapitel ermitteln //! Anzahl der Unterkapitel ermitteln
/*! \return Anzahl der Unterkapitel */ /*! \return Anzahl der Unterkapitel */
inline int countChapter() const { return m_listChapter.size(); } inline int countChapter() const { return m_listChapter.size(); }
inline const CChapter* chapterAt(int i) const { return m_listChapter.at(i); } inline const CChapter* chapterAt(int i) const { return m_listChapter.at(i); }
inline int indexOfChapter(CChapter* c) const { return m_listChapter.indexOf(c); } inline int indexOfChapter(CChapter* c) const { return m_listChapter.indexOf(c); }
inline void appendChapter(CChapter* c) { m_listChapter.append(c); c->setParentChapter(this); } inline void appendChapter(CChapter* c) { m_listChapter.append(c); c->setParentChapter(this); }
// inline void removeChapter(int i) { delete m_listChapter.takeAt(i); } // inline void removeChapter(int i) { delete m_listChapter.takeAt(i); }
QList<CChapter*> subChapters() const; QList<CChapter*> subChapters() const;
inline void sortAll() { sortSubChapters(true); sortQuestions(); } inline void sortAll() { sortSubChapters(true); sortQuestions(); }
void sortSubChapters(bool bSortQuestions); void sortSubChapters(bool bSortQuestions);
void sortQuestions(); void sortQuestions();
//! Anzahl der Fragen dieses Kapitels und aller Unterkapitel ermitteln //! Anzahl der Fragen dieses Kapitels und aller Unterkapitel ermitteln
/*! \return Anzahl der Fragen */ /*! \return Anzahl der Fragen */
int countSubQuestion() const; int countSubQuestion() const;
//! Anzahl der Fragen dieses Kapitels (ohne Unterkapitel) ermitteln //! Anzahl der Fragen dieses Kapitels (ohne Unterkapitel) ermitteln
/*! \return Anzahl der Fragen */ /*! \return Anzahl der Fragen */
inline int countQuestion() const { return m_listQuestion.size(); } inline int countQuestion() const { return m_listQuestion.size(); }
inline const CQuestion* questionAt(int i) const { return m_listQuestion.at(i); } inline const CQuestion* questionAt(int i) const { return m_listQuestion.at(i); }
inline CQuestion* questionAt(int i) { return m_listQuestion.at(i); } inline CQuestion* questionAt(int i) { return m_listQuestion.at(i); }
inline void appendQuestion(CQuestion* q) { m_listQuestion.append(q); q->setParentChapter(this); } inline void appendQuestion(CQuestion* q) { m_listQuestion.append(q); q->setParentChapter(this); }
QList<CQuestion*> questionPool() const; QList<CQuestion*> questionPool() const;
QList<CQuestion*> questionPoolLevel(const unsigned uLevel) const; QList<CQuestion*> questionPoolLevel(const unsigned uLevel) const;
QList<CQuestion*> questionPoolDeepen() const; QList<CQuestion*> questionPoolDeepen() const;
QList<CQuestion*> questionPoolRepeat(const QDate d=QDate::currentDate()) const; QList<CQuestion*> questionPoolRepeat(const QDate d=QDate::currentDate()) const;
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc); void save (QDomElement& parent, QDomDocument& doc);
bool loadLearnStatistic (QDomElement elem); bool loadLearnStatistic (QDomElement elem);
bool saveLearnStatistic (QDomElement& parent, QDomDocument& doc); bool saveLearnStatistic (QDomElement& parent, QDomDocument& doc);
QString checkForErrors() const; QString checkForErrors() const;
// Kapitelstatistik auslesen // Kapitelstatistik auslesen
/* /*
\return Kapitelstatistik (Variable m_cs) \return Kapitelstatistik (Variable m_cs)
\sa m_cs \sa m_cs
*/ */
// inline CChapterStatistic statistic() const { return m_cs; } // inline CChapterStatistic statistic() const { return m_cs; }
//! @name Funktionen zur Statistik //! @name Funktionen zur Statistik
//@{ //@{
void updateStatistic(); //!< Kapitelstatistik aktualisieren void updateStatistic(); //!< Kapitelstatistik aktualisieren
//! Anzahl der Fragen einer bestimmten Abfragehäufigkeit //! Anzahl der Fragen einer bestimmten Abfragehäufigkeit
inline unsigned countQuestion(const unsigned uLevel) const { return m_uLevelCount[uLevel]; } inline unsigned countQuestion(const unsigned uLevel) const { return m_uLevelCount[uLevel]; }
double levelAvg() const; //!< Durchschnittlicher Lernfortschritt des Kapitels double levelAvg() const; //!< Durchschnittlicher Lernfortschritt des Kapitels
unsigned levelAvgRounded() const; //!< Durchschnittlicher, gerundeter Lernfortschritt des Kapitels unsigned levelAvgRounded() const; //!< Durchschnittlicher, gerundeter Lernfortschritt des Kapitels
QString levelAvgText() const; //!< Durchschnittlicher Lernfortschritt als Text QString levelAvgText() const; //!< Durchschnittlicher Lernfortschritt als Text
QIcon levelAvgIcon() const; //!< Icon zum durchschnittlichen Lernfortschritt QIcon levelAvgIcon() const; //!< Icon zum durchschnittlichen Lernfortschritt
QPixmap levelAvgPixmap() const; //!< Pixmap zum durchschnittlichen Lernfortschritt QPixmap levelAvgPixmap() const; //!< Pixmap zum durchschnittlichen Lernfortschritt
//! Anzahl der noch nie abgefragen Fragen //! Anzahl der noch nie abgefragen Fragen
inline unsigned countNeverAsked() const { return m_uNeverAskedCount; } inline unsigned countNeverAsked() const { return m_uNeverAskedCount; }
//!< Kapitel inkl. Unterkapitel enthalten Fragen, die gerade gelernt werden //!< Kapitel inkl. Unterkapitel enthalten Fragen, die gerade gelernt werden
inline bool hasLearningNewQuestions() const { return m_bHasLearningNew; } inline bool hasLearningNewQuestions() const { return m_bHasLearningNew; }
inline bool hasKnownQuestions() const { return m_bHasKnownQuestions; } inline bool hasKnownQuestions() const { return m_bHasKnownQuestions; }
inline bool hasKnownQuestionsRepeatToday() const { return m_bHasKnownQuestionsRepeatToday; } inline bool hasKnownQuestionsRepeatToday() const { return m_bHasKnownQuestionsRepeatToday; }
CDayStatistic dayStatistic (const QDate& date) const; //<! Statistik eines Tages CDayStatistic dayStatistic (const QDate& date) const; //<! Statistik eines Tages
CDayStatistic completeStatistic() const; //<! Statistik des kompletten Zeitraums CDayStatistic completeStatistic() const; //<! Statistik des kompletten Zeitraums
QDateTime firstAnswerClicked() const; //<! Datum, zu dem zum allerersten Mal eine Frage beantwortet wurde QDateTime firstAnswerClicked() const; //<! Datum, zu dem zum allerersten Mal eine Frage beantwortet wurde
//@} //@}
//! @name Funktionen zur Lernempfehlung //! @name Funktionen zur Lernempfehlung
//@{ //@{
QDate repeatDate() const; //!< Wiederhol-Datum des Kapitels QDate repeatDate() const; //!< Wiederhol-Datum des Kapitels
//! Lernempfehlung für das Kapitel //! Lernempfehlung für das Kapitel
/*! \return Lernempfehlung (Variable m_recom) \sa m_recom */ /*! \return Lernempfehlung (Variable m_recom) \sa m_recom */
inline Recommendation recommendation() const { return m_recom; } inline Recommendation recommendation() const { return m_recom; }
QString recommendationIconName(const CCatalog *pCatalog) const; //!< Name des Icons zur Lernempfehlung ermitteln QString recommendationIconName(const CCatalog *pCatalog) const; //!< Name des Icons zur Lernempfehlung ermitteln
//! Ermittelt Icon zur Lernempfehlung //! Ermittelt Icon zur Lernempfehlung
inline QIcon recommendationIcon (const CCatalog *pCatalog) const { return QIcon (recommendationIconName(pCatalog)); } inline QIcon recommendationIcon (const CCatalog *pCatalog) const { return QIcon (recommendationIconName(pCatalog)); }
QString recommendationText() const; //!< Lernempfehlungstext (kurz) QString recommendationText() const; //!< Lernempfehlungstext (kurz)
QString recommendationTextExtended(const CCatalog *pCatalog) const; //!< Lernempfehlungstext (ausführlich) QString recommendationTextExtended(const CCatalog *pCatalog) const; //!< Lernempfehlungstext (ausführlich)
QString recommendationToolTip() const; //!< Lernempfehlungstext für Tooltip QString recommendationToolTip() const; //!< Lernempfehlungstext für Tooltip
bool isRecommendedNow(const CCatalog *pCatalog) const; //!< Kapitel sollte jetzt gelernt werden bool isRecommendedNow(const CCatalog *pCatalog) const; //!< Kapitel sollte jetzt gelernt werden
//! Anzahl der Unterkapitel mit einer bestimmten Lernempfehlung //! Anzahl der Unterkapitel mit einer bestimmten Lernempfehlung
inline unsigned recommendationCount(const Recommendation r) const { return m_uRecomCount[r]; } inline unsigned recommendationCount(const Recommendation r) const { return m_uRecomCount[r]; }
//! Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen //! Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen
inline QList<CQuestion*> recommendedQuestions() const { return m_listQuestionRecommended; } inline QList<CQuestion*> recommendedQuestions() const { return m_listQuestionRecommended; }
//! Kapitel hat Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen //! Kapitel hat Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen
inline bool hasRecommendedQuestions() const { return m_listQuestionRecommended.size() > 0; } inline bool hasRecommendedQuestions() const { return m_listQuestionRecommended.size() > 0; }
//! Anzahl der Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen //! Anzahl der Fragen, die beantwortet müssen, um die Lernempfehlung zu erfüllen
inline int recommendedQuestionCount() const { return m_listQuestionRecommended.size(); } inline int recommendedQuestionCount() const { return m_listQuestionRecommended.size(); }
//! Alternative Lernempfehlung für das Kapitel //! Alternative Lernempfehlung für das Kapitel
inline Recommendation recommendation2() const { return m_recom2; } inline Recommendation recommendation2() const { return m_recom2; }
QString recommendationTextExtended2(const CCatalog *pCatalog) const; //!< Alternativer Lernempfehlungstext (ausführlich) QString recommendationTextExtended2(const CCatalog *pCatalog) const; //!< Alternativer Lernempfehlungstext (ausführlich)
//@} //@}
//! @name Funktionen zu Prüfungen //! @name Funktionen zu Prüfungen
//@{ //@{
// inline void setExam(const QString& strId, const unsigned uQuestionCount) { m_mapExam.insert(strId, uQuestionCount); } // inline void setExam(const QString& strId, const unsigned uQuestionCount) { m_mapExam.insert(strId, uQuestionCount); }
// inline unsigned examQuestionCount(const QString& strId) const { return m_mapExam[strId]; } // inline unsigned examQuestionCount(const QString& strId) const { return m_mapExam[strId]; }
//@} //@}
// static // static
static QString tr (const char *sourceText, const char *comment=0); static QString tr (const char *sourceText, const char *comment=0);
static QString recommendationText(const Recommendation r, const QDate dRepeat); static QString recommendationText(const Recommendation r, const QDate dRepeat);
static QString recommendationIconName(const Recommendation r, const CCatalog *pCatalog); static QString recommendationIconName(const Recommendation r, const CCatalog *pCatalog);
protected: protected:
void updateStatisticCount(); //!< Zählt alle Fragen des Kapitels (inkl. Unterkapitel) für die Statistik void updateStatisticCount(); //!< Zählt alle Fragen des Kapitels (inkl. Unterkapitel) für die Statistik
void updateRecommendation(); //!< Lernempfehlung für das Kapitel (inkl. Unterkapitel) aktualisieren void updateRecommendation(); //!< Lernempfehlung für das Kapitel (inkl. Unterkapitel) aktualisieren
void updateRecommendationStatistic(); //!< Statistik über Lernempfehlungen für das Kapitel (inkl. Unterkapitel) aktualisieren void updateRecommendationStatistic(); //!< Statistik über Lernempfehlungen für das Kapitel (inkl. Unterkapitel) aktualisieren
Recommendation recommendationIndividual() const; //!< Empfehlung nur für dieses Kapitel, Unterkapitel und Elternkapitel werden ignoriert Recommendation recommendationIndividual() const; //!< Empfehlung nur für dieses Kapitel, Unterkapitel und Elternkapitel werden ignoriert
protected: protected:
CChapter *m_pParentChapter; //!< Übergeordnetes Kapitel CChapter *m_pParentChapter; //!< Übergeordnetes Kapitel
QString m_strId; //!< ID des Kapitels QString m_strId; //!< ID des Kapitels
QString m_strText; //!< Name des Kapitels QString m_strText; //!< Name des Kapitels
QString m_strComment; //!< Kommentar QString m_strComment; //!< Kommentar
QList<CChapter*> m_listChapter; //!< Liste mit Unterkapiteln QList<CChapter*> m_listChapter; //!< Liste mit Unterkapiteln
QList<CQuestion*> m_listQuestion; //!< Liste mit Fragen QList<CQuestion*> m_listQuestion; //!< Liste mit Fragen
// Statistik // Statistik
unsigned m_uLevelCount[LEVEL_MAX+1]; //!< Anzahl der Fragen einer bestimmten Abfragehäufigkeit unsigned m_uLevelCount[LEVEL_MAX+1]; //!< Anzahl der Fragen einer bestimmten Abfragehäufigkeit
unsigned m_uNeverAskedCount; //!< Anzahl der Fragen, die noch nie abgefragt wurden unsigned m_uNeverAskedCount; //!< Anzahl der Fragen, die noch nie abgefragt wurden
unsigned m_uRecomCount[RecommendationMax]; //!< Anzahl der Unterkapitel (inkl. selbst) mit bestimmter Lernempfehlung unsigned m_uRecomCount[RecommendationMax]; //!< Anzahl der Unterkapitel (inkl. selbst) mit bestimmter Lernempfehlung
bool m_bHasLearningNew; //!< Kapitel enthält Fragen, die gerade neu gelernt werden bool m_bHasLearningNew; //!< Kapitel enthält Fragen, die gerade neu gelernt werden
bool m_bHasKnownQuestions; //!< Kapitel enthält Fragen, die seit mind. gestern bekannt sind bool m_bHasKnownQuestions; //!< Kapitel enthält Fragen, die seit mind. gestern bekannt sind
bool m_bHasKnownQuestionsRepeatToday; //!< Kapitel enthält Fragen, die seit mind. gestern bekannt sind und heute wiederholt werden sollten bool m_bHasKnownQuestionsRepeatToday; //!< Kapitel enthält Fragen, die seit mind. gestern bekannt sind und heute wiederholt werden sollten
Recommendation m_recom; //!< Lernempfehlung Recommendation m_recom; //!< Lernempfehlung
Recommendation m_recom2; //!< Alternative Lernempfehlung Recommendation m_recom2; //!< Alternative Lernempfehlung
//! Empfohlenes Datum zur Wiederholung der Fragen //! Empfohlenes Datum zur Wiederholung der Fragen
/*! Diese Variable wird mit der Funktion updateRecommendation() aktualisiert */ /*! Diese Variable wird mit der Funktion updateRecommendation() aktualisiert */
QDate m_recomRepeatDate; QDate m_recomRepeatDate;
//! Liste mit Fragen zum Erfüllen der Lernempfehlung //! Liste mit Fragen zum Erfüllen der Lernempfehlung
/*! Diese Liste wird mit der Funktion updateRecommendation() aktualisiert */ /*! Diese Liste wird mit der Funktion updateRecommendation() aktualisiert */
QList<CQuestion*> m_listQuestionRecommended; QList<CQuestion*> m_listQuestionRecommended;
}; };
#endif #endif

View File

@ -1,184 +1,184 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "chaptermodel.h" #include "chaptermodel.h"
#include "catalog.h" #include "catalog.h"
#include <qtextdocument.h> #include <qtextdocument.h>
#define COL_CHAPTER 0 #define COL_CHAPTER 0
#define COL_QUESTION 1 #define COL_QUESTION 1
#define COL_ASSIST 2 #define COL_ASSIST 2
#define COL_AVG 3 #define COL_AVG 3
CChapterModel::CChapterModel(QObject *pParent) : QAbstractItemModel (pParent) CChapterModel::CChapterModel(QObject *pParent) : QAbstractItemModel (pParent)
{ {
m_pCatalog = 0; m_pCatalog = 0;
} }
CChapterModel::~CChapterModel() CChapterModel::~CChapterModel()
{ {
} }
void CChapterModel::onLanguageChanged() void CChapterModel::onLanguageChanged()
{ {
headerDataChanged(Qt::Horizontal, 0, columnCount()-1); headerDataChanged(Qt::Horizontal, 0, columnCount()-1);
} }
void CChapterModel::clear() void CChapterModel::clear()
{ {
m_listChapter.clear(); m_listChapter.clear();
m_pCatalog = 0; m_pCatalog = 0;
reset(); reset();
} }
void CChapterModel::setModelData (CCatalog *pCatalog, QList<CChapter*> listChapter) void CChapterModel::setModelData (CCatalog *pCatalog, QList<CChapter*> listChapter)
{ {
m_listChapter = listChapter; m_listChapter = listChapter;
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
reset(); reset();
} }
int CChapterModel::columnCount (const QModelIndex & parent) const int CChapterModel::columnCount (const QModelIndex & parent) const
{ {
Q_UNUSED(parent) Q_UNUSED(parent)
return 4; return 4;
} }
QVariant CChapterModel::data (const QModelIndex & index, int role) const QVariant CChapterModel::data (const QModelIndex & index, int role) const
{ {
CChapter *p = (CChapter*) index.internalPointer(); CChapter *p = (CChapter*) index.internalPointer();
if (m_pCatalog == 0 || !index.isValid()) return QVariant(); if (m_pCatalog == 0 || !index.isValid()) return QVariant();
if (role == Qt::TextAlignmentRole && index.column() == COL_QUESTION) return Qt::AlignRight; if (role == Qt::TextAlignmentRole && index.column() == COL_QUESTION) return Qt::AlignRight;
if (p == 0) return QVariant(); if (p == 0) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (index.column() == COL_CHAPTER) if (index.column() == COL_CHAPTER)
{ {
if (p->id().isEmpty()) if (p->id().isEmpty())
return p->text(); return p->text();
else else
return p->idWithParents() + " - " + p->text(); return p->idWithParents() + " - " + p->text();
} }
else if (index.column() == COL_QUESTION) else if (index.column() == COL_QUESTION)
return QString("%1").arg(p->countSubQuestion()); return QString("%1").arg(p->countSubQuestion());
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationText(); return p->recommendationText();
/* CRecommendation r(p); /* CRecommendation r(p);
return r.textShort(); return r.textShort();
*/ */
} }
} }
else if (role == Qt::DecorationRole) else if (role == Qt::DecorationRole)
{ {
if (index.column() == COL_CHAPTER) if (index.column() == COL_CHAPTER)
return QIcon(":/icons/16x16/folder.png"); return QIcon(":/icons/16x16/folder.png");
else if (index.column() == COL_AVG) else if (index.column() == COL_AVG)
{ {
return p->levelAvgIcon(); return p->levelAvgIcon();
} }
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationIcon(m_pCatalog); return p->recommendationIcon(m_pCatalog);
//TODO return p->recommendation().icon(m_pCatalog); //TODO return p->recommendation().icon(m_pCatalog);
} }
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (index.column() == COL_AVG) if (index.column() == COL_AVG)
{ {
return QString ("%1 - Kennzahl: %2").arg(p->/*statistic().*/levelAvgText()).arg(p->/*statistic().*/levelAvg(), 4, 'f', 2); return QString ("%1 - Kennzahl: %2").arg(p->/*statistic().*/levelAvgText()).arg(p->/*statistic().*/levelAvg(), 4, 'f', 2);
} }
else if (index.column() == COL_ASSIST) else if (index.column() == COL_ASSIST)
{ {
return p->recommendationToolTip(); return p->recommendationToolTip();
//TODO return p->recommendation().recommendationText(m_pCatalog); //TODO return p->recommendation().recommendationText(m_pCatalog);
} }
} }
return QVariant(); return QVariant();
} }
bool CChapterModel::hasChildren (const QModelIndex & parent) const bool CChapterModel::hasChildren (const QModelIndex & parent) const
{ {
if (parent.isValid()) return false; if (parent.isValid()) return false;
return (!m_listChapter.isEmpty()); return (!m_listChapter.isEmpty());
} }
QVariant CChapterModel::headerData (int section, Qt::Orientation orientation, int role) const QVariant CChapterModel::headerData (int section, Qt::Orientation orientation, int role) const
{ {
if (orientation == Qt::Vertical) return QVariant(); if (orientation == Qt::Vertical) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (section == COL_CHAPTER) if (section == COL_CHAPTER)
return tr("Kapitel"); return tr("Kapitel");
else if (section == COL_QUESTION) else if (section == COL_QUESTION)
return tr("Fragen"); return tr("Fragen");
else if (section == COL_AVG) else if (section == COL_AVG)
return tr("Ø"); return tr("Ø");
else if (section == COL_ASSIST) else if (section == COL_ASSIST)
return tr("Lernassistent"); return tr("Lernassistent");
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (section == COL_CHAPTER) if (section == COL_CHAPTER)
return tr("Kapitelname\nBitte markieren Sie das Kapitel, das Sie lernen möchten."); return tr("Kapitelname\nBitte markieren Sie das Kapitel, das Sie lernen möchten.");
else if (section == COL_QUESTION) else if (section == COL_QUESTION)
return tr("Anzahl d. Fragen inkl. Unterkapitel"); return tr("Anzahl d. Fragen inkl. Unterkapitel");
else if (section == COL_AVG) else if (section == COL_AVG)
return tr("Durchschnittlicher Lernfortschritt"); return tr("Durchschnittlicher Lernfortschritt");
else if (section == COL_ASSIST) else if (section == COL_ASSIST)
return tr("Empfehlung des Lernassistentes"); return tr("Empfehlung des Lernassistentes");
} }
else if (role == Qt::WhatsThisRole) else if (role == Qt::WhatsThisRole)
{ {
} }
return QVariant(); return QVariant();
} }
QModelIndex CChapterModel::index (int row, int column, const QModelIndex & parent) const QModelIndex CChapterModel::index (int row, int column, const QModelIndex & parent) const
{ {
CChapter *p=0; CChapter *p=0;
if (parent.isValid() || row >= m_listChapter.size()) return QModelIndex(); if (parent.isValid() || row >= m_listChapter.size()) return QModelIndex();
p = m_listChapter.at (row); p = m_listChapter.at (row);
return createIndex (row, column, (void*)p); return createIndex (row, column, (void*)p);
} }
QModelIndex CChapterModel::parent (const QModelIndex & index) const QModelIndex CChapterModel::parent (const QModelIndex & index) const
{ {
Q_UNUSED(index); Q_UNUSED(index);
return QModelIndex(); return QModelIndex();
} }
int CChapterModel::rowCount (const QModelIndex & parent) const int CChapterModel::rowCount (const QModelIndex & parent) const
{ {
if (parent.isValid()) return 0; if (parent.isValid()) return 0;
return m_listChapter.size(); return m_listChapter.size();
} }

View File

@ -1,60 +1,60 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CHAPTERMODEL_H #ifndef CHAPTERMODEL_H
#define CHAPTERMODEL_H #define CHAPTERMODEL_H
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
class CChapter; class CChapter;
class CCatalog; class CCatalog;
class CChapterModel : public QAbstractItemModel class CChapterModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
public: public:
CChapterModel(QObject *pParent=0); CChapterModel(QObject *pParent=0);
~CChapterModel(); ~CChapterModel();
void clear(); void clear();
void setModelData (CCatalog *pCatalog, QList<CChapter*> listChapter); void setModelData (CCatalog *pCatalog, QList<CChapter*> listChapter);
public: public:
virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const; virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const; virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const;
virtual QModelIndex parent ( const QModelIndex & index ) const; virtual QModelIndex parent ( const QModelIndex & index ) const;
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
public slots: public slots:
void onLanguageChanged(); void onLanguageChanged();
protected: protected:
void recalcColumn(); void recalcColumn();
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
QList<CChapter*> m_listChapter; QList<CChapter*> m_listChapter;
}; };
#endif // CHAPTERMODEL_H #endif // CHAPTERMODEL_H

View File

@ -1,300 +1,300 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlgexam.h" #include "dlgexam.h"
#include "question.h" #include "question.h"
#include "error.h" #include "error.h"
#include "catalog.h" #include "catalog.h"
#include <qmessagebox.h> #include <qmessagebox.h>
CDlgExam::CDlgExam (CCatalog *pCatalog, QWidget *pParent) : QDialog (pParent, Qt::WindowMaximizeButtonHint) CDlgExam::CDlgExam (CCatalog *pCatalog, QWidget *pParent) : QDialog (pParent, Qt::WindowMaximizeButtonHint)
{ {
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
m_iCurrentQuestion = -1; m_iCurrentQuestion = -1;
m_bIsFinished = false; m_bIsFinished = false;
m_bTimeout = false; m_bTimeout = false;
setupUi(this); setupUi(this);
connect (&m_timer, SIGNAL(timeout()), this, SLOT(onTimer())); connect (&m_timer, SIGNAL(timeout()), this, SLOT(onTimer()));
} }
CDlgExam::~CDlgExam () CDlgExam::~CDlgExam ()
{ {
} }
bool CDlgExam::setup (const CExam& exam) bool CDlgExam::setup (const CExam& exam)
{ {
m_exam = exam; m_exam = exam;
labHeader->setText(exam.name()); labHeader->setText(exam.name());
try try
{ {
m_listQuestion = exam.createQuestionPool(m_pCatalog->questionPool()); m_listQuestion = exam.createQuestionPool(m_pCatalog->questionPool());
} }
catch (CError e) catch (CError e)
{ {
QMessageBox::critical(this, tr("Fehler"), e.toHtml()); QMessageBox::critical(this, tr("Fehler"), e.toHtml());
return false; return false;
} }
m_listAnswerMask.clear(); m_listAnswerMask.clear();
while (m_listAnswerMask.size() < m_listQuestion.size()) while (m_listAnswerMask.size() < m_listQuestion.size())
m_listAnswerMask.append(0); m_listAnswerMask.append(0);
// Antworten bei Bedarf durchmischen // Antworten bei Bedarf durchmischen
if (m_pCatalog->useMixedAnswers()) if (m_pCatalog->useMixedAnswers())
{ {
for (int i=0; i<m_listQuestion.size(); i++) for (int i=0; i<m_listQuestion.size(); i++)
m_listQuestion.at(i)->mixAnswers(); m_listQuestion.at(i)->mixAnswers();
} }
init(); init();
return true; return true;
} }
void CDlgExam::init() void CDlgExam::init()
{ {
// Zeitbalken & Zeitüberwachung // Zeitbalken & Zeitüberwachung
m_timer.setInterval(1000); m_timer.setInterval(1000);
m_timer.start(); m_timer.start();
m_dtStart = QDateTime::currentDateTime(); m_dtStart = QDateTime::currentDateTime();
pgTime->setMaximum (m_exam.duration() * 60); pgTime->setMaximum (m_exam.duration() * 60);
// Sonstiges // Sonstiges
pgQuestions->setMaximum (m_listQuestion.size()); pgQuestions->setMaximum (m_listQuestion.size());
m_bIsFinished = false; m_bIsFinished = false;
m_bTimeout = false; m_bTimeout = false;
labMaxWrong->setText(QString("%1").arg(m_exam.maxErrorPoints())); labMaxWrong->setText(QString("%1").arg(m_exam.maxErrorPoints()));
// Navigation // Navigation
spinBox->setRange (1, m_listQuestion.size()); spinBox->setRange (1, m_listQuestion.size());
spinBox->setValue(1); spinBox->setValue(1);
m_iCurrentQuestion = 1; m_iCurrentQuestion = 1;
// Alles updaten // Alles updaten
updateNavi(); updateNavi();
showQuestion(); showQuestion();
updateProgressTimer(); updateProgressTimer();
updateProgressQuestion(); updateProgressQuestion();
} }
void CDlgExam::onTimer() void CDlgExam::onTimer()
{ {
updateProgressTimer(); updateProgressTimer();
} }
void CDlgExam::updateNavi() void CDlgExam::updateNavi()
{ {
pbFirst->setEnabled (spinBox->value() > spinBox->minimum()); pbFirst->setEnabled (spinBox->value() > spinBox->minimum());
pbPrev->setEnabled (spinBox->value() > spinBox->minimum()); pbPrev->setEnabled (spinBox->value() > spinBox->minimum());
pbNext->setEnabled (spinBox->value() < spinBox->maximum()); pbNext->setEnabled (spinBox->value() < spinBox->maximum());
pbLast->setEnabled (spinBox->value() < spinBox->maximum()); pbLast->setEnabled (spinBox->value() < spinBox->maximum());
} }
unsigned CDlgExam::answeredQuestionCount() unsigned CDlgExam::answeredQuestionCount()
{ {
unsigned u=0; unsigned u=0;
for (int i=0; i<m_listAnswerMask.size(); i++) for (int i=0; i<m_listAnswerMask.size(); i++)
{ {
if (m_listAnswerMask.at(i) != 0) u++; if (m_listAnswerMask.at(i) != 0) u++;
} }
return u; return u;
} }
void CDlgExam::updateProgressQuestion() void CDlgExam::updateProgressQuestion()
{ {
unsigned uAnswered = answeredQuestionCount(); unsigned uAnswered = answeredQuestionCount();
labProgressQuestions->setText(tr("%1 von %2").arg(uAnswered).arg(m_listAnswerMask.size())); labProgressQuestions->setText(tr("%1 von %2").arg(uAnswered).arg(m_listAnswerMask.size()));
pgQuestions->setValue(uAnswered); pgQuestions->setValue(uAnswered);
} }
void CDlgExam::updateProgressTimer() void CDlgExam::updateProgressTimer()
{ {
QDateTime dt = QDateTime::currentDateTime(); QDateTime dt = QDateTime::currentDateTime();
unsigned uSecs = m_dtStart.secsTo(dt); unsigned uSecs = m_dtStart.secsTo(dt);
labProgessTime->setText(tr("Abgelaufene Zeit: %1:%2 min von %3:00 min") labProgessTime->setText(tr("Abgelaufene Zeit: %1:%2 min von %3:00 min")
.arg(uSecs / 60) .arg(uSecs / 60)
.arg(uSecs % 60, 2, 10, QChar('0')) .arg(uSecs % 60, 2, 10, QChar('0'))
.arg(m_exam.duration())); .arg(m_exam.duration()));
pgTime->setValue (uSecs); pgTime->setValue (uSecs);
if (uSecs > m_exam.duration()*60) if (uSecs > m_exam.duration()*60)
{ {
m_bTimeout = true; m_bTimeout = true;
m_timer.stop(); m_timer.stop();
QMessageBox::information(this, tr("Information"), tr("Die Zeit ist abgelaufen.\nDie Prüfung wird deswegen beendet.")); QMessageBox::information(this, tr("Information"), tr("Die Zeit ist abgelaufen.\nDie Prüfung wird deswegen beendet."));
on_pbFinish_clicked(); on_pbFinish_clicked();
} }
} }
void CDlgExam::on_pbFirst_clicked() void CDlgExam::on_pbFirst_clicked()
{ {
spinBox->setValue(1); spinBox->setValue(1);
} }
void CDlgExam::on_pbPrev_clicked() void CDlgExam::on_pbPrev_clicked()
{ {
int iNew = spinBox->value() - 1; int iNew = spinBox->value() - 1;
if (iNew < 1) iNew = 1; if (iNew < 1) iNew = 1;
spinBox->setValue(iNew); spinBox->setValue(iNew);
} }
void CDlgExam::on_pbNext_clicked() void CDlgExam::on_pbNext_clicked()
{ {
int iNew = spinBox->value() + 1; int iNew = spinBox->value() + 1;
if (iNew > m_listQuestion.size()) iNew = m_listQuestion.size(); if (iNew > m_listQuestion.size()) iNew = m_listQuestion.size();
spinBox->setValue(iNew); spinBox->setValue(iNew);
} }
void CDlgExam::on_pbLast_clicked() void CDlgExam::on_pbLast_clicked()
{ {
spinBox->setValue(m_listQuestion.size()); spinBox->setValue(m_listQuestion.size());
} }
void CDlgExam::on_spinBox_valueChanged(int i) void CDlgExam::on_spinBox_valueChanged(int i)
{ {
Q_UNUSED(i); Q_UNUSED(i);
onQuestionChanged(); onQuestionChanged();
} }
void CDlgExam::saveCurrentAnswer() void CDlgExam::saveCurrentAnswer()
{ {
unsigned uAnswerMask=0; unsigned uAnswerMask=0;
if (m_iCurrentQuestion >= 0) if (m_iCurrentQuestion >= 0)
{ // Antwort zur aktuellen Frage abspeichern { // Antwort zur aktuellen Frage abspeichern
if (rbA->isChecked()) uAnswerMask |= 1; if (rbA->isChecked()) uAnswerMask |= 1;
if (rbB->isChecked()) uAnswerMask |= 2; if (rbB->isChecked()) uAnswerMask |= 2;
if (rbC->isChecked()) uAnswerMask |= 4; if (rbC->isChecked()) uAnswerMask |= 4;
if (rbD->isChecked()) uAnswerMask |= 8; if (rbD->isChecked()) uAnswerMask |= 8;
m_listAnswerMask[m_iCurrentQuestion] = uAnswerMask; m_listAnswerMask[m_iCurrentQuestion] = uAnswerMask;
} }
} }
void CDlgExam::onQuestionChanged() void CDlgExam::onQuestionChanged()
{ {
saveCurrentAnswer(); saveCurrentAnswer();
updateNavi(); updateNavi();
updateProgressQuestion(); updateProgressQuestion();
showQuestion(); // neue Frage anzeigen showQuestion(); // neue Frage anzeigen
} }
void CDlgExam::showQuestion() void CDlgExam::showQuestion()
{ {
CQuestion *q=0; CQuestion *q=0;
unsigned uAnswerMask; unsigned uAnswerMask;
QString str; QString str;
m_iCurrentQuestion = spinBox->value()-1; m_iCurrentQuestion = spinBox->value()-1;
q = m_listQuestion.at(m_iCurrentQuestion); q = m_listQuestion.at(m_iCurrentQuestion);
uAnswerMask = m_listAnswerMask.at(m_iCurrentQuestion); uAnswerMask = m_listAnswerMask.at(m_iCurrentQuestion);
str = q->learnText(m_pCatalog, m_bIsFinished, false); str = q->learnText(m_pCatalog, m_bIsFinished, false);
if (m_bIsFinished) if (m_bIsFinished)
{ {
str += "<hr><p><b>"; str += "<hr><p><b>";
if (!q->isCorrectAnswer(uAnswerMask)) if (!q->isCorrectAnswer(uAnswerMask))
str += "<font color='red'>"; str += "<font color='red'>";
else else
str += "<font color='green'>"; str += "<font color='green'>";
str += q->correctionText(uAnswerMask) + "</font></p>"; str += q->correctionText(uAnswerMask) + "</font></p>";
} }
textBrowser->setHtml(str); textBrowser->setHtml(str);
rbA->setChecked(uAnswerMask & 1); rbA->setChecked(uAnswerMask & 1);
rbB->setChecked(uAnswerMask & 2); rbB->setChecked(uAnswerMask & 2);
rbC->setChecked(uAnswerMask & 4); rbC->setChecked(uAnswerMask & 4);
rbD->setChecked(uAnswerMask & 8); rbD->setChecked(uAnswerMask & 8);
rbNoIdea->setChecked(uAnswerMask == 0); rbNoIdea->setChecked(uAnswerMask == 0);
} }
void CDlgExam::on_pbFinish_clicked() void CDlgExam::on_pbFinish_clicked()
{ {
unsigned uCorrect=0, uWrong=0, uAnsweredCount = answeredQuestionCount(), uErrorPoints=0; unsigned uCorrect=0, uWrong=0, uAnsweredCount = answeredQuestionCount(), uErrorPoints=0;
bool bSaveStat=true, bPassed=false; bool bSaveStat=true, bPassed=false;
QDateTime dt = QDateTime::currentDateTime(); QDateTime dt = QDateTime::currentDateTime();
unsigned uSecs = m_dtStart.secsTo(dt); unsigned uSecs = m_dtStart.secsTo(dt);
saveCurrentAnswer(); saveCurrentAnswer();
if (uAnsweredCount < (unsigned)m_listQuestion.size() && !m_bTimeout) if (uAnsweredCount < (unsigned)m_listQuestion.size() && !m_bTimeout)
{ {
if (QMessageBox::question (this, if (QMessageBox::question (this,
tr("Sicherheitsabfrage"), tr("Sicherheitsabfrage"),
tr("Sie haben noch nicht alle Fragen beantwortet.\nWirklich abgeben?"), tr("Sie haben noch nicht alle Fragen beantwortet.\nWirklich abgeben?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) return; QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No) return;
} }
m_timer.stop(); m_timer.stop();
pbFinish->setEnabled(false); pbFinish->setEnabled(false);
rbA->setEnabled(false); rbA->setEnabled(false);
rbB->setEnabled(false); rbB->setEnabled(false);
rbC->setEnabled(false); rbC->setEnabled(false);
rbD->setEnabled(false); rbD->setEnabled(false);
rbNoIdea->setEnabled(false); rbNoIdea->setEnabled(false);
pbCancel->setText(tr("Beenden")); pbCancel->setText(tr("Beenden"));
m_bIsFinished = true; m_bIsFinished = true;
showQuestion(); showQuestion();
for (int i=0; i<m_listQuestion.size(); i++) for (int i=0; i<m_listQuestion.size(); i++)
{ {
CQuestion *q = m_listQuestion.at(i); CQuestion *q = m_listQuestion.at(i);
unsigned uAnswerMask = m_listAnswerMask.at(i); unsigned uAnswerMask = m_listAnswerMask.at(i);
if (q->isCorrectAnswer(uAnswerMask)) if (q->isCorrectAnswer(uAnswerMask))
uCorrect++; uCorrect++;
else else
{ {
uWrong++; uWrong++;
uErrorPoints+=q->errorPoints(); uErrorPoints+=q->errorPoints();
} }
} }
labCorrect->setText(QString("%1").arg(uCorrect)); labCorrect->setText(QString("%1").arg(uCorrect));
labWrong->setText(QString("%1").arg(uWrong)); labWrong->setText(QString("%1").arg(uWrong));
if (uAnsweredCount < (unsigned)m_listQuestion.size()/2) if (uAnsweredCount < (unsigned)m_listQuestion.size()/2)
{ {
bPassed = false; bPassed = false;
bSaveStat = false; bSaveStat = false;
labResult->setText(tr("Ohne Wertung\n(Nicht bestanden)")); labResult->setText(tr("Ohne Wertung\n(Nicht bestanden)"));
QMessageBox::information(this, tr("Information"), tr("Sie haben weniger als die Hälfte aller Fragen beantwortet.\nDiese Prüfung wird deswegen nicht gewertet.")); QMessageBox::information(this, tr("Information"), tr("Sie haben weniger als die Hälfte aller Fragen beantwortet.\nDiese Prüfung wird deswegen nicht gewertet."));
} }
else if (uErrorPoints > m_exam.maxErrorPoints()) else if (uErrorPoints > m_exam.maxErrorPoints())
{ {
bPassed = false; bPassed = false;
labResult->setText(tr("<font color='red'>Nicht bestanden</font>")); labResult->setText(tr("<font color='red'>Nicht bestanden</font>"));
QMessageBox::information(this, tr("Ergebnis"), tr("Sie haben die Prüfung leider nicht bestanden.")); QMessageBox::information(this, tr("Ergebnis"), tr("Sie haben die Prüfung leider nicht bestanden."));
} }
else else
{ {
bPassed = true; bPassed = true;
labResult->setText(tr("<font color='green'>Bestanden</font>")); labResult->setText(tr("<font color='green'>Bestanden</font>"));
QMessageBox::information(this, tr("Ergebnis"), tr("<b>Herzlichen Glückwunsch!</b><p>Sie haben die Prüfung bestanden!")); QMessageBox::information(this, tr("Ergebnis"), tr("<b>Herzlichen Glückwunsch!</b><p>Sie haben die Prüfung bestanden!"));
} }
if (bSaveStat) if (bSaveStat)
{ // Prüfungsstatistik speichern { // Prüfungsstatistik speichern
CExamStat es(m_exam); CExamStat es(m_exam);
es.setSecs(uSecs); es.setSecs(uSecs);
es.setQuestions(m_listQuestion, m_listAnswerMask); es.setQuestions(m_listQuestion, m_listAnswerMask);
es.setResult(uCorrect, uWrong, uErrorPoints, bPassed); es.setResult(uCorrect, uWrong, uErrorPoints, bPassed);
m_pCatalog->appendExamStat(es); m_pCatalog->appendExamStat(es);
m_pCatalog->saveStatistic(this); m_pCatalog->saveStatistic(this);
} }
} }

162
dlgexam.h
View File

@ -1,81 +1,81 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include "exam.h" #include "exam.h"
#include "ui_dlgexam.h" #include "ui_dlgexam.h"
#include <qdialog.h> #include <qdialog.h>
#include <qtimer.h> #include <qtimer.h>
#include <qdatetime.h> #include <qdatetime.h>
class CCatalog; class CCatalog;
class CQuestion; class CQuestion;
class CDlgExam : public QDialog, Ui::DlgExam class CDlgExam : public QDialog, Ui::DlgExam
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgExam (CCatalog *pCatalog, QWidget *pParent=0); CDlgExam (CCatalog *pCatalog, QWidget *pParent=0);
~CDlgExam (); ~CDlgExam ();
bool setup (const CExam& exam); bool setup (const CExam& exam);
protected: protected:
void init(); void init();
void updateNavi(); void updateNavi();
void updateProgressQuestion(); void updateProgressQuestion();
void updateProgressTimer(); void updateProgressTimer();
void showQuestion(); void showQuestion();
void onQuestionChanged(); void onQuestionChanged();
unsigned answeredQuestionCount(); unsigned answeredQuestionCount();
void saveCurrentAnswer(); void saveCurrentAnswer();
protected slots: protected slots:
void onTimer(); void onTimer();
void on_pbFirst_clicked(); void on_pbFirst_clicked();
void on_pbPrev_clicked(); void on_pbPrev_clicked();
void on_pbNext_clicked(); void on_pbNext_clicked();
void on_pbLast_clicked(); void on_pbLast_clicked();
void on_spinBox_valueChanged(int i); void on_spinBox_valueChanged(int i);
void on_pbFinish_clicked(); void on_pbFinish_clicked();
inline void on_rbA_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); } inline void on_rbA_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); }
inline void on_rbB_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); } inline void on_rbB_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); }
inline void on_rbC_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); } inline void on_rbC_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); }
inline void on_rbD_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); } inline void on_rbD_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); }
inline void on_rbNoIdea_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); } inline void on_rbNoIdea_toggled(bool bChecked) { Q_UNUSED(bChecked); saveCurrentAnswer(); updateProgressQuestion(); }
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
CExam m_exam; CExam m_exam;
QList<CQuestion*> m_listQuestion; QList<CQuestion*> m_listQuestion;
QList<unsigned> m_listAnswerMask; QList<unsigned> m_listAnswerMask;
QTimer m_timer; QTimer m_timer;
QDateTime m_dtStart; QDateTime m_dtStart;
QDateTime m_dtStop; QDateTime m_dtStop;
int m_iCurrentQuestion; int m_iCurrentQuestion;
bool m_bIsFinished; bool m_bIsFinished;
bool m_bTimeout; bool m_bTimeout;
}; };

View File

@ -1,93 +1,93 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlgexamselect.h" #include "dlgexamselect.h"
#include <qmessagebox.h> #include <qmessagebox.h>
#include <qheaderview.h> #include <qheaderview.h>
#include "catalog.h" #include "catalog.h"
CDlgExamSelect::CDlgExamSelect (QWidget *pParent) : QDialog (pParent) CDlgExamSelect::CDlgExamSelect (QWidget *pParent) : QDialog (pParent)
{ {
m_pCatalog = 0; m_pCatalog = 0;
m_iSelectedExam = -1; m_iSelectedExam = -1;
setupUi(this); setupUi(this);
twList->headerItem()->setText(0, tr("Name")); twList->headerItem()->setText(0, tr("Name"));
twList->headerItem()->setText(1, tr("Dauer (min)")); twList->headerItem()->setText(1, tr("Dauer (min)"));
//twList->header()->setStretchLastSection(false); //twList->header()->setStretchLastSection(false);
twList->header()->resizeSection(0, 370); twList->header()->resizeSection(0, 370);
//twList->header()->resizeSection(1, 70); //twList->header()->resizeSection(1, 70);
} }
CDlgExamSelect::~CDlgExamSelect () CDlgExamSelect::~CDlgExamSelect ()
{ {
} }
void CDlgExamSelect::setup (const CCatalog *pCatalog) void CDlgExamSelect::setup (const CCatalog *pCatalog)
{ {
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
for (int i=0; i<m_pCatalog->countExam(); i++) for (int i=0; i<m_pCatalog->countExam(); i++)
{ {
CExam exam = m_pCatalog->examAt(i); CExam exam = m_pCatalog->examAt(i);
QTreeWidgetItem *pItem = new QTreeWidgetItem (twList); QTreeWidgetItem *pItem = new QTreeWidgetItem (twList);
pItem->setText(0, exam.name()); pItem->setText(0, exam.name());
pItem->setText(1, QString("%1 min").arg(exam.duration())); pItem->setText(1, QString("%1 min").arg(exam.duration()));
pItem->setTextAlignment(1, Qt::AlignRight); pItem->setTextAlignment(1, Qt::AlignRight);
pItem->setData(0, Qt::UserRole, i); pItem->setData(0, Qt::UserRole, i);
} }
} }
void CDlgExamSelect::on_twList_currentItemChanged (QTreeWidgetItem *current, QTreeWidgetItem *previous) void CDlgExamSelect::on_twList_currentItemChanged (QTreeWidgetItem *current, QTreeWidgetItem *previous)
{ {
Q_UNUSED(previous); Q_UNUSED(previous);
if (current) if (current)
{ {
m_iSelectedExam = current->data(0, Qt::UserRole).toInt(); m_iSelectedExam = current->data(0, Qt::UserRole).toInt();
CExam exam = m_pCatalog->examAt(m_iSelectedExam); CExam exam = m_pCatalog->examAt(m_iSelectedExam);
labName->setText(exam.name()); labName->setText(exam.name());
labComment->setText(exam.comment()); labComment->setText(exam.comment());
labDuration->setText(QString("%1 min").arg(exam.duration())); labDuration->setText(QString("%1 min").arg(exam.duration()));
labQuestions->setText(QString("%1").arg(exam.questionCount())); labQuestions->setText(QString("%1").arg(exam.questionCount()));
labError->setText(QString("%1").arg(exam.maxErrorPoints())); labError->setText(QString("%1").arg(exam.maxErrorPoints()));
} }
else else
{ {
m_iSelectedExam = -1; m_iSelectedExam = -1;
labName->clear(); labName->clear();
labComment->clear(); labComment->clear();
labDuration->clear(); labDuration->clear();
labQuestions->clear(); labQuestions->clear();
labError->clear(); labError->clear();
} }
} }
void CDlgExamSelect::on_buttonBox_accepted() void CDlgExamSelect::on_buttonBox_accepted()
{ {
if (m_iSelectedExam == -1) if (m_iSelectedExam == -1)
{ {
QMessageBox::information(this, tr("Information"), tr("Bitte eine Prüfung auswählen!")); QMessageBox::information(this, tr("Information"), tr("Bitte eine Prüfung auswählen!"));
return; return;
} }
accept(); accept();
} }

View File

@ -1,46 +1,46 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include "ui_dlgexamselect.h" #include "ui_dlgexamselect.h"
#include <qdialog.h> #include <qdialog.h>
class CCatalog; class CCatalog;
class CDlgExamSelect : public QDialog, Ui::DlgExamSelect class CDlgExamSelect : public QDialog, Ui::DlgExamSelect
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgExamSelect (QWidget *pParent=0); CDlgExamSelect (QWidget *pParent=0);
~CDlgExamSelect (); ~CDlgExamSelect ();
void setup (const CCatalog *pCatalog); void setup (const CCatalog *pCatalog);
inline int selectedExam() const { return m_iSelectedExam; } inline int selectedExam() const { return m_iSelectedExam; }
protected slots: protected slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
void on_twList_currentItemChanged (QTreeWidgetItem *current, QTreeWidgetItem *previous); void on_twList_currentItemChanged (QTreeWidgetItem *current, QTreeWidgetItem *previous);
protected: protected:
const CCatalog *m_pCatalog; const CCatalog *m_pCatalog;
int m_iSelectedExam; int m_iSelectedExam;
}; };

View File

@ -1,109 +1,109 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlgexamstatistic.h" #include "dlgexamstatistic.h"
#include "catalog.h" #include "catalog.h"
#include <qmessagebox.h> #include <qmessagebox.h>
#include <qheaderview.h> #include <qheaderview.h>
CDlgExamStatistic::CDlgExamStatistic(QWidget *pParent) : QDialog(pParent) CDlgExamStatistic::CDlgExamStatistic(QWidget *pParent) : QDialog(pParent)
{ {
m_pCatalog = 0; m_pCatalog = 0;
setupUi(this); setupUi(this);
twExamStat->headerItem()->setText(0, "Datum/Uhrzeit"); twExamStat->headerItem()->setText(0, "Datum/Uhrzeit");
twExamStat->headerItem()->setText(1, "Ergebnis"); twExamStat->headerItem()->setText(1, "Ergebnis");
twExamStat->headerItem()->setText(2, "Fehler"); twExamStat->headerItem()->setText(2, "Fehler");
twExamStat->headerItem()->setText(3, "Dauer"); twExamStat->headerItem()->setText(3, "Dauer");
twExamStat->headerItem()->setText(4, "Ø pro Frage"); twExamStat->headerItem()->setText(4, "Ø pro Frage");
twExamStat->header()->resizeSection(0, 130); twExamStat->header()->resizeSection(0, 130);
twExamStat->header()->resizeSection(2, 50); twExamStat->header()->resizeSection(2, 50);
twExamStat->header()->resizeSection(3, 75); twExamStat->header()->resizeSection(3, 75);
} }
void CDlgExamStatistic::go (CCatalog *pCatalog) void CDlgExamStatistic::go (CCatalog *pCatalog)
{ {
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
if (pCatalog->countExamStat() == 0) if (pCatalog->countExamStat() == 0)
{ {
QMessageBox::information(parentWidget(), tr("Information"), tr("Es wurden bisher noch keine Prüfungen durchgeführt.")); QMessageBox::information(parentWidget(), tr("Information"), tr("Es wurden bisher noch keine Prüfungen durchgeführt."));
return; return;
} }
cbExam->clear(); cbExam->clear();
for (int i=0; i<pCatalog->countExam(); i++) for (int i=0; i<pCatalog->countExam(); i++)
{ {
cbExam->addItem(pCatalog->examAt(i).name(), pCatalog->examAt(i).id()); cbExam->addItem(pCatalog->examAt(i).name(), pCatalog->examAt(i).id());
} }
exec(); exec();
} }
void CDlgExamStatistic::on_cbExam_currentIndexChanged (int index) void CDlgExamStatistic::on_cbExam_currentIndexChanged (int index)
{ {
QString strExamId = cbExam->itemData(index).toString(); QString strExamId = cbExam->itemData(index).toString();
CExam exam = m_pCatalog->examById(strExamId); CExam exam = m_pCatalog->examById(strExamId);
unsigned uExamCount=0, uPassedCount=0, uFailedCount=0, uErrorCount=0, uDuration=0, uQuestions=0; unsigned uExamCount=0, uPassedCount=0, uFailedCount=0, uErrorCount=0, uDuration=0, uQuestions=0;
QTreeWidgetItem *pItem=0; QTreeWidgetItem *pItem=0;
twExamStat->clear(); twExamStat->clear();
labExamQCount->setText(QString::number(exam.questionCount())); labExamQCount->setText(QString::number(exam.questionCount()));
labExamTime->setText(QString("%1 min").arg(exam.duration())); labExamTime->setText(QString("%1 min").arg(exam.duration()));
labExamWrong->setText(QString::number(exam.maxErrorPoints())); labExamWrong->setText(QString::number(exam.maxErrorPoints()));
for (int i=0; i<m_pCatalog->countExamStat(); i++) for (int i=0; i<m_pCatalog->countExamStat(); i++)
{ {
CExamStat es = m_pCatalog->examStatAt(i); CExamStat es = m_pCatalog->examStatAt(i);
if (es.id() != strExamId) continue; if (es.id() != strExamId) continue;
uExamCount++; uExamCount++;
if (es.passed()) uPassedCount++; else uFailedCount++; if (es.passed()) uPassedCount++; else uFailedCount++;
uErrorCount += es.errorPoints(); uErrorCount += es.errorPoints();
uDuration += es.duration(); uDuration += es.duration();
uQuestions += es.correctAnswers() + es.wrongAnswers(); uQuestions += es.correctAnswers() + es.wrongAnswers();
pItem = new QTreeWidgetItem (twExamStat); pItem = new QTreeWidgetItem (twExamStat);
pItem->setText(0, es.datetime().toString(Qt::LocalDate)); pItem->setText(0, es.datetime().toString(Qt::LocalDate));
pItem->setText(1, es.passed() ? tr("Bestanden") : tr("Nicht bestanden")); pItem->setText(1, es.passed() ? tr("Bestanden") : tr("Nicht bestanden"));
pItem->setText(2, QString::number(es.errorPoints())); pItem->setText(2, QString::number(es.errorPoints()));
pItem->setTextAlignment(2, Qt::AlignRight); pItem->setTextAlignment(2, Qt::AlignRight);
pItem->setText(3, QString("%1 m %2 s").arg(es.duration() / 60).arg(es.duration() % 60, 2, 10, QChar('0'))); pItem->setText(3, QString("%1 m %2 s").arg(es.duration() / 60).arg(es.duration() % 60, 2, 10, QChar('0')));
pItem->setTextAlignment(3, Qt::AlignRight); pItem->setTextAlignment(3, Qt::AlignRight);
unsigned uQuestionCount = es.correctAnswers() + es.wrongAnswers(); unsigned uQuestionCount = es.correctAnswers() + es.wrongAnswers();
if (uQuestionCount != 0) if (uQuestionCount != 0)
pItem->setText(4, QString("%1 m %2 s").arg(es.duration() / uQuestionCount / 60).arg(es.duration() / uQuestionCount % 60, 2, 10, QChar('0'))); pItem->setText(4, QString("%1 m %2 s").arg(es.duration() / uQuestionCount / 60).arg(es.duration() / uQuestionCount % 60, 2, 10, QChar('0')));
else else
pItem->setText(4, "--"); pItem->setText(4, "--");
pItem->setTextAlignment(4, Qt::AlignRight); pItem->setTextAlignment(4, Qt::AlignRight);
} }
labExamCount->setText(QString::number(uExamCount)); labExamCount->setText(QString::number(uExamCount));
labExamPassed->setText(uExamCount != 0 ? QString::number(uPassedCount) : "--"); labExamPassed->setText(uExamCount != 0 ? QString::number(uPassedCount) : "--");
labExamFailed->setText(uExamCount != 0 ? QString::number(uFailedCount) : "--"); labExamFailed->setText(uExamCount != 0 ? QString::number(uFailedCount) : "--");
labExamPassedP->setText(uExamCount != 0 ? QString("%1 %").arg((double)uPassedCount / uExamCount * 100.0, 0, 'f', 1) : "--"); labExamPassedP->setText(uExamCount != 0 ? QString("%1 %").arg((double)uPassedCount / uExamCount * 100.0, 0, 'f', 1) : "--");
labExamFailedP->setText(uExamCount != 0 ? QString("%1 %").arg((double)uFailedCount / uExamCount * 100.0, 0, 'f', 1) : "--"); labExamFailedP->setText(uExamCount != 0 ? QString("%1 %").arg((double)uFailedCount / uExamCount * 100.0, 0, 'f', 1) : "--");
labAvgWrong->setText(uExamCount != 0 ? QString::number(uErrorCount / uExamCount) : "--"); labAvgWrong->setText(uExamCount != 0 ? QString::number(uErrorCount / uExamCount) : "--");
labTimeExam->setText(uExamCount != 0 ? QString("%1 m %2 s").arg(uDuration / uExamCount / 60).arg(uDuration / uExamCount % 60, 2, 10, QChar('0')) : "--"); labTimeExam->setText(uExamCount != 0 ? QString("%1 m %2 s").arg(uDuration / uExamCount / 60).arg(uDuration / uExamCount % 60, 2, 10, QChar('0')) : "--");
labTimeQuestion->setText(uQuestions != 0 ? QString("%1 m %2 s").arg(uDuration / uQuestions / 60).arg(uDuration / uQuestions % 60, 2, 10, QChar('0')) : "--"); labTimeQuestion->setText(uQuestions != 0 ? QString("%1 m %2 s").arg(uDuration / uQuestions / 60).arg(uDuration / uQuestions % 60, 2, 10, QChar('0')) : "--");
} }

View File

@ -1,43 +1,43 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include <qdialog.h> #include <qdialog.h>
#include "ui_dlgexamstatistic.h" #include "ui_dlgexamstatistic.h"
class CCatalog; class CCatalog;
class CDlgExamStatistic : public QDialog, Ui::DlgExamStatistic class CDlgExamStatistic : public QDialog, Ui::DlgExamStatistic
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgExamStatistic(QWidget *pParent=0); CDlgExamStatistic(QWidget *pParent=0);
~CDlgExamStatistic() {} ~CDlgExamStatistic() {}
void go (CCatalog *pCatalog); void go (CCatalog *pCatalog);
protected slots: protected slots:
void on_cbExam_currentIndexChanged (int index); void on_cbExam_currentIndexChanged (int index);
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
}; };

View File

@ -1,51 +1,51 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlginformation.h" #include "dlginformation.h"
#include <qmessagebox.h> #include <qmessagebox.h>
#include "catalog.h" #include "catalog.h"
CDlgInformation::CDlgInformation (QWidget *pParent) : QDialog(pParent) CDlgInformation::CDlgInformation (QWidget *pParent) : QDialog(pParent)
{ {
m_pCatalog=0; m_pCatalog=0;
setupUi(this); setupUi(this);
} }
bool CDlgInformation::setup(CCatalog *pCatalog) bool CDlgInformation::setup(CCatalog *pCatalog)
{ {
labName->setText(pCatalog->name()); labName->setText(pCatalog->name());
labVersion->setText(pCatalog->versionText()); labVersion->setText(pCatalog->versionText());
labPublished->setText(pCatalog->published().toString(Qt::LocalDate)); labPublished->setText(pCatalog->published().toString(Qt::LocalDate));
labStatQuestion->setText(QString("%1").arg(pCatalog->countSubQuestion())); labStatQuestion->setText(QString("%1").arg(pCatalog->countSubQuestion()));
labStatChapter->setText(QString("%1").arg(pCatalog->subChapters().size())); labStatChapter->setText(QString("%1").arg(pCatalog->subChapters().size()));
labValidFrom->setText(pCatalog->validFrom().toString(Qt::LocalDate)); labValidFrom->setText(pCatalog->validFrom().toString(Qt::LocalDate));
labValidUntil->setText(pCatalog->validUntil().toString(Qt::LocalDate)); labValidUntil->setText(pCatalog->validUntil().toString(Qt::LocalDate));
labDate->setText(pCatalog->created().toString(Qt::LocalDate)); labDate->setText(pCatalog->created().toString(Qt::LocalDate));
labComment->setText(pCatalog->comment()); labComment->setText(pCatalog->comment());
labPublisher->setText(pCatalog->publisher()); labPublisher->setText(pCatalog->publisher());
labContact->setText(pCatalog->contact()); labContact->setText(pCatalog->contact());
return true; return true;
} }

View File

@ -1,47 +1,47 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DLGINFORMATION_H #ifndef DLGINFORMATION_H
#define DLGINFORMATION_H #define DLGINFORMATION_H
#include <qdialog.h> #include <qdialog.h>
#include "ui_dlginformation.h" #include "ui_dlginformation.h"
class CCatalog; class CCatalog;
class CDlgInformation : public QDialog, Ui::DlgInformation class CDlgInformation : public QDialog, Ui::DlgInformation
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgInformation (QWidget *pParent=0); CDlgInformation (QWidget *pParent=0);
~CDlgInformation () {} ~CDlgInformation () {}
bool setup(CCatalog *pCatalog); bool setup(CCatalog *pCatalog);
protected slots: protected slots:
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
}; };
#endif #endif

View File

@ -1,435 +1,435 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "catalog.h" #include "catalog.h"
#include "dlglearn.h" #include "dlglearn.h"
#include "dlgviewquestion.h" #include "dlgviewquestion.h"
#include "dlglearnassistant.h" #include "dlglearnassistant.h"
#include "tools.h" #include "tools.h"
#include <qmessagebox.h> #include <qmessagebox.h>
CDlgLearn::CDlgLearn (QWidget *pParent) : QDialog (pParent, Qt::WindowMaximizeButtonHint) CDlgLearn::CDlgLearn (QWidget *pParent) : QDialog (pParent, Qt::WindowMaximizeButtonHint)
{ {
m_pCatalog = 0; m_pCatalog = 0;
m_pChapter = 0; m_pChapter = 0;
m_pQuestion=0; m_pQuestion=0;
m_pLastQuestion=0; m_pLastQuestion=0;
m_uLastAnswerMask=0; m_uLastAnswerMask=0;
m_bHintsUsed=false; m_bHintsUsed=false;
m_uElapsedBeforeBreak=0; m_uElapsedBeforeBreak=0;
#ifdef _DEBUG #ifdef _DEBUG
m_bCheatEnable=true; m_bCheatEnable=true;
#else #else
m_bCheatEnable=false; m_bCheatEnable=false;
#endif #endif
m_bAssistantEnable=true; m_bAssistantEnable=true;
setupUi(this); setupUi(this);
if (!m_bAssistantEnable) if (!m_bAssistantEnable)
gbAssistant->hide(); gbAssistant->hide();
} }
CDlgLearn::~CDlgLearn() CDlgLearn::~CDlgLearn()
{ {
} }
void CDlgLearn::go (CCatalog *pCatalog, CChapter *pChapter) void CDlgLearn::go (CCatalog *pCatalog, CChapter *pChapter)
{ {
Q_ASSERT (pChapter != 0); Q_ASSERT (pChapter != 0);
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
setNewChapter(pChapter); setNewChapter(pChapter);
m_ds = pCatalog->dayStatistic(QDate::currentDate()); m_ds = pCatalog->dayStatistic(QDate::currentDate());
onUpdateDS(); onUpdateDS();
exec(); exec();
} }
void CDlgLearn::setNewChapter(CChapter *pChapter) void CDlgLearn::setNewChapter(CChapter *pChapter)
{ {
m_pQuestion=0; m_pQuestion=0;
m_bHintsUsed=false; m_bHintsUsed=false;
m_pChapter = pChapter; m_pChapter = pChapter;
m_listQuestion = m_pChapter->questionPool(); m_listQuestion = m_pChapter->questionPool();
nextQuestion(); nextQuestion();
} }
void CDlgLearn::updateStatistic() void CDlgLearn::updateStatistic()
{ {
const int w=60, h=16; const int w=60, h=16;
// CHAPTER STATISTICS // CHAPTER STATISTICS
labChapter->setText (m_pChapter->text()); labChapter->setText (m_pChapter->text());
labChapterCount->setText(QString("%1").arg(m_listQuestion.size())); labChapterCount->setText(QString("%1").arg(m_listQuestion.size()));
labChapterVeryOften->setText(QString("%1").arg(m_pChapter->countQuestion(0))); labChapterVeryOften->setText(QString("%1").arg(m_pChapter->countQuestion(0)));
labChapterOften->setText(QString("%1").arg(m_pChapter->countQuestion(1))); labChapterOften->setText(QString("%1").arg(m_pChapter->countQuestion(1)));
labChapterNormal->setText(QString("%1").arg(m_pChapter->countQuestion(2))); labChapterNormal->setText(QString("%1").arg(m_pChapter->countQuestion(2)));
labChapterRare->setText(QString("%1").arg(m_pChapter->countQuestion(3))); labChapterRare->setText(QString("%1").arg(m_pChapter->countQuestion(3)));
labChapterVeryRare->setText(QString("%1").arg(m_pChapter->countQuestion(4))); labChapterVeryRare->setText(QString("%1").arg(m_pChapter->countQuestion(4)));
labChapterExtremeRare->setText(QString("%1").arg(m_pChapter->countQuestion(5))); labChapterExtremeRare->setText(QString("%1").arg(m_pChapter->countQuestion(5)));
labChapterAvgText->setText(m_pChapter->levelAvgText()); labChapterAvgText->setText(m_pChapter->levelAvgText());
labChapterAvgIcon->setPixmap(m_pChapter->levelAvgPixmap()); labChapterAvgIcon->setPixmap(m_pChapter->levelAvgPixmap());
labChapterAvgIcon->setToolTip(QString("Kennzahl: %1").arg(m_pChapter->levelAvg(), 4, 'g', 2)); labChapterAvgIcon->setToolTip(QString("Kennzahl: %1").arg(m_pChapter->levelAvg(), 4, 'g', 2));
double dQuestionCount = m_listQuestion.size(), dPercent; double dQuestionCount = m_listQuestion.size(), dPercent;
// dPercent = (double)m_listQuestion.size()/(double)m_pCatalog->countSubQuestion(); // dPercent = (double)m_listQuestion.size()/(double)m_pCatalog->countSubQuestion();
// labChapterCountBar->setPixmap(createProgressBar(w, h, dPercent)); // labChapterCountBar->setPixmap(createProgressBar(w, h, dPercent));
// labChapterCountBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); // labChapterCountBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(0)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(0)/dQuestionCount;
labChapterVeryOftenBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterVeryOftenBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterVeryOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterVeryOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(1)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(1)/dQuestionCount;
labChapterOftenBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterOftenBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(2)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(2)/dQuestionCount;
labChapterNormalBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterNormalBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterNormalBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterNormalBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(3)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(3)/dQuestionCount;
labChapterRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(4)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(4)/dQuestionCount;
labChapterVeryRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterVeryRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterVeryRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterVeryRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(5)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(5)/dQuestionCount;
labChapterExtremeRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterExtremeRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterExtremeRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterExtremeRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
// QUESTION STATISTICS // QUESTION STATISTICS
labQuestion->setText (tr("Frage %1").arg(m_pQuestion->id())); labQuestion->setText (tr("Frage %1").arg(m_pQuestion->id()));
labQuestionLevelIcon->setPixmap(m_pQuestion->levelPixmap()); labQuestionLevelIcon->setPixmap(m_pQuestion->levelPixmap());
labQuestionLevelText->setText(m_pQuestion->levelText()); labQuestionLevelText->setText(m_pQuestion->levelText());
if (m_pQuestion->clickedCorrectSuccessive() != 0) if (m_pQuestion->clickedCorrectSuccessive() != 0)
labQuestionSuccessive->setText(tr("%1x richtig").arg(m_pQuestion->clickedCorrectSuccessive())); labQuestionSuccessive->setText(tr("%1x richtig").arg(m_pQuestion->clickedCorrectSuccessive()));
else if (m_pQuestion->clickedWrongSuccessive() != 0) else if (m_pQuestion->clickedWrongSuccessive() != 0)
labQuestionSuccessive->setText(tr("%1x falsch").arg(m_pQuestion->clickedWrongSuccessive())); labQuestionSuccessive->setText(tr("%1x falsch").arg(m_pQuestion->clickedWrongSuccessive()));
else else
labQuestionSuccessive->setText(tr("--")); labQuestionSuccessive->setText(tr("--"));
labQuestionCount->setText(QString("%1").arg(m_pQuestion->clickedCount())); labQuestionCount->setText(QString("%1").arg(m_pQuestion->clickedCount()));
labQuestionCorrect->setText(QString("%1").arg(m_pQuestion->clickedCorrect())); labQuestionCorrect->setText(QString("%1").arg(m_pQuestion->clickedCorrect()));
labQuestionWrong->setText(QString("%1").arg(m_pQuestion->clickedWrong())); labQuestionWrong->setText(QString("%1").arg(m_pQuestion->clickedWrong()));
QDateTime dtLastClicked = m_pQuestion->lastClicked(); QDateTime dtLastClicked = m_pQuestion->lastClicked();
if (!dtLastClicked.isValid()) if (!dtLastClicked.isValid())
labQuestionDate->setText("--"); labQuestionDate->setText("--");
else else
{ {
labQuestionDate->setText(m_pQuestion->lastClickedText()); labQuestionDate->setText(m_pQuestion->lastClickedText());
} }
onUpdateDS(); onUpdateDS();
} }
void CDlgLearn::updateLearnAssistant() void CDlgLearn::updateLearnAssistant()
{ {
QString strRecom1, strRecom2, str; QString strRecom1, strRecom2, str;
QPixmap pixRecom1, pixRecom2, pix; QPixmap pixRecom1, pixRecom2, pix;
// first recommendation // first recommendation
strRecom1 = m_pChapter->recommendationTextExtended(m_pCatalog); strRecom1 = m_pChapter->recommendationTextExtended(m_pCatalog);
if (m_pChapter->isRecommendedNow(m_pCatalog)) if (m_pChapter->isRecommendedNow(m_pCatalog))
strRecom1 = "<font color='green'>" + strRecom1 + "</font>"; strRecom1 = "<font color='green'>" + strRecom1 + "</font>";
else else
strRecom1 = "<font color='red'>" + strRecom1 + "</font>"; strRecom1 = "<font color='red'>" + strRecom1 + "</font>";
pixRecom1 = QPixmap (m_pChapter->recommendationIconName (m_pCatalog)); pixRecom1 = QPixmap (m_pChapter->recommendationIconName (m_pCatalog));
// second recommendation // second recommendation
strRecom2 = m_pChapter->recommendationTextExtended2(m_pCatalog); strRecom2 = m_pChapter->recommendationTextExtended2(m_pCatalog);
pixRecom2 = QPixmap (m_pChapter->recommendationIconName (m_pChapter->recommendation2(), m_pCatalog)); pixRecom2 = QPixmap (m_pChapter->recommendationIconName (m_pChapter->recommendation2(), m_pCatalog));
if (m_pChapter->recommendation() == CChapter::RecommendationSubChapter && m_pChapter->recommendation2() == CChapter::RecommendationRepeatToday) if (m_pChapter->recommendation() == CChapter::RecommendationSubChapter && m_pChapter->recommendation2() == CChapter::RecommendationRepeatToday)
{ {
labRecommendationIcon->setPixmap (pixRecom2); labRecommendationIcon->setPixmap (pixRecom2);
labRecommendation->setText("<font color='green'>" + strRecom2 + "</font>"); labRecommendation->setText("<font color='green'>" + strRecom2 + "</font>");
} }
else else
{ {
str = strRecom1; str = strRecom1;
if (!strRecom2.isEmpty()) if (!strRecom2.isEmpty())
str += "<p><font color='green'>" + strRecom2 + "</font>"; str += "<p><font color='green'>" + strRecom2 + "</font>";
labRecommendationIcon->setPixmap (pixRecom1); labRecommendationIcon->setPixmap (pixRecom1);
labRecommendation->setText(str); labRecommendation->setText(str);
} }
} }
CQuestion *CDlgLearn::findNextQuestion() CQuestion *CDlgLearn::findNextQuestion()
{ {
CQuestion *p = 0; CQuestion *p = 0;
if (m_bAssistantEnable && m_pChapter->hasRecommendedQuestions()) if (m_bAssistantEnable && m_pChapter->hasRecommendedQuestions())
{ {
// if (afu_random (0, 99) >= 0) // hier kann ggf. das Verhältnis zwischen RecommendedQuestion und Zufalls-Question ausgewählt werden // if (afu_random (0, 99) >= 0) // hier kann ggf. das Verhältnis zwischen RecommendedQuestion und Zufalls-Question ausgewählt werden
// { // {
p = findNextTargetQuestion(); p = findNextTargetQuestion();
// Wichtig: p kann hier immernoch 0 sein! Dies bedeutet, dass keine passende Frage im TargetPool gefunden wurde. // Wichtig: p kann hier immernoch 0 sein! Dies bedeutet, dass keine passende Frage im TargetPool gefunden wurde.
// } // }
} }
if (p == 0) if (p == 0)
p = findNextPoolQuestion(); p = findNextPoolQuestion();
return p; return p;
} }
CQuestion *CDlgLearn::findNextTargetQuestion() CQuestion *CDlgLearn::findNextTargetQuestion()
{ {
CQuestion *pQuestion=0; CQuestion *pQuestion=0;
QList<CQuestion*> list = m_pChapter->recommendedQuestions(); QList<CQuestion*> list = m_pChapter->recommendedQuestions();
int iSize = list.size(); int iSize = list.size();
unsigned uRnd=0; unsigned uRnd=0;
if (iSize == 0) return 0; if (iSize == 0) return 0;
if (iSize == 1) if (iSize == 1)
{ {
if (list.at(0) == m_pQuestion) if (list.at(0) == m_pQuestion)
// Regel: Niemals die gleiche Frage mehrfach hintereinander // Regel: Niemals die gleiche Frage mehrfach hintereinander
// -> kann hier nicht erfüllt werden -> 0 zurückgeben -> hole Frage aus allg. Pool (siehe findNextQuestion) // -> kann hier nicht erfüllt werden -> 0 zurückgeben -> hole Frage aus allg. Pool (siehe findNextQuestion)
return 0; return 0;
else else
return list.at(0); return list.at(0);
} }
do do
{ {
uRnd = afu_random (0, iSize-1); uRnd = afu_random (0, iSize-1);
pQuestion = list.at(uRnd); pQuestion = list.at(uRnd);
} }
while (m_pQuestion == pQuestion); while (m_pQuestion == pQuestion);
return pQuestion; return pQuestion;
} }
CQuestion *CDlgLearn::findNextPoolQuestion() CQuestion *CDlgLearn::findNextPoolQuestion()
{ {
CQuestion *pQuestion=0; CQuestion *pQuestion=0;
unsigned uCountQuestion[LEVEL_MAX+1]; unsigned uCountQuestion[LEVEL_MAX+1];
unsigned uRnd=0, uLevel=0; unsigned uRnd=0, uLevel=0;
int i=0; int i=0;
unsigned uGewichtung[LEVEL_MAX+1], uEdge[LEVEL_MAX+1]; unsigned uGewichtung[LEVEL_MAX+1], uEdge[LEVEL_MAX+1];
unsigned uRndMax = 0; unsigned uRndMax = 0;
memset (uCountQuestion, 0, sizeof(unsigned)*(LEVEL_MAX+1)); memset (uCountQuestion, 0, sizeof(unsigned)*(LEVEL_MAX+1));
for (i=0;i<m_listQuestion.size(); i++) for (i=0;i<m_listQuestion.size(); i++)
{ {
uLevel = m_listQuestion[i]->level(); uLevel = m_listQuestion[i]->level();
Q_ASSERT(uLevel < LEVEL_MAX+1); Q_ASSERT(uLevel < LEVEL_MAX+1);
if (uLevel > LEVEL_MAX) continue; if (uLevel > LEVEL_MAX) continue;
uCountQuestion[uLevel]++; uCountQuestion[uLevel]++;
} }
uGewichtung[LEVEL_MAX] = 1; uGewichtung[LEVEL_MAX] = 1;
uRndMax = 1; uRndMax = 1;
for (i=LEVEL_MAX-1; i>=0; i--) for (i=LEVEL_MAX-1; i>=0; i--)
{ {
uRndMax += uGewichtung[i+1]; uRndMax += uGewichtung[i+1];
uGewichtung[i] = uRndMax; uGewichtung[i] = uRndMax;
} }
for (i=0; i<=LEVEL_MAX; i++) for (i=0; i<=LEVEL_MAX; i++)
uGewichtung[i] *= uCountQuestion[i]; uGewichtung[i] *= uCountQuestion[i];
uRndMax=0; uRndMax=0;
for (i=0; i<=LEVEL_MAX; i++) for (i=0; i<=LEVEL_MAX; i++)
{ {
uLevel = LEVEL_MAX-i; uLevel = LEVEL_MAX-i;
uRndMax += uGewichtung[uLevel]; uRndMax += uGewichtung[uLevel];
uEdge[uLevel] = uRndMax; uEdge[uLevel] = uRndMax;
} }
do /* diese Schleife verhindert, dass eine Frage zweimal hintereinander kommt */ do /* diese Schleife verhindert, dass eine Frage zweimal hintereinander kommt */
{ {
do /* diese Schleife wählt die Abfragehäufigkeit aus */ do /* diese Schleife wählt die Abfragehäufigkeit aus */
{ {
uRnd = afu_random (1, uRndMax); uRnd = afu_random (1, uRndMax);
uLevel = LEVEL_MAX; uLevel = LEVEL_MAX;
while (uLevel != LEVEL_VERYOFTEN && uRnd > uEdge[uLevel]) while (uLevel != LEVEL_VERYOFTEN && uRnd > uEdge[uLevel])
uLevel--; uLevel--;
Q_ASSERT(uCountQuestion[uLevel] != 0); // Wenn hier assertion failed => algorithmus falsch Q_ASSERT(uCountQuestion[uLevel] != 0); // Wenn hier assertion failed => algorithmus falsch
} }
while (uCountQuestion[uLevel] == 0); while (uCountQuestion[uLevel] == 0);
// Zufällige Frage bestimmen // Zufällige Frage bestimmen
uRnd = afu_random (1, uCountQuestion[uLevel]); uRnd = afu_random (1, uCountQuestion[uLevel]);
for (i=0; i<m_listQuestion.size()-1; i++) for (i=0; i<m_listQuestion.size()-1; i++)
if (m_listQuestion[i]->level() == uLevel && --uRnd == 0) break; if (m_listQuestion[i]->level() == uLevel && --uRnd == 0) break;
} }
while (m_pQuestion == m_listQuestion[i] && m_listQuestion.size() > 1); while (m_pQuestion == m_listQuestion[i] && m_listQuestion.size() > 1);
pQuestion = m_listQuestion[i]; pQuestion = m_listQuestion[i];
return pQuestion; return pQuestion;
} }
void CDlgLearn::nextQuestion() void CDlgLearn::nextQuestion()
{ {
QString str, strCheat; QString str, strCheat;
if (m_listQuestion.size() == 0) if (m_listQuestion.size() == 0)
{ {
QMessageBox::critical (this, "Fehler", "Es gibt keine Fragen, die gelernt werden könnten!"); QMessageBox::critical (this, "Fehler", "Es gibt keine Fragen, die gelernt werden könnten!");
accept(); accept();
return; return;
} }
if (m_pQuestion) if (m_pQuestion)
{ // Save current question as new last question { // Save current question as new last question
pbLastQuestion->setEnabled(true); pbLastQuestion->setEnabled(true);
m_pLastQuestion = m_pQuestion; m_pLastQuestion = m_pQuestion;
} }
m_pQuestion = findNextQuestion(); m_pQuestion = findNextQuestion();
// show answer // show answer
m_pQuestion->mixAnswers(); m_pQuestion->mixAnswers();
str = m_pQuestion->learnText(m_pCatalog, true, false); str = m_pQuestion->learnText(m_pCatalog, true, false);
if (m_bCheatEnable) if (m_bCheatEnable)
{ {
strCheat = "<p><font size=-1><i><b>Schummel-Modus</b><br>Richtige Antwort: " + CAnswerClicked::answerText (m_pQuestion->correctAnswerMask()) + "</i>"; strCheat = "<p><font size=-1><i><b>Schummel-Modus</b><br>Richtige Antwort: " + CAnswerClicked::answerText (m_pQuestion->correctAnswerMask()) + "</i>";
strCheat += "<br>Empfohlene Wiederholung: " + m_pQuestion->repeatDateText(); strCheat += "<br>Empfohlene Wiederholung: " + m_pQuestion->repeatDateText();
strCheat += QString("<br>isLearningNew(): %1").arg(m_pQuestion->isLearningNew()); strCheat += QString("<br>isLearningNew(): %1").arg(m_pQuestion->isLearningNew());
strCheat += "</font><p>"; strCheat += "</font><p>";
} }
teQuestion->setHtml(strCheat + str); teQuestion->setHtml(strCheat + str);
pbShowHelper->setEnabled (m_pCatalog->hasHints(m_pQuestion->id())); pbShowHelper->setEnabled (m_pCatalog->hasHints(m_pQuestion->id()));
m_bHintsUsed = false; m_bHintsUsed = false;
m_timeElapsed.restart(); m_timeElapsed.restart();
updateStatistic(); updateStatistic();
updateLearnAssistant(); updateLearnAssistant();
} }
void CDlgLearn::on_pbAnswerA_clicked() void CDlgLearn::on_pbAnswerA_clicked()
{ {
handleAnswer(0); handleAnswer(0);
} }
void CDlgLearn::on_pbAnswerB_clicked() void CDlgLearn::on_pbAnswerB_clicked()
{ {
handleAnswer(1); handleAnswer(1);
} }
void CDlgLearn::on_pbAnswerC_clicked() void CDlgLearn::on_pbAnswerC_clicked()
{ {
handleAnswer(2); handleAnswer(2);
} }
void CDlgLearn::on_pbAnswerD_clicked() void CDlgLearn::on_pbAnswerD_clicked()
{ {
handleAnswer(3); handleAnswer(3);
} }
void CDlgLearn::handleAnswer(const int i) void CDlgLearn::handleAnswer(const int i)
{ {
unsigned uAnswerMask = 1<<i; unsigned uAnswerMask = 1<<i;
if (!m_pQuestion->isCorrectAnswer(uAnswerMask)) if (!m_pQuestion->isCorrectAnswer(uAnswerMask))
{ {
QMessageBox::information(this, tr("Hinweis"), m_pQuestion->correctionText(uAnswerMask)); QMessageBox::information(this, tr("Hinweis"), m_pQuestion->correctionText(uAnswerMask));
} }
m_uLastAnswerMask=uAnswerMask; m_uLastAnswerMask=uAnswerMask;
if (!m_bHintsUsed) if (!m_bHintsUsed)
{ {
m_pQuestion->registerAnswerClicked(uAnswerMask, m_timeElapsed.elapsed() + m_uElapsedBeforeBreak); m_pQuestion->registerAnswerClicked(uAnswerMask, m_timeElapsed.elapsed() + m_uElapsedBeforeBreak);
bool bIsRecommendedOld = m_pChapter->isRecommendedNow(m_pCatalog) ; bool bIsRecommendedOld = m_pChapter->isRecommendedNow(m_pCatalog) ;
m_pCatalog->updateStatistic(); m_pCatalog->updateStatistic();
m_ds = m_pCatalog->dayStatistic(QDate::currentDate()); m_ds = m_pCatalog->dayStatistic(QDate::currentDate());
if (bIsRecommendedOld && !m_pChapter->isRecommendedNow(m_pCatalog)) if (bIsRecommendedOld && !m_pChapter->isRecommendedNow(m_pCatalog))
{ {
QMessageBox msgBox(this); QMessageBox msgBox(this);
QPushButton *pbAssistant = msgBox.addButton(tr("Assistent"), QMessageBox::AcceptRole); QPushButton *pbAssistant = msgBox.addButton(tr("Assistent"), QMessageBox::AcceptRole);
QPushButton *pbIgnore = msgBox.addButton(QMessageBox::Ignore); QPushButton *pbIgnore = msgBox.addButton(QMessageBox::Ignore);
QPushButton *pbExit = msgBox.addButton(QMessageBox::Cancel); QPushButton *pbExit = msgBox.addButton(QMessageBox::Cancel);
pbAssistant->setIcon(QIcon(":/icons/16x16/idea_info.png")); pbAssistant->setIcon(QIcon(":/icons/16x16/idea_info.png"));
pbAssistant->setToolTip(tr("Lern-Assistent aufrufen")); pbAssistant->setToolTip(tr("Lern-Assistent aufrufen"));
pbIgnore->setToolTip(tr("Meldung ignorieren, dieses Kapitel weiterlernen")); pbIgnore->setToolTip(tr("Meldung ignorieren, dieses Kapitel weiterlernen"));
pbExit->setToolTip(tr("Lernmodus beenden")); pbExit->setToolTip(tr("Lernmodus beenden"));
msgBox.setText(tr("<b>Herzlichen Glückwunsch!</b><p>Sie haben das heutige Lernziel für dieses Kapitel erreicht.<br>Bitte folgen Sie den weiteren Empfehlungen des Lernassistents.")); msgBox.setText(tr("<b>Herzlichen Glückwunsch!</b><p>Sie haben das heutige Lernziel für dieses Kapitel erreicht.<br>Bitte folgen Sie den weiteren Empfehlungen des Lernassistents."));
msgBox.setWindowTitle(tr("Ziel erreicht")); msgBox.setWindowTitle(tr("Ziel erreicht"));
msgBox.exec(); msgBox.exec();
if (msgBox.clickedButton() == pbExit) if (msgBox.clickedButton() == pbExit)
{ {
reject(); reject();
return; return;
} }
else if (msgBox.clickedButton() == pbAssistant) else if (msgBox.clickedButton() == pbAssistant)
{ {
on_pbLearnAssistant_clicked(); on_pbLearnAssistant_clicked();
return; return;
} }
} }
} }
nextQuestion(); nextQuestion();
} }
void CDlgLearn::on_pbShowHelper_clicked() void CDlgLearn::on_pbShowHelper_clicked()
{ {
m_bHintsUsed = true; m_bHintsUsed = true;
QString str = m_pQuestion->learnText(m_pCatalog, true, true); QString str = m_pQuestion->learnText(m_pCatalog, true, true);
teQuestion->setHtml(str); teQuestion->setHtml(str);
} }
void CDlgLearn::on_pbLastQuestion_clicked() void CDlgLearn::on_pbLastQuestion_clicked()
{ {
CDlgViewQuestion dlg(this); CDlgViewQuestion dlg(this);
dlg.go(m_pCatalog, m_pLastQuestion, m_uLastAnswerMask); dlg.go(m_pCatalog, m_pLastQuestion, m_uLastAnswerMask);
} }
void CDlgLearn::on_pbSkip_clicked() void CDlgLearn::on_pbSkip_clicked()
{ {
m_uLastAnswerMask=0; m_uLastAnswerMask=0;
nextQuestion(); nextQuestion();
} }
void CDlgLearn::on_pbQuit_clicked() void CDlgLearn::on_pbQuit_clicked()
{ {
m_pCatalog->updateStatistic(); m_pCatalog->updateStatistic();
accept(); accept();
} }
void CDlgLearn::on_pbLearnAssistant_clicked() void CDlgLearn::on_pbLearnAssistant_clicked()
{ {
CDlgLearnAssistant dlg(this); CDlgLearnAssistant dlg(this);
CChapter *pChapter=0; CChapter *pChapter=0;
if (!dlg.setup(m_pCatalog)) if (!dlg.setup(m_pCatalog))
{ {
QMessageBox::information(this, tr("Information"), tr("Derzeit gibt es keine Empfehlung des Lernassistentes.")); QMessageBox::information(this, tr("Information"), tr("Derzeit gibt es keine Empfehlung des Lernassistentes."));
return; return;
} }
if (dlg.exec() != QDialog::Accepted) return; if (dlg.exec() != QDialog::Accepted) return;
pChapter = dlg.selectedChapter(); pChapter = dlg.selectedChapter();
if (pChapter == 0) return; if (pChapter == 0) return;
setNewChapter(pChapter); setNewChapter(pChapter);
} }
void CDlgLearn::onUpdateDS() void CDlgLearn::onUpdateDS()
{ {
labDSTime->setText(QString("%1 h %2 m").arg(m_ds.timeExpediture()/1000/3600).arg(m_ds.timeExpediture()/1000/60 % 60, 2, 10, QChar('0'))); labDSTime->setText(QString("%1 h %2 m").arg(m_ds.timeExpediture()/1000/3600).arg(m_ds.timeExpediture()/1000/60 % 60, 2, 10, QChar('0')));
labDSCount->setText(QString::number(m_ds.clickedCount())); labDSCount->setText(QString::number(m_ds.clickedCount()));
labDSCorrect->setText(QString::number(m_ds.clickedCorrect())); labDSCorrect->setText(QString::number(m_ds.clickedCorrect()));
labDSWrong->setText(QString::number(m_ds.clickedWrong())); labDSWrong->setText(QString::number(m_ds.clickedWrong()));
} }

View File

@ -1,84 +1,84 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DLGLEARN_H #ifndef DLGLEARN_H
#define DLGLEARN_H #define DLGLEARN_H
#include <qdialog.h> #include <qdialog.h>
#include <qlist.h> #include <qlist.h>
#include <qdatetime.h> #include <qdatetime.h>
#include "question.h" #include "question.h"
#include "ui_dlglearn.h" #include "ui_dlglearn.h"
class CChapter; class CChapter;
class CCatalog; class CCatalog;
class CDlgLearn : public QDialog, Ui::DlgLearn class CDlgLearn : public QDialog, Ui::DlgLearn
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgLearn (QWidget *pParent=0); CDlgLearn (QWidget *pParent=0);
~CDlgLearn(); ~CDlgLearn();
void go (CCatalog *pCatalog, CChapter *pChapter); void go (CCatalog *pCatalog, CChapter *pChapter);
protected: protected:
void setNewChapter(CChapter *pChapter); void setNewChapter(CChapter *pChapter);
void updateStatistic(); void updateStatistic();
void updateLearnAssistant(); void updateLearnAssistant();
void nextQuestion(); void nextQuestion();
CQuestion *findNextQuestion(); CQuestion *findNextQuestion();
CQuestion *findNextPoolQuestion(); CQuestion *findNextPoolQuestion();
CQuestion *findNextTargetQuestion(); CQuestion *findNextTargetQuestion();
void handleAnswer(const int i); void handleAnswer(const int i);
protected slots: protected slots:
void on_pbAnswerA_clicked(); void on_pbAnswerA_clicked();
void on_pbAnswerB_clicked(); void on_pbAnswerB_clicked();
void on_pbAnswerC_clicked(); void on_pbAnswerC_clicked();
void on_pbAnswerD_clicked(); void on_pbAnswerD_clicked();
void on_pbShowHelper_clicked(); void on_pbShowHelper_clicked();
void on_pbSkip_clicked(); void on_pbSkip_clicked();
void on_pbLastQuestion_clicked(); void on_pbLastQuestion_clicked();
void on_pbQuit_clicked(); void on_pbQuit_clicked();
void on_pbLearnAssistant_clicked(); void on_pbLearnAssistant_clicked();
void onUpdateDS(); void onUpdateDS();
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
CChapter *m_pChapter; CChapter *m_pChapter;
QList<CQuestion*> m_listQuestion; QList<CQuestion*> m_listQuestion;
CQuestion *m_pQuestion; CQuestion *m_pQuestion;
CQuestion *m_pLastQuestion; CQuestion *m_pLastQuestion;
unsigned m_uLastAnswerMask; unsigned m_uLastAnswerMask;
bool m_bHintsUsed; bool m_bHintsUsed;
QTime m_timeElapsed; QTime m_timeElapsed;
unsigned m_uElapsedBeforeBreak; // if the user makes a break unsigned m_uElapsedBeforeBreak; // if the user makes a break
bool m_bMsgBoxTargetReachedShowed; bool m_bMsgBoxTargetReachedShowed;
CDayStatistic m_ds; CDayStatistic m_ds;
bool m_bAssistantEnable; bool m_bAssistantEnable;
bool m_bCheatEnable; bool m_bCheatEnable;
}; };
#endif #endif

View File

@ -1,117 +1,117 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlglearnassistant.h" #include "dlglearnassistant.h"
#include <qheaderview.h> #include <qheaderview.h>
#include <qmessagebox.h> #include <qmessagebox.h>
#include "catalog.h" #include "catalog.h"
CDlgLearnAssistant::CDlgLearnAssistant (QWidget *pParent) : QDialog(pParent) CDlgLearnAssistant::CDlgLearnAssistant (QWidget *pParent) : QDialog(pParent)
{ {
m_pCatalog=0; m_pCatalog=0;
setupUi(this); setupUi(this);
tvChapters->setModel (&m_modelChapter); tvChapters->setModel (&m_modelChapter);
tvChapters->header()->setStretchLastSection(false); tvChapters->header()->setStretchLastSection(false);
tvChapters->header()->setResizeMode (0, QHeaderView::Stretch); tvChapters->header()->setResizeMode (0, QHeaderView::Stretch);
tvChapters->header()->setResizeMode (1, QHeaderView::Interactive); tvChapters->header()->setResizeMode (1, QHeaderView::Interactive);
tvChapters->header()->setResizeMode (3, QHeaderView::Interactive); tvChapters->header()->setResizeMode (3, QHeaderView::Interactive);
tvChapters->header()->resizeSection(1, 50); tvChapters->header()->resizeSection(1, 50);
tvChapters->header()->resizeSection(2, 140); tvChapters->header()->resizeSection(2, 140);
tvChapters->header()->resizeSection(3, 20); tvChapters->header()->resizeSection(3, 20);
} }
bool CDlgLearnAssistant::setup(CCatalog *pCatalog) bool CDlgLearnAssistant::setup(CCatalog *pCatalog)
{ {
bool bEnableRepeat; bool bEnableRepeat;
QList<CChapter*> listAll, listNow, listToday, listSelected; QList<CChapter*> listAll, listNow, listToday, listSelected;
CChapter *c; CChapter *c;
m_pCatalog = pCatalog; m_pCatalog = pCatalog;
if (pCatalog->recommendationCount (CChapter::RecommendationRepeatToday) > 0) if (pCatalog->recommendationCount (CChapter::RecommendationRepeatToday) > 0)
{ {
bEnableRepeat = true; bEnableRepeat = true;
labRepeat->setText(tr("Es sind %1 Fragen vorhanden").arg(pCatalog->recommendedQuestions().count())); labRepeat->setText(tr("Es sind %1 Fragen vorhanden").arg(pCatalog->recommendedQuestions().count()));
rbRepeat->setChecked(true); rbRepeat->setChecked(true);
} }
else else
{ {
bEnableRepeat = false; bEnableRepeat = false;
labRepeat->setText(tr("Keine Fragen vorhanden.")); labRepeat->setText(tr("Keine Fragen vorhanden."));
rbList->setChecked(true); rbList->setChecked(true);
} }
rbRepeat->setEnabled(bEnableRepeat); rbRepeat->setEnabled(bEnableRepeat);
labRepeat->setEnabled(bEnableRepeat); labRepeat->setEnabled(bEnableRepeat);
// update list // update list
listAll = pCatalog->chapters(); listAll = pCatalog->chapters();
for (int i=0; i<listAll.size(); i++) for (int i=0; i<listAll.size(); i++)
{ {
c = listAll.at(i); c = listAll.at(i);
if (c->isRecommendedNow(pCatalog)) if (c->isRecommendedNow(pCatalog))
listNow << c; listNow << c;
else if (c->recommendation() == CChapter::RecommendationLearnNew) else if (c->recommendation() == CChapter::RecommendationLearnNew)
listToday << c; listToday << c;
} }
listSelected << listNow << listToday; listSelected << listNow << listToday;
m_modelChapter.setModelData (pCatalog, listSelected); m_modelChapter.setModelData (pCatalog, listSelected);
if (!bEnableRepeat && listSelected.isEmpty()) return false; if (!bEnableRepeat && listSelected.isEmpty()) return false;
updateEnable(); updateEnable();
return true; return true;
} }
void CDlgLearnAssistant::updateEnable() void CDlgLearnAssistant::updateEnable()
{ {
labRepeat->setEnabled(rbRepeat->isChecked()); labRepeat->setEnabled(rbRepeat->isChecked());
tvChapters->setEnabled(rbList->isChecked()); tvChapters->setEnabled(rbList->isChecked());
} }
void CDlgLearnAssistant::on_buttonBox_accepted() void CDlgLearnAssistant::on_buttonBox_accepted()
{ {
QModelIndexList list = tvChapters->selectionModel()->selectedIndexes(); QModelIndexList list = tvChapters->selectionModel()->selectedIndexes();
if (rbList->isChecked() && list.isEmpty()) if (rbList->isChecked() && list.isEmpty())
{ {
QMessageBox::information(this, tr("Information"), tr("Bitte markieren Sie in der Liste ein Kapitel, das Sie lernen möchten!")); QMessageBox::information(this, tr("Information"), tr("Bitte markieren Sie in der Liste ein Kapitel, das Sie lernen möchten!"));
return; return;
} }
accept(); accept();
} }
CChapter* CDlgLearnAssistant::selectedChapter() CChapter* CDlgLearnAssistant::selectedChapter()
{ {
QModelIndexList list = tvChapters->selectionModel()->selectedIndexes(); QModelIndexList list = tvChapters->selectionModel()->selectedIndexes();
if (rbRepeat->isChecked()) if (rbRepeat->isChecked())
return m_pCatalog; return m_pCatalog;
if (rbList->isChecked()) if (rbList->isChecked())
{ {
if (list.isEmpty()) return 0; if (list.isEmpty()) return 0;
return (CChapter*)list.first().internalPointer(); return (CChapter*)list.first().internalPointer();
} }
return 0; return 0;
} }

View File

@ -1,56 +1,56 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DLGLEARNASSISTANT_H #ifndef DLGLEARNASSISTANT_H
#define DLGLEARNASSISTANT_H #define DLGLEARNASSISTANT_H
#include <qdialog.h> #include <qdialog.h>
#include "ui_dlglearnassistant.h" #include "ui_dlglearnassistant.h"
#include "chaptermodel.h" #include "chaptermodel.h"
class CDlgLearnAssistant : public QDialog, Ui::DlgLearnAssistant class CDlgLearnAssistant : public QDialog, Ui::DlgLearnAssistant
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgLearnAssistant (QWidget *pParent=0); CDlgLearnAssistant (QWidget *pParent=0);
~CDlgLearnAssistant () {} ~CDlgLearnAssistant () {}
bool setup(CCatalog *pCatalog); bool setup(CCatalog *pCatalog);
CChapter* selectedChapter(); CChapter* selectedChapter();
protected slots: protected slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
inline void on_rbList_toggled() { updateEnable(); } inline void on_rbList_toggled() { updateEnable(); }
inline void on_rbRepeat_toggled() { updateEnable(); } inline void on_rbRepeat_toggled() { updateEnable(); }
protected: protected:
void updateEnable(); void updateEnable();
protected: protected:
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
CChapterModel m_modelChapter; CChapterModel m_modelChapter;
// CRecommendation m_recomDeepen; // CRecommendation m_recomDeepen;
// CRecommendation m_recomRepeat; // CRecommendation m_recomRepeat;
}; };
#endif #endif

View File

@ -1,417 +1,417 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlglearnstatistic.h" #include "dlglearnstatistic.h"
#include "chapter.h" #include "chapter.h"
#include "tools.h" #include "tools.h"
#include "plotwidget.h" #include "plotwidget.h"
#include <qdatetime.h> #include <qdatetime.h>
CDlgLearnStatistic::CDlgLearnStatistic(QWidget *pParent) : QDialog(pParent) CDlgLearnStatistic::CDlgLearnStatistic(QWidget *pParent) : QDialog(pParent)
{ {
m_pChapter = 0; m_pChapter = 0;
setupUi(this); setupUi(this);
cbPeriod->addItem(tr("2 Wochen"), 14); cbPeriod->addItem(tr("2 Wochen"), 14);
cbPeriod->addItem(tr("1 Monat"), 30); cbPeriod->addItem(tr("1 Monat"), 30);
cbPeriod->addItem(tr("3 Monate"), 90); cbPeriod->addItem(tr("3 Monate"), 90);
cbPeriod->addItem(tr("6 Monate"), 30*6); cbPeriod->addItem(tr("6 Monate"), 30*6);
cbPeriod->addItem(tr("1 Jahr"), 365); cbPeriod->addItem(tr("1 Jahr"), 365);
cbPeriod->setCurrentIndex(0); cbPeriod->setCurrentIndex(0);
m_pPlotLevel = new CPlotWidget(groupLevel); m_pPlotLevel = new CPlotWidget(groupLevel);
m_pPlotLevel->setFrameShape(QFrame::Panel); m_pPlotLevel->setFrameShape(QFrame::Panel);
m_pPlotLevel->setFrameShadow(QFrame::Sunken); m_pPlotLevel->setFrameShadow(QFrame::Sunken);
groupLevel->layout()->addWidget(m_pPlotLevel); groupLevel->layout()->addWidget(m_pPlotLevel);
m_pPlotLevel->setBorderDistance(25, 5, 5, 25); m_pPlotLevel->setBorderDistance(25, 5, 5, 25);
m_pPlotLevel->setLimitY(0.0, 5.5); m_pPlotLevel->setLimitY(0.0, 5.5);
m_pPlotLevel->setBorderPen(QPen(Qt::black)); m_pPlotLevel->setBorderPen(QPen(Qt::black));
m_pPlotLevel->setBorder(CPlotWidget::BorderLeft | CPlotWidget::BorderBottom); m_pPlotLevel->setBorder(CPlotWidget::BorderLeft | CPlotWidget::BorderBottom);
m_pPlotLevel->setTicY(1.0); m_pPlotLevel->setTicY(1.0);
QList<CPlotWidgetTic> listTics; QList<CPlotWidgetTic> listTics;
for (int i=0; i<=LEVEL_MAX; i++) for (int i=0; i<=LEVEL_MAX; i++)
{ {
CPlotWidgetTic tic (i, QPixmap(CQuestion::levelIconName(i))); CPlotWidgetTic tic (i, QPixmap(CQuestion::levelIconName(i)));
listTics.append(tic); listTics.append(tic);
} }
m_pPlotLevel->setTicListY(listTics); m_pPlotLevel->setTicListY(listTics);
m_pPlotClicked = new CPlotWidget(groupClicked); m_pPlotClicked = new CPlotWidget(groupClicked);
m_pPlotClicked->setFrameShape(QFrame::Panel); m_pPlotClicked->setFrameShape(QFrame::Panel);
m_pPlotClicked->setFrameShadow(QFrame::Sunken); m_pPlotClicked->setFrameShadow(QFrame::Sunken);
groupClicked->layout()->addWidget(m_pPlotClicked); groupClicked->layout()->addWidget(m_pPlotClicked);
m_pPlotClicked->setType(CPlotWidget::PlotBarsSum); m_pPlotClicked->setType(CPlotWidget::PlotBarsSum);
m_pPlotClicked->setBarOffset(-0.5); m_pPlotClicked->setBarOffset(-0.5);
m_pPlotClicked->setBorderDistance(25, 5, 5, 25); m_pPlotClicked->setBorderDistance(25, 5, 5, 25);
// Zeitaufwand // Zeitaufwand
cbPeriod2->addItem(tr("2 Wochen"), 14); cbPeriod2->addItem(tr("2 Wochen"), 14);
cbPeriod2->addItem(tr("1 Monat"), 30); cbPeriod2->addItem(tr("1 Monat"), 30);
cbPeriod2->addItem(tr("3 Monate"), 90); cbPeriod2->addItem(tr("3 Monate"), 90);
cbPeriod2->addItem(tr("6 Monate"), 30*6); cbPeriod2->addItem(tr("6 Monate"), 30*6);
cbPeriod2->addItem(tr("1 Jahr"), 365); cbPeriod2->addItem(tr("1 Jahr"), 365);
cbPeriod2->setCurrentIndex(0); cbPeriod2->setCurrentIndex(0);
m_pPlotTime = new CPlotWidget(groupTimeExpediture); m_pPlotTime = new CPlotWidget(groupTimeExpediture);
m_pPlotTime->setFrameShape(QFrame::Panel); m_pPlotTime->setFrameShape(QFrame::Panel);
m_pPlotTime->setFrameShadow(QFrame::Sunken); m_pPlotTime->setFrameShadow(QFrame::Sunken);
groupTimeExpediture->layout()->addWidget(m_pPlotTime); groupTimeExpediture->layout()->addWidget(m_pPlotTime);
m_pPlotTime->setType(CPlotWidget::PlotBarsSum); m_pPlotTime->setType(CPlotWidget::PlotBarsSum);
m_pPlotTime->setBarOffset(-0.5); m_pPlotTime->setBarOffset(-0.5);
m_pPlotTime->setBorderDistance(25, 5, 5, 25); m_pPlotTime->setBorderDistance(25, 5, 5, 25);
/* /*
m_pPlotTimePerQuestion = new CPlotWidget(groupTimeExpediturePerQuestion); m_pPlotTimePerQuestion = new CPlotWidget(groupTimeExpediturePerQuestion);
m_pPlotTimePerQuestion->setFrameShape(QFrame::Panel); m_pPlotTimePerQuestion->setFrameShape(QFrame::Panel);
m_pPlotTimePerQuestion->setFrameShadow(QFrame::Sunken); m_pPlotTimePerQuestion->setFrameShadow(QFrame::Sunken);
groupTimeExpediturePerQuestion->layout()->addWidget(m_pPlotTimePerQuestion); groupTimeExpediturePerQuestion->layout()->addWidget(m_pPlotTimePerQuestion);
m_pPlotTimePerQuestion->setType(CPlotWidget::PlotLines); m_pPlotTimePerQuestion->setType(CPlotWidget::PlotLines);
m_pPlotTimePerQuestion->setBorderDistance(25, 5, 5, 25); m_pPlotTimePerQuestion->setBorderDistance(25, 5, 5, 25);
*/ */
} }
void CDlgLearnStatistic::go(CChapter *pChapter) void CDlgLearnStatistic::go(CChapter *pChapter)
{ {
m_pChapter = pChapter; m_pChapter = pChapter;
updateTable(); updateTable();
updateHistory(); updateHistory();
updateTimeExpediture(); updateTimeExpediture();
exec(); exec();
} }
void CDlgLearnStatistic::updateTable() void CDlgLearnStatistic::updateTable()
{ {
const int w=60, h=16; const int w=60, h=16;
QList<CQuestion*> listQuestion = m_pChapter->questionPool(); QList<CQuestion*> listQuestion = m_pChapter->questionPool();
CDayStatistic ds; CDayStatistic ds;
// CHAPTER STATISTICS // CHAPTER STATISTICS
labChapter->setText (m_pChapter->text()); labChapter->setText (m_pChapter->text());
labChapterCount->setText(QString("%1").arg(listQuestion.size())); labChapterCount->setText(QString("%1").arg(listQuestion.size()));
labChapterVeryOften->setText(QString("%1").arg(m_pChapter->countQuestion(0))); labChapterVeryOften->setText(QString("%1").arg(m_pChapter->countQuestion(0)));
labChapterOften->setText(QString("%1").arg(m_pChapter->countQuestion(1))); labChapterOften->setText(QString("%1").arg(m_pChapter->countQuestion(1)));
labChapterNormal->setText(QString("%1").arg(m_pChapter->countQuestion(2))); labChapterNormal->setText(QString("%1").arg(m_pChapter->countQuestion(2)));
labChapterRare->setText(QString("%1").arg(m_pChapter->countQuestion(3))); labChapterRare->setText(QString("%1").arg(m_pChapter->countQuestion(3)));
labChapterVeryRare->setText(QString("%1").arg(m_pChapter->countQuestion(4))); labChapterVeryRare->setText(QString("%1").arg(m_pChapter->countQuestion(4)));
labChapterExtremeRare->setText(QString("%1").arg(m_pChapter->countQuestion(5))); labChapterExtremeRare->setText(QString("%1").arg(m_pChapter->countQuestion(5)));
labChapterAvgText->setText(m_pChapter->levelAvgText()); labChapterAvgText->setText(m_pChapter->levelAvgText());
labChapterAvgIcon->setPixmap(m_pChapter->levelAvgPixmap()); labChapterAvgIcon->setPixmap(m_pChapter->levelAvgPixmap());
labChapterAvgIcon->setToolTip(QString("Kennzahl: %1").arg(m_pChapter->levelAvg(), 4, 'g', 2)); labChapterAvgIcon->setToolTip(QString("Kennzahl: %1").arg(m_pChapter->levelAvg(), 4, 'g', 2));
double dQuestionCount = listQuestion.size(), dPercent=0.0; double dQuestionCount = listQuestion.size(), dPercent=0.0;
dPercent = (double)m_pChapter->countQuestion(0)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(0)/dQuestionCount;
labChapterVeryOftenBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterVeryOftenBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterVeryOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterVeryOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(1)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(1)/dQuestionCount;
labChapterOftenBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterOftenBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterOftenBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(2)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(2)/dQuestionCount;
labChapterNormalBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterNormalBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterNormalBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterNormalBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(3)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(3)/dQuestionCount;
labChapterRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(4)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(4)/dQuestionCount;
labChapterVeryRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterVeryRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterVeryRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterVeryRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
dPercent = (double)m_pChapter->countQuestion(5)/dQuestionCount; dPercent = (double)m_pChapter->countQuestion(5)/dQuestionCount;
labChapterExtremeRareBar->setPixmap(createProgressBar(w, h, dPercent)); labChapterExtremeRareBar->setPixmap(createProgressBar(w, h, dPercent));
labChapterExtremeRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1)); labChapterExtremeRareBar->setToolTip(QString("%1 %").arg(dPercent * 100, 0, 'f', 1));
ds = m_pChapter->dayStatistic(QDate()); ds = m_pChapter->dayStatistic(QDate());
labClickCount->setText(QString::number(ds.clickedCount())); labClickCount->setText(QString::number(ds.clickedCount()));
labClickCorrect->setText(QString::number(ds.clickedCorrect())); labClickCorrect->setText(QString::number(ds.clickedCorrect()));
labClickWrong->setText(QString::number(ds.clickedWrong())); labClickWrong->setText(QString::number(ds.clickedWrong()));
labClickCorrectP->setText(ds.clickedCount() != 0 ? QString("%1 %").arg(100.0 * ds.clickedCorrect() / ds.clickedCount(), 0, 'f', 1) : "--"); labClickCorrectP->setText(ds.clickedCount() != 0 ? QString("%1 %").arg(100.0 * ds.clickedCorrect() / ds.clickedCount(), 0, 'f', 1) : "--");
labClickWrongP->setText(ds.clickedCount() != 0 ? QString("%1 %").arg(100.0 * ds.clickedWrong() / ds.clickedCount(), 0, 'f', 1) : "--"); labClickWrongP->setText(ds.clickedCount() != 0 ? QString("%1 %").arg(100.0 * ds.clickedWrong() / ds.clickedCount(), 0, 'f', 1) : "--");
labTimeExpediture->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpediture() / 3600000).arg(ds.timeExpediture() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpediture()/1000 % 60, 2, 10, QChar('0'))); labTimeExpediture->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpediture() / 3600000).arg(ds.timeExpediture() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpediture()/1000 % 60, 2, 10, QChar('0')));
labTimeExpeditureCorrect->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpeditureCorrect() / 3600000).arg(ds.timeExpeditureCorrect() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpeditureCorrect()/1000 % 60, 2, 10, QChar('0'))); labTimeExpeditureCorrect->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpeditureCorrect() / 3600000).arg(ds.timeExpeditureCorrect() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpeditureCorrect()/1000 % 60, 2, 10, QChar('0')));
labTimeExpeditureWrong->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpeditureWrong() / 3600000).arg(ds.timeExpeditureWrong() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpeditureWrong()/1000 % 60, 2, 10, QChar('0'))); labTimeExpeditureWrong->setText(QString("%1 h %2 m %3 s").arg(ds.timeExpeditureWrong() / 3600000).arg(ds.timeExpeditureWrong() / 60000 % 60, 2, 10, QChar('0')).arg(ds.timeExpeditureWrong()/1000 % 60, 2, 10, QChar('0')));
labTimeExpeditureCorrectP->setText(ds.timeExpediture() != 0 ? QString("%1 %").arg(100.0 * ds.timeExpeditureCorrect() / ds.timeExpediture(), 0, 'f', 1) : "--"); labTimeExpeditureCorrectP->setText(ds.timeExpediture() != 0 ? QString("%1 %").arg(100.0 * ds.timeExpeditureCorrect() / ds.timeExpediture(), 0, 'f', 1) : "--");
labTimeExpeditureWrongP->setText(ds.timeExpediture() != 0 ? QString("%1 %").arg(100.0 * ds.timeExpeditureWrong() / ds.timeExpediture(), 0, 'f', 1) : "--"); labTimeExpeditureWrongP->setText(ds.timeExpediture() != 0 ? QString("%1 %").arg(100.0 * ds.timeExpeditureWrong() / ds.timeExpediture(), 0, 'f', 1) : "--");
labTimePerQuestion->setText(ds.clickedCount() != 0 ? QString("%2 m %3 s").arg(ds.timeExpediture() / ds.clickedCount() / 60000).arg(ds.timeExpediture() / 1000 / ds.clickedCount() % 60, 2, 10, QChar('0')) : "--"); labTimePerQuestion->setText(ds.clickedCount() != 0 ? QString("%2 m %3 s").arg(ds.timeExpediture() / ds.clickedCount() / 60000).arg(ds.timeExpediture() / 1000 / ds.clickedCount() % 60, 2, 10, QChar('0')) : "--");
labTimePerQuestionCorrect->setText(ds.clickedCorrect() != 0 ? QString("%2 m %3 s").arg(ds.timeExpeditureCorrect() / ds.clickedCorrect() / 60000).arg(ds.timeExpeditureCorrect() / 1000 / ds.clickedCorrect() % 60, 2, 10, QChar('0')) : "--"); labTimePerQuestionCorrect->setText(ds.clickedCorrect() != 0 ? QString("%2 m %3 s").arg(ds.timeExpeditureCorrect() / ds.clickedCorrect() / 60000).arg(ds.timeExpeditureCorrect() / 1000 / ds.clickedCorrect() % 60, 2, 10, QChar('0')) : "--");
labTimePerQuestionWrong->setText(ds.clickedWrong() != 0 ? QString("%2 m %3 s").arg(ds.timeExpeditureWrong() / ds.clickedWrong() / 60000).arg(ds.timeExpeditureWrong() / 1000 / ds.clickedWrong() % 60, 2, 10, QChar('0')) : "--"); labTimePerQuestionWrong->setText(ds.clickedWrong() != 0 ? QString("%2 m %3 s").arg(ds.timeExpeditureWrong() / ds.clickedWrong() / 60000).arg(ds.timeExpeditureWrong() / 1000 / ds.clickedWrong() % 60, 2, 10, QChar('0')) : "--");
} }
void CDlgLearnStatistic::on_cbPeriod_currentIndexChanged(int index) void CDlgLearnStatistic::on_cbPeriod_currentIndexChanged(int index)
{ {
Q_UNUSED(index); Q_UNUSED(index);
updateHistory(); updateHistory();
} }
void CDlgLearnStatistic::updateHistory() void CDlgLearnStatistic::updateHistory()
{ {
int iDays = cbPeriod->itemData(cbPeriod->currentIndex()).toInt(), idx=0; int iDays = cbPeriod->itemData(cbPeriod->currentIndex()).toInt(), idx=0;
CPlotWidgetCurve curveLevel, curveClickedCorrect, curveClickedWrong; CPlotWidgetCurve curveLevel, curveClickedCorrect, curveClickedWrong;
QDate date = QDate::currentDate(); QDate date = QDate::currentDate();
CDayStatistic ds; CDayStatistic ds;
QList<CPlotWidgetTic> listTics; QList<CPlotWidgetTic> listTics;
CPlotWidgetTic tic; CPlotWidgetTic tic;
bool bAddTic=false; bool bAddTic=false;
unsigned uMaxClicked=0; unsigned uMaxClicked=0;
if (m_pChapter == 0) return; if (m_pChapter == 0) return;
setCursor(Qt::WaitCursor); setCursor(Qt::WaitCursor);
date = date.addDays(-iDays); date = date.addDays(-iDays);
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
tic.setFillType(CPlotWidgetTic::FillAll); tic.setFillType(CPlotWidgetTic::FillAll);
tic.setPen(QPen(Qt::darkGray)); tic.setPen(QPen(Qt::darkGray));
while (date <= QDate::currentDate()) while (date <= QDate::currentDate())
{ {
if (bAddTic) if (bAddTic)
{ {
bAddTic=false; bAddTic=false;
tic.setPos(idx-1); tic.setPos(idx-1);
if (listTics.size() % 2) if (listTics.size() % 2)
tic.setBrush(QBrush(Qt::white)); tic.setBrush(QBrush(Qt::white));
else else
tic.setBrush(QBrush(QColor(232,232,232))); tic.setBrush(QBrush(QColor(232,232,232)));
listTics.append(tic); listTics.append(tic);
} }
ds = m_pChapter->dayStatistic(date); ds = m_pChapter->dayStatistic(date);
curveLevel.append(CPlotWidgetPoint(idx, ds.level())); curveLevel.append(CPlotWidgetPoint(idx, ds.level()));
curveClickedCorrect.append(CPlotWidgetPoint((double)idx, ds.clickedCorrect())); curveClickedCorrect.append(CPlotWidgetPoint((double)idx, ds.clickedCorrect()));
curveClickedWrong.append(CPlotWidgetPoint((double)idx, ds.clickedWrong())); curveClickedWrong.append(CPlotWidgetPoint((double)idx, ds.clickedWrong()));
if (ds.clickedCount() > uMaxClicked) uMaxClicked = ds.clickedCount(); if (ds.clickedCount() > uMaxClicked) uMaxClicked = ds.clickedCount();
date = date.addDays(1); date = date.addDays(1);
// X-Tics // X-Tics
if (iDays <= 14) if (iDays <= 14)
{ // daily tics { // daily tics
tic.setText(date.toString("ddd")); tic.setText(date.toString("ddd"));
tic.setWidth(1); tic.setWidth(1);
if (date.dayOfWeek() == Qt::Monday) if (date.dayOfWeek() == Qt::Monday)
tic.setLineType(CPlotWidgetTic::LinePlot); tic.setLineType(CPlotWidgetTic::LinePlot);
else else
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
bAddTic=true; bAddTic=true;
} }
else if (iDays <= 90 && date.dayOfWeek() == Qt::Monday) else if (iDays <= 90 && date.dayOfWeek() == Qt::Monday)
{ {
tic.setText(QString("KW %1").arg(date.weekNumber())); tic.setText(QString("KW %1").arg(date.weekNumber()));
tic.setWidth(7); tic.setWidth(7);
bAddTic=true; bAddTic=true;
} }
else if (iDays > 90 && date.day() == 1) else if (iDays > 90 && date.day() == 1)
{ {
tic.setText(date.toString("MMM")); tic.setText(date.toString("MMM"));
tic.setWidth(date.daysInMonth()); tic.setWidth(date.daysInMonth());
if (date.month() == 1) if (date.month() == 1)
tic.setLineType(CPlotWidgetTic::LinePlot); tic.setLineType(CPlotWidgetTic::LinePlot);
else else
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
bAddTic=true; bAddTic=true;
} }
idx++; idx++;
} }
m_pPlotLevel->setTicListX(listTics); m_pPlotLevel->setTicListX(listTics);
m_pPlotClicked->setTicListX(listTics); m_pPlotClicked->setTicListX(listTics);
curveLevel.setPen(QPen(Qt::darkBlue)); curveLevel.setPen(QPen(Qt::darkBlue));
curveClickedCorrect.setPen(QPen(Qt::green)); curveClickedCorrect.setPen(QPen(Qt::green));
curveClickedCorrect.setBrush(QBrush(Qt::green)); curveClickedCorrect.setBrush(QBrush(Qt::green));
curveClickedWrong.setPen(QPen(Qt::red)); curveClickedWrong.setPen(QPen(Qt::red));
curveClickedWrong.setBrush(QBrush(Qt::red)); curveClickedWrong.setBrush(QBrush(Qt::red));
m_pPlotLevel->clearCurves(); m_pPlotLevel->clearCurves();
m_pPlotLevel->appendCurve(curveLevel); m_pPlotLevel->appendCurve(curveLevel);
m_pPlotLevel->update(); m_pPlotLevel->update();
m_pPlotClicked->clearCurves(); m_pPlotClicked->clearCurves();
m_pPlotClicked->appendCurve(curveClickedCorrect); m_pPlotClicked->appendCurve(curveClickedCorrect);
m_pPlotClicked->appendCurve(curveClickedWrong); m_pPlotClicked->appendCurve(curveClickedWrong);
m_pPlotClicked->update(); m_pPlotClicked->update();
unsigned uDiffBase[] = {1, 2, 5, 10}, uDiffMulti=1, uDiff=0, uDiffCount=0; unsigned uDiffBase[] = {1, 2, 5, 10}, uDiffMulti=1, uDiff=0, uDiffCount=0;
idx = 0; idx = 0;
do do
{ {
if (idx == 4) { idx = 0; uDiffMulti*=10; } if (idx == 4) { idx = 0; uDiffMulti*=10; }
uDiff = uDiffBase[idx] * uDiffMulti; uDiff = uDiffBase[idx] * uDiffMulti;
uDiffCount = (uMaxClicked / uDiff) + 1; uDiffCount = (uMaxClicked / uDiff) + 1;
idx++; idx++;
} }
while (uDiffCount > 9); while (uDiffCount > 9);
m_pPlotClicked->setLimitY(0, uDiffCount * uDiff + uDiff/2); m_pPlotClicked->setLimitY(0, uDiffCount * uDiff + uDiff/2);
listTics.clear(); listTics.clear();
tic.clear(); tic.clear();
tic.setTextFlags(Qt::AlignRight | Qt::AlignVCenter); tic.setTextFlags(Qt::AlignRight | Qt::AlignVCenter);
for (unsigned u=0; u<=uDiffCount * uDiff; u+=uDiff) for (unsigned u=0; u<=uDiffCount * uDiff; u+=uDiff)
{ {
tic.setPos(u); tic.setPos(u);
tic.setText(QString("%1").arg(u)); tic.setText(QString("%1").arg(u));
listTics.append(tic); listTics.append(tic);
} }
m_pPlotClicked->setTicListY(listTics); m_pPlotClicked->setTicListY(listTics);
setCursor(Qt::ArrowCursor); setCursor(Qt::ArrowCursor);
} }
void CDlgLearnStatistic::on_cbPeriod2_currentIndexChanged(int index) void CDlgLearnStatistic::on_cbPeriod2_currentIndexChanged(int index)
{ {
Q_UNUSED(index); Q_UNUSED(index);
updateTimeExpediture(); updateTimeExpediture();
} }
void CDlgLearnStatistic::updateTimeExpediture() void CDlgLearnStatistic::updateTimeExpediture()
{ {
int iDays = cbPeriod2->itemData(cbPeriod2->currentIndex()).toInt(), idx=0; int iDays = cbPeriod2->itemData(cbPeriod2->currentIndex()).toInt(), idx=0;
CPlotWidgetCurve curveTimeWrong, curveTimeCorrect,curveTimePQWrong, curveTimePQCorrect; // PQ=per question CPlotWidgetCurve curveTimeWrong, curveTimeCorrect,curveTimePQWrong, curveTimePQCorrect; // PQ=per question
QDate date = QDate::currentDate(); QDate date = QDate::currentDate();
CDayStatistic ds; CDayStatistic ds;
QList<CPlotWidgetTic> listTics; QList<CPlotWidgetTic> listTics;
CPlotWidgetTic tic; CPlotWidgetTic tic;
bool bAddTic=false; bool bAddTic=false;
unsigned uMaxTime=0; unsigned uMaxTime=0;
if (m_pChapter == 0) return; if (m_pChapter == 0) return;
setCursor(Qt::WaitCursor); setCursor(Qt::WaitCursor);
date = date.addDays(-iDays); date = date.addDays(-iDays);
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
tic.setFillType(CPlotWidgetTic::FillAll); tic.setFillType(CPlotWidgetTic::FillAll);
tic.setPen(QPen(Qt::darkGray)); tic.setPen(QPen(Qt::darkGray));
while (date <= QDate::currentDate()) while (date <= QDate::currentDate())
{ {
if (bAddTic) if (bAddTic)
{ {
bAddTic=false; bAddTic=false;
tic.setPos(idx-1); tic.setPos(idx-1);
if (listTics.size() % 2) if (listTics.size() % 2)
tic.setBrush(QBrush(Qt::white)); tic.setBrush(QBrush(Qt::white));
else else
tic.setBrush(QBrush(QColor(232,232,232))); tic.setBrush(QBrush(QColor(232,232,232)));
listTics.append(tic); listTics.append(tic);
} }
ds = m_pChapter->dayStatistic(date); ds = m_pChapter->dayStatistic(date);
curveTimeWrong.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureWrong()/1000.0/60.0)); curveTimeWrong.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureWrong()/1000.0/60.0));
curveTimeCorrect.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureCorrect()/1000.0/60.0)); curveTimeCorrect.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureCorrect()/1000.0/60.0));
/* if (ds.clickedWrong() > 0) /* if (ds.clickedWrong() > 0)
curveTimePQWrong.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureWrong()/1000.0/60.0/(double)ds.clickedWrong())); curveTimePQWrong.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureWrong()/1000.0/60.0/(double)ds.clickedWrong()));
else else
curveTimePQWrong.append(CPlotWidgetPoint(idx, 0)); curveTimePQWrong.append(CPlotWidgetPoint(idx, 0));
if (ds.clickedCorrect() > 0) if (ds.clickedCorrect() > 0)
curveTimePQCorrect.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureCorrect()/1000.0/60.0/(double)ds.clickedCorrect())); curveTimePQCorrect.append(CPlotWidgetPoint(idx, (double)ds.timeExpeditureCorrect()/1000.0/60.0/(double)ds.clickedCorrect()));
else else
curveTimePQWrong.append(CPlotWidgetPoint(idx, 0));*/ curveTimePQWrong.append(CPlotWidgetPoint(idx, 0));*/
if (ds.timeExpediture()/1000/60 > uMaxTime) uMaxTime = ds.timeExpediture()/1000/60; if (ds.timeExpediture()/1000/60 > uMaxTime) uMaxTime = ds.timeExpediture()/1000/60;
date = date.addDays(1); date = date.addDays(1);
// X-Tics // X-Tics
if (iDays <= 14) if (iDays <= 14)
{ // daily tics { // daily tics
tic.setText(date.toString("ddd")); tic.setText(date.toString("ddd"));
tic.setWidth(1); tic.setWidth(1);
if (date.dayOfWeek() == Qt::Monday) if (date.dayOfWeek() == Qt::Monday)
tic.setLineType(CPlotWidgetTic::LinePlot); tic.setLineType(CPlotWidgetTic::LinePlot);
else else
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
bAddTic=true; bAddTic=true;
} }
else if (iDays <= 90 && date.dayOfWeek() == Qt::Monday) else if (iDays <= 90 && date.dayOfWeek() == Qt::Monday)
{ {
tic.setText(QString("KW %1").arg(date.weekNumber())); tic.setText(QString("KW %1").arg(date.weekNumber()));
tic.setWidth(7); tic.setWidth(7);
bAddTic=true; bAddTic=true;
} }
else if (iDays > 90 && date.day() == 1) else if (iDays > 90 && date.day() == 1)
{ {
tic.setText(date.toString("MMM")); tic.setText(date.toString("MMM"));
tic.setWidth(date.daysInMonth()); tic.setWidth(date.daysInMonth());
if (date.month() == 1) if (date.month() == 1)
tic.setLineType(CPlotWidgetTic::LinePlot); tic.setLineType(CPlotWidgetTic::LinePlot);
else else
tic.setLineType(CPlotWidgetTic::LineNone); tic.setLineType(CPlotWidgetTic::LineNone);
bAddTic=true; bAddTic=true;
} }
idx++; idx++;
} }
m_pPlotTime->setTicListX(listTics); m_pPlotTime->setTicListX(listTics);
//m_pPlotTimePerQuestion->setTicListX(listTics); //m_pPlotTimePerQuestion->setTicListX(listTics);
curveTimeCorrect.setPen(QPen(Qt::green)); curveTimeCorrect.setPen(QPen(Qt::green));
curveTimeCorrect.setBrush(QBrush(Qt::green)); curveTimeCorrect.setBrush(QBrush(Qt::green));
curveTimeWrong.setPen(QPen(Qt::red)); curveTimeWrong.setPen(QPen(Qt::red));
curveTimeWrong.setBrush(QBrush(Qt::red)); curveTimeWrong.setBrush(QBrush(Qt::red));
m_pPlotTime->clearCurves(); m_pPlotTime->clearCurves();
m_pPlotTime->appendCurve(curveTimeCorrect); m_pPlotTime->appendCurve(curveTimeCorrect);
m_pPlotTime->appendCurve(curveTimeWrong); m_pPlotTime->appendCurve(curveTimeWrong);
m_pPlotTime->update(); m_pPlotTime->update();
/* /*
m_pPlotTimePerQuestion->clearCurves(); m_pPlotTimePerQuestion->clearCurves();
m_pPlotTimePerQuestion->appendCurve(curveTimePQCorrect); m_pPlotTimePerQuestion->appendCurve(curveTimePQCorrect);
m_pPlotTimePerQuestion->appendCurve(curveTimePQWrong); m_pPlotTimePerQuestion->appendCurve(curveTimePQWrong);
m_pPlotTimePerQuestion->setAutoLimitRoundY(0.1); m_pPlotTimePerQuestion->setAutoLimitRoundY(0.1);
m_pPlotTimePerQuestion->update(); m_pPlotTimePerQuestion->update();
*/ */
unsigned uDiffBase[] = {1, 2, 5, 10}, uDiffMulti=1, uDiff=0, uDiffCount=0; unsigned uDiffBase[] = {1, 2, 5, 10}, uDiffMulti=1, uDiff=0, uDiffCount=0;
idx = 0; idx = 0;
do do
{ {
if (idx == 4) { idx = 0; uDiffMulti*=10; } if (idx == 4) { idx = 0; uDiffMulti*=10; }
uDiff = uDiffBase[idx] * uDiffMulti; uDiff = uDiffBase[idx] * uDiffMulti;
uDiffCount = (uMaxTime / uDiff) + 1; uDiffCount = (uMaxTime / uDiff) + 1;
idx++; idx++;
} }
while (uDiffCount > 9); while (uDiffCount > 9);
m_pPlotTime->setLimitY(0, uDiffCount * uDiff + uDiff/2); m_pPlotTime->setLimitY(0, uDiffCount * uDiff + uDiff/2);
listTics.clear(); listTics.clear();
tic.clear(); tic.clear();
tic.setTextFlags(Qt::AlignRight | Qt::AlignVCenter); tic.setTextFlags(Qt::AlignRight | Qt::AlignVCenter);
for (unsigned u=0; u<=uDiffCount * uDiff; u+=uDiff) for (unsigned u=0; u<=uDiffCount * uDiff; u+=uDiff)
{ {
tic.setPos(u); tic.setPos(u);
tic.setText(QString("%1").arg(u)); tic.setText(QString("%1").arg(u));
listTics.append(tic); listTics.append(tic);
} }
m_pPlotTime->setTicListY(listTics); m_pPlotTime->setTicListY(listTics);
setCursor(Qt::ArrowCursor); setCursor(Qt::ArrowCursor);
} }

View File

@ -1,54 +1,54 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include <qdialog.h> #include <qdialog.h>
#include "ui_dlglearnstatistic.h" #include "ui_dlglearnstatistic.h"
class CChapter; class CChapter;
class CPlotWidget; class CPlotWidget;
class CDlgLearnStatistic : public QDialog, Ui::DlgLearnStatistic class CDlgLearnStatistic : public QDialog, Ui::DlgLearnStatistic
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgLearnStatistic(QWidget *pParent=0); CDlgLearnStatistic(QWidget *pParent=0);
~CDlgLearnStatistic() {} ~CDlgLearnStatistic() {}
void go(CChapter *pChapter); void go(CChapter *pChapter);
protected slots: protected slots:
void on_cbPeriod_currentIndexChanged(int index); void on_cbPeriod_currentIndexChanged(int index);
void on_cbPeriod2_currentIndexChanged(int index); void on_cbPeriod2_currentIndexChanged(int index);
protected: protected:
void updateTable(); void updateTable();
void updateHistory(); void updateHistory();
void updateTimeExpediture(); void updateTimeExpediture();
protected: protected:
CChapter *m_pChapter; CChapter *m_pChapter;
CPlotWidget *m_pPlotLevel; CPlotWidget *m_pPlotLevel;
CPlotWidget *m_pPlotClicked; CPlotWidget *m_pPlotClicked;
CPlotWidget *m_pPlotTime; CPlotWidget *m_pPlotTime;
// CPlotWidget *m_pPlotTimePerQuestion; // CPlotWidget *m_pPlotTimePerQuestion;
}; };

View File

@ -1,43 +1,43 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "dlgviewquestion.h" #include "dlgviewquestion.h"
#include "catalog.h" #include "catalog.h"
void CDlgViewQuestion::go (CCatalog *pCatalog, CQuestion *pQuestion, const unsigned uAnswer) void CDlgViewQuestion::go (CCatalog *pCatalog, CQuestion *pQuestion, const unsigned uAnswer)
{ {
QString str; QString str;
Q_ASSERT (pCatalog != 0); Q_ASSERT (pCatalog != 0);
if (!pQuestion) return; if (!pQuestion) return;
str = pQuestion->learnText(pCatalog, true, true); str = pQuestion->learnText(pCatalog, true, true);
str += "<p><b>"; str += "<p><b>";
if (uAnswer != 0 && pQuestion->isCorrectAnswer(uAnswer)) if (uAnswer != 0 && pQuestion->isCorrectAnswer(uAnswer))
str += "<font color='green'>"; str += "<font color='green'>";
else if (uAnswer != 0) else if (uAnswer != 0)
str += "<font color='red'>"; str += "<font color='red'>";
str += pQuestion->correctionText(uAnswer); str += pQuestion->correctionText(uAnswer);
str += "</font></b></p>"; str += "</font></b></p>";
textBrowser->setHtml(str); textBrowser->setHtml(str);
setWindowTitle (tr("Frage") + " " + pQuestion->id()); setWindowTitle (tr("Frage") + " " + pQuestion->id());
exec(); exec();
} }

View File

@ -1,44 +1,44 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DLGVIEWQUESTION_H #ifndef DLGVIEWQUESTION_H
#define DLGVIEWQUESTION_H #define DLGVIEWQUESTION_H
#include <qdialog.h> #include <qdialog.h>
#include "ui_dlgviewquestion.h" #include "ui_dlgviewquestion.h"
class CQuestion; class CQuestion;
class CCatalog; class CCatalog;
class CDlgViewQuestion : public QDialog, Ui::DlgViewQuestion class CDlgViewQuestion : public QDialog, Ui::DlgViewQuestion
{ {
Q_OBJECT Q_OBJECT
public: public:
CDlgViewQuestion(QWidget *pParent) : QDialog(pParent) { setupUi(this); } CDlgViewQuestion(QWidget *pParent) : QDialog(pParent) { setupUi(this); }
~CDlgViewQuestion() { } ~CDlgViewQuestion() { }
void go (CCatalog *pCatalog, CQuestion *pQuestion, const unsigned uAnswer=0); void go (CCatalog *pCatalog, CQuestion *pQuestion, const unsigned uAnswer=0);
protected: protected:
}; };
#endif // DLGVIEWQUESTION_H #endif // DLGVIEWQUESTION_H

196
error.cpp
View File

@ -1,98 +1,98 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 1999-2005 by Oliver Saal * * Copyright (C) 1999-2005 by Oliver Saal *
* http://www.oliver-saal.de/ * * http://www.oliver-saal.de/ *
* osaal@gmx.de * * osaal@gmx.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "error.h" #include "error.h"
#include <qobject.h> #include <qobject.h>
#include <qstring.h> #include <qstring.h>
#ifdef ERROR_USE_SQL #ifdef ERROR_USE_SQL
#include <qsqlerror.h> #include <qsqlerror.h>
#include <qmap.h> #include <qmap.h>
//#include <qmapiterator.h> //#include <qmapiterator.h>
#include <qvariant.h> #include <qvariant.h>
#endif #endif
CError::CError () CError::CError ()
{ {
m_uLine = 0; m_uLine = 0;
} }
CError::CError (const QString& strFunc, const QString& strFile, const unsigned int uLine) CError::CError (const QString& strFunc, const QString& strFile, const unsigned int uLine)
{ {
m_strFunction = strFunc; m_strFunction = strFunc;
m_strFile = strFile; m_strFile = strFile;
m_uLine = uLine; m_uLine = uLine;
} }
CError::CError (const QString& strText, const QString& strFunc, const QString& strFile, const unsigned int uLine) CError::CError (const QString& strText, const QString& strFunc, const QString& strFile, const unsigned int uLine)
{ {
m_strText = strText; m_strText = strText;
m_strFunction = strFunc; m_strFunction = strFunc;
m_strFile = strFile; m_strFile = strFile;
m_uLine = uLine; m_uLine = uLine;
} }
#ifdef ERROR_USE_SQL #ifdef ERROR_USE_SQL
CError::CError (const QString& strText, const QSqlDatabase* pDB, const QString& strFunc, const QString& strFile, const unsigned int uLine) CError::CError (const QString& strText, const QSqlDatabase* pDB, const QString& strFunc, const QString& strFile, const unsigned int uLine)
{ {
m_strText = QString ("%1\n%3").arg (strText, pDB->lastError().text()); m_strText = QString ("%1\n%3").arg (strText, pDB->lastError().text());
m_strFunction = strFunc; m_strFunction = strFunc;
m_strFile = strFile; m_strFile = strFile;
m_uLine = uLine; m_uLine = uLine;
} }
CError::CError (const QString& strText, const QSqlQuery& query, const QString& strFunc, const QString& strFile, const unsigned int uLine) CError::CError (const QString& strText, const QSqlQuery& query, const QString& strFunc, const QString& strFile, const unsigned int uLine)
{ {
QMap<QString, QVariant> map; QMap<QString, QVariant> map;
m_strText = QString ("%1\nSQL: %2\n").arg (strText, query.lastQuery()); m_strText = QString ("%1\nSQL: %2\n").arg (strText, query.lastQuery());
map = query.boundValues(); map = query.boundValues();
if (!map.isEmpty()) if (!map.isEmpty())
{ {
m_strText+="Bound values:\n"; m_strText+="Bound values:\n";
QMap<QString, QVariant>::const_iterator i = map.constBegin(); QMap<QString, QVariant>::const_iterator i = map.constBegin();
while (i != map.constEnd()) while (i != map.constEnd())
{ {
m_strText += QString ("%1 / %2 ==> %4\n").arg (i.key(), i.value().typeName(), i.value().isNull() ? "NULL" : i.value().toString()); m_strText += QString ("%1 / %2 ==> %4\n").arg (i.key(), i.value().typeName(), i.value().isNull() ? "NULL" : i.value().toString());
++i; ++i;
} }
} }
m_strText += query.lastError().text(); m_strText += query.lastError().text();
m_strFunction = strFunc; m_strFunction = strFunc;
m_strFile = strFile; m_strFile = strFile;
m_uLine = uLine; m_uLine = uLine;
} }
#endif #endif
QString CError::toPlainText() const QString CError::toPlainText() const
{ {
return QObject::tr("%1\n\nFunction: %2\nFile: %3 Line: %4\n").arg(m_strText, m_strFunction, m_strFile).arg(m_uLine); return QObject::tr("%1\n\nFunction: %2\nFile: %3 Line: %4\n").arg(m_strText, m_strFunction, m_strFile).arg(m_uLine);
} }
QString CError::toHtml() const QString CError::toHtml() const
{ {
QString str = m_strText; QString str = m_strText;
str.replace ('\n', "<br>"); str.replace ('\n', "<br>");
return QObject::tr("<p><font color='red'><b>%1</b></font><br>Function: %2<br>File: %3 Line: %4</p><br>\n").arg(str, m_strFunction, m_strFile).arg(m_uLine); return QObject::tr("<p><font color='red'><b>%1</b></font><br>Function: %2<br>File: %3 Line: %4</p><br>\n").arg(str, m_strFunction, m_strFile).arg(m_uLine);
} }

156
error.h
View File

@ -1,78 +1,78 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 1999-2007 by Oliver Saal * * Copyright (C) 1999-2007 by Oliver Saal *
* http://www.oliver-saal.de/ * * http://www.oliver-saal.de/ *
* osaal@gmx.de * * osaal@gmx.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ERROR_H #ifndef ERROR_H
#define ERROR_H #define ERROR_H
//#define ERROR_USE_SQL //#define ERROR_USE_SQL
#ifndef __PRETTY_FUNCTION__ #ifndef __PRETTY_FUNCTION__
# if defined __FUNCSIG__ # if defined __FUNCSIG__
# define __PRETTY_FUNCTION__ __FUNCSIG__ # define __PRETTY_FUNCTION__ __FUNCSIG__
# elif defined __func__ # elif defined __func__
# define __PRETTY_FUNCTION__ __func__ # define __PRETTY_FUNCTION__ __func__
# else # else
# define __PRETTY_FUNCTION__ __FILE__ # define __PRETTY_FUNCTION__ __FILE__
# endif # endif
#endif #endif
#include <qstring.h> #include <qstring.h>
#ifdef ERROR_USE_SQL #ifdef ERROR_USE_SQL
#include <qsqlquery.h> #include <qsqlquery.h>
#define THROW_TRANSACTION(x) throw CError (tr("Could not start database transaction."), x, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define THROW_TRANSACTION(x) throw CError (tr("Could not start database transaction."), x, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#define THROW_COMMIT(x) throw CError (tr("Could not commit database transaction."), x, __PRETTY_FUNCTION__, __FILE__, __LINE__); #define THROW_COMMIT(x) throw CError (tr("Could not commit database transaction."), x, __PRETTY_FUNCTION__, __FILE__, __LINE__);
#endif #endif
class CError class CError
{ {
public: public:
CError (); CError ();
CError (const QString& strFunc, const QString& strFile, const unsigned int uLine); CError (const QString& strFunc, const QString& strFile, const unsigned int uLine);
CError (const QString& strText, const QString& strFunc, const QString& strFile, const unsigned int uLine); CError (const QString& strText, const QString& strFunc, const QString& strFile, const unsigned int uLine);
#ifdef ERROR_USE_SQL #ifdef ERROR_USE_SQL
CError (const QString& strText, const QSqlDatabase* pDB, const QString& strFunc, const QString& strFile, const unsigned int uLine); CError (const QString& strText, const QSqlDatabase* pDB, const QString& strFunc, const QString& strFile, const unsigned int uLine);
CError (const QString& strText, const QSqlQuery& query, const QString& strFunc, const QString& strFile, const unsigned int uLine); CError (const QString& strText, const QSqlQuery& query, const QString& strFunc, const QString& strFile, const unsigned int uLine);
#endif #endif
inline void preText (const QString& str) { m_strText = str + m_strText; } inline void preText (const QString& str) { m_strText = str + m_strText; }
inline void postText (const QString& str) { m_strText += str; } inline void postText (const QString& str) { m_strText += str; }
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
inline QString function() const { return m_strFunction; } inline QString function() const { return m_strFunction; }
inline QString file() const { return m_strFile; } inline QString file() const { return m_strFile; }
inline unsigned line() const { return m_uLine; } inline unsigned line() const { return m_uLine; }
QString toPlainText() const; QString toPlainText() const;
QString toHtml() const; QString toHtml() const;
protected: protected:
QString m_strText; QString m_strText;
QString m_strFunction; QString m_strFunction;
QString m_strFile; QString m_strFile;
unsigned int m_uLine; unsigned int m_uLine;
}; };
#endif // ERROR_H #endif // ERROR_H

612
exam.cpp
View File

@ -1,306 +1,306 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "exam.h" #include "exam.h"
#include "question.h" #include "question.h"
#include "error.h" #include "error.h"
#include "tools.h" #include "tools.h"
#include <qregexp.h> #include <qregexp.h>
#include <qvariant.h> #include <qvariant.h>
//#define DEBUGMSG //#define DEBUGMSG
void CExamPart::clear() void CExamPart::clear()
{ {
m_iQuestionCount = 0; m_iQuestionCount = 0;
m_strRegExp.clear(); m_strRegExp.clear();
} }
bool CExamPart::load (QDomElement elem) bool CExamPart::load (QDomElement elem)
{ {
if (elem.tagName() != QString ("exam_part")) return false; if (elem.tagName() != QString ("exam_part")) return false;
m_iQuestionCount = elem.attribute("count").toUInt(); m_iQuestionCount = elem.attribute("count").toUInt();
if (m_iQuestionCount == 0) return false; if (m_iQuestionCount == 0) return false;
m_strGroup = elem.attribute("group"); m_strGroup = elem.attribute("group");
m_strRegExp = elem.text (); m_strRegExp = elem.text ();
if (m_strRegExp.isEmpty()) return false; if (m_strRegExp.isEmpty()) return false;
return true; return true;
} }
void CExamPart::save (QDomElement& parent, QDomDocument& doc) const void CExamPart::save (QDomElement& parent, QDomDocument& doc) const
{ {
QDomElement elemRoot = doc.createElement("exam_part"); QDomElement elemRoot = doc.createElement("exam_part");
elemRoot.setAttribute("count", QString("%1").arg(m_iQuestionCount)); elemRoot.setAttribute("count", QString("%1").arg(m_iQuestionCount));
elemRoot.setAttribute("group", m_strGroup); elemRoot.setAttribute("group", m_strGroup);
elemRoot.appendChild(doc.createTextNode(m_strRegExp)); elemRoot.appendChild(doc.createTextNode(m_strRegExp));
parent.appendChild(elemRoot); parent.appendChild(elemRoot);
} }
QList<CQuestion*> CExamPart::createQuestionPool(const QList<CQuestion*>& listAllQuestions) const QList<CQuestion*> CExamPart::createQuestionPool(const QList<CQuestion*>& listAllQuestions) const
{ {
QList<CQuestion*> listRet, listSelected; QList<CQuestion*> listRet, listSelected;
QRegExp regexp(m_strRegExp); QRegExp regexp(m_strRegExp);
int i=0; int i=0;
CQuestion *q=0; CQuestion *q=0;
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("\tPart Group = '%s' RegExp '%s' mit %i Fragen", qPrintable (m_strGroup), qPrintable(m_strRegExp), m_iQuestionCount); qDebug ("\tPart Group = '%s' RegExp '%s' mit %i Fragen", qPrintable (m_strGroup), qPrintable(m_strRegExp), m_iQuestionCount);
#endif #endif
// Alle Fragen raussuchen, die dem RegExp entsprechen // Alle Fragen raussuchen, die dem RegExp entsprechen
for (i=0; i<listAllQuestions.size(); i++) for (i=0; i<listAllQuestions.size(); i++)
{ {
q = listAllQuestions.at(i); q = listAllQuestions.at(i);
if (!m_strGroup.isEmpty() && !q->groups().contains(m_strGroup, Qt::CaseInsensitive)) if (!m_strGroup.isEmpty() && !q->groups().contains(m_strGroup, Qt::CaseInsensitive))
continue; continue;
if (regexp.exactMatch(q->id())) if (regexp.exactMatch(q->id()))
{ {
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("\t\tAdding Question '%s'", qPrintable (q->id())); qDebug ("\t\tAdding Question '%s'", qPrintable (q->id()));
#endif #endif
listSelected.append(q); listSelected.append(q);
} }
} }
if (listSelected.size() < questionCount()) if (listSelected.size() < questionCount())
{ {
throw CError ( throw CError (
QString("Für den regulären Ausdruck '%1' wurden nur %2 Fragen gefunden - zu wenig, um daraus %3 Fragen für die Prüfung auszuwählen.") QString("Für den regulären Ausdruck '%1' wurden nur %2 Fragen gefunden - zu wenig, um daraus %3 Fragen für die Prüfung auszuwählen.")
.arg(m_strRegExp).arg(listSelected.size()).arg(questionCount()), __PRETTY_FUNCTION__, __FILE__, __LINE__); .arg(m_strRegExp).arg(listSelected.size()).arg(questionCount()), __PRETTY_FUNCTION__, __FILE__, __LINE__);
} }
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("\tStarte Auswahlverfahren..."); qDebug ("\tStarte Auswahlverfahren...");
#endif #endif
for (i=0; i < questionCount(); i++) for (i=0; i < questionCount(); i++)
{ {
int rnd = afu_random (0, listSelected.size()-1); int rnd = afu_random (0, listSelected.size()-1);
q = listSelected.at(rnd); q = listSelected.at(rnd);
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("\t\tSelected question '%s'", qPrintable (q->id())); qDebug ("\t\tSelected question '%s'", qPrintable (q->id()));
#endif #endif
listRet.append (q); listRet.append (q);
listSelected.removeAt(rnd); listSelected.removeAt(rnd);
} }
return listRet; return listRet;
} }
void CExam::clear() void CExam::clear()
{ {
m_strId.clear(); m_strId.clear();
m_strName.clear(); m_strName.clear();
m_strComment.clear(); m_strComment.clear();
m_uDuration = 0; m_uDuration = 0;
m_uMaxErrorPoints = 0; m_uMaxErrorPoints = 0;
m_listParts.clear(); m_listParts.clear();
} }
bool CExam::load (QDomElement elem) bool CExam::load (QDomElement elem)
{ {
if (elem.tagName() != QString ("exam")) return false; if (elem.tagName() != QString ("exam")) return false;
m_strId = elem.attribute("id"); m_strId = elem.attribute("id");
m_strName = elem.attribute("name"); m_strName = elem.attribute("name");
m_uDuration = elem.attribute("duration").toUInt(); m_uDuration = elem.attribute("duration").toUInt();
m_uMaxErrorPoints = elem.attribute("maxerrorpoints").toUInt(); m_uMaxErrorPoints = elem.attribute("maxerrorpoints").toUInt();
m_strComment = elem.attribute("comment"); m_strComment = elem.attribute("comment");
if (m_strName.isEmpty()) return false; if (m_strName.isEmpty()) return false;
if (m_uDuration == 0) return false; if (m_uDuration == 0) return false;
QDomNode n = elem.firstChild(); QDomNode n = elem.firstChild();
while (!n.isNull()) while (!n.isNull())
{ {
if (n.isElement ()) if (n.isElement ())
{ {
QDomElement e = n.toElement (); QDomElement e = n.toElement ();
if (e.tagName() == QString ("exam_part")) if (e.tagName() == QString ("exam_part"))
{ {
CExamPart ep; CExamPart ep;
if (ep.load(e)) m_listParts.append(ep); if (ep.load(e)) m_listParts.append(ep);
} }
} }
n = n.nextSibling(); n = n.nextSibling();
} }
return true; return true;
} }
void CExam::save (QDomElement& parent, QDomDocument& doc) const void CExam::save (QDomElement& parent, QDomDocument& doc) const
{ {
QDomElement elemRoot = doc.createElement("exam"); QDomElement elemRoot = doc.createElement("exam");
elemRoot.setAttribute("id", m_strId); elemRoot.setAttribute("id", m_strId);
elemRoot.setAttribute("name", m_strName); elemRoot.setAttribute("name", m_strName);
elemRoot.setAttribute("duration", QString("%1").arg(m_uDuration)); elemRoot.setAttribute("duration", QString("%1").arg(m_uDuration));
elemRoot.setAttribute("maxerrorpoints", QString("%1").arg(m_uMaxErrorPoints)); elemRoot.setAttribute("maxerrorpoints", QString("%1").arg(m_uMaxErrorPoints));
elemRoot.setAttribute("comment", m_strComment); elemRoot.setAttribute("comment", m_strComment);
for (int i=0; i<m_listParts.size(); i++) for (int i=0; i<m_listParts.size(); i++)
m_listParts.at(i).save(elemRoot, doc); m_listParts.at(i).save(elemRoot, doc);
parent.appendChild(elemRoot); parent.appendChild(elemRoot);
} }
unsigned CExam::questionCount() const unsigned CExam::questionCount() const
{ {
unsigned u=0; unsigned u=0;
for (int i=0; i<m_listParts.size(); i++) for (int i=0; i<m_listParts.size(); i++)
{ {
u += m_listParts.at(i).questionCount(); u += m_listParts.at(i).questionCount();
} }
return u; return u;
} }
QList<CQuestion*> CExam::createQuestionPool(const QList<CQuestion*>& listAllQuestions) const QList<CQuestion*> CExam::createQuestionPool(const QList<CQuestion*>& listAllQuestions) const
{ {
QList<CQuestion*> listRet; QList<CQuestion*> listRet;
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("Erzeuge Prüfungsfragen für '%s'", qPrintable(name())); qDebug ("Erzeuge Prüfungsfragen für '%s'", qPrintable(name()));
#endif #endif
try try
{ {
for (int i=0; i<m_listParts.size(); i++) for (int i=0; i<m_listParts.size(); i++)
{ {
listRet << m_listParts.at(i).createQuestionPool(listAllQuestions); listRet << m_listParts.at(i).createQuestionPool(listAllQuestions);
} }
} }
catch (CError e) catch (CError e)
{ {
e.preText(QString("Konnte Prüfung '%1' nicht erzeugen.").arg(name())); e.preText(QString("Konnte Prüfung '%1' nicht erzeugen.").arg(name()));
throw; throw;
} }
#ifdef DEBUGMSG #ifdef DEBUGMSG
qDebug ("Insg. %i Prüfungsfragen ausgewählt", listRet.size()); qDebug ("Insg. %i Prüfungsfragen ausgewählt", listRet.size());
for (int i=0; i<listRet.size(); i++) for (int i=0; i<listRet.size(); i++)
qDebug ("\t%i. Frage ID '%s'", i+1, qPrintable(listRet.at(i)->id())); qDebug ("\t%i. Frage ID '%s'", i+1, qPrintable(listRet.at(i)->id()));
#endif #endif
return listRet; return listRet;
} }
CExamStat::CExamStat(const CExam& exam) CExamStat::CExamStat(const CExam& exam)
{ {
clear(); clear();
m_strId = exam.id(); m_strId = exam.id();
} }
void CExamStat::clear() void CExamStat::clear()
{ {
m_strId.clear(); m_strId.clear();
m_dt = QDateTime::currentDateTime(); m_dt = QDateTime::currentDateTime();
m_uSecs = 0; m_uSecs = 0;
m_strlQuestionId.clear(); m_strlQuestionId.clear();
m_listAnswer.clear(); m_listAnswer.clear();
m_uCorrect = 0; m_uCorrect = 0;
m_uWrong = 0; m_uWrong = 0;
m_uErrorPoints = 0; m_uErrorPoints = 0;
m_bPassed = false; m_bPassed = false;
} }
void CExamStat::setQuestions(const QList<CQuestion*>& listQuestion, const QList<unsigned>& listAnswerMask) void CExamStat::setQuestions(const QList<CQuestion*>& listQuestion, const QList<unsigned>& listAnswerMask)
{ {
for (int i=0; i<listQuestion.size(); i++) for (int i=0; i<listQuestion.size(); i++)
{ {
CQuestion *q = listQuestion.at(i); CQuestion *q = listQuestion.at(i);
m_strlQuestionId.append(q->id()); m_strlQuestionId.append(q->id());
m_listAnswer.append(q->orderedAnswerMask(listAnswerMask.at(i))); m_listAnswer.append(q->orderedAnswerMask(listAnswerMask.at(i)));
} }
} }
void CExamStat::setResult (const unsigned uCorrect, const unsigned uWrong, const unsigned uErrorPoints, const bool bPassed) void CExamStat::setResult (const unsigned uCorrect, const unsigned uWrong, const unsigned uErrorPoints, const bool bPassed)
{ {
m_uCorrect = uCorrect; m_uCorrect = uCorrect;
m_uWrong = uWrong; m_uWrong = uWrong;
m_uErrorPoints = uErrorPoints; m_uErrorPoints = uErrorPoints;
m_bPassed = bPassed; m_bPassed = bPassed;
} }
bool CExamStat::load (QDomElement elem) bool CExamStat::load (QDomElement elem)
{ {
if (elem.tagName() != QString ("exam")) return false; if (elem.tagName() != QString ("exam")) return false;
m_strId = elem.attribute("id"); m_strId = elem.attribute("id");
m_uSecs = elem.attribute("secs").toUInt(); m_uSecs = elem.attribute("secs").toUInt();
m_dt = QDateTime::fromString(elem.attribute("datetime"), Qt::ISODate); m_dt = QDateTime::fromString(elem.attribute("datetime"), Qt::ISODate);
m_uCorrect = elem.attribute("correct").toUInt(); m_uCorrect = elem.attribute("correct").toUInt();
m_uWrong = elem.attribute("wrong").toUInt(); m_uWrong = elem.attribute("wrong").toUInt();
m_uErrorPoints = elem.attribute("errorpoints").toUInt(); m_uErrorPoints = elem.attribute("errorpoints").toUInt();
m_bPassed = QVariant(elem.attribute("passed")).toBool(); m_bPassed = QVariant(elem.attribute("passed")).toBool();
if (m_strId.isEmpty()) return false; if (m_strId.isEmpty()) return false;
if (m_uSecs == 0) return false; if (m_uSecs == 0) return false;
QDomNode n = elem.firstChild(); QDomNode n = elem.firstChild();
while (!n.isNull()) while (!n.isNull())
{ {
if (n.isElement ()) if (n.isElement ())
{ {
QDomElement e = n.toElement (); QDomElement e = n.toElement ();
if (e.tagName() == QString ("question")) if (e.tagName() == QString ("question"))
{ {
QString strId = e.attribute("id"); QString strId = e.attribute("id");
if (!strId.isEmpty()) if (!strId.isEmpty())
{ {
m_strlQuestionId.append (strId); m_strlQuestionId.append (strId);
m_listAnswer.append(e.attribute("answer").toUInt()); m_listAnswer.append(e.attribute("answer").toUInt());
} }
} }
} }
n = n.nextSibling(); n = n.nextSibling();
} }
return true; return true;
} }
void CExamStat::save (QDomElement& parent, QDomDocument& doc) const void CExamStat::save (QDomElement& parent, QDomDocument& doc) const
{ {
QDomElement elemRoot = doc.createElement("exam"); QDomElement elemRoot = doc.createElement("exam");
elemRoot.setAttribute("id", m_strId); elemRoot.setAttribute("id", m_strId);
elemRoot.setAttribute("secs", QString("%1").arg(m_uSecs)); elemRoot.setAttribute("secs", QString("%1").arg(m_uSecs));
elemRoot.setAttribute("datetime", m_dt.toString(Qt::ISODate)); elemRoot.setAttribute("datetime", m_dt.toString(Qt::ISODate));
elemRoot.setAttribute("correct", QString("%1").arg(m_uCorrect)); elemRoot.setAttribute("correct", QString("%1").arg(m_uCorrect));
elemRoot.setAttribute("wrong", QString("%1").arg(m_uWrong)); elemRoot.setAttribute("wrong", QString("%1").arg(m_uWrong));
elemRoot.setAttribute("errorpoints", QString("%1").arg(m_uErrorPoints)); elemRoot.setAttribute("errorpoints", QString("%1").arg(m_uErrorPoints));
elemRoot.setAttribute("passed", QString("%1").arg(m_bPassed)); elemRoot.setAttribute("passed", QString("%1").arg(m_bPassed));
for (int i=0; i<m_strlQuestionId.size(); i++) for (int i=0; i<m_strlQuestionId.size(); i++)
{ {
QDomElement elemQuestion = doc.createElement("question"); QDomElement elemQuestion = doc.createElement("question");
elemQuestion.setAttribute("id", m_strlQuestionId.at(i)); elemQuestion.setAttribute("id", m_strlQuestionId.at(i));
elemQuestion.setAttribute("answer", m_listAnswer.at(i)); elemQuestion.setAttribute("answer", m_listAnswer.at(i));
elemRoot.appendChild(elemQuestion); elemRoot.appendChild(elemQuestion);
} }
parent.appendChild(elemRoot); parent.appendChild(elemRoot);
} }

284
exam.h
View File

@ -1,142 +1,142 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef EXAM_H #ifndef EXAM_H
#define EXAM_H #define EXAM_H
#include <qstring.h> #include <qstring.h>
#include <qlist.h> #include <qlist.h>
#include <qdom.h> #include <qdom.h>
#include <qdatetime.h> #include <qdatetime.h>
#include <qstringlist.h> #include <qstringlist.h>
class CQuestion; class CQuestion;
class CExamPart class CExamPart
{ {
public: public:
CExamPart() { clear(); } CExamPart() { clear(); }
~CExamPart() {} ~CExamPart() {}
void clear(); void clear();
inline int questionCount() const { return m_iQuestionCount; } inline int questionCount() const { return m_iQuestionCount; }
inline void setQuestionCount(int i) { m_iQuestionCount = i; } inline void setQuestionCount(int i) { m_iQuestionCount = i; }
inline QString group() const { return m_strGroup; } inline QString group() const { return m_strGroup; }
inline void setGroup(const QString& str) { m_strGroup = str; } inline void setGroup(const QString& str) { m_strGroup = str; }
inline QString regexp() const { return m_strRegExp; } inline QString regexp() const { return m_strRegExp; }
inline void setRegExp(const QString& str) { m_strRegExp = str; } inline void setRegExp(const QString& str) { m_strRegExp = str; }
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc) const; void save (QDomElement& parent, QDomDocument& doc) const;
QList<CQuestion*> createQuestionPool(const QList<CQuestion*>& listAllQuestions) const; QList<CQuestion*> createQuestionPool(const QList<CQuestion*>& listAllQuestions) const;
protected: protected:
int m_iQuestionCount; int m_iQuestionCount;
QString m_strGroup; QString m_strGroup;
QString m_strRegExp; QString m_strRegExp;
}; };
class CExam class CExam
{ {
public: public:
CExam() { clear(); } CExam() { clear(); }
~CExam() {} ~CExam() {}
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Daten der Prüfung gelöscht. */ /*! Es werden alle Daten der Prüfung gelöscht. */
void clear(); void clear();
//! ID abfragen //! ID abfragen
inline QString id() const { return m_strId; } inline QString id() const { return m_strId; }
//! ID setzen //! ID setzen
inline void setId(const QString& strId) { m_strId = strId; } inline void setId(const QString& strId) { m_strId = strId; }
inline QString name() const { return m_strName; } inline QString name() const { return m_strName; }
inline QString comment() const { return m_strComment; } inline QString comment() const { return m_strComment; }
unsigned duration() const { return m_uDuration; } unsigned duration() const { return m_uDuration; }
unsigned maxErrorPoints() const { return m_uMaxErrorPoints; } unsigned maxErrorPoints() const { return m_uMaxErrorPoints; }
unsigned questionCount() const; unsigned questionCount() const;
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc) const; void save (QDomElement& parent, QDomDocument& doc) const;
QList<CQuestion*> createQuestionPool(const QList<CQuestion*>& listAllQuestions) const; QList<CQuestion*> createQuestionPool(const QList<CQuestion*>& listAllQuestions) const;
protected: protected:
QString m_strId; //< ID der Prüfung QString m_strId; //< ID der Prüfung
QString m_strName; //< Name / Bezeichnung QString m_strName; //< Name / Bezeichnung
QString m_strComment; //< Kommentar / Hinweis QString m_strComment; //< Kommentar / Hinweis
unsigned m_uDuration; //< Prüfungsdauer in min unsigned m_uDuration; //< Prüfungsdauer in min
unsigned m_uMaxErrorPoints; //< Max. Anzahl an erlaubten Fehlerpunkten, um die Prüfung zu bestehen unsigned m_uMaxErrorPoints; //< Max. Anzahl an erlaubten Fehlerpunkten, um die Prüfung zu bestehen
QList<CExamPart> m_listParts; //< Abschnitte, aus denen sich die Prüfung zusammensetzt. QList<CExamPart> m_listParts; //< Abschnitte, aus denen sich die Prüfung zusammensetzt.
}; };
class CExamStat class CExamStat
{ {
public: public:
CExamStat() { clear(); } CExamStat() { clear(); }
CExamStat(const CExam& exam); CExamStat(const CExam& exam);
~CExamStat() {} ~CExamStat() {}
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Daten dieser Prüfungsstatistik gelöscht. */ /*! Es werden alle Daten dieser Prüfungsstatistik gelöscht. */
void clear(); void clear();
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc) const; void save (QDomElement& parent, QDomDocument& doc) const;
//! ID abfragen //! ID abfragen
inline QString id() const { return m_strId; } inline QString id() const { return m_strId; }
//! ID setzen //! ID setzen
inline void setId(const QString& strId) { m_strId = strId; } inline void setId(const QString& strId) { m_strId = strId; }
inline void setSecs(const unsigned uSecs) { m_uSecs = uSecs; } inline void setSecs(const unsigned uSecs) { m_uSecs = uSecs; }
void setQuestions(const QList<CQuestion*>& listQuestion, const QList<unsigned>& listAnswerMask); void setQuestions(const QList<CQuestion*>& listQuestion, const QList<unsigned>& listAnswerMask);
void setResult (const unsigned uCorrect, const unsigned uWrong, const unsigned uErrorPoints, const bool bPassed); void setResult (const unsigned uCorrect, const unsigned uWrong, const unsigned uErrorPoints, const bool bPassed);
inline unsigned duration() const { return m_uSecs; } inline unsigned duration() const { return m_uSecs; }
inline bool passed() const { return m_bPassed; } inline bool passed() const { return m_bPassed; }
inline unsigned correctAnswers() const { return m_uCorrect; } inline unsigned correctAnswers() const { return m_uCorrect; }
inline unsigned wrongAnswers() const { return m_uWrong; } inline unsigned wrongAnswers() const { return m_uWrong; }
inline unsigned errorPoints() const { return m_uErrorPoints; } inline unsigned errorPoints() const { return m_uErrorPoints; }
QDateTime datetime() const { return m_dt; } QDateTime datetime() const { return m_dt; }
protected: protected:
QString m_strId; //< ID der Prüfung QString m_strId; //< ID der Prüfung
QDateTime m_dt; //< Datum/Uhrzeit QDateTime m_dt; //< Datum/Uhrzeit
unsigned m_uSecs; //< Benötigte Zeit in sec unsigned m_uSecs; //< Benötigte Zeit in sec
QStringList m_strlQuestionId; //< IDs der Fragen QStringList m_strlQuestionId; //< IDs der Fragen
QList<unsigned> m_listAnswer; //< Antworten QList<unsigned> m_listAnswer; //< Antworten
unsigned m_uCorrect; //< Anzahl d. richtigen Fragen unsigned m_uCorrect; //< Anzahl d. richtigen Fragen
unsigned m_uWrong; //< Anzahl d. falschen Fragen unsigned m_uWrong; //< Anzahl d. falschen Fragen
unsigned m_uErrorPoints; //< Fehlerpunkte unsigned m_uErrorPoints; //< Fehlerpunkte
bool m_bPassed; //< Bestanden Ja/Nein bool m_bPassed; //< Bestanden Ja/Nein
}; };
#endif #endif

View File

@ -1,84 +1,84 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "helper.h" #include "helper.h"
#include "catalog.h" #include "catalog.h"
void CHint::clear() void CHint::clear()
{ {
m_strlQuestionId.clear(); m_strlQuestionId.clear();
m_strAuthor.clear(); m_strAuthor.clear();
m_date = QDate(); m_date = QDate();
m_strText.clear(); m_strText.clear();
m_strComment.clear(); m_strComment.clear();
} }
bool CHint::load (QDomElement elem) bool CHint::load (QDomElement elem)
{ {
QString str; QString str;
if (elem.tagName() != QString ("hint")) return false; if (elem.tagName() != QString ("hint")) return false;
m_strAuthor = elem.attribute ("author", "AFUTrainer-Hilfe"); m_strAuthor = elem.attribute ("author", "AFUTrainer-Hilfe");
m_date = QDate::fromString(elem.attribute ("date"), Qt::ISODate); m_date = QDate::fromString(elem.attribute ("date"), Qt::ISODate);
str = elem.attribute("question"); str = elem.attribute("question");
str = str.replace(' ', ';').replace(',', ';'); str = str.replace(' ', ';').replace(',', ';');
m_strlQuestionId = str.split(";", QString::SkipEmptyParts); m_strlQuestionId = str.split(";", QString::SkipEmptyParts);
m_strComment = elem.attribute ("comment"); m_strComment = elem.attribute ("comment");
m_strText = elem.text (); m_strText = elem.text ();
if (m_strText.isEmpty()) return false; if (m_strText.isEmpty()) return false;
return true; return true;
} }
void CHint::save (QDomElement& parent, QDomDocument& doc) void CHint::save (QDomElement& parent, QDomDocument& doc)
{ {
QDomElement elemRoot = doc.createElement("hint"); QDomElement elemRoot = doc.createElement("hint");
if (!m_strAuthor.isEmpty()) elemRoot.setAttribute("author", m_strAuthor); if (!m_strAuthor.isEmpty()) elemRoot.setAttribute("author", m_strAuthor);
if (m_date.isValid()) elemRoot.setAttribute("date", m_date.toString(Qt::ISODate)); if (m_date.isValid()) elemRoot.setAttribute("date", m_date.toString(Qt::ISODate));
elemRoot.setAttribute("question", m_strlQuestionId.join(";")); elemRoot.setAttribute("question", m_strlQuestionId.join(";"));
if (!m_strComment.isEmpty()) elemRoot.setAttribute("comment", m_strComment); if (!m_strComment.isEmpty()) elemRoot.setAttribute("comment", m_strComment);
parent.appendChild(elemRoot); parent.appendChild(elemRoot);
elemRoot.appendChild(doc.createTextNode(m_strText)); elemRoot.appendChild(doc.createTextNode(m_strText));
} }
QString CHint::showText() const QString CHint::showText() const
{ {
QString str; QString str;
/* if (text().isEmpty()) /* if (text().isEmpty())
{ {
if (pCatalog) if (pCatalog)
return pCatalog->hintText(id()); return pCatalog->hintText(id());
else else
return QString(); return QString();
} }
*/ */
/* str = "<p><table cellspacing='0' border='0' width='100%'>"; /* str = "<p><table cellspacing='0' border='0' width='100%'>";
str += "<tr><td bgcolor='gray'><b>"+author()+"</b></td>"; str += "<tr><td bgcolor='gray'><b>"+author()+"</b></td>";
str += "<td bgcolor='gray' align='right'><b>"+dateString()+"</b></td></tr>"; str += "<td bgcolor='gray' align='right'><b>"+dateString()+"</b></td></tr>";
str += "<tr><td colspan='2'>"+text()+"</td></tr>"; str += "<tr><td colspan='2'>"+text()+"</td></tr>";
str += "<tr><td colspan='2'>&nbsp;</td></tr>"; str += "<tr><td colspan='2'>&nbsp;</td></tr>";
str += "</table></p>"; str += "</table></p>";
*/ */
str += "<p>" + text() + "</p>"; //"<p><i><font size=-1>" + author() + "&nbsp;" + date() + "</font></i></p>"; str += "<p>" + text() + "</p>"; //"<p><i><font size=-1>" + author() + "&nbsp;" + date() + "</font></i></p>";
return (str); return (str);
} }

142
helper.h
View File

@ -1,71 +1,71 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef HELPER_H #ifndef HELPER_H
#define HELPER_H #define HELPER_H
#include <qstring.h> #include <qstring.h>
#include <qdom.h> #include <qdom.h>
#include <qdatetime.h> #include <qdatetime.h>
#include <qstringlist.h> #include <qstringlist.h>
class CCatalog; class CCatalog;
class CHint class CHint
{ {
public: public:
CHint() { clear(); } CHint() { clear(); }
~CHint() {} ~CHint() {}
void clear(); void clear();
inline void appendQuestion(const QString& id) { if (!hasQuestion(id)) m_strlQuestionId.append(id); } inline void appendQuestion(const QString& id) { if (!hasQuestion(id)) m_strlQuestionId.append(id); }
inline void removeQuestion(const QString& id) { m_strlQuestionId.removeAll(id); } inline void removeQuestion(const QString& id) { m_strlQuestionId.removeAll(id); }
inline bool hasQuestion(const QString& id) const { return m_strlQuestionId.contains(id); } inline bool hasQuestion(const QString& id) const { return m_strlQuestionId.contains(id); }
inline QString author() const { return m_strAuthor; } inline QString author() const { return m_strAuthor; }
inline void setAuthor(const QString& strAuthor) { m_strAuthor = strAuthor; } inline void setAuthor(const QString& strAuthor) { m_strAuthor = strAuthor; }
inline QDate date() const { return m_date; } inline QDate date() const { return m_date; }
inline QString dateString() const { return m_date.toString(Qt::LocalDate); } inline QString dateString() const { return m_date.toString(Qt::LocalDate); }
inline void setDate (const QDate& date) { m_date = date; } inline void setDate (const QDate& date) { m_date = date; }
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
inline void setText(const QString& strText) { m_strText = strText; } inline void setText(const QString& strText) { m_strText = strText; }
inline QString comment() const { return m_strComment; } inline QString comment() const { return m_strComment; }
inline void setComment (const QString& strComment) { m_strComment = strComment; } inline void setComment (const QString& strComment) { m_strComment = strComment; }
QString showText() const; QString showText() const;
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc); void save (QDomElement& parent, QDomDocument& doc);
protected: protected:
QStringList m_strlQuestionId; QStringList m_strlQuestionId;
QString m_strAuthor; QString m_strAuthor;
QDate m_date; QDate m_date;
QString m_strText; QString m_strText;
QString m_strComment; QString m_strComment;
}; };
#endif #endif

View File

@ -1,42 +1,42 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "mainwindow.h" #include "mainwindow.h"
#include <qapplication.h> #include <qapplication.h>
#include <qtranslator.h> #include <qtranslator.h>
#include <time.h> #include <time.h>
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
QApplication app (argc, argv); QApplication app (argc, argv);
QTranslator translator; QTranslator translator;
app.setOrganizationName ("osaal"); app.setOrganizationName ("osaal");
app.setApplicationName ("AFUTrainer"); app.setApplicationName ("AFUTrainer");
translator.load(":/translations/qt_de"); translator.load(":/translations/qt_de");
app.installTranslator(&translator); app.installTranslator(&translator);
srand (time (NULL)); srand (time (NULL));
CMainWindow mw; CMainWindow mw;
mw.show(); mw.show();
return app.exec(); return app.exec();
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,91 +1,91 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef MAINWINDOW_H #ifndef MAINWINDOW_H
#define MAINWINDOW_H #define MAINWINDOW_H
#include <qmainwindow.h> #include <qmainwindow.h>
#include <qsplitter.h> #include <qsplitter.h>
#include <qtreeview.h> #include <qtreeview.h>
#include <qtextbrowser.h> #include <qtextbrowser.h>
#include "catalogmodel.h" #include "catalogmodel.h"
#include "questionmodel.h" #include "questionmodel.h"
#include "recentfiles.h" #include "recentfiles.h"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
class CMainWindow : public QMainWindow, protected Ui::MainWindow class CMainWindow : public QMainWindow, protected Ui::MainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
CMainWindow(); CMainWindow();
~CMainWindow(); ~CMainWindow();
protected: protected:
void setCatalog (CCatalog *pCatalog); void setCatalog (CCatalog *pCatalog);
void updateWindowTitle(); void updateWindowTitle();
bool checkForErrors(); bool checkForErrors();
bool checkForHomeDir(); bool checkForHomeDir();
protected slots: protected slots:
void on_actFileNew_triggered(); void on_actFileNew_triggered();
void on_actFileOpen_triggered(); void on_actFileOpen_triggered();
void on_actFileInformation_triggered(); void on_actFileInformation_triggered();
void on_actFileSave_triggered(); void on_actFileSave_triggered();
void on_actFileSaveAs_triggered(); void on_actFileSaveAs_triggered();
void on_actFileImport_triggered(); void on_actFileImport_triggered();
void on_actFileImportUS_triggered(); void on_actFileImportUS_triggered();
void on_actFileExit_triggered(); void on_actFileExit_triggered();
void on_actQuestionAssistant_triggered(); void on_actQuestionAssistant_triggered();
void on_actQuestionsLearn_triggered(); void on_actQuestionsLearn_triggered();
void on_actQuestionsLearnStatistics_triggered(); void on_actQuestionsLearnStatistics_triggered();
void on_actQuestionsTest_triggered(); void on_actQuestionsTest_triggered();
void on_actQuestionsTestStatistics_triggered(); void on_actQuestionsTestStatistics_triggered();
void on_actViewToolbar_toggled(bool bChecked); void on_actViewToolbar_toggled(bool bChecked);
void on_actViewStatusbar_toggled(bool bChecked); void on_actViewStatusbar_toggled(bool bChecked);
void on_actHelpWhatsThis_triggered(); void on_actHelpWhatsThis_triggered();
void on_actHelpAbout_triggered(); void on_actHelpAbout_triggered();
void on_actHelpAboutQt_triggered(); void on_actHelpAboutQt_triggered();
void onCatalogSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected); void onCatalogSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected);
void onQuestionSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected); void onQuestionSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected);
void onOpenFile(const QString& strFileName); void onOpenFile(const QString& strFileName);
// void onAnchorClicked (const QUrl &link ); // void onAnchorClicked (const QUrl &link );
protected: protected:
CRecentFiles m_rf; CRecentFiles m_rf;
QSplitter *m_pSplitter; // splitter widget QSplitter *m_pSplitter; // splitter widget
QTreeView *m_pViewChapter; // listview chapters QTreeView *m_pViewChapter; // listview chapters
QTreeView *m_pViewQuestions; // listview questions QTreeView *m_pViewQuestions; // listview questions
QSplitter *m_pSplitter2; QSplitter *m_pSplitter2;
QTextBrowser *m_pTextQuestion; QTextBrowser *m_pTextQuestion;
CCatalog *m_pCatalog; CCatalog *m_pCatalog;
CCatalogModel m_modelCatalog; CCatalogModel m_modelCatalog;
CQuestionModel m_modelQuestion; CQuestionModel m_modelQuestion;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -1,467 +1,467 @@
#include "osziparchive.h" #include "osziparchive.h"
#include "zlib/zlib.h" #include "zlib/zlib.h"
#include <qbytearray.h> #include <qbytearray.h>
#include <qdatastream.h> #include <qdatastream.h>
#include <qtextstream.h> #include <qtextstream.h>
void CZipFileHeader::clear() void CZipFileHeader::clear()
{ {
m_uVersionMadeBy = 0; m_uVersionMadeBy = 0;
m_uVersionNeeded = 0; m_uVersionNeeded = 0;
m_uFlags = 0; m_uFlags = 0;
m_uCompression = 0; m_uCompression = 0;
m_uTime = 0; m_uTime = 0;
m_uDate = 0; m_uDate = 0;
m_uCRC = 0; m_uCRC = 0;
m_uSizeCompressed = 0; m_uSizeCompressed = 0;
m_uSizeUncompressed = 0; m_uSizeUncompressed = 0;
m_uDiskNumberStart = 0; m_uDiskNumberStart = 0;
m_uInternalFileAttributes = 0; m_uInternalFileAttributes = 0;
m_uExternalFileAttributes = 0; m_uExternalFileAttributes = 0;
m_uRelativeOffsetLocalHeader = 0; m_uRelativeOffsetLocalHeader = 0;
m_strFileName.clear(); m_strFileName.clear();
m_strComment.clear(); m_strComment.clear();
m_baExtraField.clear(); m_baExtraField.clear();
// helpers // helpers
m_uDataPosition = 0; m_uDataPosition = 0;
m_uLocalHeaderPosition = 0; m_uLocalHeaderPosition = 0;
m_uCentralHeaderPosition = 0; m_uCentralHeaderPosition = 0;
} }
void CZipFileHeader::integrate(const CZipFileHeader& head) void CZipFileHeader::integrate(const CZipFileHeader& head)
{ {
if (m_uVersionMadeBy == 0) m_uVersionMadeBy = head.m_uVersionMadeBy; if (m_uVersionMadeBy == 0) m_uVersionMadeBy = head.m_uVersionMadeBy;
if (m_uVersionNeeded == 0) m_uVersionNeeded = head.m_uVersionNeeded; if (m_uVersionNeeded == 0) m_uVersionNeeded = head.m_uVersionNeeded;
if (m_uFlags == 0) m_uFlags = head.m_uFlags; if (m_uFlags == 0) m_uFlags = head.m_uFlags;
if (m_uCompression == 0) m_uCompression = head.m_uCompression; if (m_uCompression == 0) m_uCompression = head.m_uCompression;
if (m_uTime == 0) m_uTime = head.m_uTime; if (m_uTime == 0) m_uTime = head.m_uTime;
if (m_uDate == 0) m_uDate = head.m_uDate; if (m_uDate == 0) m_uDate = head.m_uDate;
if (m_uCRC == 0) m_uCRC = head.m_uCRC; if (m_uCRC == 0) m_uCRC = head.m_uCRC;
if (m_uSizeCompressed == 0) m_uSizeCompressed = head.m_uSizeCompressed; if (m_uSizeCompressed == 0) m_uSizeCompressed = head.m_uSizeCompressed;
if (m_uSizeUncompressed == 0) m_uSizeUncompressed = head.m_uSizeUncompressed; if (m_uSizeUncompressed == 0) m_uSizeUncompressed = head.m_uSizeUncompressed;
if (m_uDiskNumberStart == 0) m_uDiskNumberStart = head.m_uDiskNumberStart; if (m_uDiskNumberStart == 0) m_uDiskNumberStart = head.m_uDiskNumberStart;
if (m_uInternalFileAttributes == 0) m_uInternalFileAttributes = head.m_uInternalFileAttributes; if (m_uInternalFileAttributes == 0) m_uInternalFileAttributes = head.m_uInternalFileAttributes;
if (m_uExternalFileAttributes == 0) m_uExternalFileAttributes = head.m_uExternalFileAttributes; if (m_uExternalFileAttributes == 0) m_uExternalFileAttributes = head.m_uExternalFileAttributes;
if (m_uRelativeOffsetLocalHeader == 0) m_uRelativeOffsetLocalHeader = head.m_uRelativeOffsetLocalHeader; if (m_uRelativeOffsetLocalHeader == 0) m_uRelativeOffsetLocalHeader = head.m_uRelativeOffsetLocalHeader;
if (m_strFileName.isEmpty()) m_strFileName = head.m_strFileName; if (m_strFileName.isEmpty()) m_strFileName = head.m_strFileName;
if (m_baExtraField.isEmpty()) m_baExtraField = head.m_baExtraField; if (m_baExtraField.isEmpty()) m_baExtraField = head.m_baExtraField;
if (m_strComment.isEmpty()) m_strComment = head.m_strComment; if (m_strComment.isEmpty()) m_strComment = head.m_strComment;
if (m_uDataPosition == 0) m_uDataPosition = head.m_uDataPosition; if (m_uDataPosition == 0) m_uDataPosition = head.m_uDataPosition;
if (m_uLocalHeaderPosition == 0) m_uLocalHeaderPosition = head.m_uLocalHeaderPosition; if (m_uLocalHeaderPosition == 0) m_uLocalHeaderPosition = head.m_uLocalHeaderPosition;
if (m_uCentralHeaderPosition == 0) m_uCentralHeaderPosition = head.m_uCentralHeaderPosition; if (m_uCentralHeaderPosition == 0) m_uCentralHeaderPosition = head.m_uCentralHeaderPosition;
} }
bool CZipFileHeader::readLocalFileHeader(QFile& file) bool CZipFileHeader::readLocalFileHeader(QFile& file)
{ {
QDataStream in(&file); QDataStream in(&file);
quint16 uFileNameLength=0, uExtraFieldLength=0; quint16 uFileNameLength=0, uExtraFieldLength=0;
clear(); clear();
in.setByteOrder(QDataStream::LittleEndian); in.setByteOrder(QDataStream::LittleEndian);
m_uLocalHeaderPosition = file.pos(); m_uLocalHeaderPosition = file.pos();
in >> m_uVersionNeeded; in >> m_uVersionNeeded;
in >> m_uFlags; in >> m_uFlags;
in >> m_uCompression; in >> m_uCompression;
in >> m_uTime; in >> m_uTime;
in >> m_uDate; in >> m_uDate;
in >> m_uCRC; in >> m_uCRC;
in >> m_uSizeCompressed; in >> m_uSizeCompressed;
in >> m_uSizeUncompressed; in >> m_uSizeUncompressed;
in >> uFileNameLength; in >> uFileNameLength;
in >> uExtraFieldLength; in >> uExtraFieldLength;
if (uFileNameLength != 0) if (uFileNameLength != 0)
{ {
QByteArray a (uFileNameLength, 0); QByteArray a (uFileNameLength, 0);
in.readRawData(a.data(), uFileNameLength); in.readRawData(a.data(), uFileNameLength);
m_strFileName = a; m_strFileName = a;
} }
if (uExtraFieldLength != 0) if (uExtraFieldLength != 0)
{ {
m_baExtraField.resize(uExtraFieldLength); m_baExtraField.resize(uExtraFieldLength);
in.readRawData(m_baExtraField.data(), uExtraFieldLength); in.readRawData(m_baExtraField.data(), uExtraFieldLength);
} }
m_uDataPosition = file.pos(); m_uDataPosition = file.pos();
in.skipRawData(m_uSizeCompressed); in.skipRawData(m_uSizeCompressed);
if (hasDataDescriptor()) if (hasDataDescriptor())
{ {
in >> m_uCRC; in >> m_uCRC;
in >> m_uSizeCompressed; in >> m_uSizeCompressed;
in >> m_uSizeUncompressed; in >> m_uSizeUncompressed;
} }
return true; return true;
} }
void CZipFileHeader::writeLocalFileHeader(QFile& file) void CZipFileHeader::writeLocalFileHeader(QFile& file)
{ {
Q_UNUSED(file); Q_UNUSED(file);
} }
bool CZipFileHeader::readCentralDirectoryHeader(QFile& file) bool CZipFileHeader::readCentralDirectoryHeader(QFile& file)
{ {
QDataStream in(&file); QDataStream in(&file);
quint16 uFileNameLength=0, uExtraFieldLength=0, uCommentLength=0; quint16 uFileNameLength=0, uExtraFieldLength=0, uCommentLength=0;
clear(); clear();
in.setByteOrder(QDataStream::LittleEndian); in.setByteOrder(QDataStream::LittleEndian);
m_uCentralHeaderPosition = file.pos(); m_uCentralHeaderPosition = file.pos();
in >> m_uVersionMadeBy; in >> m_uVersionMadeBy;
in >> m_uVersionNeeded; in >> m_uVersionNeeded;
in >> m_uFlags; in >> m_uFlags;
in >> m_uCompression; in >> m_uCompression;
in >> m_uTime; in >> m_uTime;
in >> m_uDate; in >> m_uDate;
in >> m_uCRC; in >> m_uCRC;
in >> m_uSizeCompressed; in >> m_uSizeCompressed;
in >> m_uSizeUncompressed; in >> m_uSizeUncompressed;
in >> uFileNameLength; in >> uFileNameLength;
in >> uExtraFieldLength; in >> uExtraFieldLength;
in >> uCommentLength; in >> uCommentLength;
in >> m_uDiskNumberStart; in >> m_uDiskNumberStart;
in >> m_uInternalFileAttributes; in >> m_uInternalFileAttributes;
in >> m_uExternalFileAttributes; in >> m_uExternalFileAttributes;
in >> m_uRelativeOffsetLocalHeader; in >> m_uRelativeOffsetLocalHeader;
if (uFileNameLength != 0) if (uFileNameLength != 0)
{ {
QByteArray a (uFileNameLength, 0); QByteArray a (uFileNameLength, 0);
in.readRawData(a.data(), uFileNameLength); in.readRawData(a.data(), uFileNameLength);
m_strFileName = a; m_strFileName = a;
} }
if (uExtraFieldLength != 0) if (uExtraFieldLength != 0)
{ {
m_baExtraField.resize(uExtraFieldLength); m_baExtraField.resize(uExtraFieldLength);
in.readRawData(m_baExtraField.data(), uExtraFieldLength); in.readRawData(m_baExtraField.data(), uExtraFieldLength);
} }
if (uCommentLength != 0) if (uCommentLength != 0)
{ {
QByteArray a (uCommentLength, 0); QByteArray a (uCommentLength, 0);
in.readRawData(a.data(), uCommentLength); in.readRawData(a.data(), uCommentLength);
m_strComment = a; m_strComment = a;
} }
return true; return true;
} }
void CZipFileHeader::writeCentralDirectoryHeader(QFile& file) void CZipFileHeader::writeCentralDirectoryHeader(QFile& file)
{ {
Q_UNUSED(file); Q_UNUSED(file);
} }
void CZipEndRecord::clear() void CZipEndRecord::clear()
{ {
m_uDisk = 0; m_uDisk = 0;
m_uDiskCentralDir = 0; m_uDiskCentralDir = 0;
m_uEntriesCentralDirDisk = 0; m_uEntriesCentralDirDisk = 0;
m_uEntriesCentralDir = 0; m_uEntriesCentralDir = 0;
m_uCentralDirSize = 0; m_uCentralDirSize = 0;
m_uCentralDirOffset = 0; m_uCentralDirOffset = 0;
m_strComment.clear(); m_strComment.clear();
} }
bool CZipEndRecord::read (QFile& file) bool CZipEndRecord::read (QFile& file)
{ {
QDataStream in(&file); QDataStream in(&file);
quint16 uCommentLength=0; quint16 uCommentLength=0;
clear(); clear();
in.setByteOrder(QDataStream::LittleEndian); in.setByteOrder(QDataStream::LittleEndian);
in >> m_uDisk; in >> m_uDisk;
in >> m_uDiskCentralDir; in >> m_uDiskCentralDir;
in >> m_uEntriesCentralDirDisk; in >> m_uEntriesCentralDirDisk;
in >> m_uEntriesCentralDir; in >> m_uEntriesCentralDir;
in >> m_uCentralDirSize; in >> m_uCentralDirSize;
in >> m_uCentralDirOffset; in >> m_uCentralDirOffset;
in >> uCommentLength; in >> uCommentLength;
if (uCommentLength != 0) if (uCommentLength != 0)
{ {
QByteArray a (uCommentLength, 0); QByteArray a (uCommentLength, 0);
in.readRawData(a.data(), uCommentLength); in.readRawData(a.data(), uCommentLength);
m_strComment = a; m_strComment = a;
} }
return true; return true;
} }
void CZipEndRecord::write (QFile& file) void CZipEndRecord::write (QFile& file)
{ {
Q_UNUSED(file); Q_UNUSED(file);
} }
CZipFile::CZipFile(CZipArchive *pArchive) CZipFile::CZipFile(CZipArchive *pArchive)
{ {
m_pArchive = pArchive; m_pArchive = pArchive;
clear(); clear();
} }
CZipFile::~CZipFile() CZipFile::~CZipFile()
{ {
} }
void CZipFile::clear() void CZipFile::clear()
{ {
} }
bool CZipFile::readHeader () bool CZipFile::readHeader ()
{ {
QFile& file = m_pArchive->m_file; QFile& file = m_pArchive->m_file;
return (m_head.readLocalFileHeader(file)); return (m_head.readLocalFileHeader(file));
} }
QByteArray CZipFile::deflateToByteArray() QByteArray CZipFile::deflateToByteArray()
{ {
/*QByteArray a, b; /*QByteArray a, b;
if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return QByteArray(); if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return QByteArray();
m_pArchive->m_file.seek (m_head.m_uDataPosition); m_pArchive->m_file.seek (m_head.m_uDataPosition);
a = m_pArchive->m_file.read (m_head.m_uSizeCompressed); a = m_pArchive->m_file.read (m_head.m_uSizeCompressed);
b.resize(m_head.m_uSizeUncompressed); b.resize(m_head.m_uSizeUncompressed);
quint32 u = m_head.m_uSizeUncompressed; quint32 u = m_head.m_uSizeUncompressed;
Bytef* src = (Bytef*)a.data(); Bytef* src = (Bytef*)a.data();
Bytef* dst = (Bytef*)b.data(); Bytef* dst = (Bytef*)b.data();
if (uncompress(dst, (uLongf*) &u, src, m_head.m_uSizeCompressed) != Z_OK) if (uncompress(dst, (uLongf*) &u, src, m_head.m_uSizeCompressed) != Z_OK)
return QByteArray(); return QByteArray();
return b;*/ return b;*/
QByteArray a; QByteArray a;
z_stream strm; z_stream strm;
char *pIn=0, *pOut=0; char *pIn=0, *pOut=0;
int ret; int ret;
memset(&strm, 0, sizeof(z_stream)); memset(&strm, 0, sizeof(z_stream));
if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return QByteArray(); if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return QByteArray();
// prepare zip-stream // prepare zip-stream
/* windowBits is passed < 0 to tell that there is no zlib header. /* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte * Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and * after the compressed stream in order to complete decompression and
* return Z_STREAM_END. * return Z_STREAM_END.
*/ */
if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) return QByteArray(); if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) return QByteArray();
// read data // read data
pIn = new char[m_head.m_uSizeCompressed+1]; pIn = new char[m_head.m_uSizeCompressed+1];
memset (pIn, 0, m_head.m_uSizeCompressed+1); memset (pIn, 0, m_head.m_uSizeCompressed+1);
m_pArchive->m_file.seek (m_head.m_uDataPosition); m_pArchive->m_file.seek (m_head.m_uDataPosition);
m_pArchive->m_file.read (pIn, m_head.m_uSizeCompressed); m_pArchive->m_file.read (pIn, m_head.m_uSizeCompressed);
// prepare output // prepare output
pOut = new char[m_head.m_uSizeUncompressed]; pOut = new char[m_head.m_uSizeUncompressed];
memset(pOut, 0, m_head.m_uSizeUncompressed); memset(pOut, 0, m_head.m_uSizeUncompressed);
/* /*
// DEBUG START // DEBUG START
FILE *fpt; FILE *fpt;
fpt = fopen ("questions.xml", "rt"); fpt = fopen ("questions.xml", "rt");
fread (pOut, m_head.m_uSizeUncompressed, 1, fpt); fread (pOut, m_head.m_uSizeUncompressed, 1, fpt);
fclose (fpt); fclose (fpt);
unsigned u = m_head.m_uSizeCompressed; unsigned u = m_head.m_uSizeCompressed;
fpt = fopen ("test2.gz", "wb"); fpt = fopen ("test2.gz", "wb");
compress2((Bytef*)pIn, (uLongf*) &u, (Bytef*)pOut, m_head.m_uSizeUncompressed, 9); compress2((Bytef*)pIn, (uLongf*) &u, (Bytef*)pOut, m_head.m_uSizeUncompressed, 9);
fwrite (pIn, u, 1, fpt); fwrite (pIn, u, 1, fpt);
fclose (fpt); fclose (fpt);
// DEBUG ENDE // DEBUG ENDE
*/ */
do do
{ {
strm.avail_in = m_head.m_uSizeCompressed+1; strm.avail_in = m_head.m_uSizeCompressed+1;
strm.next_in = (Bytef*) pIn; strm.next_in = (Bytef*) pIn;
do do
{ {
strm.avail_out = m_head.m_uSizeUncompressed; strm.avail_out = m_head.m_uSizeUncompressed;
strm.next_out = (Bytef*) pOut; strm.next_out = (Bytef*) pOut;
ret = inflate (&strm, Z_SYNC_FLUSH); ret = inflate (&strm, Z_SYNC_FLUSH);
switch (ret) switch (ret)
{ {
case Z_NEED_DICT: case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */ ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR: case Z_DATA_ERROR:
case Z_MEM_ERROR: case Z_MEM_ERROR:
inflateEnd(&strm); inflateEnd(&strm);
delete [] pIn; delete [] pIn;
delete [] pOut; delete [] pOut;
return QByteArray(); return QByteArray();
} }
} }
while (strm.avail_out == 0); while (strm.avail_out == 0);
/* done when inflate() says it's done */ /* done when inflate() says it's done */
} }
while (ret != Z_STREAM_END); while (ret != Z_STREAM_END);
inflateEnd(&strm); inflateEnd(&strm);
a = QByteArray (pOut, m_head.m_uSizeUncompressed); a = QByteArray (pOut, m_head.m_uSizeUncompressed);
delete [] pIn; delete [] pIn;
delete [] pOut; delete [] pOut;
return a; return a;
} }
/* /*
QString CZipFile::deflateToString() QString CZipFile::deflateToString()
{ {
QByteArray a = deflateToByteArray(); QByteArray a = deflateToByteArray();
QTextStream in (a, QIODevice::ReadOnly); QTextStream in (a, QIODevice::ReadOnly);
//QString str; //QString str;
// in >> str; // in >> str;
return in.readAll(); return in.readAll();
} }
*/ */
#define CHUNK (1<<16) #define CHUNK (1<<16)
bool CZipFile::deflateToFile (QIODevice& dev) bool CZipFile::deflateToFile (QIODevice& dev)
{ {
z_stream strm; z_stream strm;
char cIn[CHUNK], cOut[CHUNK]; char cIn[CHUNK], cOut[CHUNK];
int ret; int ret;
if ((dev.openMode() & QIODevice::WriteOnly) == 0) if ((dev.openMode() & QIODevice::WriteOnly) == 0)
return false; return false;
memset(&strm, 0, sizeof(z_stream)); memset(&strm, 0, sizeof(z_stream));
if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return false; if (m_head.m_uDataPosition == 0 || m_head.m_uSizeUncompressed == 0) return false;
// prepare zip-stream // prepare zip-stream
/* windowBits is passed < 0 to tell that there is no zlib header. /* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte * Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and * after the compressed stream in order to complete decompression and
* return Z_STREAM_END. * return Z_STREAM_END.
*/ */
if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) return false; if (inflateInit2(&strm, -MAX_WBITS) != Z_OK) return false;
// prepare archive // prepare archive
m_pArchive->m_file.seek (m_head.m_uDataPosition); m_pArchive->m_file.seek (m_head.m_uDataPosition);
// unzip // unzip
unsigned uRead=0, uBytes=0; unsigned uRead=0, uBytes=0;
do do
{ {
uBytes = m_pArchive->m_file.read(cIn, CHUNK); uBytes = m_pArchive->m_file.read(cIn, CHUNK);
if (uRead + uBytes > m_head.m_uSizeCompressed) if (uRead + uBytes > m_head.m_uSizeCompressed)
uBytes = m_head.m_uSizeCompressed - uRead + 1; // one dummy byte extra uBytes = m_head.m_uSizeCompressed - uRead + 1; // one dummy byte extra
uRead += uBytes; uRead += uBytes;
strm.avail_in = uBytes; strm.avail_in = uBytes;
if (strm.avail_in == 0) break; if (strm.avail_in == 0) break;
strm.next_in = (Bytef*) cIn; strm.next_in = (Bytef*) cIn;
do do
{ {
strm.avail_out = CHUNK; strm.avail_out = CHUNK;
strm.next_out = (Bytef*) cOut; strm.next_out = (Bytef*) cOut;
ret = inflate (&strm, Z_NO_FLUSH); ret = inflate (&strm, Z_NO_FLUSH);
switch (ret) switch (ret)
{ {
case Z_NEED_DICT: case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */ ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR: case Z_DATA_ERROR:
case Z_MEM_ERROR: case Z_MEM_ERROR:
inflateEnd(&strm); inflateEnd(&strm);
return false; return false;
} }
unsigned uHave = CHUNK - strm.avail_out; unsigned uHave = CHUNK - strm.avail_out;
dev.write(cOut, uHave); dev.write(cOut, uHave);
} }
while (strm.avail_out == 0); while (strm.avail_out == 0);
/* done when inflate() says it's done */ /* done when inflate() says it's done */
} }
while (ret != Z_STREAM_END); while (ret != Z_STREAM_END);
inflateEnd(&strm); inflateEnd(&strm);
return true; return true;
} }
CZipArchive::CZipArchive() CZipArchive::CZipArchive()
{ {
} }
CZipArchive::~CZipArchive() CZipArchive::~CZipArchive()
{ {
qDeleteAll(m_listFiles); qDeleteAll(m_listFiles);
qDeleteAll(m_listEndRecords); qDeleteAll(m_listEndRecords);
} }
bool CZipArchive::open (const QString& strFileName, const OpenMode om) bool CZipArchive::open (const QString& strFileName, const OpenMode om)
{ {
unsigned uSignature=0; unsigned uSignature=0;
CZipFile *pzf=0; CZipFile *pzf=0;
if (strFileName.isEmpty()) return false; if (strFileName.isEmpty()) return false;
if (om != OpenReadOnly) return false; if (om != OpenReadOnly) return false;
m_strFileName = strFileName; m_strFileName = strFileName;
m_file.close(); m_file.close();
m_file.setFileName(strFileName); m_file.setFileName(strFileName);
if (!m_file.open(QIODevice::ReadOnly)) return false; if (!m_file.open(QIODevice::ReadOnly)) return false;
QDataStream in(&m_file); QDataStream in(&m_file);
in.setByteOrder(QDataStream::LittleEndian); in.setByteOrder(QDataStream::LittleEndian);
while (!in.atEnd()) while (!in.atEnd())
{ {
uSignature = 0; uSignature = 0;
in >> uSignature; in >> uSignature;
if (uSignature == 0x04034b50) if (uSignature == 0x04034b50)
{ // local file header with data { // local file header with data
pzf = new CZipFile(this); pzf = new CZipFile(this);
if (pzf->readHeader()) if (pzf->readHeader())
m_listFiles.append(pzf); m_listFiles.append(pzf);
//qDebug("%7i %7i %s", pzf->m_head.m_uSizeUncompressed, pzf->m_head.m_uSizeCompressed, qPrintable(pzf->fileName())); //qDebug("%7i %7i %s", pzf->m_head.m_uSizeUncompressed, pzf->m_head.m_uSizeCompressed, qPrintable(pzf->fileName()));
// file.deflateToFile("test.tmp"); // file.deflateToFile("test.tmp");
} }
else if (uSignature == 0x02014b50) else if (uSignature == 0x02014b50)
{ // central directory file header { // central directory file header
CZipFileHeader head; CZipFileHeader head;
head.readCentralDirectoryHeader(m_file); head.readCentralDirectoryHeader(m_file);
pzf = findFile(head.m_strFileName); pzf = findFile(head.m_strFileName);
if (pzf) pzf->m_head.integrate(head); if (pzf) pzf->m_head.integrate(head);
} }
else if (uSignature == 0x06054b50) else if (uSignature == 0x06054b50)
{ // End of central directory record { // End of central directory record
CZipEndRecord *pzer = new CZipEndRecord(); CZipEndRecord *pzer = new CZipEndRecord();
pzer->read(m_file); pzer->read(m_file);
m_listEndRecords.append(pzer); m_listEndRecords.append(pzer);
} }
else else
{ {
qDebug("Unknown signature: %X", uSignature); qDebug("Unknown signature: %X", uSignature);
break; break;
} }
} }
return true; return true;
} }
CZipFile* CZipArchive::findFile (const QString& strFileName) CZipFile* CZipArchive::findFile (const QString& strFileName)
{ {
for (int i=0; i<m_listFiles.size(); i++) for (int i=0; i<m_listFiles.size(); i++)
{ {
if (m_listFiles.at(i)->fileName() == strFileName) if (m_listFiles.at(i)->fileName() == strFileName)
return m_listFiles.at(i); return m_listFiles.at(i);
} }
return 0; return 0;
} }

View File

@ -1,155 +1,155 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2006 by Oliver Saal * * Copyright (C) 2003-2006 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef OSZIPARCHIVE_H #ifndef OSZIPARCHIVE_H
#define OSZIPARCHIVE_H #define OSZIPARCHIVE_H
#include <qfile.h> #include <qfile.h>
#include <qstring.h> #include <qstring.h>
#include <qlist.h> #include <qlist.h>
class CZipFile; class CZipFile;
class CZipArchive; class CZipArchive;
class CZipFileHeader class CZipFileHeader
{ {
public: public:
CZipFileHeader() { clear(); } CZipFileHeader() { clear(); }
~CZipFileHeader() {} ~CZipFileHeader() {}
void clear(); void clear();
void integrate(const CZipFileHeader& head); void integrate(const CZipFileHeader& head);
bool readLocalFileHeader(QFile& file); bool readLocalFileHeader(QFile& file);
void writeLocalFileHeader(QFile& file); void writeLocalFileHeader(QFile& file);
bool readCentralDirectoryHeader(QFile& file); bool readCentralDirectoryHeader(QFile& file);
void writeCentralDirectoryHeader(QFile& file); void writeCentralDirectoryHeader(QFile& file);
inline bool hasDataDescriptor() const { return m_uFlags & (1<<3) ? true : false; } inline bool hasDataDescriptor() const { return m_uFlags & (1<<3) ? true : false; }
public: public:
quint16 m_uVersionMadeBy; //!< version made by 2 bytes quint16 m_uVersionMadeBy; //!< version made by 2 bytes
quint16 m_uVersionNeeded; //!< version needed to extract 2 bytes quint16 m_uVersionNeeded; //!< version needed to extract 2 bytes
quint16 m_uFlags; //!< general purpose bit flag 2 bytes quint16 m_uFlags; //!< general purpose bit flag 2 bytes
quint16 m_uCompression; //!< compression method 2 bytes quint16 m_uCompression; //!< compression method 2 bytes
quint16 m_uTime; //!< last mod file time 2 bytes quint16 m_uTime; //!< last mod file time 2 bytes
quint16 m_uDate; //!< last mod file date 2 bytes quint16 m_uDate; //!< last mod file date 2 bytes
quint32 m_uCRC; //!< crc-32 4 bytes quint32 m_uCRC; //!< crc-32 4 bytes
quint32 m_uSizeCompressed; //!< compressed size 4 bytes quint32 m_uSizeCompressed; //!< compressed size 4 bytes
quint32 m_uSizeUncompressed; //!< uncompressed size 4 bytes quint32 m_uSizeUncompressed; //!< uncompressed size 4 bytes
quint16 m_uDiskNumberStart; //!< disk number start 2 bytes quint16 m_uDiskNumberStart; //!< disk number start 2 bytes
quint16 m_uInternalFileAttributes; //!< internal file attributes 2 bytes quint16 m_uInternalFileAttributes; //!< internal file attributes 2 bytes
quint32 m_uExternalFileAttributes; //!< external file attributes 4 bytes quint32 m_uExternalFileAttributes; //!< external file attributes 4 bytes
quint32 m_uRelativeOffsetLocalHeader; //!< relative offset of local header 4 bytes quint32 m_uRelativeOffsetLocalHeader; //!< relative offset of local header 4 bytes
QString m_strFileName; //!< file name (variable size) QString m_strFileName; //!< file name (variable size)
QByteArray m_baExtraField; //!< extra field (variable size) QByteArray m_baExtraField; //!< extra field (variable size)
QString m_strComment; //!< file comment (variable size) QString m_strComment; //!< file comment (variable size)
// helpers // helpers
quint64 m_uLocalHeaderPosition; //!< Position of the local file header, after the signature field quint64 m_uLocalHeaderPosition; //!< Position of the local file header, after the signature field
quint64 m_uDataPosition; //!< Position in the file of the data quint64 m_uDataPosition; //!< Position in the file of the data
quint64 m_uCentralHeaderPosition; //!< Position of the central directory file header, after the signature field quint64 m_uCentralHeaderPosition; //!< Position of the central directory file header, after the signature field
}; };
class CZipEndRecord class CZipEndRecord
{ {
public: public:
CZipEndRecord() { clear(); } CZipEndRecord() { clear(); }
~CZipEndRecord() { } ~CZipEndRecord() { }
void clear(); void clear();
bool read (QFile& file); bool read (QFile& file);
void write (QFile& file); void write (QFile& file);
public: public:
quint16 m_uDisk; //!< number of this disk 2 bytes quint16 m_uDisk; //!< number of this disk 2 bytes
quint16 m_uDiskCentralDir; //!< number of the disk with the start of the central directory 2 bytes quint16 m_uDiskCentralDir; //!< number of the disk with the start of the central directory 2 bytes
quint16 m_uEntriesCentralDirDisk; //!< total number of entries in the central directory on this disk 2 bytes quint16 m_uEntriesCentralDirDisk; //!< total number of entries in the central directory on this disk 2 bytes
quint16 m_uEntriesCentralDir; //!< total number of entries in the central directory 2 bytes quint16 m_uEntriesCentralDir; //!< total number of entries in the central directory 2 bytes
quint32 m_uCentralDirSize; //!< size of the central directory 4 bytes quint32 m_uCentralDirSize; //!< size of the central directory 4 bytes
quint32 m_uCentralDirOffset; //!< offset of start of central directory with respect to the starting disk number 4 bytes quint32 m_uCentralDirOffset; //!< offset of start of central directory with respect to the starting disk number 4 bytes
QString m_strComment; QString m_strComment;
}; };
//! Represents a file in a zip archive //! Represents a file in a zip archive
class CZipFile class CZipFile
{ {
public: public:
CZipFile() { m_pArchive = 0; clear(); } CZipFile() { m_pArchive = 0; clear(); }
CZipFile(CZipArchive *pArchive); CZipFile(CZipArchive *pArchive);
~CZipFile(); ~CZipFile();
void clear(); void clear();
inline bool isValid() const { return m_pArchive != 0; } inline bool isValid() const { return m_pArchive != 0; }
//! Reads local file header //! Reads local file header
//! Position has to be after the signature field //! Position has to be after the signature field
//! After the operation, the current position in the file is after the file data //! After the operation, the current position in the file is after the file data
bool readHeader(); bool readHeader();
bool deflateToFile (QIODevice& dev); bool deflateToFile (QIODevice& dev);
QByteArray deflateToByteArray(); QByteArray deflateToByteArray();
//QString deflateToString(); //QString deflateToString();
// bool read (FILE *fpt, unsigned uPosition); // bool read (FILE *fpt, unsigned uPosition);
//! this file has a data descriptor //! this file has a data descriptor
inline QString fileName() const { return m_head.m_strFileName; } inline QString fileName() const { return m_head.m_strFileName; }
public: public:
CZipArchive *m_pArchive; CZipArchive *m_pArchive;
CZipFileHeader m_head; CZipFileHeader m_head;
}; };
class CZipArchive class CZipArchive
{ {
public: public:
CZipArchive(); CZipArchive();
~CZipArchive(); ~CZipArchive();
enum OpenMode { OpenReadOnly, OpenCreate, OpenModify }; enum OpenMode { OpenReadOnly, OpenCreate, OpenModify };
bool open (const QString& strFileName, const OpenMode om); bool open (const QString& strFileName, const OpenMode om);
CZipFile* findFile (const QString& strFileName); CZipFile* findFile (const QString& strFileName);
inline int fileCount() const { return m_listFiles.size(); } inline int fileCount() const { return m_listFiles.size(); }
const CZipFile* fileAt(const int i) const { return m_listFiles.at(i); } const CZipFile* fileAt(const int i) const { return m_listFiles.at(i); }
CZipFile* fileAt(const int i) { return m_listFiles.at(i); } CZipFile* fileAt(const int i) { return m_listFiles.at(i); }
protected: protected:
friend class CZipFile; friend class CZipFile;
QFile m_file; QFile m_file;
QString m_strFileName; QString m_strFileName;
QList<CZipFile*> m_listFiles; QList<CZipFile*> m_listFiles;
QList<CZipEndRecord*> m_listEndRecords; QList<CZipEndRecord*> m_listEndRecords;
}; };
#endif #endif

View File

@ -1,426 +1,426 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "plotwidget.h" #include "plotwidget.h"
#include <qpainter.h> #include <qpainter.h>
void CPlotWidgetPoint::clear() void CPlotWidgetPoint::clear()
{ {
} }
void CPlotWidgetCurve::clear() void CPlotWidgetCurve::clear()
{ {
QList<CPlotWidgetPoint>::clear(); QList<CPlotWidgetPoint>::clear();
} }
QRectF CPlotWidgetCurve::boundaries() const QRectF CPlotWidgetCurve::boundaries() const
{ {
QRectF rect; QRectF rect;
for (int i=0; i<size(); i++) for (int i=0; i<size(); i++)
{ {
QPointF p = at(i); QPointF p = at(i);
if (i == 0) if (i == 0)
{ {
rect.setBottomLeft(p); rect.setBottomLeft(p);
rect.setTopRight(p); rect.setTopRight(p);
} }
else else
{ {
if (p.x() < rect.left()) if (p.x() < rect.left())
rect.setLeft(p.x()); rect.setLeft(p.x());
else if (p.x() > rect.right()) else if (p.x() > rect.right())
rect.setRight(p.x()); rect.setRight(p.x());
if (p.y() > rect.bottom()) if (p.y() > rect.bottom())
rect.setBottom(p.y()); rect.setBottom(p.y());
else if (p.y() < rect.top()) else if (p.y() < rect.top())
rect.setTop(p.y()); rect.setTop(p.y());
} }
} }
return rect; return rect;
} }
CPlotWidgetTic::CPlotWidgetTic(const double dPos, const QString& strText) CPlotWidgetTic::CPlotWidgetTic(const double dPos, const QString& strText)
{ {
clear(); clear();
m_dPos = dPos; m_dPos = dPos;
m_strText = strText; m_strText = strText;
} }
CPlotWidgetTic::CPlotWidgetTic(const double dPos, const double dWidth, const QString& strText) CPlotWidgetTic::CPlotWidgetTic(const double dPos, const double dWidth, const QString& strText)
{ {
clear(); clear();
m_dPos = dPos; m_dPos = dPos;
m_dWidth = dWidth; m_dWidth = dWidth;
m_strText = strText; m_strText = strText;
} }
CPlotWidgetTic::CPlotWidgetTic(const double dPos, const QPixmap& pixmap) CPlotWidgetTic::CPlotWidgetTic(const double dPos, const QPixmap& pixmap)
{ {
clear(); clear();
m_dPos = dPos; m_dPos = dPos;
m_pixmap = pixmap; m_pixmap = pixmap;
} }
void CPlotWidgetTic::clear() void CPlotWidgetTic::clear()
{ {
m_dPos = 0.0; m_dPos = 0.0;
m_dWidth = 0.0; m_dWidth = 0.0;
m_pen = QPen(Qt::DashLine); m_pen = QPen(Qt::DashLine);
m_pen.setColor(Qt::darkGray); m_pen.setColor(Qt::darkGray);
m_penFont = QPen(Qt::black); m_penFont = QPen(Qt::black);
m_pixmap = QPixmap(); m_pixmap = QPixmap();
m_strText.clear(); m_strText.clear();
m_fillType = FillNone; m_fillType = FillNone;
m_lineType = LinePlot; m_lineType = LinePlot;
m_iTextFlags = Qt::AlignHCenter | Qt::AlignTop; m_iTextFlags = Qt::AlignHCenter | Qt::AlignTop;
} }
void CPlotWidgetTic::paintX (QPainter *pPainter, CPlotWidget *pWidget) const void CPlotWidgetTic::paintX (QPainter *pPainter, CPlotWidget *pWidget) const
{ {
QPoint ptTL, ptBR; // TopLeft, BottomRight QPoint ptTL, ptBR; // TopLeft, BottomRight
QRect rectText; QRect rectText;
if (m_fillType != FillNone && m_dWidth > 0.0) if (m_fillType != FillNone && m_dWidth > 0.0)
{ {
ptTL = pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.top())); ptTL = pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.top()));
ptBR = pWidget->mapToPlot(QPointF(m_dPos+m_dWidth, pWidget->m_rectData.bottom())); ptBR = pWidget->mapToPlot(QPointF(m_dPos+m_dWidth, pWidget->m_rectData.bottom()));
if (m_fillType == FillAll) if (m_fillType == FillAll)
{ {
ptTL.setY(pWidget->m_rectPlot.top()); ptTL.setY(pWidget->m_rectPlot.top());
ptBR.setY(pWidget->m_rectPlot.bottom()); ptBR.setY(pWidget->m_rectPlot.bottom());
} }
if (ptTL.x() < pWidget->m_rectPlot.left()) if (ptTL.x() < pWidget->m_rectPlot.left())
ptTL.setX(pWidget->m_rectPlot.left()); ptTL.setX(pWidget->m_rectPlot.left());
if (ptBR.x() > pWidget->m_rectPlot.right()) if (ptBR.x() > pWidget->m_rectPlot.right())
ptBR.setX(pWidget->m_rectPlot.right()); ptBR.setX(pWidget->m_rectPlot.right());
pPainter->fillRect(QRect(ptTL, ptBR), m_brush); pPainter->fillRect(QRect(ptTL, ptBR), m_brush);
rectText = QRect( rectText = QRect(
QPoint(ptTL.x(), pWidget->m_rectPlot.bottom() + 5), QPoint(ptTL.x(), pWidget->m_rectPlot.bottom() + 5),
QPoint(ptBR.x(), pWidget->rect().bottom())); QPoint(ptBR.x(), pWidget->rect().bottom()));
} }
else else
{ {
rectText = QRect(); rectText = QRect();
} }
if (m_lineType != LineNone) if (m_lineType != LineNone)
{ {
pPainter->setPen(m_pen); pPainter->setPen(m_pen);
pPainter->drawLine( pPainter->drawLine(
pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.top())), pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.top())),
pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.bottom()))); pWidget->mapToPlot(QPointF(m_dPos, pWidget->m_rectData.bottom())));
} }
if (!m_strText.isEmpty()) if (!m_strText.isEmpty())
{ {
pPainter->setPen(m_penFont); pPainter->setPen(m_penFont);
pPainter->drawText(rectText, m_iTextFlags, m_strText); pPainter->drawText(rectText, m_iTextFlags, m_strText);
} }
} }
void CPlotWidgetTic::paintY (QPainter *pPainter, CPlotWidget *pWidget) const void CPlotWidgetTic::paintY (QPainter *pPainter, CPlotWidget *pWidget) const
{ {
QPoint ptTL, ptBR; // TopLeft, BottomRight QPoint ptTL, ptBR; // TopLeft, BottomRight
QRect rectText; QRect rectText;
if (m_fillType != FillNone && m_dWidth > 0.0) if (m_fillType != FillNone && m_dWidth > 0.0)
{ {
ptTL = pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos)); ptTL = pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos));
ptBR = pWidget->mapToPlot(QPointF(pWidget->m_rectData.right(), m_dPos+m_dWidth)); ptBR = pWidget->mapToPlot(QPointF(pWidget->m_rectData.right(), m_dPos+m_dWidth));
if (m_fillType == FillAll) if (m_fillType == FillAll)
{ {
ptTL.setX(pWidget->m_rectPlot.left()); ptTL.setX(pWidget->m_rectPlot.left());
ptBR.setX(pWidget->m_rectPlot.right()); ptBR.setX(pWidget->m_rectPlot.right());
} }
if (ptTL.y() < pWidget->m_rectPlot.top()) if (ptTL.y() < pWidget->m_rectPlot.top())
ptTL.setY(pWidget->m_rectPlot.top()); ptTL.setY(pWidget->m_rectPlot.top());
if (ptBR.y() > pWidget->m_rectPlot.bottom()) if (ptBR.y() > pWidget->m_rectPlot.bottom())
ptBR.setY(pWidget->m_rectPlot.bottom()); ptBR.setY(pWidget->m_rectPlot.bottom());
pPainter->fillRect(QRect(ptTL, ptBR), m_brush); pPainter->fillRect(QRect(ptTL, ptBR), m_brush);
rectText = QRect( rectText = QRect(
QPoint(3, ptTL.y()), QPoint(3, ptTL.y()),
QPoint(pWidget->m_rectPlot.left()-3, ptBR.y())); QPoint(pWidget->m_rectPlot.left()-3, ptBR.y()));
} }
else else
{ {
QFontMetrics fm(m_font); QFontMetrics fm(m_font);
QPoint pt = pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos)); QPoint pt = pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos));
rectText = QRect( rectText = QRect(
QPoint(3, pt.y()-fm.height()), QPoint(3, pt.y()-fm.height()),
QPoint(pWidget->m_rectPlot.left()-3, pt.y()+fm.height())); QPoint(pWidget->m_rectPlot.left()-3, pt.y()+fm.height()));
} }
if (m_lineType != LineNone) if (m_lineType != LineNone)
{ {
pPainter->setPen(m_pen); pPainter->setPen(m_pen);
pPainter->drawLine( pPainter->drawLine(
pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos)), pWidget->mapToPlot(QPointF(pWidget->m_rectData.left(), m_dPos)),
pWidget->mapToPlot(QPointF(pWidget->m_rectData.right(), m_dPos))); pWidget->mapToPlot(QPointF(pWidget->m_rectData.right(), m_dPos)));
} }
if (!m_pixmap.isNull()) if (!m_pixmap.isNull())
{ {
// Ziel-Mittelpunkt errechnen // Ziel-Mittelpunkt errechnen
QPoint pt = pWidget->mapToPlot(QPointF(0, m_dPos)); QPoint pt = pWidget->mapToPlot(QPointF(0, m_dPos));
pt.setX(pWidget->m_rectPlot.left() - m_pixmap.width()/2 - 5); pt.setX(pWidget->m_rectPlot.left() - m_pixmap.width()/2 - 5);
// Linke obere Ecke errechnen und malen! // Linke obere Ecke errechnen und malen!
pt -= QPoint (m_pixmap.width()/2, m_pixmap.height()/2); pt -= QPoint (m_pixmap.width()/2, m_pixmap.height()/2);
pPainter->drawPixmap(pt, m_pixmap); pPainter->drawPixmap(pt, m_pixmap);
} }
if (!m_strText.isEmpty()) if (!m_strText.isEmpty())
{ {
pPainter->setPen(m_penFont); pPainter->setPen(m_penFont);
pPainter->drawText(rectText, m_iTextFlags, m_strText); pPainter->drawText(rectText, m_iTextFlags, m_strText);
} }
} }
CPlotWidget::CPlotWidget(QWidget *pParent) : QFrame(pParent) CPlotWidget::CPlotWidget(QWidget *pParent) : QFrame(pParent)
{ {
clear(); clear();
} }
void CPlotWidget::clear() void CPlotWidget::clear()
{ {
m_type = PlotLines; m_type = PlotLines;
m_bLimitAutoY = true; m_bLimitAutoY = true;
m_bLimitAutoX = true; m_bLimitAutoX = true;
m_dLimitXMin = 0.0; m_dLimitXMin = 0.0;
m_dLimitXMax = 10.0; m_dLimitXMax = 10.0;
m_dLimitYMin = 0.0; m_dLimitYMin = 0.0;
m_dLimitYMax = 10.0; m_dLimitYMax = 10.0;
m_dLimitXRound = 0.0; m_dLimitXRound = 0.0;
m_dLimitYRound = 0.0; m_dLimitYRound = 0.0;
m_dTicX = 0.0; m_dTicX = 0.0;
m_penTicX = QPen(Qt::DashLine); m_penTicX = QPen(Qt::DashLine);
m_penTicX.setColor(Qt::darkGray); m_penTicX.setColor(Qt::darkGray);
m_dTicY = 0.0; m_dTicY = 0.0;
m_penTicY = QPen(Qt::DashLine); m_penTicY = QPen(Qt::DashLine);
m_penTicY.setColor(Qt::darkGray); m_penTicY.setColor(Qt::darkGray);
m_iBorder = BorderLeft|BorderBottom; m_iBorder = BorderLeft|BorderBottom;
m_iBorderDistTop = 5; m_iBorderDistTop = 5;
m_iBorderDistBottom = 5; m_iBorderDistBottom = 5;
m_iBorderDistLeft = 5; m_iBorderDistLeft = 5;
m_iBorderDistRight = 5; m_iBorderDistRight = 5;
m_brushPlotBkg = QBrush(Qt::white); m_brushPlotBkg = QBrush(Qt::white);
m_listTicX.clear(); m_listTicX.clear();
m_listTicY.clear(); m_listTicY.clear();
m_dBarWidth = 0.6; m_dBarWidth = 0.6;
m_dBarOffset = 0.0; m_dBarOffset = 0.0;
m_listCurves.clear(); m_listCurves.clear();
} }
void CPlotWidget::setBorderDistance(const int iLeft, const int iRight, const int iTop, const int iBottom) void CPlotWidget::setBorderDistance(const int iLeft, const int iRight, const int iTop, const int iBottom)
{ {
m_iBorderDistTop = iTop; m_iBorderDistTop = iTop;
m_iBorderDistBottom = iBottom; m_iBorderDistBottom = iBottom;
m_iBorderDistLeft = iLeft; m_iBorderDistLeft = iLeft;
m_iBorderDistRight = iRight; m_iBorderDistRight = iRight;
} }
void CPlotWidget::updateCache() void CPlotWidget::updateCache()
{ {
m_rectPlot = plotArea(); m_rectPlot = plotArea();
m_rectData = rectData(); m_rectData = rectData();
} }
QRect CPlotWidget::plotArea() const QRect CPlotWidget::plotArea() const
{ {
QRect rect = frameRect(); QRect rect = frameRect();
rect.adjust(m_iBorderDistLeft, m_iBorderDistTop, -m_iBorderDistRight, -m_iBorderDistBottom); rect.adjust(m_iBorderDistLeft, m_iBorderDistTop, -m_iBorderDistRight, -m_iBorderDistBottom);
return rect; return rect;
} }
QRectF CPlotWidget::rectData() const QRectF CPlotWidget::rectData() const
{ {
QRectF rect; QRectF rect;
if (m_bLimitAutoX || m_bLimitAutoY) if (m_bLimitAutoX || m_bLimitAutoY)
{ {
for (int i=0; i<m_listCurves.size(); i++) for (int i=0; i<m_listCurves.size(); i++)
{ {
rect = rect.united(m_listCurves.at(i).boundaries()); rect = rect.united(m_listCurves.at(i).boundaries());
} }
} }
if (!m_bLimitAutoX) if (!m_bLimitAutoX)
{ {
rect.setLeft(m_dLimitXMin); rect.setLeft(m_dLimitXMin);
rect.setRight(m_dLimitXMax); rect.setRight(m_dLimitXMax);
} }
else if (m_dLimitXRound > 0.0) else if (m_dLimitXRound > 0.0)
{ {
rect.setLeft((unsigned)(rect.left() / m_dLimitXRound) * m_dLimitXRound); rect.setLeft((unsigned)(rect.left() / m_dLimitXRound) * m_dLimitXRound);
rect.setRight((unsigned)(rect.right() / m_dLimitXRound + 1) * m_dLimitXRound); rect.setRight((unsigned)(rect.right() / m_dLimitXRound + 1) * m_dLimitXRound);
} }
if (!m_bLimitAutoY) if (!m_bLimitAutoY)
{ {
rect.setTop(m_dLimitYMin); rect.setTop(m_dLimitYMin);
rect.setBottom(m_dLimitYMax); rect.setBottom(m_dLimitYMax);
} }
else if (m_dLimitYRound > 0.0) else if (m_dLimitYRound > 0.0)
{ {
rect.setTop((unsigned)(rect.top() / m_dLimitYRound) * m_dLimitYRound); rect.setTop((unsigned)(rect.top() / m_dLimitYRound) * m_dLimitYRound);
rect.setBottom((unsigned)(rect.bottom() / m_dLimitYRound + 1) * m_dLimitYRound); rect.setBottom((unsigned)(rect.bottom() / m_dLimitYRound + 1) * m_dLimitYRound);
} }
return rect; return rect;
} }
QPoint CPlotWidget::mapToPlot (QPointF p) QPoint CPlotWidget::mapToPlot (QPointF p)
{ {
QPointF ret; QPointF ret;
double m; double m;
// Umrechung X-Koordinate // Umrechung X-Koordinate
m = ((double) (m_rectPlot.left() - m_rectPlot.right())) / (m_rectData.left() - m_rectData.right()); m = ((double) (m_rectPlot.left() - m_rectPlot.right())) / (m_rectData.left() - m_rectData.right());
ret.setX(m * (p.x() - m_rectData.left()) + m_rectPlot.left()); ret.setX(m * (p.x() - m_rectData.left()) + m_rectPlot.left());
// Umrechnung Y-Koordinate (mit Spiegelung) // Umrechnung Y-Koordinate (mit Spiegelung)
m = ((double) (m_rectPlot.bottom() - m_rectPlot.top())) / (m_rectData.top() - m_rectData.bottom()); m = ((double) (m_rectPlot.bottom() - m_rectPlot.top())) / (m_rectData.top() - m_rectData.bottom());
ret.setY(m * (p.y() - m_rectData.top()) + m_rectPlot.bottom()); ret.setY(m * (p.y() - m_rectData.top()) + m_rectPlot.bottom());
return ret.toPoint(); return ret.toPoint();
} }
void CPlotWidget::paintEvent (QPaintEvent *e) void CPlotWidget::paintEvent (QPaintEvent *e)
{ {
QList<QPoint> listPoints; QList<QPoint> listPoints;
QList<CPlotWidgetTic> listTicsX, listTicsY; QList<CPlotWidgetTic> listTicsX, listTicsY;
double d=0.0; double d=0.0;
int i=0; int i=0;
QFrame::paintEvent(e); QFrame::paintEvent(e);
QPainter painter(this); QPainter painter(this);
updateCache(); updateCache();
// Draw Background // Draw Background
if (m_brushPlotBkg.style() != Qt::NoBrush) if (m_brushPlotBkg.style() != Qt::NoBrush)
{ {
painter.fillRect(m_rectPlot, m_brushPlotBkg); painter.fillRect(m_rectPlot, m_brushPlotBkg);
} }
// Draw Tics // Draw Tics
listTicsX = m_listTicX; listTicsX = m_listTicX;
if (listTicsX.isEmpty() && m_dTicX > 0.0) if (listTicsX.isEmpty() && m_dTicX > 0.0)
{ {
d = ((unsigned)(m_rectData.left() / m_dTicX)) * m_dTicX; d = ((unsigned)(m_rectData.left() / m_dTicX)) * m_dTicX;
if (d < m_rectData.left()) d+=m_dTicX; if (d < m_rectData.left()) d+=m_dTicX;
while (d <= m_rectData.right()) while (d <= m_rectData.right())
{ {
CPlotWidgetTic tic(d, QString("%1").arg(d,0,'f',2)); CPlotWidgetTic tic(d, QString("%1").arg(d,0,'f',2));
tic.setPen(m_penTicX); tic.setPen(m_penTicX);
listTicsX.append(tic); listTicsX.append(tic);
d += m_dTicX; d += m_dTicX;
} }
} }
listTicsY = m_listTicY; listTicsY = m_listTicY;
if (listTicsY.isEmpty() && m_dTicY > 0.0) if (listTicsY.isEmpty() && m_dTicY > 0.0)
{ {
d = ((unsigned)(m_rectData.top() / m_dTicY)) * m_dTicY; d = ((unsigned)(m_rectData.top() / m_dTicY)) * m_dTicY;
if (d < m_rectData.top()) d+=m_dTicY; if (d < m_rectData.top()) d+=m_dTicY;
while (d <= m_rectData.bottom()) while (d <= m_rectData.bottom())
{ {
CPlotWidgetTic tic(d, QString("%1").arg(d,0,'f',2)); CPlotWidgetTic tic(d, QString("%1").arg(d,0,'f',2));
tic.setPen(m_penTicY); tic.setPen(m_penTicY);
listTicsY.append(tic); listTicsY.append(tic);
d += m_dTicY; d += m_dTicY;
} }
} }
for (i=0; i<listTicsX.size(); i++) for (i=0; i<listTicsX.size(); i++)
listTicsX.at(i).paintX(&painter, this); listTicsX.at(i).paintX(&painter, this);
for (i=0; i<listTicsY.size(); i++) for (i=0; i<listTicsY.size(); i++)
listTicsY.at(i).paintY(&painter, this); listTicsY.at(i).paintY(&painter, this);
// Draw Curves // Draw Curves
if (m_type == PlotLines) if (m_type == PlotLines)
{ {
for (int i=0; i<m_listCurves.size(); i++) for (int i=0; i<m_listCurves.size(); i++)
{ {
CPlotWidgetCurve c = m_listCurves.at(i); CPlotWidgetCurve c = m_listCurves.at(i);
for (int j=0; j<c.size(); j++) for (int j=0; j<c.size(); j++)
{ {
CPlotWidgetPoint p = c.at(j); CPlotWidgetPoint p = c.at(j);
listPoints.append(mapToPlot (p)); listPoints.append(mapToPlot (p));
} }
painter.setPen(c.pen()); painter.setPen(c.pen());
painter.drawPolyline(listPoints.toVector()); painter.drawPolyline(listPoints.toVector());
} }
} }
else if (m_type == PlotBarsSum && m_listCurves.size() != 0) else if (m_type == PlotBarsSum && m_listCurves.size() != 0)
{ {
CPlotWidgetCurve c1 = m_listCurves.at(0); CPlotWidgetCurve c1 = m_listCurves.at(0);
//painter.setPen(c1.pen()); //painter.setPen(c1.pen());
//painter.setBrush(c1.brush()); //painter.setBrush(c1.brush());
QPoint ptTL, ptBR; QPoint ptTL, ptBR;
for (int j=0; j<c1.size(); j++) for (int j=0; j<c1.size(); j++)
{ // Alle Punkte der ersten Kurve durchgehen { // Alle Punkte der ersten Kurve durchgehen
CPlotWidgetPoint p1 = c1.at(j); CPlotWidgetPoint p1 = c1.at(j);
ptTL = mapToPlot(QPointF(p1.x() + m_dBarOffset - m_dBarWidth/2, p1.y())); ptTL = mapToPlot(QPointF(p1.x() + m_dBarOffset - m_dBarWidth/2, p1.y()));
ptBR = mapToPlot(QPointF(p1.x() + m_dBarOffset + m_dBarWidth/2, m_rectData.top())); ptBR = mapToPlot(QPointF(p1.x() + m_dBarOffset + m_dBarWidth/2, m_rectData.top()));
if (p1.y() != 0.0 && m_rectPlot.contains(ptTL) && m_rectPlot.contains(ptBR)) if (p1.y() != 0.0 && m_rectPlot.contains(ptTL) && m_rectPlot.contains(ptBR))
painter.fillRect(QRect(ptTL, ptBR), c1.brush()); painter.fillRect(QRect(ptTL, ptBR), c1.brush());
double dStart = p1.y(); double dStart = p1.y();
for (int i=1; i<m_listCurves.size(); i++) for (int i=1; i<m_listCurves.size(); i++)
{ // alle Weiteren Kurven durchgehen { // alle Weiteren Kurven durchgehen
CPlotWidgetCurve c2 = m_listCurves.at(i); CPlotWidgetCurve c2 = m_listCurves.at(i);
for (int jj=0; jj<c2.size(); jj++) for (int jj=0; jj<c2.size(); jj++)
{ // alle Punkte der zweiten Kurve durchgehen { // alle Punkte der zweiten Kurve durchgehen
CPlotWidgetPoint p2 = c2.at(jj); CPlotWidgetPoint p2 = c2.at(jj);
if (p2.x() != p1.x()) continue; if (p2.x() != p1.x()) continue;
ptTL = mapToPlot(QPointF(p2.x() + m_dBarOffset - m_dBarWidth/2, dStart+p2.y())); ptTL = mapToPlot(QPointF(p2.x() + m_dBarOffset - m_dBarWidth/2, dStart+p2.y()));
ptBR = mapToPlot(QPointF(p2.x() + m_dBarOffset + m_dBarWidth/2, dStart+m_rectData.top())); ptBR = mapToPlot(QPointF(p2.x() + m_dBarOffset + m_dBarWidth/2, dStart+m_rectData.top()));
if (p2.y() != 0 && m_rectPlot.contains(ptTL) && m_rectPlot.contains(ptBR)) if (p2.y() != 0 && m_rectPlot.contains(ptTL) && m_rectPlot.contains(ptBR))
{ {
dStart += p2.y(); dStart += p2.y();
painter.fillRect(QRect(ptTL, ptBR), c2.brush()); painter.fillRect(QRect(ptTL, ptBR), c2.brush());
} }
} }
} }
} }
} }
// Draw border // Draw border
painter.setPen(m_penBorder); painter.setPen(m_penBorder);
if (m_iBorder & BorderLeft) if (m_iBorder & BorderLeft)
painter.drawLine(m_rectPlot.topLeft(), m_rectPlot.bottomLeft()); painter.drawLine(m_rectPlot.topLeft(), m_rectPlot.bottomLeft());
if (m_iBorder & BorderRight) if (m_iBorder & BorderRight)
painter.drawLine(m_rectPlot.topRight(), m_rectPlot.bottomRight()); painter.drawLine(m_rectPlot.topRight(), m_rectPlot.bottomRight());
if (m_iBorder & BorderTop) if (m_iBorder & BorderTop)
painter.drawLine(m_rectPlot.topRight(), m_rectPlot.topLeft()); painter.drawLine(m_rectPlot.topRight(), m_rectPlot.topLeft());
if (m_iBorder & BorderBottom) if (m_iBorder & BorderBottom)
painter.drawLine(m_rectPlot.bottomRight(), m_rectPlot.bottomLeft()); painter.drawLine(m_rectPlot.bottomRight(), m_rectPlot.bottomLeft());
} }

View File

@ -1,215 +1,215 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include <qframe.h> #include <qframe.h>
#include <qpoint.h> #include <qpoint.h>
#include <qrect.h> #include <qrect.h>
#include <qpen.h> #include <qpen.h>
#include <qbrush.h> #include <qbrush.h>
#include <qmap.h> #include <qmap.h>
#include <qfont.h> #include <qfont.h>
class CPlotWidgetPoint; class CPlotWidgetPoint;
class CPlotWidgetCurve; class CPlotWidgetCurve;
class CPlotWidgetTic; class CPlotWidgetTic;
class CPlotWidget; class CPlotWidget;
class CPlotWidgetPoint : public QPointF class CPlotWidgetPoint : public QPointF
{ {
public: public:
CPlotWidgetPoint() { clear(); } CPlotWidgetPoint() { clear(); }
CPlotWidgetPoint(const double x, const double y) : QPointF(x,y) {} CPlotWidgetPoint(const double x, const double y) : QPointF(x,y) {}
~CPlotWidgetPoint() {} ~CPlotWidgetPoint() {}
void clear(); void clear();
protected: protected:
}; };
class CPlotWidgetCurve : public QList<CPlotWidgetPoint> class CPlotWidgetCurve : public QList<CPlotWidgetPoint>
{ {
public: public:
CPlotWidgetCurve() { clear(); } CPlotWidgetCurve() { clear(); }
~CPlotWidgetCurve() {} ~CPlotWidgetCurve() {}
void clear(); void clear();
QRectF boundaries() const; QRectF boundaries() const;
inline void setPen(const QPen& pen) { m_pen = pen; } inline void setPen(const QPen& pen) { m_pen = pen; }
inline QPen pen() const { return m_pen; } inline QPen pen() const { return m_pen; }
inline void setBrush(const QBrush& brush) { m_brush = brush; } inline void setBrush(const QBrush& brush) { m_brush = brush; }
inline QBrush brush() const { return m_brush; } inline QBrush brush() const { return m_brush; }
protected: protected:
QPen m_pen; QPen m_pen;
QBrush m_brush; QBrush m_brush;
}; };
class CPlotWidgetTic class CPlotWidgetTic
{ {
public: public:
enum LineType { LineNone, LineShort, LinePlot, LineFull }; enum LineType { LineNone, LineShort, LinePlot, LineFull };
enum FillType { FillNone, FillPlot, FillAll }; enum FillType { FillNone, FillPlot, FillAll };
CPlotWidgetTic() { clear(); } CPlotWidgetTic() { clear(); }
CPlotWidgetTic(const double dPos, const QString& strText); CPlotWidgetTic(const double dPos, const QString& strText);
CPlotWidgetTic(const double dPos, const double dWidth, const QString& strText); CPlotWidgetTic(const double dPos, const double dWidth, const QString& strText);
CPlotWidgetTic(const double dPos, const QPixmap& pixmap); CPlotWidgetTic(const double dPos, const QPixmap& pixmap);
~CPlotWidgetTic() {} ~CPlotWidgetTic() {}
void clear(); void clear();
inline void setPen(const QPen& pen) { m_pen = pen; } inline void setPen(const QPen& pen) { m_pen = pen; }
inline QPen pen() const { return m_pen; } inline QPen pen() const { return m_pen; }
inline void setBrush(const QBrush& brush) { m_brush = brush; } inline void setBrush(const QBrush& brush) { m_brush = brush; }
inline QBrush brush() const { return m_brush; } inline QBrush brush() const { return m_brush; }
inline void setFont(const QFont& font) { m_font = font; } inline void setFont(const QFont& font) { m_font = font; }
inline QFont font() const { return m_font; } inline QFont font() const { return m_font; }
inline void setFontPen(const QPen& pen) { m_penFont = pen; } inline void setFontPen(const QPen& pen) { m_penFont = pen; }
inline QPen fontPen() const { return m_penFont; } inline QPen fontPen() const { return m_penFont; }
inline void setPos(const double dPos) { m_dPos = dPos; } inline void setPos(const double dPos) { m_dPos = dPos; }
inline double pos() const { return m_dPos; } inline double pos() const { return m_dPos; }
inline void setWidth(const double dWidth) { m_dWidth = dWidth; } inline void setWidth(const double dWidth) { m_dWidth = dWidth; }
inline double width() const { return m_dWidth; } inline double width() const { return m_dWidth; }
inline void setFillType(const FillType t) { m_fillType = t; } inline void setFillType(const FillType t) { m_fillType = t; }
inline FillType fillType () const { return m_fillType; } inline FillType fillType () const { return m_fillType; }
inline void setLineType(const LineType t) { m_lineType = t; } inline void setLineType(const LineType t) { m_lineType = t; }
inline LineType lineType () const { return m_lineType; } inline LineType lineType () const { return m_lineType; }
inline void setText(const QString& str) { m_strText = str; } inline void setText(const QString& str) { m_strText = str; }
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
inline void setTextFlags (const int iFlags) { m_iTextFlags = iFlags; } inline void setTextFlags (const int iFlags) { m_iTextFlags = iFlags; }
inline int textFlags() const { return m_iTextFlags; } inline int textFlags() const { return m_iTextFlags; }
void paintX (QPainter *pPainter, CPlotWidget *pWidget) const; void paintX (QPainter *pPainter, CPlotWidget *pWidget) const;
void paintY (QPainter *pPainter, CPlotWidget *pWidget) const; void paintY (QPainter *pPainter, CPlotWidget *pWidget) const;
protected: protected:
double m_dPos; double m_dPos;
// Beschriftung // Beschriftung
QPixmap m_pixmap; QPixmap m_pixmap;
QString m_strText; QString m_strText;
QFont m_font; QFont m_font;
QPen m_penFont; QPen m_penFont;
int m_iTextFlags; int m_iTextFlags;
// Line // Line
QPen m_pen; QPen m_pen;
LineType m_lineType; LineType m_lineType;
// Background // Background
double m_dWidth; double m_dWidth;
QBrush m_brush; QBrush m_brush;
FillType m_fillType; FillType m_fillType;
}; };
class CPlotWidget : public QFrame class CPlotWidget : public QFrame
{ {
Q_OBJECT Q_OBJECT
public: public:
enum PlotType { PlotPoints, PlotLines, PlotBarsSum, PlotBars }; enum PlotType { PlotPoints, PlotLines, PlotBarsSum, PlotBars };
enum Border { BorderTop=0x01, BorderBottom=0x02, BorderLeft=0x04, BorderRight=0x08 }; enum Border { BorderTop=0x01, BorderBottom=0x02, BorderLeft=0x04, BorderRight=0x08 };
CPlotWidget(QWidget *pParent=0); CPlotWidget(QWidget *pParent=0);
~CPlotWidget() {} ~CPlotWidget() {}
void clear(); void clear();
inline void clearCurves() { m_listCurves.clear(); } inline void clearCurves() { m_listCurves.clear(); }
inline void appendCurve (const CPlotWidgetCurve& c) { m_listCurves.append(c); } inline void appendCurve (const CPlotWidgetCurve& c) { m_listCurves.append(c); }
QRect plotArea() const; QRect plotArea() const;
QRectF rectData() const; QRectF rectData() const;
inline void setType (const PlotType t) { m_type = t; } inline void setType (const PlotType t) { m_type = t; }
inline PlotType type() const { return m_type; } inline PlotType type() const { return m_type; }
inline void setLimitX(const double min, const double max) { m_dLimitXMin = min; m_dLimitXMax = max; m_bLimitAutoX = false; } inline void setLimitX(const double min, const double max) { m_dLimitXMin = min; m_dLimitXMax = max; m_bLimitAutoX = false; }
inline void setLimitY(const double min, const double max) { m_dLimitYMin = min; m_dLimitYMax = max; m_bLimitAutoY = false; } inline void setLimitY(const double min, const double max) { m_dLimitYMin = min; m_dLimitYMax = max; m_bLimitAutoY = false; }
inline void setAutoLimitX(const bool bAutoLimit) { m_bLimitAutoX = bAutoLimit; } inline void setAutoLimitX(const bool bAutoLimit) { m_bLimitAutoX = bAutoLimit; }
inline void setAutoLimitY(const bool bAutoLimit) { m_bLimitAutoY = bAutoLimit; } inline void setAutoLimitY(const bool bAutoLimit) { m_bLimitAutoY = bAutoLimit; }
inline void setAutoLimitRoundX(const double dRound) { m_dLimitXRound = dRound; } inline void setAutoLimitRoundX(const double dRound) { m_dLimitXRound = dRound; }
inline void setAutoLimitRoundY(const double dRound) { m_dLimitYRound = dRound; } inline void setAutoLimitRoundY(const double dRound) { m_dLimitYRound = dRound; }
inline void setLabelX(const QString& str) { m_strLabelX = str; } inline void setLabelX(const QString& str) { m_strLabelX = str; }
inline void setLabelY(const QString& str) { m_strLabelY = str; } inline void setLabelY(const QString& str) { m_strLabelY = str; }
inline void setPlotBackground (const QBrush& brush) { m_brushPlotBkg = brush; } inline void setPlotBackground (const QBrush& brush) { m_brushPlotBkg = brush; }
inline void setBorderPen(const QPen& pen) { m_penBorder = pen; } inline void setBorderPen(const QPen& pen) { m_penBorder = pen; }
inline QPen borderPen() const { return m_penBorder; } inline QPen borderPen() const { return m_penBorder; }
inline void setBorder(const int iBorder=BorderLeft|BorderBottom) { m_iBorder = iBorder; } inline void setBorder(const int iBorder=BorderLeft|BorderBottom) { m_iBorder = iBorder; }
inline int border() const { return m_iBorder; } inline int border() const { return m_iBorder; }
void setBorderDistance(const int iLeft, const int iRight, const int iTop, const int iBottom); void setBorderDistance(const int iLeft, const int iRight, const int iTop, const int iBottom);
inline void setTicX(const double dTic) { m_dTicX = dTic; } inline void setTicX(const double dTic) { m_dTicX = dTic; }
inline void setTicY(const double dTic) { m_dTicY = dTic; } inline void setTicY(const double dTic) { m_dTicY = dTic; }
inline void setTicXPen(const QPen& pen) { m_penTicX = pen; } inline void setTicXPen(const QPen& pen) { m_penTicX = pen; }
inline void setTicYPen(const QPen& pen) { m_penTicY = pen; } inline void setTicYPen(const QPen& pen) { m_penTicY = pen; }
inline void setTicListX (const QList<CPlotWidgetTic>& list) { m_listTicX = list; } inline void setTicListX (const QList<CPlotWidgetTic>& list) { m_listTicX = list; }
inline void setTicListY (const QList<CPlotWidgetTic>& list) { m_listTicY = list; } inline void setTicListY (const QList<CPlotWidgetTic>& list) { m_listTicY = list; }
inline void setBarWidth(const double d) { m_dBarWidth = d; } inline void setBarWidth(const double d) { m_dBarWidth = d; }
inline void setBarOffset(const double d) { m_dBarOffset = d; } inline void setBarOffset(const double d) { m_dBarOffset = d; }
protected: protected:
virtual void paintEvent (QPaintEvent *e); virtual void paintEvent (QPaintEvent *e);
void updateCache(); void updateCache();
QPoint mapToPlot (QPointF p); QPoint mapToPlot (QPointF p);
friend class CPlotWidgetTic; friend class CPlotWidgetTic;
protected: protected:
PlotType m_type; PlotType m_type;
QList<CPlotWidgetCurve> m_listCurves; QList<CPlotWidgetCurve> m_listCurves;
double m_dLimitXMin, m_dLimitXMax, m_dLimitYMin, m_dLimitYMax; double m_dLimitXMin, m_dLimitXMax, m_dLimitYMin, m_dLimitYMax;
double m_dLimitXRound, m_dLimitYRound; double m_dLimitXRound, m_dLimitYRound;
bool m_bLimitAutoX, m_bLimitAutoY; bool m_bLimitAutoX, m_bLimitAutoY;
// Border // Border
QBrush m_brushPlotBkg; QBrush m_brushPlotBkg;
QPen m_penBorder; QPen m_penBorder;
int m_iBorder; //!< Logische Verknüpfung aus BorderTop, BorderBottom, BorderLeft, BorderRight int m_iBorder; //!< Logische Verknüpfung aus BorderTop, BorderBottom, BorderLeft, BorderRight
int m_iBorderDistTop; int m_iBorderDistTop;
int m_iBorderDistBottom; int m_iBorderDistBottom;
int m_iBorderDistLeft; int m_iBorderDistLeft;
int m_iBorderDistRight; int m_iBorderDistRight;
// Tics & Labels // Tics & Labels
QList<CPlotWidgetTic> m_listTicX; QList<CPlotWidgetTic> m_listTicX;
QList<CPlotWidgetTic> m_listTicY; QList<CPlotWidgetTic> m_listTicY;
double m_dTicX; double m_dTicX;
QPen m_penTicX; QPen m_penTicX;
double m_dTicY; double m_dTicY;
QPen m_penTicY; QPen m_penTicY;
QString m_strLabelX; QString m_strLabelX;
QString m_strLabelY; QString m_strLabelY;
// Bars // Bars
double m_dBarWidth; double m_dBarWidth;
double m_dBarOffset; double m_dBarOffset;
// Cache // Cache
QRect m_rectPlot; QRect m_rectPlot;
QRectF m_rectData; QRectF m_rectData;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -1,247 +1,247 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef QUESTION_H #ifndef QUESTION_H
#define QUESTION_H #define QUESTION_H
#include <qstring.h> #include <qstring.h>
#include <qdom.h> #include <qdom.h>
#include <qlist.h> #include <qlist.h>
#include <qdatetime.h> #include <qdatetime.h>
#include <qstringlist.h> #include <qstringlist.h>
#include <qicon.h> #include <qicon.h>
#include <qpixmap.h> #include <qpixmap.h>
#include "answer.h" #include "answer.h"
#include "helper.h" #include "helper.h"
unsigned afu_random (const unsigned uMin, const unsigned uMax); unsigned afu_random (const unsigned uMin, const unsigned uMax);
class CChapter; class CChapter;
#define LEVEL_VERYOFTEN 0 #define LEVEL_VERYOFTEN 0
#define LEVEL_OFTEN 1 #define LEVEL_OFTEN 1
#define LEVEL_NORMAL 2 #define LEVEL_NORMAL 2
#define LEVEL_RARE 3 #define LEVEL_RARE 3
#define LEVEL_VERYRARE 4 #define LEVEL_VERYRARE 4
#define LEVEL_EXTREMERARE 5 #define LEVEL_EXTREMERARE 5
#define LEVEL_MAX 5 #define LEVEL_MAX 5
class CDayStatistic class CDayStatistic
{ {
public: public:
CDayStatistic() { clear(); } CDayStatistic() { clear(); }
~CDayStatistic() {} ~CDayStatistic() {}
void clear(); void clear();
inline QDate date() const { return m_date; } inline QDate date() const { return m_date; }
inline unsigned clickedCount() const { return m_uClickedWrong + m_uClickedCorrect; } inline unsigned clickedCount() const { return m_uClickedWrong + m_uClickedCorrect; }
inline unsigned clickedCorrect() const { return m_uClickedCorrect; } inline unsigned clickedCorrect() const { return m_uClickedCorrect; }
inline unsigned clickedWrong() const { return m_uClickedWrong; } inline unsigned clickedWrong() const { return m_uClickedWrong; }
inline unsigned timeExpediture() const { return m_uTimeExpeditureCorrect + m_uTimeExpeditureWrong; } inline unsigned timeExpediture() const { return m_uTimeExpeditureCorrect + m_uTimeExpeditureWrong; }
inline unsigned timeExpeditureCorrect() const { return m_uTimeExpeditureCorrect; } inline unsigned timeExpeditureCorrect() const { return m_uTimeExpeditureCorrect; }
inline unsigned timeExpeditureWrong() const { return m_uTimeExpeditureWrong; } inline unsigned timeExpeditureWrong() const { return m_uTimeExpeditureWrong; }
inline unsigned levelRounded() const { return (unsigned) (m_dLevel + 0.5); } inline unsigned levelRounded() const { return (unsigned) (m_dLevel + 0.5); }
inline double level() const { return m_dLevel; } inline double level() const { return m_dLevel; }
CDayStatistic& operator += (const CDayStatistic& ds); CDayStatistic& operator += (const CDayStatistic& ds);
void debug() const; void debug() const;
protected: protected:
QDate m_date; QDate m_date;
unsigned m_uClickedWrong; unsigned m_uClickedWrong;
unsigned m_uClickedCorrect; unsigned m_uClickedCorrect;
unsigned m_uTimeExpeditureCorrect; unsigned m_uTimeExpeditureCorrect;
unsigned m_uTimeExpeditureWrong; unsigned m_uTimeExpeditureWrong;
double m_dLevel; double m_dLevel;
friend class CQuestion; friend class CQuestion;
friend class CChapter; friend class CChapter;
}; };
//! CQuestion speichert eine Frage mit allen Antworten und der Klick-Statistik. //! CQuestion speichert eine Frage mit allen Antworten und der Klick-Statistik.
class CQuestion class CQuestion
{ {
public: public:
//! Standard-Konstruktor //! Standard-Konstruktor
/*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */ /*! Initialisiert die Klasse, indem die Funktion clear() aufgerufen wird. */
CQuestion() { clear(); } CQuestion() { clear(); }
//! Standard-Destruktor //! Standard-Destruktor
/*! In der Standard-Implementierung tut der Destruktor nichts. */ /*! In der Standard-Implementierung tut der Destruktor nichts. */
~CQuestion() {} ~CQuestion() {}
/** @name Basisdaten /** @name Basisdaten
* Auslesen und setzen der Basisdaten einer Frage * Auslesen und setzen der Basisdaten einer Frage
*/ */
//@{ //@{
//! Zurücksetzen aller Werte //! Zurücksetzen aller Werte
/*! Es werden alle Daten der Frage gelöscht. */ /*! Es werden alle Daten der Frage gelöscht. */
void clear(); void clear();
//! Elternkapitel abfragen //! Elternkapitel abfragen
/*! /*!
\return Elternkapitel m_pParentChapter \return Elternkapitel m_pParentChapter
\sa CChapter, setParentChapter(), m_pParentChapter \sa CChapter, setParentChapter(), m_pParentChapter
*/ */
inline CChapter* parentChapter() const { return m_pParentChapter; } inline CChapter* parentChapter() const { return m_pParentChapter; }
//! Elternkapitel setzen //! Elternkapitel setzen
/*! /*!
Durch diese Funktion wird lediglich die Variable m_pParentChapter gesetzt, jedoch nicht die Statistiken Durch diese Funktion wird lediglich die Variable m_pParentChapter gesetzt, jedoch nicht die Statistiken
des Eltern-Kapitels aktualisiert. des Eltern-Kapitels aktualisiert.
\param pChapter Das zu setzende Elternkapitel der Frage \param pChapter Das zu setzende Elternkapitel der Frage
\sa CChapter, parentChapter(), m_pParentChapter \sa CChapter, parentChapter(), m_pParentChapter
*/ */
inline void setParentChapter(CChapter *pChapter) { m_pParentChapter = pChapter; } inline void setParentChapter(CChapter *pChapter) { m_pParentChapter = pChapter; }
//! ID abfragen //! ID abfragen
inline QString id() const { return m_strId; } inline QString id() const { return m_strId; }
//! Text abfragen //! Text abfragen
inline QString text() const { return m_strText; } inline QString text() const { return m_strText; }
//! ID setzen //! ID setzen
inline void setId(const QString& strId) { m_strId = strId; } inline void setId(const QString& strId) { m_strId = strId; }
//! Text setzen //! Text setzen
inline void setText(const QString& strText) { m_strText = strText; } inline void setText(const QString& strText) { m_strText = strText; }
//! Anhängen eines Textes an den Fragentext //! Anhängen eines Textes an den Fragentext
/*! /*!
\param strText Anzuhängender Text \param strText Anzuhängender Text
\sa m_strText \sa m_strText
*/ */
inline void appendText(const QString& strText) { m_strText += strText; } inline void appendText(const QString& strText) { m_strText += strText; }
//@} //@}
QString plainText() const; QString plainText() const;
QString firstTextLine() const; QString firstTextLine() const;
QString showText(CCatalog *pCatalog) const; QString showText(CCatalog *pCatalog) const;
QString learnText(CCatalog *pCatalog, const bool bShowId=true, const bool bShowHints=false); QString learnText(CCatalog *pCatalog, const bool bShowId=true, const bool bShowHints=false);
inline unsigned errorPoints() const { return m_uErrorPoints; } inline unsigned errorPoints() const { return m_uErrorPoints; }
inline void setErrorPoints (const unsigned u) { m_uErrorPoints = u; } inline void setErrorPoints (const unsigned u) { m_uErrorPoints = u; }
QStringList groups() const { return m_strlGroups; } QStringList groups() const { return m_strlGroups; }
bool load (QDomElement elem); bool load (QDomElement elem);
void save (QDomElement& parent, QDomDocument& doc); void save (QDomElement& parent, QDomDocument& doc);
static QString removeTempPath(const QString& strText); static QString removeTempPath(const QString& strText);
bool loadLearnStatistic (QDomElement elem); bool loadLearnStatistic (QDomElement elem);
bool saveLearnStatistic (QDomElement& parent, QDomDocument& doc); bool saveLearnStatistic (QDomElement& parent, QDomDocument& doc);
QString checkForErrors() const; QString checkForErrors() const;
// answers // answers
inline int countAnswer() const { return m_listAnswer.size(); } inline int countAnswer() const { return m_listAnswer.size(); }
inline const CAnswer& answerAt(int i) const { return m_listAnswer.at(i); } inline const CAnswer& answerAt(int i) const { return m_listAnswer.at(i); }
inline CAnswer& answerAt(int i) { return m_listAnswer[i]; } inline CAnswer& answerAt(int i) { return m_listAnswer[i]; }
inline void appendAnswer(const CAnswer& a) { m_listAnswer.append(a); } inline void appendAnswer(const CAnswer& a) { m_listAnswer.append(a); }
int countCorrectAnswer() const; int countCorrectAnswer() const;
// helpers // helpers
// inline bool hasHints() const { return !m_listHint.isEmpty(); } // inline bool hasHints() const { return !m_listHint.isEmpty(); }
// learning // learning
void mixAnswers(const bool bMix=true); void mixAnswers(const bool bMix=true);
const CAnswer& learnAnswerAt(int i) const; const CAnswer& learnAnswerAt(int i) const;
unsigned correctAnswerMask() const; unsigned correctAnswerMask() const;
inline bool isCorrectAnswer (const unsigned uAnswerMask) const { return uAnswerMask == correctAnswerMask(); } inline bool isCorrectAnswer (const unsigned uAnswerMask) const { return uAnswerMask == correctAnswerMask(); }
unsigned orderedAnswerMask(const unsigned uMixedAnswerMask); unsigned orderedAnswerMask(const unsigned uMixedAnswerMask);
void registerAnswerClicked (const unsigned uAnswerMask, const unsigned uNeededTime); void registerAnswerClicked (const unsigned uAnswerMask, const unsigned uNeededTime);
static QString answerMaskToString(const unsigned uAnswerMask); static QString answerMaskToString(const unsigned uAnswerMask);
QString correctionText(const unsigned uAnswerMask); QString correctionText(const unsigned uAnswerMask);
// statistics // statistics
//! Abfragehäufigkeit der Frage //! Abfragehäufigkeit der Frage
inline unsigned level() const { return m_uLevel; } inline unsigned level() const { return m_uLevel; }
inline QString levelIconName() const { return levelIconName (m_uLevel); } inline QString levelIconName() const { return levelIconName (m_uLevel); }
inline QIcon levelIcon() const { return levelIcon (m_uLevel); } inline QIcon levelIcon() const { return levelIcon (m_uLevel); }
inline QPixmap levelPixmap() const { return QPixmap(levelIconName (m_uLevel)); } inline QPixmap levelPixmap() const { return QPixmap(levelIconName (m_uLevel)); }
inline QString levelText() const { return levelText (m_uLevel); } inline QString levelText() const { return levelText (m_uLevel); }
inline int clickedCount() const { return m_listAnswerClicked.size(); } inline int clickedCount() const { return m_listAnswerClicked.size(); }
inline unsigned clickedCorrect() const { return m_uCorrectAnswers; } inline unsigned clickedCorrect() const { return m_uCorrectAnswers; }
inline unsigned clickedWrong() const { return m_uWrongAnswers; } inline unsigned clickedWrong() const { return m_uWrongAnswers; }
inline unsigned clickedCorrectSuccessive() const { return m_uCorrectSuccessive; } inline unsigned clickedCorrectSuccessive() const { return m_uCorrectSuccessive; }
inline unsigned clickedWrongSuccessive() const { return m_uWrongSuccessive; } inline unsigned clickedWrongSuccessive() const { return m_uWrongSuccessive; }
inline bool isNeverAsked() const { return m_listAnswerClicked.isEmpty(); } inline bool isNeverAsked() const { return m_listAnswerClicked.isEmpty(); }
unsigned levelAtEndOfDay(const QDate& date) const; //!< Lernfortschritt am Ende eines bestimmten Tages unsigned levelAtEndOfDay(const QDate& date) const; //!< Lernfortschritt am Ende eines bestimmten Tages
CDayStatistic dayStatistic(const QDate& date) const; CDayStatistic dayStatistic(const QDate& date) const;
QDateTime firstClicked() const; QDateTime firstClicked() const;
QDateTime lastClicked() const; QDateTime lastClicked() const;
QString lastClickedText() const; QString lastClickedText() const;
QString lastClickedTextExtended() const; QString lastClickedTextExtended() const;
QDate repeatDate() const; //!< Wiederhol-Datum der Frage bestimmen QDate repeatDate() const; //!< Wiederhol-Datum der Frage bestimmen
QString repeatDateText() const; QString repeatDateText() const;
QString repeatDateTextExtended() const; QString repeatDateTextExtended() const;
bool isRepeatToday() const; //!< Frage sollte heute wiederholt werden bool isRepeatToday() const; //!< Frage sollte heute wiederholt werden
bool isLearningNew() const; //!< Ist dies eine neue Frage, die gerade gelernt wird? bool isLearningNew() const; //!< Ist dies eine neue Frage, die gerade gelernt wird?
bool isKnownQuestion() const; //!< Ist die Frage schon (länger) bekannt? bool isKnownQuestion() const; //!< Ist die Frage schon (länger) bekannt?
//! Name des Icons einer bestimmten Abfragehäufigkeit ermitteln //! Name des Icons einer bestimmten Abfragehäufigkeit ermitteln
static QString levelIconName(const unsigned uLevel); static QString levelIconName(const unsigned uLevel);
//! Icon einer bestimmten Abfragehäufigkeit //! Icon einer bestimmten Abfragehäufigkeit
static QIcon levelIcon(const unsigned uLevel); static QIcon levelIcon(const unsigned uLevel);
//! Name einer bestimmten Abfragehäufigkeit //! Name einer bestimmten Abfragehäufigkeit
static QString levelText(const unsigned uLevel); static QString levelText(const unsigned uLevel);
static QString tr (const char *sourceText, const char *comment=0); static QString tr (const char *sourceText, const char *comment=0);
//! Berechnung der Wartezeit für eine bestimmte Abfragehäufigkeit //! Berechnung der Wartezeit für eine bestimmte Abfragehäufigkeit
static unsigned waitDaysForRepeat (const unsigned uLevel); static unsigned waitDaysForRepeat (const unsigned uLevel);
protected: protected:
CChapter *m_pParentChapter; //!< Zeiger auf das (Eltern-) Kapitel, zu dem die Frage gehört. CChapter *m_pParentChapter; //!< Zeiger auf das (Eltern-) Kapitel, zu dem die Frage gehört.
// masterdata // masterdata
QString m_strId; //!< ID der Frage QString m_strId; //!< ID der Frage
QString m_strText; //!< Fragentext QString m_strText; //!< Fragentext
QList<CAnswer> m_listAnswer; //!< Liste mit Antworten QList<CAnswer> m_listAnswer; //!< Liste mit Antworten
unsigned m_uErrorPoints; //!< Fehlerpunkte bei Falschantwort in Prüfung unsigned m_uErrorPoints; //!< Fehlerpunkte bei Falschantwort in Prüfung
QStringList m_strlGroups; //!< Liste der Klassen/Gruppen, zu denen diese Frage gehört QStringList m_strlGroups; //!< Liste der Klassen/Gruppen, zu denen diese Frage gehört
// learning // learning
//! Durchmischte Antworten //! Durchmischte Antworten
/*! Die Liste enthält die Positionen der Liste m_listAnswer */ /*! Die Liste enthält die Positionen der Liste m_listAnswer */
QList<int> m_listMixedAnswer; QList<int> m_listMixedAnswer;
// Statistics // Statistics
QList<CAnswerClicked> m_listAnswerClicked; //!< Liste mit sämtlichen Antwort-Klicks QList<CAnswerClicked> m_listAnswerClicked; //!< Liste mit sämtlichen Antwort-Klicks
unsigned m_uCorrectAnswers; //!< Anzahl der richtigen Antworten unsigned m_uCorrectAnswers; //!< Anzahl der richtigen Antworten
unsigned m_uCorrectSuccessive; //!< Anzahl der richtigen Antworten zuletzt hintereinander unsigned m_uCorrectSuccessive; //!< Anzahl der richtigen Antworten zuletzt hintereinander
unsigned m_uWrongAnswers; //!< Anzahl der falschen Antworten unsigned m_uWrongAnswers; //!< Anzahl der falschen Antworten
unsigned m_uWrongSuccessive; //!< Anzahl der falschen Antworten zuletzt hintereinander unsigned m_uWrongSuccessive; //!< Anzahl der falschen Antworten zuletzt hintereinander
//! Aktuelle Stufe der Abfragehäufigkeit //! Aktuelle Stufe der Abfragehäufigkeit
/*! /*!
Stufe 0: sehr häufige ... Stufe 5: sehr seltene Abfrage Stufe 0: sehr häufige ... Stufe 5: sehr seltene Abfrage
Die Abfragehäufigkeit wird nicht in der Statistik-Datei gespeichert, sondern bei jedem Laden der Die Abfragehäufigkeit wird nicht in der Statistik-Datei gespeichert, sondern bei jedem Laden der
Datei anhand der Beantwortungen in der Vergangenheit neu berechnet. Datei anhand der Beantwortungen in der Vergangenheit neu berechnet.
*/ */
unsigned m_uLevel; unsigned m_uLevel;
}; };
#endif #endif

View File

@ -1,175 +1,175 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "chapter.h" #include "chapter.h"
#include "questionmodel.h" #include "questionmodel.h"
#include <qtextdocument.h> #include <qtextdocument.h>
CQuestionModel::CQuestionModel(QObject *pParent) : QAbstractItemModel (pParent) CQuestionModel::CQuestionModel(QObject *pParent) : QAbstractItemModel (pParent)
{ {
m_pChapter=0; m_pChapter=0;
} }
CQuestionModel::~CQuestionModel() CQuestionModel::~CQuestionModel()
{ {
} }
void CQuestionModel::onLanguageChanged() void CQuestionModel::onLanguageChanged()
{ {
headerDataChanged(Qt::Horizontal, 0, columnCount()-1); headerDataChanged(Qt::Horizontal, 0, columnCount()-1);
} }
void CQuestionModel::clear() void CQuestionModel::clear()
{ {
m_pChapter=0; m_pChapter=0;
reset(); reset();
} }
void CQuestionModel::setModelData (CChapter *pChapter) void CQuestionModel::setModelData (CChapter *pChapter)
{ {
m_pChapter = pChapter; m_pChapter = pChapter;
reset(); reset();
} }
int CQuestionModel::columnCount (const QModelIndex & parent) const int CQuestionModel::columnCount (const QModelIndex & parent) const
{ {
Q_UNUSED(parent) Q_UNUSED(parent)
return 7; return 7;
} }
QVariant CQuestionModel::data (const QModelIndex & index, int role) const QVariant CQuestionModel::data (const QModelIndex & index, int role) const
{ {
CQuestion *p; CQuestion *p;
QTextDocument t; QTextDocument t;
if (!index.isValid()) return QVariant(); if (!index.isValid()) return QVariant();
p = (CQuestion*) index.internalPointer(); p = (CQuestion*) index.internalPointer();
if (p == 0) return QVariant(); if (p == 0) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (index.column() == 0) if (index.column() == 0)
return p->id(); return p->id();
else if (index.column() == 1) else if (index.column() == 1)
return p->firstTextLine(); return p->firstTextLine();
//return p->text(); //return p->text();
else if (index.column() == 2) else if (index.column() == 2)
return p->clickedCorrect(); return p->clickedCorrect();
else if (index.column() == 3) else if (index.column() == 3)
return p->clickedWrong(); return p->clickedWrong();
else if (index.column() == 4) else if (index.column() == 4)
return p->levelText(); return p->levelText();
else if (index.column() == 5) else if (index.column() == 5)
{ {
t.setHtml(p->lastClickedText()); t.setHtml(p->lastClickedText());
return t.toPlainText(); return t.toPlainText();
} }
else if (index.column() == 6) else if (index.column() == 6)
{ {
t.setHtml(p->repeatDateText()); t.setHtml(p->repeatDateText());
return t.toPlainText(); return t.toPlainText();
} }
} }
else if (role == Qt::DecorationRole) else if (role == Qt::DecorationRole)
{ {
if (index.column() == 4) if (index.column() == 4)
//return QIcon (QString(":/icons/16x16/level%1.png").arg(p->level())); //return QIcon (QString(":/icons/16x16/level%1.png").arg(p->level()));
return p->levelIcon(); return p->levelIcon();
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (index.column() == 5) if (index.column() == 5)
return p->lastClickedTextExtended(); return p->lastClickedTextExtended();
else if (index.column() == 6) else if (index.column() == 6)
return p->repeatDateTextExtended(); return p->repeatDateTextExtended();
/* if (index.column() == 4) /* if (index.column() == 4)
return "<img src='" + p->levelIconName() + "'> " + p->levelText(); return "<img src='" + p->levelIconName() + "'> " + p->levelText();
*/ } */ }
/* else if (role == Qt::WhatsThisRole) /* else if (role == Qt::WhatsThisRole)
{ {
if (index.column() == 4) if (index.column() == 4)
return QString("Was ist das?"); return QString("Was ist das?");
} }
*/ */
return QVariant(); return QVariant();
} }
bool CQuestionModel::hasChildren (const QModelIndex & parent) const bool CQuestionModel::hasChildren (const QModelIndex & parent) const
{ {
if (parent.isValid()) return false; if (parent.isValid()) return false;
return (m_pChapter != 0); return (m_pChapter != 0);
} }
QVariant CQuestionModel::headerData (int section, Qt::Orientation orientation, int role) const QVariant CQuestionModel::headerData (int section, Qt::Orientation orientation, int role) const
{ {
if (orientation == Qt::Vertical) return QVariant(); if (orientation == Qt::Vertical) return QVariant();
if (role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
if (section == 0) if (section == 0)
return tr("Kennung"); return tr("Kennung");
else if (section == 1) else if (section == 1)
return tr("Frage"); return tr("Frage");
else if (section == 2) else if (section == 2)
return tr("R"); return tr("R");
else if (section == 3) else if (section == 3)
return tr("F"); return tr("F");
else if (section == 4) else if (section == 4)
return tr("Lernfortschritt"); return tr("Lernfortschritt");
else if (section == 5) else if (section == 5)
return tr("letzte Abfrage"); return tr("letzte Abfrage");
else if (section == 6) else if (section == 6)
return tr("Wiederholung"); return tr("Wiederholung");
} }
/* else if (role == Qt::DecorationRole) /* else if (role == Qt::DecorationRole)
{ {
if (section == m_iColBookmarkFlag) if (section == m_iColBookmarkFlag)
return QIcon (":/icons/16x16/bookmark.png"); return QIcon (":/icons/16x16/bookmark.png");
}*/ }*/
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
{ {
if (section == 2) if (section == 2)
return tr("Anzahl der richtigen Antworten"); return tr("Anzahl der richtigen Antworten");
else if (section == 3) else if (section == 3)
return tr("Anzahl der falschen Antworten"); return tr("Anzahl der falschen Antworten");
} }
return QVariant(); return QVariant();
} }
QModelIndex CQuestionModel::index (int row, int column, const QModelIndex & parent) const QModelIndex CQuestionModel::index (int row, int column, const QModelIndex & parent) const
{ {
CQuestion *p=0; CQuestion *p=0;
if (m_pChapter == 0 || parent.isValid() || row >= m_pChapter->countQuestion()) return QModelIndex(); if (m_pChapter == 0 || parent.isValid() || row >= m_pChapter->countQuestion()) return QModelIndex();
p = m_pChapter->questionAt (row); p = m_pChapter->questionAt (row);
return createIndex (row, column, (void*)p); return createIndex (row, column, (void*)p);
} }
QModelIndex CQuestionModel::parent (const QModelIndex & index) const QModelIndex CQuestionModel::parent (const QModelIndex & index) const
{ {
return QModelIndex(); return QModelIndex();
} }
int CQuestionModel::rowCount (const QModelIndex & parent) const int CQuestionModel::rowCount (const QModelIndex & parent) const
{ {
if (m_pChapter == 0 || parent.isValid()) return 0; if (m_pChapter == 0 || parent.isValid()) return 0;
return m_pChapter->countQuestion(); return m_pChapter->countQuestion();
} }

View File

@ -1,58 +1,58 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef QUESTIONMODEL_H #ifndef QUESTIONMODEL_H
#define QUESTIONMODEL_H #define QUESTIONMODEL_H
#include <qabstractitemmodel.h> #include <qabstractitemmodel.h>
class CChapter; class CChapter;
class CQuestionModel : public QAbstractItemModel class CQuestionModel : public QAbstractItemModel
{ {
Q_OBJECT Q_OBJECT
public: public:
CQuestionModel(QObject *pParent=0); CQuestionModel(QObject *pParent=0);
~CQuestionModel(); ~CQuestionModel();
void clear(); void clear();
void setModelData (CChapter *pChapter); void setModelData (CChapter *pChapter);
public: public:
virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const; virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const; virtual bool hasChildren (const QModelIndex & parent = QModelIndex()) const;
virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const; virtual QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex()) const;
virtual QModelIndex parent ( const QModelIndex & index ) const; virtual QModelIndex parent ( const QModelIndex & index ) const;
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const; virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
public slots: public slots:
void onLanguageChanged(); void onLanguageChanged();
protected: protected:
void recalcColumn(); void recalcColumn();
protected: protected:
CChapter *m_pChapter; CChapter *m_pChapter;
}; };
#endif #endif

View File

@ -1,178 +1,178 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "recentfiles.h" #include "recentfiles.h"
#include <qmenu.h> #include <qmenu.h>
#include <qstringlist.h> #include <qstringlist.h>
#include <qsettings.h> #include <qsettings.h>
CRecentFiles::CRecentFiles(QObject *pParent) : QObject(pParent) CRecentFiles::CRecentFiles(QObject *pParent) : QObject(pParent)
{ {
m_actNoEntry = new QAction(this); m_actNoEntry = new QAction(this);
m_actSepTop = new QAction(this); m_actSepTop = new QAction(this);
m_actSepTop->setSeparator(true); m_actSepTop->setSeparator(true);
m_actSepTop->setVisible(false); m_actSepTop->setVisible(false);
m_actSepBottom = new QAction(this); m_actSepBottom = new QAction(this);
m_actSepBottom->setSeparator(true); m_actSepBottom->setSeparator(true);
m_actSepBottom->setVisible(false); m_actSepBottom->setVisible(false);
m_showSeperator = SeperatorNone; m_showSeperator = SeperatorNone;
m_actNoEntry->setEnabled(false); m_actNoEntry->setEnabled(false);
m_bShowNoEntry = true; m_bShowNoEntry = true;
onLanguageChanged(); onLanguageChanged();
} }
CRecentFiles::~CRecentFiles() CRecentFiles::~CRecentFiles()
{ {
qDeleteAll(m_listActions); qDeleteAll(m_listActions);
} }
void CRecentFiles::clear() void CRecentFiles::clear()
{ {
qDeleteAll(m_listActions); qDeleteAll(m_listActions);
m_listActions.clear(); m_listActions.clear();
} }
void CRecentFiles::onLanguageChanged() void CRecentFiles::onLanguageChanged()
{ {
m_actNoEntry->setText(tr("No recent files")); m_actNoEntry->setText(tr("No recent files"));
} }
void CRecentFiles::create (const QString& strName, const unsigned uMaxCount) void CRecentFiles::create (const QString& strName, const unsigned uMaxCount)
{ {
QAction *pAct=0; QAction *pAct=0;
qDeleteAll(m_listActions); qDeleteAll(m_listActions);
m_listActions.clear(); m_listActions.clear();
m_strName = strName; m_strName = strName;
m_uMaxCount = uMaxCount; m_uMaxCount = uMaxCount;
for (unsigned u=0; u<uMaxCount; u++) for (unsigned u=0; u<uMaxCount; u++)
{ {
pAct = new QAction(this); pAct = new QAction(this);
pAct->setVisible(false); pAct->setVisible(false);
connect(pAct, SIGNAL(triggered()), this, SLOT(onRecentFile())); connect(pAct, SIGNAL(triggered()), this, SLOT(onRecentFile()));
m_listActions.append(pAct); m_listActions.append(pAct);
} }
updateActions(); updateActions();
} }
void CRecentFiles::insertToMenu(QMenu *pMenu, QAction *pBefore) void CRecentFiles::insertToMenu(QMenu *pMenu, QAction *pBefore)
{ {
pMenu->insertAction(pBefore, m_actSepTop); pMenu->insertAction(pBefore, m_actSepTop);
pMenu->insertAction(pBefore, m_actNoEntry); pMenu->insertAction(pBefore, m_actNoEntry);
pMenu->insertActions(pBefore, m_listActions); pMenu->insertActions(pBefore, m_listActions);
pMenu->insertAction(pBefore, m_actSepBottom); pMenu->insertAction(pBefore, m_actSepBottom);
} }
QString CRecentFiles::settingName() const QString CRecentFiles::settingName() const
{ {
QString str = "RecentFileList"; QString str = "RecentFileList";
if (!m_strName.isEmpty()) str += "_" + m_strName; if (!m_strName.isEmpty()) str += "_" + m_strName;
return str; return str;
} }
void CRecentFiles::onRecentFile() void CRecentFiles::onRecentFile()
{ {
QAction *action = qobject_cast<QAction *>(sender()); QAction *action = qobject_cast<QAction *>(sender());
if (action) if (action)
loadFile(action->data().toString()); loadFile(action->data().toString());
} }
void CRecentFiles::setRecentFile(const QString& strFileName) void CRecentFiles::setRecentFile(const QString& strFileName)
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
strl.removeAll(strFileName); strl.removeAll(strFileName);
strl.prepend(strFileName); strl.prepend(strFileName);
while ((unsigned)strl.size() > m_uMaxCount) while ((unsigned)strl.size() > m_uMaxCount)
strl.removeLast(); strl.removeLast();
set.setValue(settingName(), strl); set.setValue(settingName(), strl);
updateActions(); updateActions();
} }
void CRecentFiles::removeFile(const QString& strFileName) void CRecentFiles::removeFile(const QString& strFileName)
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
strl.removeAll(strFileName); strl.removeAll(strFileName);
set.setValue(settingName(), strl); set.setValue(settingName(), strl);
updateActions(); updateActions();
} }
void CRecentFiles::removeAll() void CRecentFiles::removeAll()
{ {
QSettings set; QSettings set;
set.setValue(settingName(), QStringList()); set.setValue(settingName(), QStringList());
updateActions(); updateActions();
} }
void CRecentFiles::updateActions() void CRecentFiles::updateActions()
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount); unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount);
QString str; QString str;
m_actNoEntry->setVisible(m_bShowNoEntry && uNumRecentFiles == 0); m_actNoEntry->setVisible(m_bShowNoEntry && uNumRecentFiles == 0);
m_actSepTop->setVisible((m_showSeperator == SeperatorTop || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0); m_actSepTop->setVisible((m_showSeperator == SeperatorTop || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0);
m_actSepBottom->setVisible((m_showSeperator == SeperatorBottom || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0); m_actSepBottom->setVisible((m_showSeperator == SeperatorBottom || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0);
for (unsigned i=0; i<uNumRecentFiles; ++i) for (unsigned i=0; i<uNumRecentFiles; ++i)
{ {
str = tr("&%1 %2").arg(i + 1).arg(strl[i]); str = tr("&%1 %2").arg(i + 1).arg(strl[i]);
m_listActions[i]->setText(str); m_listActions[i]->setText(str);
m_listActions[i]->setData(strl[i]); m_listActions[i]->setData(strl[i]);
m_listActions[i]->setVisible(true); m_listActions[i]->setVisible(true);
} }
for (unsigned j=uNumRecentFiles; j<m_uMaxCount; ++j) for (unsigned j=uNumRecentFiles; j<m_uMaxCount; ++j)
m_listActions[j]->setVisible(false); m_listActions[j]->setVisible(false);
} }
QString CRecentFiles::recentFile(const int idx) const QString CRecentFiles::recentFile(const int idx) const
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
if (idx >= strl.size()) return QString(); if (idx >= strl.size()) return QString();
return strl.at(idx); return strl.at(idx);
} }
void CRecentFiles::setShowNoEntry (const bool bShow) void CRecentFiles::setShowNoEntry (const bool bShow)
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount); unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount);
m_bShowNoEntry = bShow; m_bShowNoEntry = bShow;
m_actNoEntry->setVisible(m_bShowNoEntry && uNumRecentFiles == 0); m_actNoEntry->setVisible(m_bShowNoEntry && uNumRecentFiles == 0);
} }
void CRecentFiles::setShowSeperator(const ShowSeperator show) void CRecentFiles::setShowSeperator(const ShowSeperator show)
{ {
QSettings set; QSettings set;
QStringList strl = set.value(settingName()).toStringList(); QStringList strl = set.value(settingName()).toStringList();
unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount); unsigned uNumRecentFiles = qMin((unsigned)strl.size(), m_uMaxCount);
m_showSeperator = show; m_showSeperator = show;
m_actSepTop->setVisible((m_showSeperator == SeperatorTop || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0); m_actSepTop->setVisible((m_showSeperator == SeperatorTop || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0);
m_actSepBottom->setVisible((m_showSeperator == SeperatorBottom || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0); m_actSepBottom->setVisible((m_showSeperator == SeperatorBottom || m_showSeperator == SeperatorBoth) && uNumRecentFiles != 0);
} }

View File

@ -1,82 +1,82 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#pragma once #pragma once
#include <qlist.h> #include <qlist.h>
#include <qaction.h> #include <qaction.h>
#include <qstring.h> #include <qstring.h>
class QMenu; class QMenu;
class CRecentFiles : public QObject class CRecentFiles : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum ShowSeperator { SeperatorNone, SeperatorTop, SeperatorBottom, SeperatorBoth }; enum ShowSeperator { SeperatorNone, SeperatorTop, SeperatorBottom, SeperatorBoth };
CRecentFiles(QObject *pParent=0); CRecentFiles(QObject *pParent=0);
~CRecentFiles(); ~CRecentFiles();
void clear(); void clear();
void create (const QString& strName, const unsigned uMaxCount=4); void create (const QString& strName, const unsigned uMaxCount=4);
void insertToMenu(QMenu *pMenu, QAction *pBefore=0); void insertToMenu(QMenu *pMenu, QAction *pBefore=0);
inline unsigned maxCount() const { return m_uMaxCount; } inline unsigned maxCount() const { return m_uMaxCount; }
inline QString name() const { return m_strName; } inline QString name() const { return m_strName; }
void setRecentFile(const QString& strFileName); void setRecentFile(const QString& strFileName);
void removeFile(const QString& strFileName); void removeFile(const QString& strFileName);
void removeAll(); void removeAll();
QString recentFile(const int idx) const; QString recentFile(const int idx) const;
void setShowNoEntry (const bool bShow); void setShowNoEntry (const bool bShow);
inline bool showNoEntry() const { return m_bShowNoEntry; } inline bool showNoEntry() const { return m_bShowNoEntry; }
void setShowSeperator(const ShowSeperator show); void setShowSeperator(const ShowSeperator show);
inline ShowSeperator showSeperator() const { return m_showSeperator; } inline ShowSeperator showSeperator() const { return m_showSeperator; }
public slots: public slots:
void onLanguageChanged(); void onLanguageChanged();
protected slots: protected slots:
void onRecentFile(); void onRecentFile();
signals: signals:
void loadFile(QString strFile); void loadFile(QString strFile);
protected: protected:
QString settingName() const; QString settingName() const;
void updateActions(); void updateActions();
protected: protected:
QString m_strName; QString m_strName;
unsigned m_uMaxCount; unsigned m_uMaxCount;
QList<QAction*> m_listActions; QList<QAction*> m_listActions;
QAction *m_actNoEntry; QAction *m_actNoEntry;
QAction *m_actSepTop; QAction *m_actSepTop;
QAction *m_actSepBottom; QAction *m_actSepBottom;
bool m_bShowNoEntry; bool m_bShowNoEntry;
ShowSeperator m_showSeperator; ShowSeperator m_showSeperator;
}; };

106
tools.cpp
View File

@ -1,53 +1,53 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "tools.h" #include "tools.h"
#include <qpainter.h> #include <qpainter.h>
#include <qpalette.h> #include <qpalette.h>
unsigned afu_random (const unsigned uMin, const unsigned uMax) unsigned afu_random (const unsigned uMin, const unsigned uMax)
{ {
unsigned u=0; unsigned u=0;
float f = (float) (uMax-uMin+1) / (float) RAND_MAX; float f = (float) (uMax-uMin+1) / (float) RAND_MAX;
u = (unsigned) ((float) rand () * f) + uMin;; u = (unsigned) ((float) rand () * f) + uMin;;
return (u); return (u);
} }
QDomElement createXmlTextElement(const QString& strName, const QString& strText, QDomDocument& doc) QDomElement createXmlTextElement(const QString& strName, const QString& strText, QDomDocument& doc)
{ {
QDomElement elem = doc.createElement(strName); QDomElement elem = doc.createElement(strName);
elem.appendChild(doc.createTextNode(strText)); elem.appendChild(doc.createTextNode(strText));
return elem; return elem;
} }
QPixmap createProgressBar (int w, int h, double dPercent) QPixmap createProgressBar (int w, int h, double dPercent)
{ {
QPixmap pix(w,h); QPixmap pix(w,h);
QPainter p(&pix); QPainter p(&pix);
pix.fill(QPalette().color(QPalette::Dark)); pix.fill(QPalette().color(QPalette::Dark));
p.setBrush(Qt::blue); p.setBrush(Qt::blue);
p.setPen(Qt::blue); p.setPen(Qt::blue);
if (dPercent != 0.0) if (dPercent != 0.0)
p.drawRect(0, 0, (int)(((double)w)*dPercent), h); p.drawRect(0, 0, (int)(((double)w)*dPercent), h);
return pix; return pix;
} }

64
tools.h
View File

@ -1,32 +1,32 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2003-2007 by Oliver Saal * * Copyright (C) 2003-2007 by Oliver Saal *
* osaal@gmx.de * * osaal@gmx.de *
* http://www.oliver-saal.de/software/afutrainer/ * * http://www.oliver-saal.de/software/afutrainer/ *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef TOOLS_H #ifndef TOOLS_H
#define TOOLS_H #define TOOLS_H
#include <qdom.h> #include <qdom.h>
#include <qpixmap.h> #include <qpixmap.h>
unsigned afu_random (const unsigned uMin, const unsigned uMax); unsigned afu_random (const unsigned uMin, const unsigned uMax);
QDomElement createXmlTextElement(const QString& strName, const QString& strText, QDomDocument& doc); QDomElement createXmlTextElement(const QString& strName, const QString& strText, QDomDocument& doc);
QPixmap createProgressBar (int w, int h, double dPercent); QPixmap createProgressBar (int w, int h, double dPercent);
#endif #endif