Convert CRLF to Unix newlines
This commit is contained in:
parent
9898b3404a
commit
1010914f41
238
answer.cpp
238
answer.cpp
|
@ -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("< 1 sec");
|
return tr("< 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
284
answer.h
|
@ -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
|
||||||
|
|
866
catalog.cpp
866
catalog.cpp
|
@ -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
240
catalog.h
|
@ -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
|
||||||
|
|
410
catalogmodel.cpp
410
catalogmodel.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
110
catalogmodel.h
110
catalogmodel.h
|
@ -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
|
||||||
|
|
||||||
|
|
1616
chapter.cpp
1616
chapter.cpp
File diff suppressed because it is too large
Load Diff
484
chapter.h
484
chapter.h
|
@ -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
|
||||||
|
|
368
chaptermodel.cpp
368
chaptermodel.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
120
chaptermodel.h
120
chaptermodel.h
|
@ -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
|
||||||
|
|
600
dlgexam.cpp
600
dlgexam.cpp
|
@ -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
162
dlgexam.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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')) : "--");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
870
dlglearn.cpp
870
dlglearn.cpp
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
168
dlglearn.h
168
dlglearn.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
196
error.cpp
|
@ -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
156
error.h
|
@ -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
612
exam.cpp
|
@ -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
284
exam.h
|
@ -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
|
||||||
|
|
||||||
|
|
168
helper.cpp
168
helper.cpp
|
@ -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'> </td></tr>";
|
str += "<tr><td colspan='2'> </td></tr>";
|
||||||
str += "</table></p>";
|
str += "</table></p>";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
str += "<p>" + text() + "</p>"; //"<p><i><font size=-1>" + author() + " " + date() + "</font></i></p>";
|
str += "<p>" + text() + "</p>"; //"<p><i><font size=-1>" + author() + " " + date() + "</font></i></p>";
|
||||||
return (str);
|
return (str);
|
||||||
}
|
}
|
||||||
|
|
142
helper.h
142
helper.h
|
@ -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
|
||||||
|
|
84
main.cpp
84
main.cpp
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
1638
mainwindow.cpp
1638
mainwindow.cpp
File diff suppressed because it is too large
Load Diff
182
mainwindow.h
182
mainwindow.h
|
@ -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
|
||||||
|
|
||||||
|
|
934
osziparchive.cpp
934
osziparchive.cpp
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
310
osziparchive.h
310
osziparchive.h
|
@ -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
|
||||||
|
|
||||||
|
|
852
plotwidget.cpp
852
plotwidget.cpp
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
430
plotwidget.h
430
plotwidget.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
1418
question.cpp
1418
question.cpp
File diff suppressed because it is too large
Load Diff
494
question.h
494
question.h
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
116
questionmodel.h
116
questionmodel.h
|
@ -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
|
||||||
|
|
356
recentfiles.cpp
356
recentfiles.cpp
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
164
recentfiles.h
164
recentfiles.h
|
@ -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
106
tools.cpp
|
@ -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
64
tools.h
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue