1 /***************************************************************************
2 kwordquiz.cpp - description
4 begin : Wed Jul 24 20:12:30 PDT 2002
5 copyright : (C) 2002 by Peter Hedlund
6 email : peter@peterandlinda.com
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 ***************************************************************************/
18 // include files for QT
21 #include <qcheckbox.h>
23 // include files for KDE
24 #include <kmessagebox.h>
25 #include <kfiledialog.h>
26 #include <kstatusbar.h>
28 #include <kedittoolbar.h>
29 #include <kstandarddirs.h> //locate
30 #include <kfontdialog.h>
31 #include <kpopupmenu.h>
32 #include <knotifydialog.h>
33 #include <kiconloader.h>
34 //#include <keduvocdata.h>
37 // application specific includes
38 #include "kwordquiz.h"
39 #include "kwordquizdoc.h"
40 #include "dlglanguage.h"
41 #include "kwordquizprefs.h"
43 #include "flashview.h"
44 #include "multipleview.h"
45 #include "wqprintdialogpage.h"
48 #define ID_STATUS_MSG 1
49 #define ID_STATUS_MSG_MODE 2
50 #define ID_STATUS_MSG_SCORE 3
54 #define ID_MENU_QUIZ 1001
56 KWordQuizApp::KWordQuizApp(QWidget
* , const char* name
):KMainWindow(0, name
)
59 ///////////////////////////////////////////////////////////////////
60 // call inits to invoke all other construction parts
69 m_dirWatch
= KDirWatch::self();
70 m_quizType
= WQQuiz::qtEditor
;
77 slotUndoChange(i18n("Cannot &Undo"), false);
78 updateMode(Prefs::mode());
82 editMarkBlank
->setEnabled(Prefs::enableBlanks());
83 editUnmarkBlank
->setEnabled(Prefs::enableBlanks());
85 if (Prefs::firstRun())
87 fileOpenRecent
->addURL( locate("data", "kwordquiz/examples/example.kvtml"));
88 fileOpenRecent
->addURL( locate("data", "kwordquiz/examples/french_verbs.kvtml"));
89 fileOpenRecent
->addURL( locate("data", "kwordquiz/examples/fill_in_the_blank.kvtml"));
90 fileOpenRecent
->addURL( locate("data", "kwordquiz/examples/us_states_and_capitals.kvtml"));
91 Prefs::setFirstRun(false);
95 KWordQuizApp::~KWordQuizApp()
100 void KWordQuizApp::initActions()
102 KAction
* configToolbar
;
103 KAction
* configNotifications
;
106 fileNew
= KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection());
107 fileNew
->setWhatsThis(i18n("Creates a new blank vocabulary document"));
108 fileNew
->setToolTip(fileNew
->whatsThis());
110 fileOpen
= KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
111 fileOpen
->setWhatsThis(i18n("Opens an existing vocabulary document"));
112 fileOpen
->setToolTip(fileOpen
->whatsThis());
114 fileOpenRecent
= KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL
&)), actionCollection());
116 fileSave
= KStdAction::save(this, SLOT(slotFileSave()), actionCollection());
117 fileSave
->setWhatsThis(i18n("Saves the active vocabulary document"));
118 fileSave
->setToolTip(fileSave
->whatsThis());
120 fileSaveAs
= KStdAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection());
121 fileSaveAs
->setWhatsThis(i18n("Saves the active vocabulary document with a different name"));
122 fileSaveAs
->setToolTip(fileSaveAs
->whatsThis());
124 fileClose
= KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
125 fileClose
->setWhatsThis(i18n("Closes the active vocabulary document"));
126 fileClose
->setToolTip(fileClose
->whatsThis());
128 filePrint
= KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
129 filePrint
->setWhatsThis(i18n("Prints the active vocabulary document"));
130 filePrint
->setToolTip(filePrint
->whatsThis());
132 fileQuit
= KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
133 fileQuit
->setWhatsThis(i18n("Quits KWordQuiz"));
134 fileQuit
->setToolTip(fileQuit
->whatsThis());
136 editUndo
= KStdAction::undo(this, SLOT(slotEditUndo()), actionCollection());
137 editUndo
->setWhatsThis(i18n("Undoes the last command"));
138 editUndo
->setToolTip(editUndo
->whatsThis());
140 editCut
= KStdAction::cut(this, SLOT(slotEditCut()), actionCollection());
141 editCut
->setWhatsThis(i18n("Cuts the text from the selected cells and places it on the clipboard"));
142 editCut
->setToolTip(editCut
->whatsThis());
144 editCopy
= KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
145 editCopy
->setWhatsThis(i18n("Copies the text from the selected cells and places it on the clipboard"));
146 editCopy
->setToolTip(editCopy
->whatsThis());
148 editPaste
= KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
149 editPaste
->setWhatsThis(i18n("Pastes previously cut or copied text from the clipboard into the selected cells"));
150 editPaste
->setToolTip(editPaste
->whatsThis());
152 editClear
= KStdAction::clear(this, SLOT(slotEditClear()), actionCollection());
153 editClear
->setWhatsThis(i18n("Clears the content of the selected cells"));
154 editClear
->setToolTip(editClear
->whatsThis());
156 editInsert
= new KAction(i18n("&Insert Row"), "insert_table_row", "CTRL+I", this, SLOT(slotEditInsert()), actionCollection(),"edit_insert");
157 editInsert
->setWhatsThis(i18n("Inserts a new row above the current row"));
158 editInsert
->setToolTip(editInsert
->whatsThis());
160 editDelete
= new KAction(i18n("&Delete Row"), "delete_table_row", "CTRL+K", this, SLOT(slotEditDelete()), actionCollection(),"edit_delete");
161 editDelete
->setWhatsThis(i18n("Deletes the selected row(s)"));
162 editDelete
->setToolTip(editDelete
->whatsThis());
164 editMarkBlank
= new KAction(i18n("&Mark as Blank"), "markasblank", "CTRL+M", this, SLOT(slotEditMarkBlank()), actionCollection(),"edit_mark_blank");
165 editMarkBlank
->setWhatsThis(i18n("Marks the current or selected word as a blank for Fill-in-the-blank"));
166 editMarkBlank
->setToolTip(editMarkBlank
->whatsThis());
168 editUnmarkBlank
= new KAction(i18n("&Unmark Blanks"), "unmarkasblank", 0, this, SLOT(slotEditUnmarkBlank()), actionCollection(),"edit_unmark_blank");
169 editUnmarkBlank
->setWhatsThis(i18n("Removes blanks from the current or selected word"));
170 editUnmarkBlank
->setToolTip(editUnmarkBlank
->whatsThis());
172 //@todo implement editFind = KStdAction::find(this, SLOT(slotEditFind()), actionCollection());
174 vocabLanguages
= new KAction(i18n("&Column Titles..."), "languages", "CTRL+L", this, SLOT(slotVocabLanguages()), actionCollection(),"vocab_languages");
175 vocabLanguages
->setWhatsThis(i18n("Defines the column titles for the active vocabulary"));
176 vocabLanguages
->setToolTip(vocabLanguages
->whatsThis());
178 vocabFont
= new KAction(i18n("&Font..."), "fonts", 0, this, SLOT(slotVocabFont()), actionCollection(),"vocab_font");
179 vocabFont
->setWhatsThis(i18n("Defines the font used by the editor"));
180 vocabFont
->setToolTip(vocabFont
->whatsThis());
182 //@todo implement vocabKeyboard = new KAction(i18n("&Keyboard..."), "kxkb", 0, this, SLOT(slotVocabKeyboard()), actionCollection(),"vocab_keyboard");
184 vocabRC
= new KAction(i18n("&Rows/Columns..."), "rowcol", 0, this, SLOT(slotVocabRC()), actionCollection(),"vocab_rc");
185 vocabRC
->setWhatsThis(i18n("Defines the number of rows, row heights, and column widths for the active vocabulary"));
186 vocabRC
->setToolTip(vocabRC
->whatsThis());
188 vocabSort
= new KAction(i18n("&Sort..."), "sort_incr", 0, this, SLOT(slotVocabSort()), actionCollection(),"vocab_sort");
189 vocabSort
->setWhatsThis(i18n("Sorts the vocabulary in ascending or descending order based on the left or right column"));
190 vocabSort
->setToolTip(vocabSort
->whatsThis());
192 vocabShuffle
= new KAction(i18n("Sh&uffle"), "shuffle", 0, this, SLOT(slotVocabShuffle()), actionCollection(),"vocab_shuffle");
193 vocabShuffle
->setWhatsThis(i18n("Shuffles the entries of the active vocabulary"));
194 vocabShuffle
->setToolTip(vocabShuffle
->whatsThis());
196 mode
= new KToolBarPopupAction(i18n("Change Mode"), "mode1", 0, this, SLOT(slotMode0()), actionCollection(),"mode_0");
197 mode
->setWhatsThis(i18n("Changes the mode used in quiz sessions"));
198 mode
->setToolTip(mode
->whatsThis());
200 KPopupMenu
*popup
= mode
->popupMenu();
202 popup
->insertItem(KGlobal::iconLoader()->loadIconSet("mode1", KIcon::Toolbar
), "", this, SLOT(slotMode1()), 0, 0);
203 popup
->insertItem(KGlobal::iconLoader()->loadIconSet("mode2", KIcon::Toolbar
), "", this, SLOT(slotMode2()), 0, 1);
204 popup
->insertItem(KGlobal::iconLoader()->loadIconSet("mode3", KIcon::Toolbar
), "", this, SLOT(slotMode3()), 0, 2);
205 popup
->insertItem(KGlobal::iconLoader()->loadIconSet("mode4", KIcon::Toolbar
), "", this, SLOT(slotMode4()), 0, 3);
206 popup
->insertItem(KGlobal::iconLoader()->loadIconSet("mode5", KIcon::Toolbar
), "", this, SLOT(slotMode5()), 0, 4);
208 mode1
= new KToggleAction("", "mode1", 0, this, SLOT(slotMode1()), actionCollection(),"mode_1");
209 mode2
= new KToggleAction("", "mode2", 0, this, SLOT(slotMode2()), actionCollection(),"mode_2");
210 mode3
= new KToggleAction("", "mode3", 0, this, SLOT(slotMode3()), actionCollection(),"mode_3");
211 mode4
= new KToggleAction("", "mode4", 0, this, SLOT(slotMode4()), actionCollection(),"mode_4");
212 mode5
= new KToggleAction("", "mode5", 0, this, SLOT(slotMode5()), actionCollection(),"mode_5");
213 mode1
->setWhatsThis(i18n("Selects this mode"));
214 mode2
->setWhatsThis(i18n("Selects this mode"));
215 mode3
->setWhatsThis(i18n("Selects this mode"));
216 mode4
->setWhatsThis(i18n("Selects this mode"));
217 mode5
->setWhatsThis(i18n("Selects this mode"));
218 mode1
->setToolTip(mode1
->whatsThis());
219 mode2
->setToolTip(mode2
->whatsThis());
220 mode3
->setToolTip(mode3
->whatsThis());
221 mode4
->setToolTip(mode4
->whatsThis());
222 mode5
->setToolTip(mode5
->whatsThis());
224 quizEditor
= new KAction(i18n("&Editor"), "editor", "F6", this, SLOT(slotQuizEditor()), actionCollection(),"quiz_editor");
225 quizEditor
->setWhatsThis(i18n("Activates the vocabulary editor"));
226 quizEditor
->setToolTip(quizEditor
->whatsThis());
228 quizFlash
= new KAction(i18n("&Flashcard"), "flash", "F7", this, SLOT(slotQuizFlash()), actionCollection(),"quiz_flash");
229 quizFlash
->setWhatsThis(i18n("Starts a flashcard session using the active vocabulary"));
230 quizFlash
->setToolTip(quizFlash
->whatsThis());
232 quizMultiple
= new KAction(i18n("&Multiple Choice"), "multiple", "F8", this, SLOT(slotQuizMultiple()), actionCollection(),"quiz_multiple");
233 quizMultiple
->setWhatsThis(i18n("Starts a multiple choice session using the active vocabulary"));
234 quizMultiple
->setToolTip(quizMultiple
->whatsThis());
236 quizQA
= new KAction(i18n("&Question && Answer"), "qa", "F9", this, SLOT(slotQuizQA()), actionCollection(),"quiz_qa");
237 quizQA
->setWhatsThis(i18n("Starts a question and answer session using the active vocabulary"));
238 quizQA
->setToolTip(quizQA
->whatsThis());
240 quizCheck
= new KAction(i18n("&Check"), "check", "Return", this, 0, actionCollection(),"quiz_check");
241 quizCheck
->setWhatsThis(i18n("Checks your answer to this question"));
242 quizCheck
->setToolTip(quizCheck
->whatsThis());
244 flashKnow
= new KAction(i18n("I &Know"), "know", "K", this, 0, actionCollection(),"flash_know");
245 flashKnow
->setWhatsThis(i18n("Counts this card as correct and shows the next card"));
246 flashKnow
->setToolTip(flashKnow
->whatsThis());
248 flashDontKnow
= new KAction(i18n("I &Do Not Know"), "dontknow", "D", this, 0, actionCollection(),"flash_dont_know");
249 flashDontKnow
->setWhatsThis(i18n("Counts this card as incorrect and shows the next card"));
250 flashDontKnow
->setToolTip(flashDontKnow
->whatsThis());
252 qaHint
= new KAction(i18n("&Hint"), "hint", "CTRL+H", this, 0, actionCollection(),"qa_hint");
253 qaHint
->setWhatsThis(i18n("Gets the next correct letter of the answer"));
254 qaHint
->setToolTip(qaHint
->whatsThis());
256 quizRestart
= new KAction(i18n("&Restart"), "restart.png", "CTRL+R", this, 0, actionCollection(), "quiz_restart");
257 quizRestart
->setWhatsThis(i18n("Restarts the quiz session from the beginning"));
258 quizRestart
->setToolTip(quizRestart
->whatsThis());
260 quizRepeatErrors
= new KAction(i18n("Repeat &Errors"), "repeat", "CTRL+E", this, 0, actionCollection(),"quiz_repeat_errors");
261 quizRepeatErrors
->setWhatsThis(i18n("Repeats all incorrectly answered questions"));
262 quizRepeatErrors
->setToolTip(quizRepeatErrors
->whatsThis());
264 configNotifications
= KStdAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection());
265 configNotifications
->setWhatsThis(i18n("Configures sound and other notifications for certain events"));
266 configNotifications
->setToolTip(configNotifications
->whatsThis());
268 configApp
= KStdAction::preferences(this, SLOT( slotConfigure()), actionCollection());
269 configApp
->setWhatsThis(i18n("Specifies preferences for the vocabulary editor and quiz sessions"));
270 configApp
->setToolTip(configApp
->whatsThis());
272 charMapper
= new QSignalMapper(this);
273 connect(charMapper
, SIGNAL(mapped(int)), this, SLOT(slotInsertChar(int)));
275 specialChar1
= new KAction(i18n("Special Character 1"), "", "CTRL+1", charMapper
, SLOT(map()), actionCollection(), "char_1") ;
276 specialChar2
= new KAction(i18n("Special Character 2"), 0, "CTRL+2", charMapper
, SLOT(map()), actionCollection(), "char_2") ;
277 specialChar3
= new KAction(i18n("Special Character 3"), 0, "CTRL+3", charMapper
, SLOT(map()), actionCollection(), "char_3") ;
278 specialChar4
= new KAction(i18n("Special Character 4"), 0, "CTRL+4", charMapper
, SLOT(map()), actionCollection(), "char_4") ;
279 specialChar5
= new KAction(i18n("Special Character 5"), 0, "CTRL+5", charMapper
, SLOT(map()), actionCollection(), "char_5") ;
280 specialChar6
= new KAction(i18n("Special Character 6"), 0, "CTRL+6", charMapper
, SLOT(map()), actionCollection(), "char_6") ;
281 specialChar7
= new KAction(i18n("Special Character 7"), 0, "CTRL+7", charMapper
, SLOT(map()), actionCollection(), "char_7") ;
282 specialChar8
= new KAction(i18n("Special Character 8"), 0, "CTRL+8", charMapper
, SLOT(map()), actionCollection(), "char_8") ;
283 specialChar9
= new KAction(i18n("Special Character 9"), 0, "CTRL+9", charMapper
, SLOT(map()), actionCollection(), "char_9") ;
285 charMapper
->setMapping(specialChar1
, 1);
286 charMapper
->setMapping(specialChar2
, 2);
287 charMapper
->setMapping(specialChar3
, 3);
288 charMapper
->setMapping(specialChar4
, 4);
289 charMapper
->setMapping(specialChar5
, 5);
290 charMapper
->setMapping(specialChar6
, 6);
291 charMapper
->setMapping(specialChar7
, 7);
292 charMapper
->setMapping(specialChar8
, 8);
293 charMapper
->setMapping(specialChar9
, 9);
295 actionCollection()->setHighlightingEnabled(true);
296 connect(actionCollection(), SIGNAL(actionStatusText(const QString
&)), this, SLOT(slotStatusMsg(const QString
&)));
297 connect(actionCollection(), SIGNAL(actionHighlighted(KAction
*, bool)), this, SLOT(slotActionHighlighted(KAction
*, bool)));
298 updateSpecialCharIcons();
300 if (!initialGeometrySet())
301 resize( QSize(650, 500).expandedTo(minimumSizeHint()));
302 setupGUI(ToolBar
| Keys
| StatusBar
| Create
);
303 setAutoSaveSettings();
305 configToolbar
= actionCollection()->action("options_configure_toolbars");
306 configToolbar
->setWhatsThis(i18n("Toggles display of the toolbars"));
307 configToolbar
->setToolTip(configToolbar
->whatsThis());
310 void KWordQuizApp::initStatusBar()
312 statusBar()->insertFixedItem("", ID_STATUS_MSG_MODE
, true);
313 statusBar()->setItemFixed(ID_STATUS_MSG_MODE
, 250);
314 statusBar()->setItemAlignment(ID_STATUS_MSG_MODE
, AlignLeft
|AlignVCenter
);
317 void KWordQuizApp::initDocument()
319 doc
= new KWordQuizDoc(this);
323 void KWordQuizApp::initView()
325 m_editView
= new KWordQuizView(this);
326 doc
->addView(m_editView
);
327 setCentralWidget(m_editView
);
328 setCaption(doc
->URL().fileName(),false);
329 m_editView
->setFont(Prefs::editorFont());
330 connect(m_editView
, SIGNAL(undoChange(const QString
&, bool )), this, SLOT(slotUndoChange(const QString
&, bool)));
331 connect(m_editView
, SIGNAL(contextMenuRequested(int, int, const QPoint
&)), this, SLOT(slotContextMenuRequested(int, int, const QPoint
& )));
334 void KWordQuizApp::openURL(const KURL
& url
)
337 if (m_dirWatch
->contains(url
.path()))
342 for(w
=memberList
->first(); w
!=0; w
=memberList
->next())
344 KWordQuizApp
*a
=(KWordQuizApp
*) w
;
345 if(a
->doc
->URL().path() == url
.path())
347 if (w
->isMinimized())
349 w
->setActiveWindow();
358 if (doc
->URL().fileName() == i18n("Untitled") && m_editView
->gridIsEmpty()){
359 // neither saved nor has content, as good as new
360 openDocumentFile(url
);
364 KWordQuizApp
*new_window
= new KWordQuizApp();
366 new_window
->openDocumentFile(url
);
372 void KWordQuizApp::openDocumentFile(const KURL
& url
)
374 slotStatusMsg(i18n("Opening file..."));
375 if (!url
.isEmpty()) {
376 doc
->openDocument( url
);
377 m_dirWatch
->addFile(url
.path());
378 setCaption(doc
->URL().fileName(), false);
379 fileOpenRecent
->addURL( url
);
380 updateMode(Prefs::mode());
382 slotStatusMsg(i18n("Ready"));
386 KWordQuizDoc
*KWordQuizApp::getDocument() const
391 void KWordQuizApp::saveOptions()
393 fileOpenRecent
->saveEntries(kapp
->config(), "Recent Files");
394 Prefs::writeConfig();
398 void KWordQuizApp::readOptions()
400 //Prefs::readConfig();
401 fileOpenRecent
->loadEntries(kapp
->config(), "Recent Files");
404 void KWordQuizApp::saveProperties(KConfig
*_cfg
)
406 if(doc
->URL().fileName()!=i18n("Untitled") && !doc
->isModified())
408 // saving to tempfile not necessary
414 _cfg
->writeEntry("filename", url
.url());
415 _cfg
->writeEntry("modified", doc
->isModified());
416 QString tempname
= kapp
->tempSaveName(url
.url());
417 QString tempurl
= KURL::encode_string(tempname
);
419 doc
->saveDocument(_url
);
424 void KWordQuizApp::readProperties(KConfig
* _cfg
)
426 QString filename
= _cfg
->readEntry("filename", "");
428 bool modified
= _cfg
->readBoolEntry("modified", false);
432 QString tempname
= kapp
->checkRecoverFile(filename
, canRecover
);
437 doc
->openDocument(_url
);
439 setCaption(_url
.fileName(),true);
440 QFile::remove(tempname
);
445 if(!filename
.isEmpty())
447 doc
->openDocument(url
);
448 setCaption(url
.fileName(),false);
453 bool KWordQuizApp::queryClose()
455 bool f
= doc
->saveModified();
457 if (m_dirWatch
->contains(doc
->URL().path()))
458 m_dirWatch
->removeFile(doc
->URL().path());
462 bool KWordQuizApp::queryExit()
468 /////////////////////////////////////////////////////////////////////
469 // SLOT IMPLEMENTATION
470 /////////////////////////////////////////////////////////////////////
472 void KWordQuizApp::slotFileNew()
474 slotStatusMsg(i18n("Opening a new document window..."));
475 if (doc
->URL().fileName() == i18n("Untitled") && m_editView
->gridIsEmpty()){
476 // neither saved nor has content, as good as new
480 KWordQuizApp
*new_window
= new KWordQuizApp();
483 slotStatusMsg(i18n("Ready"));
486 void KWordQuizApp::slotFileOpen()
488 slotStatusMsg(i18n("Opening file..."));
490 QCheckBox
* cb
= new QCheckBox(i18n("&Join selected files into one list"), 0, 0);
491 cb
-> setChecked(false);
493 QString filter
= i18n("*.kvtml *.wql *.xml.gz *.csv|All Supported Documents\n*.kvtml|KDE Vocabulary Document\n*.wql|KWordQuiz Document\n*.xml.gz|Pauker Lesson\n*.csv|Comma-Separated Values");
494 KFileDialog
*fd
= new KFileDialog(QString::null
, filter
, this, 0, true, cb
);
495 fd
-> setOperationMode(KFileDialog::Opening
);
496 fd
-> setMode(KFile::Files
| KFile::ExistingOnly
);
497 fd
-> setCaption(i18n("Open Vocabulary Document"));
499 if (fd
->exec() == QDialog::Accepted
)
501 KURL::List l
= fd
-> selectedURLs();
502 bool append
= ((cb
-> isChecked()) && (l
.count() > 1));
507 if (doc
->URL().fileName() == i18n("Untitled") && m_editView
->gridIsEmpty()){
508 // neither saved nor has content, as good as new
513 w
= new KWordQuizApp();
517 KURL::List::iterator it
;
519 for(it
= l
.begin(); it
!= l
.end(); ++it
)
521 w
->getDocument()->openDocument(*it
, true, i
);
527 KURL::List::iterator it
;
528 for(it
= l
.begin(); it
!= l
.end(); ++it
)
535 delete (fd
); //deletes cb also
537 slotStatusMsg(i18n("Ready"));
540 void KWordQuizApp::slotFileOpenRecent(const KURL
& url
)
542 slotStatusMsg(i18n("Opening file..."));
543 fileOpenRecent
->setCurrentItem(-1);
545 slotStatusMsg(i18n("Ready"));
548 void KWordQuizApp::slotFileSave()
550 slotStatusMsg(i18n("Saving file..."));
551 if (doc
->URL().fileName() == i18n("Untitled") )
557 doc
->saveDocument(doc
->URL());
559 slotStatusMsg(i18n("Ready"));
562 void KWordQuizApp::slotFileSaveAs()
564 slotStatusMsg(i18n("Saving file with a new filename..."));
566 slotStatusMsg(i18n("Ready"));
569 bool KWordQuizApp::saveAsFileName( )
572 bool success
= false;
574 QString filter
= i18n("*.kvtml|KDE Vocabulary Document\n*.wql|KWordQuiz Document\n*.csv|Comma-Separated Values\n*.html|Hypertext Markup Language");
575 KFileDialog
*fd
= new KFileDialog(QString::null
, filter
, this, 0, true);
576 fd
-> setOperationMode(KFileDialog::Saving
);
577 fd
-> setCaption(i18n("Save Vocabulary Document As"));
579 if (fd
->exec() == QDialog::Accepted
)
581 KURL url
= fd
-> selectedURL();
584 //@todo check that a valid extension was really given
585 if (!url
.fileName().contains('.'))
587 if (fd
->currentFilter() == "*.wql")
588 url
= KURL(url
.path() + ".wql");
589 else if (fd
->currentFilter() == "*.csv")
590 url
= KURL(url
.path() + ".csv");
591 else if (fd
->currentFilter() == "*.html")
592 url
= KURL(url
.path() + ".html");
594 url
= KURL(url
.path() + ".kvtml");
597 QFileInfo
fileinfo(url
.path());
598 if (fileinfo
.exists() && KMessageBox::questionYesNo(0,
599 i18n("<qt>The file<br><b>%1</b><br>already exists. Do you want to overwrite it?</qt>")
600 .arg(url
.path())) == KMessageBox::No
)
606 if (m_dirWatch
->contains(doc
->URL().path()))
607 m_dirWatch
->removeFile(doc
->URL().path());
608 doc
->saveDocument(url
);
609 m_dirWatch
->addFile(url
.path());
610 fileOpenRecent
->addURL(url
);
611 setCaption(doc
->URL().fileName(), doc
->isModified());
620 void KWordQuizApp::slotFileClose()
622 slotStatusMsg(i18n("Closing file..."));
624 if (memberList
->count() > 1)
630 setCaption(doc
->URL().fileName(), doc
->isModified());
634 slotUndoChange(i18n("Cannot &Undo"), false);
635 updateMode(Prefs::mode());
636 m_editView
->setFocus();
639 slotStatusMsg(i18n("Ready"));
642 void KWordQuizApp::slotFilePrint()
644 slotStatusMsg(i18n("Printing..."));
645 WQPrintDialogPage
* p
= new WQPrintDialogPage(this);
647 printer
.addDialogPage(p
);
648 printer
.setFullPage(true);
649 if (printer
.setup(this))
651 m_editView
->print(&printer
);
654 slotStatusMsg(i18n("Ready"));
657 void KWordQuizApp::slotFileQuit()
659 slotStatusMsg(i18n("Exiting..."));
661 // close the first window, the list makes the next one the first again.
662 // This ensures that queryClose() is called on each window to ask for closing
666 for(w
=memberList
->first(); w
!=0; w
=memberList
->next())
668 // only close the window if the closeEvent is accepted. If the user presses Cancel on the saveModified() dialog,
669 // the window and the application stay open.
676 void KWordQuizApp::slotUndoChange( const QString
& text
, bool enabled
)
678 editUndo
->setText(text
);
679 editUndo
->setEnabled(enabled
);
682 void KWordQuizApp::slotEditUndo()
684 slotStatusMsg(i18n("Undoing previous command..."));
685 m_editView
->doEditUndo();
686 slotStatusMsg(i18n("Ready"));
689 void KWordQuizApp::slotEditCut()
691 slotStatusMsg(i18n("Cutting selection..."));
692 m_editView
->doEditCut();
693 slotStatusMsg(i18n("Ready"));
696 void KWordQuizApp::slotEditCopy()
698 slotStatusMsg(i18n("Copying selection to clipboard..."));
699 m_editView
->doEditCopy();
700 slotStatusMsg(i18n("Ready"));
703 void KWordQuizApp::slotEditPaste()
705 slotStatusMsg(i18n("Inserting clipboard contents..."));
706 m_editView
->doEditPaste();
707 slotStatusMsg(i18n("Ready"));
710 void KWordQuizApp::slotEditClear()
712 slotStatusMsg(i18n("Clearing the selected cells..."));
713 m_editView
->doEditClear();
714 slotStatusMsg(i18n("Ready"));
717 void KWordQuizApp::slotEditInsert()
719 slotStatusMsg(i18n("Inserting rows..."));
720 m_editView
->doEditInsert();
721 slotStatusMsg(i18n("Ready"));
724 void KWordQuizApp::slotEditDelete()
726 slotStatusMsg(i18n("Deleting selected rows..."));
727 m_editView
->doEditDelete();
728 slotStatusMsg(i18n("Ready"));
731 void KWordQuizApp::slotEditMarkBlank()
733 slotStatusMsg(i18n("Marking selected text as a blank..."));
734 m_editView
->doEditMarkBlank();
735 slotStatusMsg(i18n("Ready"));
738 void KWordQuizApp::slotEditUnmarkBlank()
740 slotStatusMsg(i18n("Removing blank markings..."));
741 m_editView
->doEditUnmarkBlank();
742 slotStatusMsg(i18n("Ready"));
745 void KWordQuizApp::slotEditFind()
747 slotStatusMsg(i18n("Searching for indicated text..."));
748 KMessageBox::sorry(0, i18n("Not implemented yet"));
749 slotStatusMsg(i18n("Ready"));
752 void KWordQuizApp::slotVocabLanguages()
754 slotStatusMsg(i18n("Setting the column titles of the vocabulary..."));
756 dlg
= new DlgLanguage(this, "dlg_lang", true);
757 dlg
->setLanguage(1, m_editView
-> horizontalHeader()->label(0));
758 dlg
->setLanguage(2, m_editView
-> horizontalHeader()->label(1));
759 dlg
->disableResize();
760 if (dlg
->exec() == KDialogBase::Accepted
)
762 m_editView
-> horizontalHeader()->setLabel(0, dlg
->Language(1));
763 m_editView
-> horizontalHeader()->setLabel(1, dlg
->Language(2));
764 updateMode(Prefs::mode());
766 slotStatusMsg(i18n("Ready"));
769 void KWordQuizApp::slotVocabFont()
771 slotStatusMsg(i18n("Setting the font of the vocabulary..."));
773 dlg
= new KFontDialog(this, "dlg_font", false, true);
774 dlg
->setFont(m_editView
-> font());
775 if (dlg
->exec() == KFontDialog::Accepted
)
777 m_editView
->setFont(dlg
->font());
778 Prefs::setEditorFont(dlg
->font());
779 doc
->setModified(true);
781 slotStatusMsg(i18n("Ready"));
784 void KWordQuizApp::slotVocabKeyboard()
786 slotStatusMsg(i18n("Changing the keyboard layout..."));
787 KMessageBox::sorry(0, i18n("Not implemented yet"));
788 slotStatusMsg(i18n("Ready"));
791 void KWordQuizApp::slotVocabChar()
793 slotStatusMsg(i18n("Inserting special character..."));
794 m_editView
->doVocabSpecChar();
795 slotStatusMsg(i18n("Ready"));
798 void KWordQuizApp::slotVocabRC()
800 slotStatusMsg(i18n("Changing row and column properties..."));
801 m_editView
->doVocabRC();
802 slotStatusMsg(i18n("Ready"));
805 void KWordQuizApp::slotVocabSort()
807 slotStatusMsg(i18n("Sorting the vocabulary..."));
808 m_editView
->doVocabSort();
809 slotStatusMsg(i18n("Ready"));
812 void KWordQuizApp::slotVocabShuffle()
814 slotStatusMsg(i18n("Randomizing the vocabulary..."));
815 m_editView
->doVocabShuffle();
816 slotStatusMsg(i18n("Ready"));
819 void KWordQuizApp::slotMode0()
821 slotStatusMsg(i18n("Updating mode..."));
822 if (Prefs::mode() < 5) {
823 updateMode(Prefs::mode() + 1);
829 slotStatusMsg(i18n("Ready"));
832 void KWordQuizApp::slotMode1()
834 slotStatusMsg(i18n("Updating mode..."));
836 slotStatusMsg(i18n("Ready"));
839 void KWordQuizApp::slotMode2()
841 slotStatusMsg(i18n("Updating mode..."));
843 slotStatusMsg(i18n("Ready"));
846 void KWordQuizApp::slotMode3()
848 slotStatusMsg(i18n("Updating mode..."));
850 slotStatusMsg(i18n("Ready"));
853 void KWordQuizApp::slotMode4()
855 slotStatusMsg(i18n("Updating mode..."));
857 slotStatusMsg(i18n("Ready"));
860 void KWordQuizApp::slotMode5()
862 slotStatusMsg(i18n("Updating mode..."));
864 slotStatusMsg(i18n("Ready"));
867 void KWordQuizApp::slotQuizEditor()
869 slotStatusMsg(i18n("Starting editor session..."));
870 updateSession(WQQuiz::qtEditor
);
871 slotStatusMsg(i18n("Ready"));
874 void KWordQuizApp::slotQuizFlash()
876 slotStatusMsg(i18n("Starting flashcard session..."));
877 updateSession(WQQuiz::qtFlash
);
878 slotStatusMsg(i18n("Ready"));
881 void KWordQuizApp::slotQuizMultiple()
883 slotStatusMsg(i18n("Starting multiple choice session..."));
884 updateSession(WQQuiz::qtMultiple
);
885 slotStatusMsg(i18n("Ready"));
888 void KWordQuizApp::slotQuizQA()
890 slotStatusMsg(i18n("Starting question & answer session..."));
891 updateSession(WQQuiz::qtQA
);
892 slotStatusMsg(i18n("Ready"));
895 void KWordQuizApp::updateSession(WQQuiz::QuizType qt
)
903 switch( m_quizType
){
904 case WQQuiz::qtEditor
:
907 case WQQuiz::qtFlash
:
908 if (m_flashView
!= 0)
914 case WQQuiz::qtMultiple
:
915 if (m_multipleView
!= 0)
917 delete(m_multipleView
);
933 switch( m_quizType
){
934 case WQQuiz::qtEditor
:
936 setCentralWidget(m_editView
);
937 m_editView
-> setFocus();
939 case WQQuiz::qtFlash
:
940 m_quiz
= new WQQuiz(m_editView
);
941 connect(m_quiz
, SIGNAL(checkingAnswer(int )), m_editView
, SLOT(slotCheckedAnswer(int )));
942 m_quiz
->setQuizType(WQQuiz::qtFlash
);
943 m_quiz
->setQuizMode(Prefs::mode());
944 if (m_quiz
-> init())
946 m_editView
->saveCurrentSelection(true);
948 m_flashView
= new FlashView(this);
949 connect(quizCheck
, SIGNAL(activated()), m_flashView
, SLOT(slotFlip()));
950 connect(flashKnow
, SIGNAL(activated()), m_flashView
, SLOT(slotKnow()));
951 connect(flashDontKnow
, SIGNAL(activated()), m_flashView
, SLOT(slotDontKnow()));
952 connect(quizRestart
, SIGNAL(activated()), m_flashView
, SLOT(slotRestart()));
953 connect(quizRepeatErrors
, SIGNAL(activated()), m_flashView
, SLOT(slotRepeat()));
954 connect(this, SIGNAL(settingsChanged()), m_flashView
, SLOT(slotApplySettings()));
956 setCentralWidget(m_flashView
);
957 m_flashView
-> setQuiz(m_quiz
);
958 m_flashView
->init();
967 case WQQuiz::qtMultiple
:
968 m_quiz
= new WQQuiz(m_editView
);
969 connect(m_quiz
, SIGNAL(checkingAnswer(int )), m_editView
, SLOT(slotCheckedAnswer(int )));
970 m_quiz
->setQuizType(WQQuiz::qtMultiple
);
971 m_quiz
->setQuizMode(Prefs::mode());
972 if (m_quiz
-> init())
974 m_editView
->saveCurrentSelection(true);
976 m_multipleView
= new MultipleView(this);
977 connect(quizCheck
, SIGNAL(activated()), m_multipleView
, SLOT(slotCheck()));
978 connect(quizRestart
, SIGNAL(activated()), m_multipleView
, SLOT(slotRestart()));
979 connect(quizRepeatErrors
, SIGNAL(activated()), m_multipleView
, SLOT(slotRepeat()));
980 connect(this, SIGNAL(settingsChanged()), m_multipleView
, SLOT(slotApplySettings()));
982 setCentralWidget(m_multipleView
);
984 m_multipleView
-> setQuiz(m_quiz
);
985 m_multipleView
->init();
986 m_multipleView
->show();
995 m_quiz
= new WQQuiz(m_editView
);
996 connect(m_quiz
, SIGNAL(checkingAnswer(int )), m_editView
, SLOT(slotCheckedAnswer(int )));
997 m_quiz
->setQuizType(WQQuiz::qtQA
);
998 m_quiz
->setQuizMode(Prefs::mode());
999 if (m_quiz
-> init())
1001 m_editView
->saveCurrentSelection(true);
1003 m_qaView
= new QAView(this);
1004 connect(quizCheck
, SIGNAL(activated()), m_qaView
, SLOT(slotCheck()));
1005 connect(qaHint
, SIGNAL(activated()), m_qaView
, SLOT(slotHint()));
1006 connect(quizRestart
, SIGNAL(activated()), m_qaView
, SLOT(slotRestart()));
1007 connect(quizRepeatErrors
, SIGNAL(activated()), m_qaView
, SLOT(slotRepeat()));
1008 connect(this, SIGNAL(settingsChanged()), m_qaView
, SLOT(slotApplySettings()));
1010 setCentralWidget(m_qaView
);
1012 m_qaView
-> setQuiz(m_quiz
);
1026 /** Configure notifications */
1027 void KWordQuizApp::slotConfigureNotifications( )
1029 KNotifyDialog::configure(this, "Notification Configuration Dialog");
1032 /** Configure kwordquiz */
1033 void KWordQuizApp::slotConfigure()
1035 if ( KWordQuizPrefs::showDialog( "settings" ) )
1038 //KConfigDialog didn't find an instance of this dialog, so lets create it :
1039 KWordQuizPrefs
* dialog
= new KWordQuizPrefs( this, "settings", Prefs::self() );
1040 connect(dialog
, SIGNAL(settingsChanged()), this, SLOT(slotApplyPreferences()));
1044 void KWordQuizApp::slotApplyPreferences()
1046 kdDebug() << "Prefs Update" << endl
;
1047 editMarkBlank
->setEnabled(Prefs::enableBlanks());
1048 editUnmarkBlank
->setEnabled(Prefs::enableBlanks());
1049 m_editView
->viewport()->repaint(true);
1050 updateSpecialCharIcons();
1051 emit
settingsChanged();
1054 void KWordQuizApp::updateSpecialCharIcons( )
1056 for (int i
= 0; i
< 9; i
++){
1057 KAction
* act
= actionCollection()->action(QString("char_" + QString::number(i
+ 1)).latin1());
1058 act
->setIcon(charIcon(Prefs::specialCharacters()[i
]));
1059 act
->setToolTip(i18n("Inserts the character %1").arg(Prefs::specialCharacters()[i
]));
1063 QString
KWordQuizApp::charIcon(const QChar
& c
)
1065 ///Create a name and path for the icon
1066 QString s
= locateLocal("icon", "char" + QString::number(c
.unicode()) + ".png");
1068 ///No need to redraw if it already exists
1069 if (KStandardDirs::exists(s
))
1072 QRect
r(4, 4, 120, 120);
1074 ///A font to draw the character with
1076 font
.setPixelSize(100);
1077 font
.setWeight(QFont::Bold
);
1079 ///Create the pixmap
1080 QPixmap
pm(128, 128);
1085 p
.drawText(r
, Qt::AlignCenter
, (QString
) c
);
1087 ///Create transparency mask
1088 QBitmap
bm(128, 128);
1089 bm
.fill(Qt::color0
);
1092 b
.setPen(Qt::color1
);
1093 b
.drawText(r
, Qt::AlignCenter
, (QString
) c
);
1098 ///Save the icon to disk
1104 void KWordQuizApp::slotStatusMsg(const QString
&text
)
1106 statusBar()->clear();
1107 statusBar()->message(text
);
1111 \fn KWordQuizApp::updateMode(int m)
1113 void KWordQuizApp::updateMode(int m
)
1116 if (KMessageBox::warningContinueCancel(this, i18n("This will restart your quiz. Do you wish to continue?"), QString::null
, KStdGuiItem::cont(), "askModeQuiz") != KMessageBox::Continue
)
1118 mode1
->setChecked(Prefs::mode() == 1);
1119 mode2
->setChecked(Prefs::mode() == 2);
1120 mode3
->setChecked(Prefs::mode() == 3);
1121 mode4
->setChecked(Prefs::mode() == 4);
1122 mode5
->setChecked(Prefs::mode() == 5);
1127 QString s1
= m_editView
-> horizontalHeader()->label(0);
1128 QString s2
= m_editView
-> horizontalHeader()->label(1);
1130 mode1
->setText(i18n("&1 %1 -> %2 In Order").arg(s1
).arg(s2
));
1131 mode2
->setText(i18n("&2 %1 -> %2 In Order").arg(s2
).arg(s1
));
1132 mode3
->setText(i18n("&3 %1 -> %2 Randomly").arg(s1
).arg(s2
));
1133 mode4
->setText(i18n("&4 %1 -> %2 Randomly").arg(s2
).arg(s1
));
1134 mode5
->setText(i18n("&5 %1 <-> %2 Randomly").arg(s1
).arg(s2
));
1136 mode1
->setChecked(Prefs::mode() == 1);
1137 mode2
->setChecked(Prefs::mode() == 2);
1138 mode3
->setChecked(Prefs::mode() == 3);
1139 mode4
->setChecked(Prefs::mode() == 4);
1140 mode5
->setChecked(Prefs::mode() == 5);
1142 KPopupMenu
*popup
= mode
->popupMenu();
1143 popup
->setItemChecked(0, Prefs::mode() == 1);
1144 popup
->setItemChecked(1, Prefs::mode() == 2);
1145 popup
->setItemChecked(2, Prefs::mode() == 3);
1146 popup
->setItemChecked(3, Prefs::mode() == 4);
1147 popup
->setItemChecked(4, Prefs::mode() == 5);
1149 popup
->changeItem(0, i18n("&1 %1 -> %2 In Order").arg(s1
).arg(s2
));
1150 popup
->changeItem(1, i18n("&2 %1 -> %2 In Order").arg(s2
).arg(s1
));
1151 popup
->changeItem(2, i18n("&3 %1 -> %2 Randomly").arg(s1
).arg(s2
));
1152 popup
->changeItem(3, i18n("&4 %1 -> %2 Randomly").arg(s2
).arg(s1
));
1153 popup
->changeItem(4, i18n("&5 %1 <-> %2 Randomly").arg(s1
).arg(s2
));
1156 mode
->setIcon("mode" + s
.setNum(Prefs::mode()));
1158 switch( Prefs::mode() ){
1160 statusBar()->changeItem(i18n("%1 -> %2 In Order").arg(s1
).arg(s2
), ID_STATUS_MSG_MODE
);
1163 statusBar()->changeItem(i18n("%1 -> %2 In Order").arg(s2
).arg(s1
), ID_STATUS_MSG_MODE
);
1166 statusBar()->changeItem(i18n("%1 -> %2 Randomly").arg(s1
).arg(s2
), ID_STATUS_MSG_MODE
);
1169 statusBar()->changeItem(i18n("%1 -> %2 Randomly").arg(s2
).arg(s1
), ID_STATUS_MSG_MODE
);
1172 statusBar()->changeItem(i18n("%1 <-> %2 Randomly").arg(s1
).arg(s2
), ID_STATUS_MSG_MODE
);
1177 updateSession(m_quizType
);
1180 void KWordQuizApp::slotInsertChar( int i
)
1183 m_qaView
->slotSpecChar(Prefs::specialCharacters()[i
- 1]);
1185 if (centralWidget() == m_editView
)
1186 m_editView
->slotSpecChar(Prefs::specialCharacters()[i
- 1]);
1189 void KWordQuizApp::slotActionHighlighted( KAction
* action
, bool hl
)
1192 slotStatusMsg(i18n("Ready"));
1195 void KWordQuizApp::slotContextMenuRequested(int row
, int col
, const QPoint
& pos
)
1197 QWidget
*w
= factory()->container("editor_popup", this);
1198 QPopupMenu
*popup
= static_cast<QPopupMenu
*>(w
);
1202 void KWordQuizApp::updateActions( WQQuiz::QuizType qt
)
1204 bool fEdit
= (qt
== WQQuiz::qtEditor
);
1206 fileSave
->setEnabled(fEdit
);
1207 fileSaveAs
->setEnabled(fEdit
);
1208 filePrint
->setEnabled(fEdit
);
1209 //editFind->setEnabled(fEdit);
1210 editClear
->setEnabled(fEdit
);
1211 editInsert
->setEnabled(fEdit
);
1212 editDelete
->setEnabled(fEdit
);
1213 editMarkBlank
->setEnabled(fEdit
&& Prefs::enableBlanks());
1214 editUnmarkBlank
->setEnabled(fEdit
&& Prefs::enableBlanks());
1215 vocabLanguages
->setEnabled(fEdit
);
1216 vocabFont
->setEnabled(fEdit
);
1217 //vocabKeyboard->setEnabled(fEdit);
1218 vocabRC
->setEnabled(fEdit
);
1219 vocabSort
->setEnabled(fEdit
);
1220 vocabShuffle
->setEnabled(fEdit
);
1222 quizEditor
->setEnabled(qt
!= WQQuiz::qtEditor
);
1223 quizFlash
->setEnabled(qt
!= WQQuiz::qtFlash
);
1224 quizMultiple
->setEnabled(qt
!= WQQuiz::qtMultiple
);
1225 quizQA
->setEnabled(qt
!= WQQuiz::qtQA
);
1227 quizCheck
->setEnabled(qt
!= WQQuiz::qtEditor
);
1228 quizRestart
->setEnabled(qt
!= WQQuiz::qtEditor
);
1229 quizRepeatErrors
->setEnabled(false);
1231 flashKnow
->setEnabled(qt
== WQQuiz::qtFlash
);
1232 flashDontKnow
->setEnabled(qt
== WQQuiz::qtFlash
);
1234 qaHint
->setEnabled(qt
== WQQuiz::qtQA
);
1236 toolBar("quizToolBar")->setHidden(qt
== WQQuiz::qtEditor
);
1240 #include "kwordquiz.moc"