2022-06-30 23:13:43 +02:00
/***************************************************************************
* Copyright ( C ) 2003 - 2007 by Oliver Saal *
* osaal @ gmx . de *
* http : //www.oliver-saal.de/software/afutrainer/ *
* *
* 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 *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "catalog.h"
# include <qcoreapplication.h>
QString CChapter : : tr ( const char * sourceText , const char * comment )
{
return QCoreApplication : : translate ( " CChapter " , sourceText , comment ) ;
}
void CChapter : : clear ( )
{
m_pParentChapter = 0 ;
m_strId . clear ( ) ;
m_strText . clear ( ) ;
m_strComment . clear ( ) ;
m_recom = RecommendationNone ;
m_recom2 = RecommendationNone ;
qDeleteAll ( m_listChapter ) ;
qDeleteAll ( m_listQuestion ) ;
m_bHasLearningNew = false ;
m_bHasKnownQuestions = false ;
m_bHasKnownQuestionsRepeatToday = false ;
m_uNeverAskedCount = 0 ;
for ( int i = 0 ; i < = LEVEL_MAX ; i + + ) m_uLevelCount [ i ] = 0 ;
for ( int i = 0 ; i < = RecommendationMax ; i + + ) m_uRecomCount [ i ] = 0 ;
// m_mapExam.clear();
}
int CChapter : : countSubQuestion ( ) const
{
int i = 0 , iRet = 0 ;
for ( i = 0 ; i < m_listChapter . size ( ) ; i + + )
iRet + = m_listChapter . at ( i ) - > countSubQuestion ( ) ;
return ( iRet + m_listQuestion . size ( ) ) ;
}
bool CChapter : : load ( QDomElement elem )
{
CChapter * pChapter = 0 ;
if ( elem . tagName ( ) ! = QString ( " chapter " ) ) return false ;
if ( ! elem . hasAttribute ( " name " ) ) return false ;
// if (pParent != NULL && !elem.hasAttribute ("id")) return false;
m_strId = elem . attribute ( " id " ) ;
m_strText = elem . attribute ( " name " ) ;
QDomNode n = elem . firstChild ( ) ;
while ( ! n . isNull ( ) )
{
if ( n . isElement ( ) )
{
QDomElement e = n . toElement ( ) ;
if ( e . tagName ( ) = = " comment " )
m_strComment = e . text ( ) ;
else if ( e . tagName ( ) = = QString ( " chapter " ) )
{
pChapter = new CChapter ( ) ;
if ( pChapter - > load ( e ) )
appendChapter ( pChapter ) ;
else
delete pChapter ;
}
else if ( e . tagName ( ) = = QString ( " question " ) )
{
CQuestion * pQuestion = new CQuestion ( ) ;
if ( pQuestion - > load ( e ) )
appendQuestion ( pQuestion ) ;
else
delete pQuestion ;
}
}
n = n . nextSibling ( ) ;
}
updateStatistic ( ) ;
return true ;
}
void CChapter : : save ( QDomElement & parent , QDomDocument & doc )
{
QDomElement elem = doc . createElement ( " chapter " ) ;
elem . setAttribute ( " name " , text ( ) ) ;
elem . setAttribute ( " id " , id ( ) ) ;
if ( ! m_strComment . isEmpty ( ) )
{
QDomElement elemComment = doc . createElement ( " comment " ) ;
QDomText textComment = doc . createTextNode ( text ( ) ) ;
elemComment . appendChild ( textComment ) ;
elem . appendChild ( elemComment ) ;
}
parent . appendChild ( elem ) ;
// save exams
/* QStringList strl = m_mapExam.keys();
for ( int i = 0 ; i < strl . size ( ) ; i + + )
{
QDomElement e = doc . createElement ( " exam " ) ;
e . setAttribute ( " id " , strl . at ( i ) ) ;
e . setAttribute ( " questions " , QString ( " %1 " ) . arg ( m_mapExam [ strl . at ( i ) ] ) ) ;
elem . appendChild ( e ) ;
}
*/
// save chapters
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
m_listChapter [ i ] - > save ( elem , doc ) ;
}
// save questions
for ( int i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
m_listQuestion [ i ] - > save ( elem , doc ) ;
}
}
bool CChapter : : loadLearnStatistic ( QDomElement elem )
{
QList < CQuestion * > listQuestionPool = questionPool ( ) ;
if ( elem . tagName ( ) ! = QString ( " learning " ) ) return false ;
QDomNode n = elem . firstChild ( ) ;
while ( ! n . isNull ( ) )
{
if ( n . isElement ( ) )
{
QDomElement e = n . toElement ( ) ;
if ( e . tagName ( ) = = QString ( " question " ) )
{
QString strId = e . attribute ( " id " ) ;
for ( int i = 0 ; i < listQuestionPool . size ( ) ; i + + )
{
if ( listQuestionPool . at ( i ) - > id ( ) = = strId )
listQuestionPool [ i ] - > loadLearnStatistic ( e ) ;
}
}
}
n = n . nextSibling ( ) ;
}
updateRecommendation ( ) ;
return true ;
}
bool CChapter : : saveLearnStatistic ( QDomElement & parent , QDomDocument & doc )
{
// questions from sub-chapters
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
m_listChapter [ i ] - > saveLearnStatistic ( parent , doc ) ;
}
// save questions
for ( int i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
m_listQuestion [ i ] - > saveLearnStatistic ( parent , doc ) ;
}
return true ;
}
QString CChapter : : checkForErrors ( ) const
{
QString str ;
// check chapters
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
str + = m_listChapter [ i ] - > checkForErrors ( ) ;
}
// check questions
for ( int i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
str + = m_listQuestion [ i ] - > checkForErrors ( ) ;
}
return str ;
}
QList < CChapter * > CChapter : : subChapters ( ) const
{
QList < CChapter * > list ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
list < < m_listChapter . at ( i ) ;
list < < m_listChapter [ i ] - > subChapters ( ) ;
}
return list ;
}
QList < CQuestion * > CChapter : : questionPool ( ) const
{
QList < CQuestion * > list ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
list < < m_listChapter [ i ] - > questionPool ( ) ;
}
list < < m_listQuestion ;
return list ;
}
QList < CQuestion * > CChapter : : questionPoolLevel ( const unsigned uLevel ) const
{
QList < CQuestion * > list ;
int i ;
for ( i = 0 ; i < m_listChapter . size ( ) ; i + + )
list < < m_listChapter [ i ] - > questionPoolLevel ( uLevel ) ;
for ( i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
if ( m_listQuestion . at ( i ) - > level ( ) = = uLevel )
list . append ( m_listQuestion . at ( i ) ) ;
}
return list ;
}
QList < CQuestion * > CChapter : : questionPoolDeepen ( ) const
{
QList < CQuestion * > list ;
int i ;
for ( i = 0 ; i < m_listChapter . size ( ) ; i + + )
list < < m_listChapter [ i ] - > questionPoolDeepen ( ) ;
for ( i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
CQuestion * q = m_listQuestion . at ( i ) ;
if ( q - > level ( ) = = LEVEL_VERYOFTEN & & ! q - > isNeverAsked ( ) )
list . append ( q ) ;
}
return list ;
}
QList < CQuestion * > CChapter : : questionPoolRepeat ( const QDate d ) const
{
QList < CQuestion * > list ;
int i ;
for ( i = 0 ; i < m_listChapter . size ( ) ; i + + )
list < < m_listChapter [ i ] - > questionPoolRepeat ( d ) ;
for ( i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
CQuestion * q = m_listQuestion . at ( i ) ;
if ( q - > repeatDate ( ) < = d )
list . append ( q ) ;
}
return list ;
}
void CChapter : : updateStatisticCount ( )
{
/* for (int i=0; i<m_listQuestion.size(); i++)
if ( m_listQuestion . at ( i ) - > isLearningNew ( ) ) return true ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
if ( m_listChapter . at ( i ) - > isLearningNew ( ) ) return true ;
return false ;
*/
// Alle Statistiken zurücksetzen
m_uNeverAskedCount = 0 ;
m_bHasLearningNew = false ;
m_bHasKnownQuestions = false ;
m_bHasKnownQuestionsRepeatToday = false ;
for ( int i = 0 ; i < = LEVEL_MAX ; i + + ) m_uLevelCount [ i ] = 0 ;
// Zuerst Statistiken für Unterkapitel berechnen und integrieren
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
CChapter * p = m_listChapter . at ( i ) ;
p - > updateStatisticCount ( ) ;
for ( int j = 0 ; j < = LEVEL_MAX ; j + + )
m_uLevelCount [ j ] + = p - > m_uLevelCount [ j ] ;
m_uNeverAskedCount + = p - > m_uNeverAskedCount ;
if ( p - > hasLearningNewQuestions ( ) ) m_bHasLearningNew = true ;
if ( p - > hasKnownQuestions ( ) ) m_bHasKnownQuestions = true ;
if ( p - > hasKnownQuestionsRepeatToday ( ) ) m_bHasKnownQuestionsRepeatToday = true ;
}
// Anschließend Statistiken für eigene Fragen neu berechnen und hinzufügen
for ( int i = 0 ; i < m_listQuestion . size ( ) ; i + + )
{
CQuestion * q = m_listQuestion . at ( i ) ;
if ( q - > isNeverAsked ( ) ) m_uNeverAskedCount + + ;
m_uLevelCount [ q - > level ( ) ] + + ;
if ( q - > isLearningNew ( ) ) m_bHasLearningNew = true ;
if ( q - > isKnownQuestion ( ) ) m_bHasKnownQuestions = true ;
if ( q - > isKnownQuestion ( ) & & q - > isRepeatToday ( ) ) m_bHasKnownQuestionsRepeatToday = true ;
}
}
void CChapter : : updateRecommendationStatistic ( )
{
for ( int i = 0 ; i < RecommendationMax ; i + + ) m_uRecomCount [ i ] = 0 ;
m_uRecomCount [ recommendation ( ) ] = 1 ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
CChapter * p = m_listChapter . at ( i ) ;
p - > updateRecommendationStatistic ( ) ;
for ( int j = 0 ; j < RecommendationMax ; j + + )
m_uRecomCount [ j ] + = p - > m_uRecomCount [ j ] ;
}
}
/*
Berechnet die Statistik für das Kapitel inkl . aller Unterkapitel neu .
*/
void CChapter : : updateStatistic ( )
{
updateStatisticCount ( ) ;
updateRecommendation ( ) ;
updateRecommendationStatistic ( ) ;
}
/*
CRecommendation CChapter : : recommendation ( ) const
{
CRecommendation r ;
r . create ( this ) ;
return r ;
}
*/
/*
CRecommendationStatistic CChapter : : recommendationStatistic ( ) const
{
CRecommendationStatistic rs ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
rs . append ( m_listChapter . at ( i ) - > recommendationStatistic ( ) ) ;
}
//TODO
// rs.append(recommendation());
return rs ;
}
*/
QString CChapter : : idWithParents ( ) const
{
CChapter * pParent = m_pParentChapter ;
QString str ;
str = id ( ) ;
while ( pParent ! = 0 )
{
str = pParent - > id ( ) + str ;
pParent = pParent - > m_pParentChapter ;
}
return str ;
}
/*!
Das empfohlene Wiederholdatum eines Kapitels das frühestete Datum ,
an dem eine Frage des Kapitels oder Unterkapitels wiederholt werden sollte .
\ return Datum , wann das Kapitel wiederholt werden soll .
Gibt es kein solches Datum , so wird ein ungültiges Datum ( QDate : : isValid ( ) ) zurückgegeben .
Hinweis : Das Datum kann auch in der Vergangenheit liegen !
*/
QDate CChapter : : repeatDate ( ) const
{
QDate d ;
QList < CQuestion * > list = questionPool ( ) ;
for ( int i = 0 ; i < list . size ( ) ; i + + )
{
QDate dq = list . at ( i ) - > repeatDate ( ) ;
if ( ! dq . isValid ( ) ) continue ;
if ( ! d . isValid ( ) | | dq < d ) d = dq ;
}
return d ;
}
/*!
Die Variable m_recomRepeatDate muss up to date sein !
\ return Lernempfehlung dieses Kapitels ohne Berücksichtigung evt . vorhandener ü nter - oder ü bergeordneter Kapitel .
\ sa m_recomRepeatDate
*/
CChapter : : Recommendation CChapter : : recommendationIndividual ( ) const
{
if ( ! m_recomRepeatDate . isValid ( ) )
return RecommendationLearnNew ;
else if ( m_recomRepeatDate < = QDate : : currentDate ( ) )
{
if ( hasLearningNewQuestions ( ) & & ! hasKnownQuestionsRepeatToday ( ) )
return RecommendationLearnNew ;
else
return RecommendationRepeatToday ;
}
else
{
if ( countNeverAsked ( ) > 0 )
return RecommendationLearnNew ;
else
return RecommendationRepeatLater ;
}
}
/*!
Aktualisiert die Lernempfehlung für dieses Kapitel und alle Unterkapitel
\ sa m_recom
*/
void CChapter : : updateRecommendation ( )
{
m_recom = RecommendationNone ;
m_recom2 = RecommendationNone ;
m_recomRepeatDate = repeatDate ( ) ; /*QDate();*/
if ( m_listChapter . isEmpty ( ) & & m_listQuestion . isEmpty ( ) ) return ;
if ( m_pParentChapter & & m_pParentChapter - > recommendation ( ) ! = RecommendationSubChapter )
m_recom = RecommendationParentChapter ;
else
{
if ( countSubQuestion ( ) > 20 )
{ // Nur wenn in den Unterkapiteln zusammen mehr als x Fragen sind, zuerst die Unterkapitel einzeln lernen lassen
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
CChapter * p = m_listChapter . at ( i ) ;
if ( p - > levelAvg ( ) < LEVEL_NORMAL | | p - > countNeverAsked ( ) > 0 )
m_recom = RecommendationSubChapter ;
}
}
if ( m_recom = = RecommendationNone )
{
//m_recomRepeatDate = repeatDate();
m_recom = recommendationIndividual ( ) ;
}
}
// Alternative Empfehlung
if ( m_recom = = RecommendationParentChapter | | m_recom = = RecommendationSubChapter )
{
m_recom2 = recommendationIndividual ( ) ;
if ( m_recom2 ! = RecommendationLearnNew & & m_recom2 ! = RecommendationRepeatToday )
m_recom2 = RecommendationNone ;
}
// find recommended questions
m_listQuestionRecommended . clear ( ) ;
QList < CQuestion * > list = questionPool ( ) ;
for ( int i = 0 ; i < list . size ( ) ; i + + )
{
CQuestion * q = list . at ( i ) ;
if ( m_recom = = RecommendationLearnNew | | m_recom2 = = RecommendationLearnNew )
{
if ( q - > isNeverAsked ( ) | | q - > isLearningNew ( ) )
m_listQuestionRecommended . append ( q ) ;
}
else if ( m_recom = = RecommendationRepeatToday | | m_recom2 = = RecommendationRepeatToday )
{
if ( q - > isRepeatToday ( ) )
m_listQuestionRecommended . append ( q ) ;
}
}
// update child chapters
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
CChapter * p = m_listChapter . at ( i ) ;
p - > updateRecommendation ( ) ;
//m_listQuestionRecommended << p->m_listQuestionRecommended;
}
}
/*
bool CChapter : : hasRecommendedQuestions ( ) const
{
return ( m_recom = = RecommendationLearnNew | | m_recom = = RecommendationRepeatToday ) ;
}
QList < CQuestion * > CChapter : : recommendedQuestions ( ) const
{
QList < CQuestion * > listRet , list = questionPool ( ) ;
if ( m_recom ! = RecommendationLearnNew & & m_recom ! = RecommendationRepeatToday ) return listRet ;
for ( int i = 0 ; i < list . size ( ) ; i + + )
{
CQuestion * q = list . at ( i ) ;
switch ( m_recom )
{
case RecommendationLearnNew :
if ( q - > isNeverAsked ( ) | | q - > isLearningNew ( ) )
listRet . append ( q ) ;
break ;
case RecommendationRepeatToday :
if ( q - > isRepeatToday ( ) )
listRet . append ( q ) ;
break ;
}
}
return listRet ;
}
*/
QString CChapter : : recommendationText ( const Recommendation r , const QDate dRepeat )
{
unsigned uDays = 0 ;
switch ( r )
{
default :
case RecommendationNone :
return tr ( " Keine Lernempfehlung " ) ;
case RecommendationSubChapter :
return tr ( " Zuerst Unterkapitel lernen " ) ;
case RecommendationParentChapter :
return tr ( " Übergeordnetes Kapitel lernen " ) ;
case RecommendationLearnNew :
return tr ( " Neue Fragen lernen " ) ;
case RecommendationRepeatToday :
return tr ( " Heute wiederholen " ) ;
case RecommendationRepeatLater :
uDays = QDate : : currentDate ( ) . daysTo ( dRepeat ) ;
if ( uDays = = 1 )
return tr ( " Morgen wiederholen " ) ;
else
return tr ( " In %1 Tagen wiederholen " ) . arg ( uDays ) ;
}
return QString ( ) ;
}
QString CChapter : : recommendationText ( ) const
{
return recommendationText ( m_recom , m_recomRepeatDate ) ;
}
QString CChapter : : recommendationToolTip ( ) const
{
QString str = recommendationText ( ) ;
unsigned uCount = recommendedQuestionCount ( ) ;
if ( hasRecommendedQuestions ( ) & & m_recom2 = = RecommendationNone )
{
str + = " " ;
if ( uCount = = 1 )
str + = tr ( " (1 Frage) " ) ;
else
str + = tr ( " (%1 Fragen) " ) . arg ( uCount ) ;
}
if ( m_recom2 ! = RecommendationNone )
{
str + = " \n " + tr ( " Alternativ: " ) ;
if ( m_recom2 = = RecommendationLearnNew )
{
if ( uCount = = 1 )
str + = tr ( " 1 neue Frage lernen " ) ;
else
str + = tr ( " %1 neue Fragen lernen " ) . arg ( uCount ) ;
}
else if ( m_recom2 = = RecommendationRepeatToday )
{
if ( uCount = = 1 )
str + = tr ( " 1 Frage wiederholen " ) ;
else
str + = tr ( " %1 Fragen wiederholen " ) . arg ( uCount ) ;
}
else
str + = recommendationText ( m_recom2 , m_recomRepeatDate ) ;
}
return str ;
}
QString CChapter : : recommendationTextExtended ( const CCatalog * pCatalog ) const
{
unsigned uDays = 0 ;
QString str ;
switch ( m_recom )
{
default :
case RecommendationNone :
str = tr ( " Keine Lernempfehlung " ) ;
break ;
case RecommendationSubChapter :
str = tr ( " Dieses Kapitel enthält Unterkapitel, dessen Fragen Sie noch nicht ausreichend gelernt haben. \n Es wird empohlen in kleinen Etappen zu lernen und damit zuerst die Unterkapitel zu vertiefen. " ) ;
break ;
case RecommendationParentChapter :
if ( levelAvgRounded ( ) > = LEVEL_NORMAL )
str = tr ( " Sie können die Fragen dieses Kapitels gut beantworten. \n " ) ;
str + = tr ( " Es wird empfohlen, alle Fragen des übergeordneten Kapitels gemischt zusammen zu lernen. " ) ;
break ;
case RecommendationLearnNew :
if ( ! isRecommendedNow ( pCatalog ) )
str = tr ( " Es gibt andere Kapitel, deren Fragen heute wiederholt werden sollten. Bitte lernen Sie diese Kapitel zuerst. " ) ;
else
str = tr ( " Bitte beantworten Sie alle neuen Fragen mindestens einmal richtig. " ) ;
break ;
case RecommendationRepeatToday :
str = tr ( " Bitte lernen Sie alle heute zu wiederholenden Fragen, bis sie eine Lernfortschritts-Stufe höher eingestuft sind. " ) ;
break ;
case RecommendationRepeatLater :
uDays = QDate : : currentDate ( ) . daysTo ( m_recomRepeatDate ) ;
if ( uDays > 1 )
str = tr ( " Die Wiederholung dieses Kapitels ist erst in %1 Tagen geplant. \n " ) . arg ( uDays ) ;
else
str = tr ( " Die Wiederholung dieses Kapitels ist erst für morgen geplant. \n " ) ;
if ( pCatalog - > m_uRecomCount [ RecommendationRepeatToday ] > 0 )
str + = tr ( " Es gibt andere Kapitel, deren Fragen heute wiederholt werden müssen. Bitte lernen Sie diese Kapitel zuerst. " ) ;
else if ( pCatalog - > m_uRecomCount [ RecommendationLearnNew ] > 0 )
str + = tr ( " Bitte lernen Sie zuerst Kapitel mit neuen Fragen. " ) ;
break ;
}
if ( hasRecommendedQuestions ( ) & & isRecommendedNow ( pCatalog ) )
str + = tr ( " <p>Dafür sind noch %1 Fragen zu lernen. " ) . arg ( recommendedQuestionCount ( ) ) ;
return str ;
}
QString CChapter : : recommendationTextExtended2 ( const CCatalog * pCatalog ) const
{
QString str ;
if ( m_recom2 = = RecommendationLearnNew | | ( m_recom = = RecommendationLearnNew & & ! isRecommendedNow ( pCatalog ) ) )
{
//str = tr("Bitte beantworten Sie alle neuen Fragen mindestens einmal richtig.");
str = tr ( " Alternativ können Sie jetzt die neuen Fragen dieses Kapitels lernen (%1 Fragen). " ) . arg ( recommendedQuestionCount ( ) ) ;
}
else if ( m_recom2 = = RecommendationRepeatToday )
{
if ( m_recom = = RecommendationSubChapter )
str = tr ( " Bitte lernen Sie alle heute zu wiederholenden Fragen, bis sie eine Lernfortschritts-Stufe höher eingestuft sind (%1 Fragen). " ) . arg ( recommendedQuestionCount ( ) ) ;
else
str = tr ( " Alternativ können Sie jetzt die heute zu wiederholenden Fragen dieses Kapitels lernen (%1 Fragen). " ) . arg ( recommendedQuestionCount ( ) ) ;
}
return str ;
}
QString CChapter : : recommendationIconName ( const Recommendation r , const CCatalog * pCatalog )
{
switch ( r )
{
case RecommendationSubChapter :
return QString ( " :/icons/16x16/button_cancel.png " ) ;
case RecommendationParentChapter :
return QString ( " :/icons/16x16/button_ok.png " ) ;
case RecommendationLearnNew :
if ( pCatalog - > m_uRecomCount [ RecommendationRepeatToday ] > 0 )
return QString ( " :/icons/16x16/idea_gray.png " ) ;
else
return QString ( " :/icons/16x16/idea.png " ) ;
case RecommendationRepeatToday :
return QString ( " :/icons/16x16/idea.png " ) ;
case RecommendationRepeatLater :
return QString ( " :/icons/16x16/idea_gray.png " ) ;
default :
return QString ( ) ;
}
}
QString CChapter : : recommendationIconName ( const CCatalog * pCatalog ) const
{
return recommendationIconName ( m_recom , pCatalog ) ;
}
/*!
\ return true : Kapitel kann jetzt gelernt werden ,
false : Kapitel sollte ü berhaupt nicht oder erst später gelernt werden
*/
bool CChapter : : isRecommendedNow ( const CCatalog * pCatalog ) const
{
switch ( m_recom )
{
case RecommendationSubChapter :
if ( pCatalog - > m_uRecomCount [ RecommendationRepeatToday ] > 0 )
return true ;
break ;
case RecommendationRepeatToday :
return true ;
case RecommendationLearnNew :
if ( pCatalog - > m_uRecomCount [ RecommendationRepeatToday ] = = 0 )
return true ;
break ;
default :
break ;
}
return false ;
}
/*
\ return true : Das Kapitel enthält noch neue Fragen , die gerade ( = " heute " ) gelernt werden
bool CChapter : : isLearningNew ( ) const
{
for ( int i = 0 ; i < m_listQuestion . size ( ) ; i + + )
if ( m_listQuestion . at ( i ) - > isLearningNew ( ) ) return true ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
if ( m_listChapter . at ( i ) - > isLearningNew ( ) ) return true ;
return false ;
}
*/
CDayStatistic CChapter : : dayStatistic ( const QDate & date ) const
{
CDayStatistic dsRet , ds ;
QList < CQuestion * > listPool = questionPool ( ) ;
for ( int i = 0 ; i < listPool . size ( ) ; i + + )
{
ds = listPool . at ( i ) - > dayStatistic ( date ) ;
dsRet + = ds ;
}
if ( listPool . size ( ) ! = 0 ) dsRet . m_dLevel / = listPool . size ( ) ;
return dsRet ;
}
CDayStatistic CChapter : : completeStatistic ( ) const
{
return dayStatistic ( QDate ( ) ) ;
}
QDateTime CChapter : : firstAnswerClicked ( ) const
{
QList < CQuestion * > listPool = questionPool ( ) ;
QDateTime dtRet , dt ;
for ( int i = 0 ; i < listPool . size ( ) ; i + + )
{
dt = listPool . at ( i ) - > firstClicked ( ) ;
if ( dt . isNull ( ) ) continue ;
if ( dtRet . isNull ( ) | | dt < dtRet ) dtRet = dt ;
}
return dtRet ;
}
double CChapter : : levelAvg ( ) const
{
double d = 0.0 ;
double dCount = 0.0 ;
for ( int i = 0 ; i < = LEVEL_MAX ; i + + )
{
d + = m_uLevelCount [ i ] * i ;
dCount + = m_uLevelCount [ i ] ;
}
if ( dCount ! = 0.0 ) d / = dCount ;
return d ;
}
unsigned CChapter : : levelAvgRounded ( ) const
{
return ( ( unsigned ) ( levelAvg ( ) + 0.5 ) ) ;
}
QString CChapter : : levelAvgText ( ) const
{
return QString ( " %1 " ) . arg ( CQuestion : : levelText ( levelAvgRounded ( ) ) ) ;
}
QIcon CChapter : : levelAvgIcon ( ) const
{
return QIcon ( CQuestion : : levelIconName ( levelAvgRounded ( ) ) ) ;
}
QPixmap CChapter : : levelAvgPixmap ( ) const
{
return QPixmap ( CQuestion : : levelIconName ( levelAvgRounded ( ) ) ) ;
}
static bool chapterLessThan ( const CChapter * c1 , const CChapter * c2 )
{
return c1 - > id ( ) < c2 - > id ( ) ;
}
void CChapter : : sortSubChapters ( bool bSortQuestions )
{
if ( bSortQuestions ) sortQuestions ( ) ;
qSort ( m_listChapter . begin ( ) , m_listChapter . end ( ) , chapterLessThan ) ;
for ( int i = 0 ; i < m_listChapter . size ( ) ; i + + )
{
m_listChapter . at ( i ) - > sortSubChapters ( bSortQuestions ) ;
}
}
static bool questionLessThan ( const CQuestion * q1 , const CQuestion * q2 )
{
return q1 - > id ( ) < q2 - > id ( ) ;
}
void CChapter : : sortQuestions ( )
{
qSort ( m_listQuestion . begin ( ) , m_listQuestion . end ( ) , questionLessThan ) ;
}