summaryrefslogtreecommitdiffstats
path: root/keduca/keducabuilder/keducabuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'keduca/keducabuilder/keducabuilder.cpp')
-rw-r--r--keduca/keducabuilder/keducabuilder.cpp600
1 files changed, 600 insertions, 0 deletions
diff --git a/keduca/keducabuilder/keducabuilder.cpp b/keduca/keducabuilder/keducabuilder.cpp
new file mode 100644
index 00000000..08487cc9
--- /dev/null
+++ b/keduca/keducabuilder/keducabuilder.cpp
@@ -0,0 +1,600 @@
+/***************************************************************************
+ keducabuilder.cpp - description
+ -------------------
+ begin : Sat May 26 2001
+ copyright : (C) 2001 by Javier Campos
+ email : javi@asyris.org
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "keducabuilder.h"
+#include "keducabuilder.moc"
+
+#include "kcontroladdedit.h"
+#include "kcontrolheader.h"
+#include "keducaeditorstartdialog.h"
+#include "../libkeduca/kgallerydialog.h"
+
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kfiledialog.h>
+#include <kedittoolbar.h>
+#include <kdebug.h>
+#include <kio/netaccess.h>
+#include <kmessagebox.h>
+#include <kprinter.h>
+
+#include <qlayout.h>
+#include <qcheckbox.h>
+#include <qpaintdevicemetrics.h>
+#include <qpainter.h>
+
+static const char* const keducabuilder_data[] = {
+ "15 16 4 1",
+ "a c #0000ff",
+ "# c #008183",
+ "b c #c5c2c5",
+ ". c #ffffff",
+ "...............",
+ ".#############.",
+ ".#...........#.",
+ ".#...aaaa....#.",
+ ".#..aa.baa...#.",
+ ".#......aa...#.",
+ ".#.....aab...#.",
+ ".#....aab....#.",
+ ".#....aab....#.",
+ ".#.....b.....#.",
+ ".#....aa.....#.",
+ ".#....aa.....#.",
+ ".#...........#.",
+ ".#...........#.",
+ ".#############.",
+ "..............."};
+
+KEducaBuilder::KEducaBuilder(QWidget* parent, const char *name, WFlags f )
+ : KMainWindow(parent,name,f),
+ _nativeFormat("application/x-edu")
+{
+ _keducaFile = new FileRead();
+ initMenuBar();
+ init();
+ configRead();
+ setIcon( KGlobal::iconLoader()->loadIcon("control.png",
+ KIcon::Small) );
+ _isOpenFile = false;
+}
+
+KEducaBuilder::~KEducaBuilder()
+{
+ delete _keducaFile;
+}
+
+/** Init graphical interface */
+void KEducaBuilder::init()
+{
+ QWidget *mainView = new QWidget(this, "mainview");
+
+ QVBoxLayout *form2Layout = new QVBoxLayout( mainView );
+ form2Layout->setSpacing( 2 );
+ form2Layout->setMargin( 0 );
+
+ _split = new QSplitter( mainView );
+ _split->setOrientation( QSplitter::Vertical );
+
+ _listAnswer = new KListBox( _split, "_listAnswer" );
+ _listAnswer->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)7, (QSizePolicy::SizeType)7, _listAnswer->sizePolicy().hasHeightForWidth() ) );
+ connect( _listAnswer, SIGNAL( highlighted(QListBoxItem *) ), this, SLOT( slotPreview(QListBoxItem *) ) );
+ connect( _listAnswer, SIGNAL( doubleClicked(QListBoxItem *) ), this, SLOT( slotEditbyList(QListBoxItem *) ) );
+
+ _preview = new QTextView( _split, "_preview" );
+ _preview->setFrameShape( QTextView::NoFrame );
+ _preview->setLineWidth( 1 );
+
+ form2Layout->addWidget( _split );
+
+ setCentralWidget( mainView );
+ if (!initialGeometrySet())
+ resize( QSize(500, 400).expandedTo(minimumSizeHint()));
+ setupGUI( ToolBar | Keys | StatusBar | Create, "keducabuilderui.rc" );
+ setAutoSaveSettings();
+}
+
+/** Init menu bar settings */
+void KEducaBuilder::initMenuBar()
+{
+ KStdAction::openNew(this, SLOT( slotFileOpenNew() ), actionCollection());
+ KStdAction::open (this, SLOT( slotFileOpen() ), actionCollection());
+ (void)new KAction(i18n("Open &Gallery..."), 0, 0, this, SLOT( slotGallery() ), actionCollection(), "open_gallery");
+ _recentFiles = KStdAction::openRecent(this, SLOT ( slotFileOpenURL(const KURL &)), actionCollection());
+ KStdAction::save (this, SLOT( slotFileSave() ), actionCollection());
+ KStdAction::saveAs (this, SLOT( slotFileSaveAs() ), actionCollection());
+ KStdAction::print (this, SLOT( slotFilePrint() ), actionCollection());
+ (void)new KAction(i18n("Document Info"), "info", 0, this, SLOT( slotHeader() ), actionCollection(), "info_doc");
+ KStdAction::quit(this, SLOT( close() ), actionCollection());
+
+ (void)new KAction(i18n("&Add..."), "addquestion", 0, this, SLOT( slotAdd() ), actionCollection(), "question_add");
+ (void)new KAction(i18n("&Edit..."), "editquestion", 0, this, SLOT( slotEdit() ), actionCollection(), "question_edit");
+ (void)new KAction(i18n("&Remove"), "delquestion", 0, this, SLOT( slotRemove() ), actionCollection(), "question_remove");
+ (void)new KAction(i18n("&Up"), "up", 0, this, SLOT( slotUp() ), actionCollection(), "question_up");
+ (void)new KAction(i18n("&Down"), "down", 0, this, SLOT( slotDown() ), actionCollection(), "question_down");
+}
+
+/** Delete current document and start new */
+void KEducaBuilder::slotFileOpenNew()
+{
+ if (!currentFileMayBeReplaced())
+ return;
+
+ if( _keducaFile ) delete _keducaFile;
+ _listAnswer->clear();
+ _preview->setText("<qt><br><center><h1>"+i18n("Welcome To KEduca!")+"</h1>"+
+ i18n("Add a new Question by using the Edit Menu or by choosing one of the icons above.")+
+ "</center></qt>");
+ _keducaFile = new FileRead();
+ _isOpenFile = false;
+ // ask for meta information
+ slotHeader();
+}
+
+/** Open new document. */
+void KEducaBuilder::slotFileOpen()
+{
+ KURL url = KFileDialog::getOpenURL( QString::null, _nativeFormat, this, i18n("Open Educa File") );
+
+ if( !url.isEmpty() )
+ slotFileOpenURL( url );
+}
+
+/** Open new file */
+void KEducaBuilder::slotFileOpenURL( const KURL &url )
+{
+ if (!currentFileMayBeReplaced())
+ return;
+
+ QPixmap image0( ( const char** ) keducabuilder_data );
+ delete _keducaFile;
+ _keducaFile = new FileRead();
+ if( !_keducaFile->openFile(url) ) { return; }
+ _recentFiles->addURL( url );
+ _listAnswer->clear();
+ _isOpenFile = true;
+
+ _keducaFile->recordFirst();
+ while( !_keducaFile->recordEOF() )
+ {
+ _listAnswer->insertItem( image0, _keducaFile->getQuestion( FileRead::QF_TEXT ) );
+ _keducaFile->recordNext();
+ }
+}
+
+/** Item select */
+void KEducaBuilder::slotPreview( QListBoxItem *item )
+{
+// bool match = false;
+ QString tmpListanswer;
+
+ // FIND THE SELECT RECORD
+ if( !item ) return;
+
+// kdDebug() << "Item : " << _listAnswer->currentItem() <<endl;
+ _keducaFile->recordAt( _listAnswer->currentItem() );
+
+ // START THE PREVIEW VALUES
+ tmpListanswer = "<p><b>" + i18n("Answers") + "</b></p><hr>";
+ tmpListanswer += "<p>";
+
+ tmpListanswer +="<TABLE WIDTH=98%>";
+ _keducaFile->recordAnswerFirst();
+ while( !_keducaFile->recordAnswerEOF() )
+ {
+ tmpListanswer += "<TR>";
+ tmpListanswer += "<TD WIDTH=3% BGCOLOR=";
+ _keducaFile->getAnswerValue() ? tmpListanswer += "#006b6b>" : tmpListanswer += "#b84747>";
+ if( _keducaFile->getQuestionInt( FileRead::QF_TYPE ) == 3 )
+ {
+ tmpListanswer += "<FONT COLOR=#ffffff><b>"
+ + _keducaFile->getAnswer( FileRead::AF_POINT )
+ + "</b></FONT>";
+ }
+ tmpListanswer += "</TD>";
+ tmpListanswer += "<TD WIDTH=95% BGCOLOR=";
+ _keducaFile->getAnswerValue() ? tmpListanswer += "#daeaea>" : tmpListanswer += "#eadada>";
+ tmpListanswer += "<span style=\"color:black;\">"+_keducaFile->getAnswer( FileRead::AF_TEXT )+"</span>";
+ tmpListanswer += "</TD></TR>";
+ _keducaFile->recordAnswerNext();
+ };
+ tmpListanswer += "</TABLE>";
+
+ if( !_keducaFile->getQuestion( FileRead::QF_PICTURE ).isEmpty() )
+ {
+ tmpListanswer += "<table><tr><td><img src=";
+ tmpListanswer += _keducaFile->getPicture();
+ tmpListanswer += "></td>";
+ tmpListanswer += "<td align=right><b>" + i18n("Question Image") + "</b><hr>";
+ tmpListanswer += _keducaFile->getQuestion( FileRead::QF_PICTURE ) + "</td></tr></table>";
+ };
+
+ if( _keducaFile->getQuestionInt( FileRead::QF_POINTS ) > 0 )
+ {
+ tmpListanswer += "<p><b>" + i18n("Question point") + ":</b> ";
+ tmpListanswer += _keducaFile->getQuestion( FileRead::QF_POINTS );
+ }
+
+ if( _keducaFile->getQuestionInt( FileRead::QF_TIME ) > 0 )
+ {
+ tmpListanswer += "<p><b>"+i18n("Time")+":</b> ";
+ tmpListanswer += _keducaFile->getQuestion( FileRead::QF_TIME );
+ tmpListanswer += i18n(" seconds</p>");
+ }
+
+ if( !_keducaFile->getQuestion( FileRead::QF_TIP ).isEmpty() )
+ {
+ tmpListanswer += "<p><b>" + i18n("Tip") +":</b> ";
+ tmpListanswer += _keducaFile->getQuestion( FileRead::QF_TIP );
+ tmpListanswer += "</p>";
+ }
+
+ if( !_keducaFile->getQuestion( FileRead::QF_EXPLAIN ).isEmpty() )
+ {
+ tmpListanswer += "<p><b>"
+ + i18n("Explain") + ":</b>"
+ + _keducaFile->getQuestion( FileRead::QF_EXPLAIN )
+ + "</p>";
+ }
+
+ _preview->setText( tmpListanswer );
+}
+
+/** Read config data */
+void KEducaBuilder::configRead()
+{
+ KConfig *config = KGlobal::config();
+
+ config->setGroup( "keducacontrol" );
+ applyMainWindowSettings( config, "keducacontrol" );
+ _split->setSizes( config->readIntListEntry("Splitter_size") );
+ _recentFiles->loadEntries(config);
+}
+
+/** Write settings */
+void KEducaBuilder::configWrite()
+{
+ KConfig *config = KGlobal::config();
+
+ config->setGroup( "keducacontrol" );
+ saveMainWindowSettings( config, "keducacontrol" );
+ config->writeEntry("Splitter_size", _split->sizes() );
+ _recentFiles->saveEntries(config);
+ config->sync();
+}
+
+bool KEducaBuilder::currentFileMayBeReplaced()
+{
+ if (_keducaFile->changed())
+ {
+ int res = KMessageBox::warningYesNoCancel( widget(),
+ // ask the user to save
+ i18n( "The document \"%1\" has been modified.\n"
+ "Do you want to save it?" ).arg( _keducaFile->getCurrentURL().fileName() ),
+ i18n( "Save Document?" ), KStdGuiItem::save(), KStdGuiItem::discard() );
+ switch (res)
+ {
+ case KMessageBox::Yes:
+ // If the saving was successful, then the file may be replaced
+ return fileSave();
+ break;
+ case KMessageBox::Cancel:
+ // User cancels operation, do not replace the file
+ return false;
+ break;
+ default: ;
+ }
+ }
+
+ // file was not changed, it may be replaced
+ return true;
+}
+
+/** Close the window */
+bool KEducaBuilder::queryClose ()
+{
+ if (_keducaFile) {
+ if (!currentFileMayBeReplaced())
+ return false;
+ }
+ configWrite();
+ return( TRUE );
+}
+
+/** Add question */
+void KEducaBuilder::slotAdd()
+{
+ QPixmap image0( ( const char** ) keducabuilder_data );
+
+ KControlAddEdit edit(this);
+ edit.init( _keducaFile, false );
+ if( !edit.exec() ) return;
+
+ _listAnswer->insertItem( image0, _keducaFile->getQuestion( FileRead::QF_TEXT ) );
+ _listAnswer->setCurrentItem( _listAnswer->count()-1 );
+ slotPreview( _listAnswer->item(_listAnswer->currentItem()) );
+}
+
+/** Edit question */
+void KEducaBuilder::slotEdit()
+{
+ if( _listAnswer->currentItem() == -1 ) return;
+
+ QPixmap image0( ( const char** ) keducabuilder_data );
+
+ KControlAddEdit edit(this);
+ edit.init( _keducaFile, true );
+ if( edit.exec() )
+ {
+ _listAnswer->changeItem( image0, _keducaFile->getQuestion( FileRead::QF_TEXT ), _listAnswer->currentItem() );
+ slotPreview( _listAnswer->item(_listAnswer->currentItem()) );
+ }
+}
+
+/** Edit question */
+void KEducaBuilder::slotRemove()
+{
+ if( _listAnswer->currentItem() == -1 ) return;
+ _keducaFile->recordDelete();
+ _listAnswer->removeItem( _listAnswer->currentItem() );
+}
+
+/** Up record */
+void KEducaBuilder::slotUp()
+{
+ int current = _listAnswer->currentItem();
+
+ if( current < 1 ) return;
+ QPixmap image0( ( const char** ) keducabuilder_data );
+
+ _keducaFile->recordSwap( true );
+ QString tmpString = _listAnswer->text( current-1 );
+ _listAnswer->changeItem( image0, _listAnswer->text( current ), current-1 );
+ _listAnswer->changeItem( image0, tmpString, current );
+ _listAnswer->setCurrentItem( current-1 );
+}
+
+/** Down record */
+void KEducaBuilder::slotDown()
+{
+ int current = _listAnswer->currentItem();
+
+ if( current == -1 || current == (signed)(_listAnswer->count()-1) ) return;
+ QPixmap image0( ( const char** ) keducabuilder_data );
+
+ _keducaFile->recordSwap( true );
+ QString tmpString = _listAnswer->text( current+1 );
+ _listAnswer->changeItem( image0, _listAnswer->text( current ), current+1 );
+ _listAnswer->changeItem( image0, tmpString, current );
+ _listAnswer->setCurrentItem( current+1 );
+}
+
+/** Save file */
+void KEducaBuilder::slotFileSave()
+{
+ fileSave();
+}
+bool KEducaBuilder::fileSave()
+{
+ if( !_isOpenFile ) { return fileSaveAs(); }
+
+ if( checkSave() ) return _keducaFile->saveFile();
+ return false;
+}
+
+/** Save As... */
+void KEducaBuilder::slotFileSaveAs()
+{
+ fileSaveAs();
+}
+
+bool KEducaBuilder::fileSaveAs()
+{
+ if( !checkSave() ) return false;
+
+ QCheckBox *saveCompressedCheckBox = new QCheckBox( i18n( "Compress the file" ), 0 );
+ saveCompressedCheckBox->setChecked( true );
+
+ KFileDialog *dialog=new KFileDialog(QString::null, QString::null, this, "file dialog", true, saveCompressedCheckBox);
+ dialog->setCaption( i18n("Save Document As") );
+ dialog->setKeepLocation( true );
+ dialog->setOperationMode( KFileDialog::Saving );
+ QStringList mimeFilter(_nativeFormat);
+ dialog->setMimeFilter( mimeFilter, _nativeFormat );
+ KURL newURL;
+ QString outputFormat (_nativeFormat);
+
+ bool bOk;
+ do {
+ bOk=true;
+ if(dialog->exec()==QDialog::Accepted) {
+ newURL=dialog->selectedURL();
+ outputFormat=dialog->currentMimeFilter();
+ }
+ else
+ {
+ bOk = false;
+ break;
+ }
+ kdDebug()<<"Requested saving to file "<<newURL.prettyURL() <<endl;
+ if ( newURL.isEmpty() )
+ {
+ bOk = false;
+ break;
+ }
+
+ if ( QFileInfo( newURL.path() ).extension().isEmpty() ) {
+ // No more extensions in filters. We need to get it from the mimetype.
+ KMimeType::Ptr mime = KMimeType::mimeType( outputFormat );
+ QString extension = mime->property( "X-KDE-NativeExtension" ).toString();
+ kdDebug() << "KEducaBuilder::slotFileSaveAs outputFormat=" << outputFormat << " extension=" << extension << endl;
+ newURL.setPath( newURL.path() + extension );
+ }
+
+ if ( KIO::NetAccess::exists( newURL, false, this ) ) { // this file exists => ask for confirmation
+ bOk = KMessageBox::warningContinueCancel( this,
+ i18n("A document with this name already exists.\n"\
+ "Do you want to overwrite it?"),
+ i18n("Warning"), i18n("Overwrite") ) == KMessageBox::Continue;
+ }
+ } while ( !bOk );
+
+ bool saveCompressed = saveCompressedCheckBox->isChecked();
+
+ delete dialog;
+
+ if (bOk) {
+ bool copyImages = KMessageBox::questionYesNo( this,
+ i18n("If you want to share this document, it is better to copy the images to the same folder as the document.\n"\
+ "Do you want to copy images?"),
+ i18n("Warning"), i18n("Copy Images"), i18n("Do Not Copy") ) == KMessageBox::Yes;
+ if (_keducaFile->saveFile( newURL, copyImages, saveCompressed ) ) {
+ _recentFiles->addURL(newURL);
+ // we saved the file, so the internal representation is now present as a file
+ _isOpenFile=true;
+ return true;
+ }else {
+ kdDebug()<< "saving of file failed" <<endl;
+ return false;
+ }
+ }else {
+ kdDebug()<< "KEducaBuilder: no valid filename selected" <<endl;
+ return false;
+ }
+}
+
+/** Print file */
+void KEducaBuilder::slotFilePrint()
+{
+ KPrinter *printer = new KPrinter();
+
+ QString file = _keducaFile->getCurrentURL().fileName();
+ if (file.isEmpty())
+ file = i18n("Test");
+ if(printer->setup(this, i18n("Print %1").arg(file)))
+ {
+ QPaintDeviceMetrics metrics(printer);
+ QPainter p;
+
+ const int margin=20;
+ int yPos=0;
+ QString text;
+
+ p.begin(printer);
+ p.setFont( QFont(font().family(), 12, QFont::Bold) );
+ QFontMetrics fm = p.fontMetrics();
+
+ _keducaFile->recordFirst();
+ while(!_keducaFile->recordEOF())
+ {
+ p.drawText( 10, yPos+margin, metrics.width(), fm.lineSpacing(),
+ ExpandTabs | DontClip, _keducaFile->getQuestion(FileRead::QF_TEXT) );
+ yPos += fm.lineSpacing();
+
+ p.drawLine(10, yPos+margin, metrics.width(), yPos+margin);
+ yPos += 2*fm.lineSpacing();
+
+ _keducaFile->recordNext();
+ }
+
+ p.end();
+ }
+
+ delete printer;
+
+}
+
+/** Header info */
+int KEducaBuilder::slotHeader() {
+ KControlHeader infoDoc(_keducaFile);
+ return infoDoc.exec();
+}
+
+/** Check if the current document can save */
+bool KEducaBuilder::checkSave()
+{
+ if( _keducaFile->getHeader("title").isEmpty() ||
+ _keducaFile->getHeader("category").isEmpty() ||
+ _keducaFile->getHeader("type").isEmpty() ||
+ _keducaFile->getHeader("level").isEmpty() ||
+ _keducaFile->getHeader("language").isEmpty() )
+ {
+ if (KMessageBox::warningContinueCancel(this, i18n("Unable to save file.\n\nYou must complete the Document Info\n(Only the description is necessary)"), QString::null, i18n("Complete Document Info..."))
+ == KMessageBox::Continue) {
+ if (slotHeader()!=KControlHeader::Accepted)
+ return false;
+ }else
+ return false;
+ }
+
+ if( _listAnswer->count() < 1 )
+ {
+ if (KMessageBox::warningContinueCancel(this, i18n("Unable to save file.\n\nYou must insert a question."),
+ QString::null, i18n("Insert Question"))==KMessageBox::Continue)
+ slotAdd();
+ else
+ return false;
+ }
+
+ return true;
+}
+
+bool KEducaBuilder::startChooser() {
+ KEducaEditorStartDialog startDialog(this, "KEducaEditorStartDialog", true);
+
+ switch (startDialog.exec()) {
+ case KEducaEditorStartDialog::OpenDoc:
+ case KEducaEditorStartDialog::OpenRecentDoc:
+ slotFileOpenURL(startDialog.getURL());
+ break;
+ case KEducaEditorStartDialog::NewDoc:
+ slotFileOpenNew();
+ break;
+ case KEducaEditorStartDialog::Gallery:
+ initGallery();
+ break;
+ default:
+ close();
+ break;
+ }
+
+ return true;
+}
+/** Init Internet Gallery Servers */
+void KEducaBuilder::initGallery(const KURL &urlFile)
+{
+ KGalleryDialog galleries;
+
+ if( !urlFile.url().isEmpty() )
+ galleries.putURL( urlFile );
+
+ if( galleries.exec() == QDialog::Accepted )
+ slotFileOpenURL( galleries.getURL() );
+}
+
+/** Init Gallery */
+void KEducaBuilder::slotGallery()
+{
+ initGallery();
+}
+
+/** Double click in list, edit question */
+void KEducaBuilder::slotEditbyList(QListBoxItem *item)
+{
+ if( item )
+ slotEdit();
+}