/*************************************************************************** * 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 "osziparchive.h" #include "tools.h" #include #include #include #include #include CCatalog::~CCatalog() { qDeleteAll(m_listFiles); } void CCatalog::clear() { CChapter::clear(); m_bMixAnswers = true; m_bSort = false; m_strFileName.clear(); m_listHint.clear(); m_strUniqueName.clear(); qDeleteAll(m_listFiles); m_strPublisher.clear(); m_strContact.clear(); m_dateValidFrom = QDate(); m_dateValidUntil = QDate(); m_dateCreated = QDate(); m_datePublished = QDate(); m_strVersion.clear(); m_listExam.clear(); m_listExamStat.clear(); } bool CCatalog::isEmpty() { return m_strText.isEmpty(); } bool CCatalog::isValid() const { if (m_dateValidFrom.isValid() && QDate::currentDate() < m_dateValidFrom) return false; if (m_dateValidUntil.isValid() && QDate::currentDate() > m_dateValidUntil) return false; return true; } bool CCatalog::hasHints (const QString& strQuestionId) const { for (int i=0; itr("Datei-Fehler"), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n%1").arg(strFileName)); return false; } // Fragen entpacken CZipFile *pzfQuestions = zip.findFile("questions.xml"); if (pzfQuestions == 0) { QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Konnte in der Datei '%1' keine Fragen finden.").arg(strFileName)); return false; } strXML = QString::fromUtf8(pzfQuestions->deflateToByteArray()); clear(); // Alle Grafiken in temp. Dateien entpacken // pParent->setCursor(Qt::WaitCursor); for (int i=0; ifileName().right(3); if (str == "png" || str == "jpg" || str == "gif" || str == "bmp") { // Datei entpacken und Pfade im XML anpassen str = QDir::temp().absoluteFilePath(pzf->fileName()+".XXXXXX"); QTemporaryFile *ptf = new QTemporaryFile(str); ptf->open(); str = ptf->fileName(); pzf->deflateToFile(*ptf); ptf->close(); m_listFiles.append(ptf); strXML.replace(pzf->fileName(), str); //qDebug ("Deflating %s to %s", qPrintable(pzf->fileName()), qPrintable(str)); } } // pParent->setCursor(Qt::ArrowCursor); 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)); return false; } elemRoot = doc.documentElement (); if (elemRoot.tagName() != "aqdf") { QMessageBox::critical(pParent, pParent->tr("Datei-Fehler"), pParent->tr("Unbekanntes XML-Datenformat '%1'.").arg(elemRoot.tagName())); return false; } //m_strText = elemRoot.attribute ("name"); m_dateCreated = QDate::fromString(elemRoot.attribute("created"), Qt::ISODate); dVersion = elemRoot.attribute("version").toDouble(); 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)); return false; } n = elemRoot.firstChild(); while (!n.isNull()) { if (n.isElement ()) { e = n.toElement (); if (e.tagName() == QString ("chapter")) { pChapter = new CChapter(); if (pChapter->load (e)) appendChapter(pChapter); else delete pChapter; } else if (e.tagName() == QString ("exam")) { CExam exam; if (exam.load(e)) m_listExam.append(exam); } else if (e.tagName () == "hint") { CHint hint; if (hint.load (e)) m_listHint.append (hint); } else if (e.tagName () == "title") { m_strText = e.text(); m_strUniqueName = e.attribute("unique"); } else if (e.tagName () == "comment") m_strComment = e.text(); else if (e.tagName () == "contact") m_strContact = e.text(); else if (e.tagName () == "publisher") m_strPublisher = e.text(); else if (e.tagName() == "valid") { m_dateValidFrom = QDate::fromString(e.attribute("from"), Qt::ISODate); m_dateValidUntil = QDate::fromString(e.attribute("until"), Qt::ISODate); } else if (e.tagName() == "version") { m_datePublished = QDate::fromString(e.attribute("published"), Qt::ISODate); m_strVersion = e.text(); } else if (e.tagName() == "options") { m_bMixAnswers = QVariant(e.attribute("mixanswers", "true")).toBool(); m_bSort = QVariant(e.attribute("sort", "false")).toBool(); } } n = n.nextSibling(); } if (m_strUniqueName.isEmpty()) m_strUniqueName = QDir(strFileName).dirName(); if (m_bSort) sortAll(); loadStatistic (pParent); updateStatistic(); m_strFileName = strFileName; return true; } bool CCatalog::save (const QString& strFileName, QWidget *pParent) { QFile file (strFileName); if (strFileName.isEmpty()) return false; if (!file.open(QIODevice::WriteOnly)) { QMessageBox::critical(pParent, QString(pParent->tr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen:\n")+strFileName); return false; } QTextStream out(&file); QDomDocument doc("afutrainer"); QDomElement elemRoot = doc.createElement("afutrainer"); //elemRoot.setAttribute("name", name()); elemRoot.setAttribute("version", 3.0); elemRoot.setAttribute("created", QDate::currentDate().toString(Qt::ISODate)); doc.appendChild(elemRoot); // save unique name QDomElement elemTitle = createXmlTextElement("title", name(), doc); elemTitle.setAttribute("unique", m_strUniqueName); elemRoot.appendChild (elemTitle); // save comment if (!m_strComment.isEmpty()) elemRoot.appendChild (createXmlTextElement("comment", m_strComment, doc)); // save contact if (!m_strContact.isEmpty()) elemRoot.appendChild (createXmlTextElement("contact", m_strContact, doc)); // save publisher if (!m_strPublisher.isEmpty()) elemRoot.appendChild (createXmlTextElement("publisher", m_strPublisher, doc)); // save version QDomElement elemVersion = createXmlTextElement("version", m_strVersion, doc); elemVersion.setAttribute("published", m_datePublished.toString(Qt::ISODate)); elemRoot.appendChild(elemVersion); // save dates if (m_dateValidFrom.isValid() || m_dateValidUntil.isValid()) { QDomElement elemValid = doc.createElement("valid"); elemValid.setAttribute("from", m_dateValidFrom.toString(Qt::ISODate)); elemValid.setAttribute("until", m_dateValidUntil.toString(Qt::ISODate)); elemRoot.appendChild(elemValid); } // TODO: save tests // save chapters for (int i=0; isave(elemRoot, doc); // save helpers for (int i=0; itr("Datei-Fehler")), pParent->tr("Konnte folgende Datei nicht zum Lesen öffnen:\n")+statisticFileName()); return false; } QTextStream in (&file); strXML = in.readAll(); 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)); return false; } file.close (); elemRoot = doc.documentElement (); if (doc.doctype().name() != "AFUTrainerStatistics") return false; if (elemRoot.tagName() != "statistic") return false; n = elemRoot.firstChild(); while (!n.isNull()) { if (n.isElement ()) { e = n.toElement (); if (e.tagName() == QString ("learning")) { loadLearnStatistic(e); } else if (e.tagName() == QString("exams")) loadExamStatistic(e); } n = n.nextSibling(); } return true; } bool CCatalog::saveStatistic(QWidget *pParent) { QDomDocument doc ("AFUTrainerStatistics"); QString strFileName = statisticFileName(); QFile file (strFileName); if (m_strUniqueName.isEmpty()) return false; QDomElement elemRoot = doc.createElement ("statistic"); elemRoot.setAttribute ("name", name()); elemRoot.setAttribute("version", 2); elemRoot.setAttribute("date", QDate::currentDate().toString(Qt::ISODate)); doc.appendChild (elemRoot); QDomElement elemLearn = doc.createElement ("learning"); elemRoot.appendChild (elemLearn); saveLearnStatistic(elemLearn, doc); QDomElement elemExams = doc.createElement ("exams"); elemRoot.appendChild (elemExams); saveExamStatistic(elemExams, doc); if (!file.open (QIODevice::WriteOnly)) { QMessageBox::critical (pParent, pParent->tr("Fehler"), pParent->tr("Konnte folgende Datei nicht zum Schreiben öffnen.\n")+strFileName); return false; } QTextStream out(&file); out << doc.toString (); return true; } bool CCatalog::loadExamStatistic (QDomElement& elemRoot) { QDomNode n; QDomElement e; n = elemRoot.firstChild(); while (!n.isNull()) { if (n.isElement ()) { e = n.toElement (); if (e.tagName() == QString ("exam")) { CExamStat es; if (es.load(e)) m_listExamStat.append(es); } } n = n.nextSibling(); } return true; } void CCatalog::saveExamStatistic (QDomElement& parent, QDomDocument& doc) { for (int i=0; i CCatalog::chapters() { QList list; list.append(this); list << subChapters(); return list; } CExam CCatalog::examById(const QString& strId) const { for (int i=0; i