1 /***************************************************************************
2 fileread.cpp - description
4 begin : Wed May 23 2001
5 copyright : (C) 2001 by Javier Campos
6 email : javi@asyris.org
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
22 #include <kio/netaccess.h>
23 #include <kstandarddirs.h>
24 #include <kmimetype.h>
26 #include <ktempfile.h>
28 #include <qfileinfo.h>
32 FileRead::FileRead( QObject
*parent
, const char *name
)
33 :QObject(parent
, name
),
43 bool FileRead::openFile(const KURL
&url
) {
46 if( KIO::NetAccess::download( url
, tmpFile
, 0 ) )
48 returnval
=loadFile( tmpFile
);
51 kdDebug()<<"... load successful: "<<_currentURL
.url()<<endl
;
54 KIO::NetAccess::removeTempFile( tmpFile
);
56 kdDebug()<<"FileRead::openFile(): download NOT successful: "<<url
.url()<<endl
;
61 bool FileRead::loadFile(const QString
&filename
)
63 QDomDocument
doc("document.xml");
65 KMimeType::Ptr type
= KMimeType::findByFileContent(filename
);
67 kdDebug() << "FileRead::loadFile(): MIME-Type is " << type
->name() << endl
;
71 if(!file
.open(IO_ReadOnly
))
76 if (type
->name() == "text/html") // Non-compressed files are recognized as HTML...
78 doc
.setContent(&file
);
82 doc
.setContent(qUncompress(file
.readAll()));
85 QDomElement docElem
= doc
.documentElement();
86 if( (doc
.doctype().isNull()) || (doc
.doctype().name() != "educa") ) {
91 QDomNode n
= docElem
.firstChild();
93 QDomNodeList dnList
= n
.childNodes();
94 for( unsigned int i
= 0; i
< dnList
.count(); ++i
)
96 // ------------------- INFORMATION BODY -----------------------
97 QDomElement element
= dnList
.item(i
).toElement();
98 if( element
.tagName() == "default" || element
.tagName() == "author" )
100 if( element
.tagName() == "default" ) { _header
.insert( "image", element
.attribute( "image", "default.png" ) ); }
101 if( element
.tagName() == "author" ) {
102 QDomNodeList AuthordnList
= element
.childNodes();
103 for( unsigned int i
= 0; i
< AuthordnList
.count(); ++i
) {
104 QDomElement authorelement
= AuthordnList
.item(i
).toElement();
105 _header
.insert( authorelement
.tagName(), authorelement
.text() );
109 _header
.insert( element
.tagName(), element
.text() );
115 dnList
= n
.childNodes();
116 for( unsigned int i
= 0; i
< dnList
.count(); ++i
)
119 // --------------------- QUESTION ATTRIBUTE------------------------
120 QDomElement elementNODE
= dnList
.item(i
).toElement();
121 setQuestion( QF_TYPE
, elementNODE
.attribute( "type", "1" ).toInt() );
122 setQuestion( QF_PICTURE
, elementNODE
.attribute( "image", "" ) );
123 setQuestion( QF_TIME
, elementNODE
.attribute( "time", "0" ).toInt() );
124 setQuestion( QF_POINTS
, elementNODE
.attribute( "points", "0" ).toInt() );
126 QDomNodeList quList
= elementNODE
.childNodes();
127 for( unsigned int x
= 0; x
< quList
.count(); ++x
)
129 // --------------------- QUESTION AND RESPONSES------------------
130 QDomElement element
= quList
.item(x
).toElement();
131 if( element
.tagName() == "text" ) setQuestion( QF_TEXT
, element
.text() );
132 if( element
.tagName() == "true" ) setAnswer( element
.text(), true, element
.attribute( "points", "0" ).toInt() );
133 if( element
.tagName() == "false" ) setAnswer( element
.text(), false,element
.attribute( "points", "0" ).toInt() );
134 if( element
.tagName() == "tip" ) setQuestion( QF_TIP
, element
.text() );
135 if( element
.tagName() == "explain" ) setQuestion( QF_EXPLAIN
, element
.text() );
141 dnList
= n
.childNodes();
143 if( dnList
.count() > 0 )
145 for( unsigned int i
= 0; i
< dnList
.count(); ++i
)
148 // --------------------- QUESTION ATTRIBUTE------------------------
149 QDomElement elementNODE
= dnList
.item(i
).toElement();
150 setResult( RS_TEXT
, elementNODE
.text() );
151 setResult( RS_PICTURE
, elementNODE
.attribute( "image", "" ) );
152 setResult( RS_MIN
, elementNODE
.attribute( "min", "0" ).toInt() );
153 setResult( RS_MAX
, elementNODE
.attribute( "max", "0" ).toInt() );
165 void FileRead::setQuestion( QuestionField field
, const QString
& text
)
167 // QF_text, QF_picture, QF_type, QF_time, QF_tip, QF_explain
171 (*_recordQuestions
).text
= text
;
174 (*_recordQuestions
).picture
= text
;
177 (*_recordQuestions
).tip
= text
;
180 (*_recordQuestions
).explain
= text
;
183 kdDebug()<<"FileRead::setQuestion(QuestionField field, QString text) called for not handled field value "<<field
<<endl
;
189 void FileRead::setQuestion( QuestionField field
, int value
)
194 (*_recordQuestions
).type
= value
;
197 (*_recordQuestions
).time
= value
;
200 (*_recordQuestions
).points
= value
;
203 kdDebug()<<"FileRead::setQuestion(QuestionField field, int value) called for not handled field value "<<field
<<endl
;
209 void FileRead::setResult( ResultField field
, const QString
& text
)
211 // RS_text, QF_picture
215 (*_recordResults
).text
= text
;
218 (*_recordResults
).picture
= text
;
221 kdDebug()<<"FileRead::setResult(ResultField field, QString text) called for not handled field value "<<field
<<endl
;
227 void FileRead::setResult( ResultField field
, int value
)
232 (*_recordResults
).min
= value
;
235 (*_recordResults
).max
= value
;
238 kdDebug()<<"FileRead::setResultInt(ResultField field, int value) called for not handled field value "<<field
<<endl
;
244 void FileRead::setAnswer( const QString
& text
, bool value
, int points
)
248 tmpAnswers
.text
= text
;
249 tmpAnswers
.value
= value
;
250 tmpAnswers
.points
= points
;
252 (*_recordQuestions
).listAnswers
.append( tmpAnswers
);
256 void FileRead::insertQuestion()
258 Questions tempQuestions
;
259 tempQuestions
.text
= "";
260 _listQuestions
.append( tempQuestions
);
265 void FileRead::insertResult()
268 tempResults
.text
= "";
269 _listResults
.append( tempResults
);
274 void FileRead::recordFirst()
276 if( _fileEOF
= true ) _fileEOF
= false;
277 if( _fileBOF
= false ) _fileBOF
= true;
278 _recordQuestions
= _listQuestions
.begin();
281 void FileRead::recordLast()
283 if( _fileBOF
= true ) _fileBOF
= false;
284 if( _fileEOF
= false ) _fileEOF
= true;
285 _recordQuestions
= _listQuestions
.end();
289 void FileRead::recordNext()
292 if( _recordQuestions
== _listQuestions
.end() )
298 if( _fileBOF
= true ) _fileBOF
= false;
301 void FileRead::recordPrevious()
303 if( _recordQuestions
== _listQuestions
.begin() )
307 if( _fileEOF
= true ) _fileEOF
= false;
312 void FileRead::recordResultFirst()
314 if( _fileResultEOF
= true ) _fileResultEOF
= false;
315 if( _fileResultBOF
= false ) _fileResultBOF
= true;
316 _recordResults
= _listResults
.begin();
319 void FileRead::recordResultLast()
321 if( _fileResultBOF
= true ) _fileResultBOF
= false;
322 if( _fileResultEOF
= false ) _fileResultEOF
= true;
323 _recordResults
= _listResults
.end();
327 void FileRead::recordResultNext()
330 if( _recordResults
== _listResults
.end() )
332 _fileResultEOF
= true;
337 if( _fileBOF
= true ) _fileBOF
= false;
341 void FileRead::recordResultPrevious()
343 if( _recordResults
== _listResults
.begin() )
345 _fileResultBOF
= true;
349 if( _fileResultEOF
= true ) _fileResultEOF
= false;
354 void FileRead::recordAnswerFirst()
356 if( _fileAnswerEOF
= true ) _fileAnswerEOF
= false;
357 if( _fileAnswerBOF
= false ) _fileAnswerBOF
= true;
358 (*_recordQuestions
).recordAnswers
= (*_recordQuestions
).listAnswers
.begin();
361 void FileRead::recordAnswerLast()
363 if( _fileAnswerBOF
= true ) _fileAnswerBOF
= false;
364 if( _fileAnswerEOF
= false ) _fileAnswerEOF
= true;
365 (*_recordQuestions
).recordAnswers
= (*_recordQuestions
).listAnswers
.end();
366 --(*_recordQuestions
).recordAnswers
;
369 void FileRead::recordAnswerNext()
371 ++(*_recordQuestions
).recordAnswers
;
372 if( (*_recordQuestions
).recordAnswers
== (*_recordQuestions
).listAnswers
.end() )
374 _fileAnswerEOF
= true;
375 --(*_recordQuestions
).recordAnswers
;
379 if( _fileAnswerBOF
= true ) _fileAnswerBOF
= false;
383 void FileRead::recordAnswerPrevious()
385 if( (*_recordQuestions
).recordAnswers
== (*_recordQuestions
).listAnswers
.begin() )
391 if( _fileAnswerEOF
= true ) _fileAnswerEOF
= false;
392 --(*_recordQuestions
).recordAnswers
;
396 void FileRead::recordAnswerAt( unsigned int index
)
398 (*_recordQuestions
).recordAnswers
= (*_recordQuestions
).listAnswers
.begin();
399 for( unsigned int i
= 0; i
< index
; ++i
)
400 ++(*_recordQuestions
).recordAnswers
;
403 unsigned int FileRead::recordAnswerCount()
405 return (*_recordQuestions
).listAnswers
.count();
408 QString
FileRead::getQuestion( QuestionField field
)
410 // QF_text, QF_picture, QF_type, QF_time, QF_tip, QF_explain
414 return (*_recordQuestions
).text
;
417 // return getPictureLocal( (*_recordQuestions).picture );
418 return( (*_recordQuestions
).picture
);
421 return QString().setNum( (*_recordQuestions
).points
);
424 return QString().setNum( (*_recordQuestions
).time
);
427 return (*_recordQuestions
).tip
;
430 return (*_recordQuestions
).explain
;
433 kdDebug()<<"FileRead::getQuestion() called for not handled field value "<<field
<<endl
;
439 int FileRead::getQuestionInt( QuestionField field
)
444 return (*_recordQuestions
).type
;
447 return (*_recordQuestions
).time
;
450 return (*_recordQuestions
).points
;
453 kdDebug()<<"FileRead::getQuestionInt() called for not handled field value "<<field
<<endl
;
458 QString
FileRead::getAnswer( AnswerField field
)
460 // AField { AF_text, AF_value, AF_picture, AF_point };
464 return (*(*_recordQuestions
).recordAnswers
).text
;
467 // (*(*_recordQuestions).RecordAnswers).Value ? return i18n("True") : return i18n("False");
470 return QString().setNum( (*(*_recordQuestions
).recordAnswers
).points
);
473 kdDebug()<<"FileRead::getAnswer() called for not handled field value "<<field
<<endl
;
478 bool FileRead::getAnswerValue()
480 return (*(*_recordQuestions
).recordAnswers
).value
;
483 int FileRead::getAnswerPoints()
485 return (*(*_recordQuestions
).recordAnswers
).points
;
488 QString
FileRead::getResult( ResultField field
)
493 return (*_recordResults
).text
;
496 return( (*_recordResults
).picture
);
499 return QString().setNum( (*_recordResults
).min
);
502 return QString().setNum( (*_recordResults
).max
);
505 kdDebug()<<"FileRead::getResult() called for not handled field value "<<field
<<endl
;
511 int FileRead::getResultInt( ResultField field
)
516 return (*_recordResults
).min
;
519 return (*_recordResults
).max
;
522 kdDebug()<<"FileRead::getResult() called for not handled field value "<<field
<<endl
;
528 bool FileRead::recordEOF()
533 bool FileRead::recordBOF()
538 bool FileRead::recordResultEOF()
540 return _fileResultEOF
;
543 bool FileRead::recordResultBOF()
545 return _fileResultBOF
;
548 bool FileRead::recordAnswerEOF()
550 return _fileAnswerEOF
;
553 bool FileRead::recordAnswerBOF()
555 return _fileAnswerBOF
;
558 QString
FileRead::getPicture()
562 if( !getQuestion(QF_PICTURE
).isEmpty() )
563 picture
= getQuestion(QF_PICTURE
);
564 else if( !(_header
["image"]).isEmpty() )
565 picture
= _header
["image"];
567 return locate("data","keduca/pics/default.png");
569 if( _currentURL
.isLocalFile() && !KURL(picture
).isValid() )
571 if( !QFileInfo(picture
).exists() )
572 picture
= _currentURL
.directory(false,true) + picture
;
573 } else if( !_currentURL
.isLocalFile() && !KURL(picture
).isValid() )
574 picture
= _currentURL
.protocol() + "://" + _currentURL
.host() + _currentURL
.directory(false,true) + picture
;
576 kdDebug()<< picture
<<endl
;
581 QPixmap
FileRead::getPicturePixmap()
584 KURL
picture ( getPicture() );
587 if( KIO::NetAccess::download( picture
, _tmpfileImage
, 0 ) )
589 kdDebug()<<"... load successful: "<< _tmpfileImage
<<endl
;
590 pict
= QPixmap( _tmpfileImage
);
591 KIO::NetAccess::removeTempFile( _tmpfileImage
);
595 kdDebug()<<"FileRead::openFile(): download NOT successful: "<< _tmpfileImage
<<endl
;
602 void FileRead::clearAnswers()
604 ((*_recordQuestions
).listAnswers
).clear();
608 void FileRead::recordDelete()
610 _listQuestions
.remove( _recordQuestions
);
614 void FileRead::recordSwap( bool moveup
)
619 listTMP
= (*_recordQuestions
);
624 listNEW
= (*_recordQuestions
);
625 (*_recordQuestions
) = listTMP
;
627 (*_recordQuestions
) = listNEW
;
632 listNEW
= (*_recordQuestions
);
633 (*_recordQuestions
) = listTMP
;
635 (*_recordQuestions
) = listNEW
;
640 bool FileRead::saveFile( const KURL
&url
, bool copyimages
, bool saveCompressed
)
646 kdDebug()<<"FileRead::saveFile() to "<<_currentURL
.url()<<endl
;
648 if ( _currentURL
.isLocalFile() )
650 if ( _tmpfile
!= 0 ) // get rid of a possible temp file first
651 { // (happens if previous _currentURL was remote)
656 if( saveFile(_currentURL
.path(), copyimages
, saveCompressed
) ) {
658 emit
setWindowCaption( _currentURL
.prettyURL() );
664 // We haven't saved yet, or we did but locally - provide a temp file
667 _tmpfile
= new KTempFile
;
669 // otherwise, we already had a temp file
670 if( saveFile(_tmpfile
->name(), copyimages
, saveCompressed
) ) {
672 KIO::Job
* job
= KIO::file_copy( KURL::fromPathOrURL( _tmpfile
->name() ), _currentURL
, -1, true /*overwrite*/ );
673 connect( job
, SIGNAL( result( KIO::Job
* ) ), this, SLOT( slotUploadFinished (KIO::Job
*) ) );
678 // Save local file and upload local file
682 bool FileRead::saveFile( const QString
&filename
, bool copyimages
, bool saveCompressed
)
684 QDomDocument
doc("document.xml");
688 QBuffer
buffer(data
);
689 QFile
file(filename
);
692 stream
.setDevice(&buffer
);
694 if ( (!file
.open(IO_WriteOnly
)) || (!buffer
.open(IO_WriteOnly
)) )
699 stream.setDevice(&file);
701 if(!file.open(IO_WriteOnly))
703 // No puede abrir la base
708 QString
head( "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><!DOCTYPE educa>" );
709 doc
.setContent( head
);
711 QDomElement Root
= doc
.createElement("Document");
712 doc
.appendChild( Root
);
714 QDomElement NodeInfo
= doc
.createElement("Info");
715 Root
.appendChild( NodeInfo
);
717 insertXML( doc
, NodeInfo
, "title", _header
["title"] );
718 insertXML( doc
, NodeInfo
, "category", _header
["category"] );
719 insertXML( doc
, NodeInfo
, "type", _header
["type"] );
720 insertXML( doc
, NodeInfo
, "level", _header
["level"] );
721 insertXML( doc
, NodeInfo
, "language", _header
["language"] );
723 if( !(_header
["image"]).isEmpty() )
725 QDomElement Nodedefault
= doc
.createElement("default");
729 copyJOB
.append( _header
["image"] );
730 Nodedefault
.setAttribute( "image", QFileInfo(_header
["image"]).fileName() );
732 Nodedefault
.setAttribute( "image", _header
["image"]);
734 NodeInfo
.appendChild( Nodedefault
);
737 if( !_header
["name"].isEmpty() || !_header
["email"].isEmpty() || !_header
["www"].isEmpty() )
739 QDomElement Nodeauthor
= doc
.createElement("author");
740 NodeInfo
.appendChild( Nodeauthor
);
741 if( !_header
["name"].isEmpty() ) insertXML( doc
, Nodeauthor
, "name", _header
["name"] );
742 if( !_header
["email"].isEmpty() ) insertXML( doc
, Nodeauthor
, "email", _header
["email"] );
743 if( !_header
["www"].isEmpty() ) insertXML( doc
, Nodeauthor
, "www", _header
["www"] );
746 QDomElement NodeData
= doc
.createElement("Data");
747 Root
.appendChild( NodeData
);
750 while ( !recordEOF() )
752 QDomElement question
= doc
.createElement("question");
753 if( !getQuestion( QF_PICTURE
).isEmpty() )
757 copyJOB
.append( getQuestion( QF_PICTURE
) );
758 question
.setAttribute("image", QFileInfo( getQuestion( QF_PICTURE
) ).fileName() );
760 question
.setAttribute("image", getQuestion( QF_PICTURE
) );
763 question
.setAttribute( "type", getQuestionInt( QF_TYPE
) );
764 if( getQuestionInt( QF_POINTS
) > 0 ) question
.setAttribute( "points", getQuestion( QF_POINTS
) );
765 if( getQuestionInt( QF_TIME
) > 0 ) question
.setAttribute( "time", getQuestion( QF_TIME
) );
766 insertXML( doc
, question
, "text", getQuestion( QF_TEXT
) );
769 while( !recordAnswerEOF() )
771 if( getAnswerValue() )
773 QDomElement domELEMENT
= doc
.createElement( "true" );
774 if( getAnswerPoints() > 0 ) domELEMENT
.setAttribute("points", getAnswerPoints() );
775 QDomText DATAelement
= doc
.createTextNode( getAnswer( AF_TEXT
) );
776 question
.appendChild( domELEMENT
);
777 domELEMENT
.appendChild( DATAelement
);
779 // insertXML( doc, question, "false", getAnswer( AF_text ) );
780 QDomElement domELEMENT
= doc
.createElement( "false" );
781 if( getAnswerPoints() > 0 ) domELEMENT
.setAttribute("points", getAnswerPoints() );
782 QDomText DATAelement
= doc
.createTextNode( getAnswer( AF_TEXT
) );
783 question
.appendChild( domELEMENT
);
784 domELEMENT
.appendChild( DATAelement
);
789 if( !getQuestion( QF_TIP
).isEmpty() ) insertXML( doc
, question
, "tip", getQuestion( QF_TIP
) );
790 if( !getQuestion( QF_EXPLAIN
).isEmpty() ) insertXML( doc
, question
, "explain", getQuestion( QF_EXPLAIN
) );
792 NodeData
.appendChild( question
);
796 doc
.save( stream
, 4);
798 if ( saveCompressed
)
799 file
.writeBlock(qCompress(data
));
801 file
.writeBlock(data
);
804 if( copyimages
== true && copyJOB
.count() > 0 )
806 KURL::List
KurlLIST( copyJOB
);
807 KIO::CopyJob
*copyjob
;
809 copyjob
= KIO::copy( KurlLIST
, KURL( _currentURL
.directory(false,true) ), true);
817 bool FileRead::saveResults( const KURL
&url
, const QString
&results
)
823 kdDebug()<<"FileRead::saveResults() to "<<_currentURL
.url()<<endl
;
825 if ( _currentURL
.isLocalFile() )
827 if ( _tmpfile
!= 0 ) // get rid of a possible temp file first
828 { // (happens if previous _currentURL was remote)
833 if( saveResults(_currentURL
.path(), results
) ) {
835 emit
setWindowCaption( _currentURL
.prettyURL() );
841 // We haven't saved yet, or we did but locally - provide a temp file
844 _tmpfile
= new KTempFile
;
846 // otherwise, we already had a temp file
847 if( saveResults(_tmpfile
->name(), results
) ) {
849 KIO::Job
* job
= KIO::file_copy( KURL::fromPathOrURL( _tmpfile
->name() ), _currentURL
, -1, true /*overwrite*/ );
850 connect( job
, SIGNAL( result( KIO::Job
* ) ), this, SLOT( slotUploadFinished (KIO::Job
*) ) );
855 // Save local file and upload local file
859 bool FileRead::saveResults( const QString
&filename
, const QString
&results
)
862 QFile
file(filename
);
865 stream
.setDevice(&file
);
867 if(!file
.open(IO_WriteOnly
))
877 /** Insert xml format data */
878 void FileRead::insertXML( QDomDocument
&doc
, QDomElement
&parent
, const QString
&tagName
, const QString
&data
)
880 QDomElement domELEMENT
= doc
.createElement( tagName
);
881 QDomText DATAelement
= doc
.createTextNode( data
);
883 parent
.appendChild( domELEMENT
);
884 domELEMENT
.appendChild( DATAelement
);
887 /** Insert xml data format */
888 void FileRead::insertXML( QDomDocument
&doc
, QDomElement
&parent
, const QString
&data
)
890 QDomText DATAelement
= doc
.createTextNode( data
);
891 parent
.appendChild( DATAelement
);
895 QString
FileRead::getHeader(const QString
&head
)
897 return _header
[head
];
900 /** Set header data */
901 void FileRead::setHeader( const QString field
, const QString value
)
903 _changed
= _header
[field
]!=value
;
905 if( (_header
[field
]).isEmpty() )
906 _header
.insert( field
, value
);
908 _header
.replace( field
, value
);
911 /** is Multi Answer */
912 bool FileRead::isMultiAnswer()
918 while( !recordAnswerEOF() )
920 if( (*(*_recordQuestions
).recordAnswers
).value
== true ) numOKanswer
++;
924 if( numOKanswer
> 1 ) {
931 /** is Multi Answer */
932 bool FileRead::isResult()
934 return _listResults
.count() > 0 ? true : false;
937 void FileRead::slotUploadFinished( KIO::Job
* job
)
940 emit
canceled( job
->errorString() );
941 kdDebug()<< "FileRead::slotUploadFinished(): " <<job
->errorString()<<endl
;
945 if ( _tmpfile
!=0 ) // We're finished with this document -> remove temp file
951 emit
setWindowCaption( _currentURL
.prettyURL() );
956 /** Record at index */
957 void FileRead::recordAt( uint index
)
959 _recordQuestions
= _listQuestions
.begin();
960 for( unsigned int i
= 0; i
< index
; ++i
)
964 /** Total questions */
965 uint
FileRead::getTotalQuestions()
967 return _totalQuestions
;
971 uint
FileRead::getTotalPoints()
977 uint
FileRead::getTotalTime()
982 /** Refresh stadistical data - Points, number questions and total points */
983 void FileRead::refreshData()
989 _recordQuestions
= _listQuestions
.begin();
990 while ( _recordQuestions
!= _listQuestions
.end() )
993 _totalPoints
+= (*_recordQuestions
).points
;
994 _totalTime
+= (*_recordQuestions
).time
;
999 #include "fileread.moc"