moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / ktouch / src / ktouch.cpp
blob51d30567fa1001dedeb7b4bf83225d0451958f53
1 /***************************************************************************
2 * ktouch.cpp *
3 * ---------- *
4 * Copyright (C) 2000 by Håvard Frøiland, 2004 by Andreas Nicolai *
5 * ghorwin@users.sourceforge.net *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 ***************************************************************************/
13 #include "ktouch.h"
14 #include "ktouch.moc"
16 // Standard files
17 #include <algorithm>
19 // QT Header
20 #include <qvbox.h>
21 #include <qsignalmapper.h>
22 #include <qcheckbox.h>
23 #include <qlabel.h>
25 // KDE Header
26 #include <klocale.h>
27 #include <kstatusbar.h>
28 #include <kfiledialog.h>
29 #include <kaction.h>
30 #include <kstandarddirs.h>
31 #include <kmessagebox.h>
32 #include <kdebug.h>
33 #include <kpopupmenu.h>
34 #include <kconfigdialog.h>
35 #include <kaction.h>
36 #include <kcombobox.h>
37 #include <kfontrequester.h>
38 #include <knuminput.h>
40 // Own header files
41 //#include "ktouchpref.h"
42 #include "ktouchlecture.h"
43 #include "ktouchlectureeditor.h"
44 #include "ktouchstatus.h"
45 #include "ktouchslideline.h"
46 #include "ktouchkeyboard.h"
47 #include "ktouchtrainer.h"
48 #include "ktouchstartnewdialog.h"
49 #include "ktouchstatistics.h"
50 #include "ktouchprefgenerallayout.h"
51 #include "ktouchpreftraininglayout.h"
52 #include "ktouchprefkeyboardlayout.h"
53 #include "ktouchprefcolorslayout.h"
54 #include "prefs.h"
56 KTouch * KTouchPtr = NULL;
58 KTouch::KTouch()
59 : KMainWindow( 0, "KTouch" ),
60 m_statusWidget(NULL),
61 m_keyboardWidget(NULL),
62 m_trainer(NULL)
64 KTouchPtr = this;
65 // General initialization of the program, common for all start modes
66 init();
67 // Setup our actions and connections
68 setupActions();
69 // create the GUI reading the ui.rc file
70 if (!initialGeometrySet())
71 resize( QSize(700, 510).expandedTo(minimumSizeHint()));
72 setupGUI(ToolBar | Keys | StatusBar | Create);
73 setAutoSaveSettings();
74 // Init a training session
75 initTrainingSession();
77 // If session was restored, the function readProperties() was already called
78 if (kapp->isRestored()) {
79 kdDebug() << "KTouch() : restoring session..." << endl;
80 // TODO : rewrite all the session management stuff
81 // for now we just do the same as for the standard startup
82 m_lecture.loadXML(this, Prefs::currentLectureFile() );
83 updateFontFromLecture();
84 updateLectureActionCheck();
85 m_trainer->m_level = 0;
86 m_trainer->goFirstLine();
87 changeStatusbarMessage( i18n("Starting training session: Waiting for first keypress...") );
88 changeStatusbarStats( m_trainer->m_session.m_correctChars,
89 m_trainer->m_session.m_totalChars, m_trainer->m_session.m_words);
91 else {
92 kdDebug() << "[KTouch::KTouch] starting standard training..." << endl;
93 // A note about safety: In this function there are a lot of things that might go
94 // wrong. What happens if the training file can't be found? What if the
95 // file cannot be opened or is corrupt? Whatever happens, the function loadXML()
96 // ensures, that there is at least the default mini-level in the lecture
97 // so that the training won't crash.
99 // Reload the last used training file.
100 if (!m_lecture.loadXML(this, Prefs::currentLectureFile() )) {
101 Prefs::setCurrentLectureFile(QString::null);
102 m_defaultLectureAction->setCurrentItem(-1);
104 else {
105 updateFontFromLecture();
106 // adjust check marks in quick-select menus
107 updateLectureActionCheck();
108 kdDebug() << "[KTouch::KTouch] lecture file = " << Prefs::currentLectureFile() << endl;
111 // Adjust check mark for the keyboard file
112 int num = 0;
113 QStringList::iterator it = m_keyboardFiles.begin();
114 QString fname = Prefs::currentKeyboardFile();
115 while (it != m_keyboardFiles.end() && (*it).find(fname) == -1) {
116 ++it;
117 ++num;
119 if (it == m_keyboardFiles.end()) m_keyboardLayoutAction->setCurrentItem(-1);
120 else m_keyboardLayoutAction->setCurrentItem(num);
122 // If the user doesn't want to restart with his old level, start from 0 (level 1)
123 if (!Prefs::rememberLevel()) m_trainer->m_level = 0;
124 else m_trainer->m_level = Prefs::currentTrainingLevel();
125 // now let's show the first line of the current level
126 m_trainer->goFirstLine();
127 // the current training session is already started and the training will start on first keypress
128 changeStatusbarMessage( i18n("Starting training session: Waiting for first keypress...") );
129 changeStatusbarStats( m_trainer->m_session.m_correctChars,
130 m_trainer->m_session.m_totalChars, m_trainer->m_session.m_words);
133 // ----------------------------------------------------------------------------
135 // Free memory of objects that are not owned by the main KTouch object
136 KTouch::~KTouch() {
137 delete m_trainer;
138 m_trainer = NULL;
140 // ----------------------------------------------------------------------------
143 // ********************
144 // *** Public slots ***
145 // ********************
147 void KTouch::applyPreferences() {
148 // This applies a new color scheme for the keyboard and also updates all other
149 // changes for the keyboard widget
150 changeColor(Prefs::colorScheme());
151 m_slideLineWidget->applyPreferences();
154 void KTouch::keyPressEvent(QKeyEvent *keyEvent) {
155 if (keyEvent->text().isEmpty()) return;
156 QChar key = keyEvent->text().at(0);
157 if (key.isPrint())
158 m_trainer->keyPressed(key);
159 else if (key==QChar(8))
160 m_trainer->backspacePressed();
161 else if (key==QChar(13))
162 m_trainer->enterPressed();
163 else
164 return; // unrecognised char -> don't accept it! Maybe the key is for somebody else?
165 keyEvent->accept();
168 void KTouch::configOverrideLectureFontToggled(bool on) {
169 if (on) {
170 m_pageGeneral->fontTextLabel->setEnabled(true);
171 m_pageGeneral->kcfg_Font->setEnabled(true);
173 else {
174 m_pageGeneral->fontTextLabel->setEnabled(false);
175 m_pageGeneral->kcfg_Font->setEnabled(false);
179 void KTouch::configOverrideKeyboardFontToggled(bool on) {
180 if (on) {
181 m_pageKeyboard->textLabel1->setEnabled(true);
182 m_pageKeyboard->kcfg_KeyboardFont->setEnabled(true);
184 else {
185 m_pageKeyboard->textLabel1->setEnabled(false);
186 m_pageKeyboard->kcfg_KeyboardFont->setEnabled(false);
190 void KTouch::configAutoLevelChangeToggled(bool on) {
191 if (on) {
192 m_pageTraining->l1->setEnabled(true);
193 m_pageTraining->l2->setEnabled(true);
194 m_pageTraining->l3->setEnabled(true);
195 m_pageTraining->l4->setEnabled(true);
196 m_pageTraining->l5->setEnabled(true);
197 m_pageTraining->l6->setEnabled(true);
198 m_pageTraining->l7->setEnabled(true);
199 m_pageTraining->l8->setEnabled(true);
200 m_pageTraining->l9->setEnabled(true);
201 m_pageTraining->l10->setEnabled(true);
202 m_pageTraining->kcfg_UpSpeedLimit->setEnabled(true);
203 m_pageTraining->kcfg_UpCorrectLimit->setEnabled(true);
204 m_pageTraining->kcfg_DownSpeedLimit->setEnabled(true);
205 m_pageTraining->kcfg_DownCorrectLimit->setEnabled(true);
207 else {
208 m_pageTraining->l1->setEnabled(false);
209 m_pageTraining->l2->setEnabled(false);
210 m_pageTraining->l3->setEnabled(false);
211 m_pageTraining->l4->setEnabled(false);
212 m_pageTraining->l5->setEnabled(false);
213 m_pageTraining->l6->setEnabled(false);
214 m_pageTraining->l7->setEnabled(false);
215 m_pageTraining->l8->setEnabled(false);
216 m_pageTraining->l9->setEnabled(false);
217 m_pageTraining->l10->setEnabled(false);
218 m_pageTraining->kcfg_UpSpeedLimit->setEnabled(false);
219 m_pageTraining->kcfg_UpCorrectLimit->setEnabled(false);
220 m_pageTraining->kcfg_DownSpeedLimit->setEnabled(false);
221 m_pageTraining->kcfg_DownCorrectLimit->setEnabled(false);
226 // *********************************
227 // *** Protected member function ***
228 // *********************************
230 bool KTouch::queryClose() {
231 // TODO : if in test mode, ask user whether he really wants to quit the test
232 return true;
235 bool KTouch::queryExit() {
236 // store some training/exam related data
237 Prefs::setCurrentTrainingLevel( m_trainer->m_level );
238 Prefs::writeConfig();
239 return true;
242 // *****************************************************
243 // *** Private slots (implementation of the actions) ***
244 // *****************************************************
246 // The action File->Open lecture...
247 void KTouch::fileOpenLecture() {
248 KURL tmp = KFileDialog::getOpenURL(QString::null, QString::null, this, i18n("Select Training Lecture File") );
249 if (!tmp.isEmpty()) {
250 Prefs::setCurrentLectureFile(tmp.url());
251 m_lecture.loadXML(this, Prefs::currentLectureFile() );
252 updateFontFromLecture();
253 // adjust check marks in quick-select menus
254 updateLectureActionCheck();
257 // ----------------------------------------------------------------------------
259 // The action File->Edit lecture...
260 void KTouch::fileEditLecture() {
261 // Create and execute editor
262 KTouchLectureEditor dlg(this);
263 dlg.startEditor( Prefs::currentLectureFile() );
264 // Reload lecture in case it was modified
265 m_lecture.loadXML(this, Prefs::currentLectureFile() );
266 updateFontFromLecture();
267 // adjust check marks in quick-select menus
268 updateLectureActionCheck();
270 // ----------------------------------------------------------------------------
272 void KTouch::fileQuit() {
273 kapp->quit();
275 // ----------------------------------------------------------------------------
277 void KTouch::trainingNewSession() {
278 trainingPause();
279 KTouchStartNewDialog dlg(this);
280 if (dlg.exec()==QDialog::Accepted) {
281 m_trainer->startNewTrainingSession(dlg.keepLevel->isChecked());
282 m_trainingPause->setEnabled(true);
283 m_trainingContinue->setEnabled(false);
285 else
286 trainingContinue();
288 // ----------------------------------------------------------------------------
290 void KTouch::trainingContinue() {
291 m_trainingPause->setEnabled(true);
292 m_trainingContinue->setEnabled(false);
293 m_trainer->continueTraining();
295 // ----------------------------------------------------------------------------
297 void KTouch::trainingPause() {
298 m_trainingPause->setEnabled(false);
299 m_trainingContinue->setEnabled(true);
300 m_trainer->pauseTraining();
302 // ----------------------------------------------------------------------------
304 void KTouch::trainingStatistics() {
305 bool sessionRunning = m_trainingPause->isEnabled();
306 trainingPause();
307 KTouchStatistics dlg(this, m_trainer);
308 dlg.exec();
309 if (sessionRunning)
310 trainingContinue();
312 // ----------------------------------------------------------------------------
314 void KTouch::optionsPreferences() {
315 trainingPause();
316 if ( KConfigDialog::showDialog( "settings" ) ) return;
317 //KConfigDialog didn't find an instance of this dialog, so lets create it :
318 KConfigDialog* dialog = new KConfigDialog( this, "settings", Prefs::self() );
319 m_pageGeneral = new KTouchPrefGeneralLayout(0, "General");
320 dialog->addPage(m_pageGeneral, i18n("General Options"), "style");
321 m_pageTraining = new KTouchPrefTrainingLayout(0, "Training");
322 dialog->addPage(m_pageTraining, i18n("Training Options"), "kalarm");
323 m_pageKeyboard = new KTouchPrefKeyboardLayout(0, "Keyboard");
324 dialog->addPage(m_pageKeyboard, i18n("Keyboard Settings"), "keyboard_layout");
325 KTouchPrefColorsLayout *m_pageColors = new KTouchPrefColorsLayout(0, "Colors");
326 dialog->addPage(m_pageColors, i18n("Color Settings"), "package_graphics");
327 connect(dialog, SIGNAL(settingsChanged()), this, SLOT(applyPreferences()));
328 // TODO : Connect some other buttons/check boxes of the dialog
329 connect(m_pageGeneral->kcfg_OverrideLectureFont, SIGNAL(toggled(bool)), this, SLOT(configOverrideLectureFontToggled(bool)));
330 connect(m_pageKeyboard->kcfg_OverrideKeyboardFont, SIGNAL(toggled(bool)), this, SLOT(configOverrideKeyboardFontToggled(bool)));
331 connect(m_pageTraining->kcfg_AutoLevelChange, SIGNAL(toggled(bool)), this, SLOT(configAutoLevelChangeToggled(bool)));
332 // call the functions to enable/disable controls depending on settings
333 configOverrideLectureFontToggled(Prefs::overrideLectureFont());
334 configOverrideKeyboardFontToggled(Prefs::overrideKeyboardFont());
335 configAutoLevelChangeToggled(Prefs::autoLevelChange());
336 dialog->show();
337 trainingContinue();
339 // ----------------------------------------------------------------------------
341 void KTouch::changeStatusbarMessage(const QString& text) {
342 statusBar()->message(text);
344 // ----------------------------------------------------------------------------
346 void KTouch::changeStatusbarStats(unsigned int correctChars, unsigned int totalChars, unsigned int words) {
347 m_barStatsLabel->setText( i18n( " Correct chars: %1 Total chars: %1 Words: %1 ")
348 .arg(correctChars).arg(totalChars).arg(words) );
350 // ----------------------------------------------------------------------------
352 void KTouch::changeKeyboard(int num) {
353 if (static_cast<unsigned int>(num)>=m_keyboardFiles.count()) return;
354 Prefs::setCurrentKeyboardFile( m_keyboardFiles[num] );
355 kdDebug() << "[KTouch::changeKeyboard] new keyboard layout = " << Prefs::currentKeyboardFile() << endl;
356 m_keyboardLayoutAction->setCurrentItem(num);
357 m_keyboardWidget->applyPreferences(this, false); // noisy, pop up an error if the chosen layout file is corrupt
359 // ----------------------------------------------------------------------------
361 void KTouch::changeColor(int num) {
362 if (static_cast<unsigned int>(num)>=m_colorSchemes.count()) return;
363 Prefs::setColorScheme(num);
364 m_keyboardWidget->applyPreferences(this, false);
366 // ----------------------------------------------------------------------------
368 void KTouch::changeLecture(int num) {
369 if (static_cast<unsigned int>(num)>=m_lectureFiles.count()) return;
370 trainingPause();
371 KTouchLecture l;
372 QString fileName = m_lectureFiles[num];
373 if (!l.loadXML(this, KURL::fromPathOrURL(fileName))) {
374 KMessageBox::sorry(0, i18n("Could not find/open the lecture file '%1'.").arg(fileName) );
375 m_defaultLectureAction->setCurrentItem(-1);
377 else {
378 Prefs::setCurrentLectureFile( fileName );
379 m_lecture = l;
380 updateFontFromLecture();
381 m_defaultLectureAction->setCurrentItem(num);
383 m_trainer->goFirstLevel();
384 trainingContinue();
386 // ----------------------------------------------------------------------------
388 // *******************************
389 // *** Private member function ***
390 // *******************************
392 // Will be called when this app is restored due to session management.
393 // This function only stored the temperary data of the last session. All permanent
394 // settings should be handled by the KTouchConfiguration object.
395 void KTouch::readProperties(KConfig *config) {
396 kdDebug() << "[KTouch::readProperties] Reading session data..." << endl;
397 // TODO : Session management rewrite
398 config->setGroup("TrainingState");
401 // The application is about to be restored due to session management.
402 // Let's read all the stuff that was set when the application was terminated (during KDE logout).
403 QString session = config->readEntry("Session");
404 if (!session.isEmpty())
405 m_trainer->m_session = KTouchTrainingSession(session);
406 m_trainer->m_level = config->readNumEntry("Level", 0);
407 m_trainer->m_line = config->readNumEntry("Line", 0);
408 m_currentLectureFile = config->readPathEntry("Lecture");
409 m_trainer->readSessionHistory(); // read session history (excluding currently active session)
410 // update the trainer object
411 m_trainer->m_teacherText = m_lecture.level(m_trainer->m_level).line(m_trainer->m_line);
412 m_trainer->m_studentText = config->readEntry("StudentText");
413 m_trainer->continueTraining();
414 changeStatusbarMessage( i18n("Restarting training session: Waiting for first keypress...") );
415 // update the slide line widget
416 m_slideLineWidget->setNewText(m_trainer->m_teacherText, m_trainer->m_studentText);
417 // update all the other widgets
418 m_trainer->updateWidgets();
419 // Read training state
420 config->setGroup("TrainingState");
421 m_currentLectureURL = config->readPathEntry("LectureURL");
422 m_trainer->m_level = config->readNumEntry("Level", 0);
426 // Will be called when the app should save its state for session management purposes.
427 void KTouch::saveProperties(KConfig *config) {
428 kdDebug() << "[KTouch::saveProperties] Saving session data..." << endl;
429 // We are going down because of session management (most likely because of
430 // KDE logout). Let's save the current status so that we can restore it
431 // next logon.
433 // TODO : Session management rewrite
434 config->setGroup("TrainingState");
436 // first write the current lecture URL and the training position
437 config->writePathEntry("Lecture", m_currentLectureURL.url());
438 config->writeEntry("Level", m_trainer->m_level);
439 config->writeEntry("Line", m_trainer->m_line);
440 config->writeEntry("StudentText", m_trainer->m_studentText);
441 config->writeEntry("Session", m_trainer->m_session.asString() );
442 // store the session history so far
443 m_trainer->writeSessionHistory();
445 config->setGroup("TrainingState");
446 config->writePathEntry("LectureURL", m_currentLectureURL.url());
447 config->writeEntry("Level", m_trainer->m_level);
448 // during normal shutdown we finish the session and add it to the session history
449 m_trainer->m_sessionHistory.append( m_trainer->m_session );
450 m_trainer->writeSessionHistory();
454 /// Initialises the program during a normal startup
455 void KTouch::init() {
456 kdDebug() << "[KTouch::init] populating file lists..." << endl;
457 updateFileLists(); // create lists with default lecture/keyboard/colour scheme files
458 kdDebug() << "[KTouch::init] " << m_lectureFiles.count() << " lectures available" << endl;
459 kdDebug() << "[KTouch::init] " << m_keyboardFiles.count() << " keyboard layouts available" << endl;
460 kdDebug() << "[KTouch::init] " << m_examinationFiles.count() << " examination files available" << endl;
462 // TODO : look up a default english lecture in the m_lectureFiles string list
463 QString default_lecture;
464 if (m_lectureFiles.count() > 0) default_lecture = m_lectureFiles[0];
465 if (Prefs::currentLectureFile() == "default")
466 Prefs::setCurrentLectureFile( default_lecture );
467 // read keyboard settings
469 QString default_keyboard = "number.keyboard";
470 // look up the default english keyboard file in the m_keyboardFiles string list
471 QStringList::iterator it = m_keyboardFiles.begin();
472 while (it != m_keyboardFiles.end() && (*it).find("en.keyboard") == -1) ++it;
473 if (it != m_keyboardFiles.end()) default_keyboard = *it;
474 // if keyboard layout (loaded by Prefs is not available (e.g. the
475 // layout file has been deleted) switch to default keyboard
476 if (m_keyboardFiles.contains(Prefs::currentKeyboardFile() )==0)
477 Prefs::setCurrentKeyboardFile ( default_keyboard );
479 // create some default colour schemes
480 createDefaultColorSchemes();
483 /// Creates the layout and GUI setup for a practice session
484 void KTouch::initTrainingSession() {
485 kdDebug() << "[KTouch::initTrainingSession] setting up layouts and widgets for new training session..." << endl;
486 // Build the training area. The status widget has a fixed vertical size, the slide line and the
487 // keyboard grow according to their vertical stretch factors (see last argument in the constructors
488 // of QSizePolicy)
489 QVBox * mainLayout = new QVBox( this );
490 m_statusWidget = new KTouchStatus( mainLayout );
491 m_slideLineWidget = new KTouchSlideLine( mainLayout );
492 m_slideLineWidget->setSizePolicy( QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding, 0, 1) );
493 m_keyboardWidget = new KTouchKeyboard( mainLayout );
494 m_keyboardWidget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding, 0, 3) );
495 setCentralWidget(mainLayout);
496 // apply the settings to the widgets
497 m_slideLineWidget->applyPreferences();
498 m_keyboardWidget->applyPreferences(this, true); // set preferences silently here
500 // create our trainer, the master object for the training stuff...
501 if (m_trainer != NULL) delete m_trainer;
502 m_trainer = new KTouchTrainer(m_statusWidget, m_slideLineWidget, m_keyboardWidget, &m_lecture);
503 // connections for the trainer object
504 connect( m_trainer, SIGNAL(statusbarMessageChanged(const QString&)), this, SLOT(changeStatusbarMessage(const QString&)) );
505 connect( m_trainer, SIGNAL(statusbarStatsChanged(unsigned int, unsigned int, unsigned int)),
506 this, SLOT(changeStatusbarStats(unsigned int, unsigned int, unsigned int)) );
508 // Setup status bar
509 statusBar()->show();
510 statusBar()->insertItem("", 0, 1); // space for the messages
511 m_barStatsLabel = new QLabel("",this);
512 statusBar()->addWidget(m_barStatsLabel, 0, true); // for the character statistics / counter
515 /// Creates the (standard) actions and entries in the menu.
516 void KTouch::setupActions() {
517 // *** File menu ***
518 new KAction(i18n("&Open Lecture..."), 0,
519 this, SLOT(fileOpenLecture()), actionCollection(), "file_openlecture");
520 new KAction(i18n("&Edit Lecture..."), 0,
521 this, SLOT(fileEditLecture()), actionCollection(), "file_editlecture");
522 KStdAction::quit(this, SLOT(fileQuit()), actionCollection());
524 // *** Training menu ***
525 new KAction(i18n("&Start New Session"), "launch", 0,
526 this, SLOT(trainingNewSession()), actionCollection(), "training_newsession");
527 m_trainingContinue = new KAction(i18n("&Continue Session"), "player_play", 0,
528 this, SLOT(trainingContinue()), actionCollection(), "training_run");
529 m_trainingPause = new KAction(i18n("&Pause Session"), "player_pause", 0,
530 this, SLOT(trainingPause()), actionCollection(), "training_pause");
531 m_trainingContinue->setEnabled(false); // because the training session is running initially
532 // new KAction(i18n("Show S&tatistics"), "frame_chart", 0,
533 // this, SLOT(trainingStatistics()), actionCollection(), "training_stats");
535 // Setup menu entries for the training lectures
536 m_defaultLectureAction = new KSelectAction(i18n("Default &Lectures"), 0, this, 0, actionCollection(), "default_lectures");
537 m_defaultLectureAction->setItems(m_lectureTitles);
538 m_defaultLectureAction->setCurrentItem(0);
539 connect (m_defaultLectureAction, SIGNAL(activated(int)), this, SLOT(changeLecture(int)));
541 // *** Settings menu ***
542 KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
543 // Setup menu entries for keyboard layouts
544 m_keyboardLayoutAction= new KSelectAction(i18n("&Keyboard Layouts"), 0, this, 0, actionCollection(), "keyboard_layouts");
545 m_keyboardLayoutAction->setItems(m_keyboardFiles);
546 connect (m_keyboardLayoutAction, SIGNAL(activated(int)), this, SLOT(changeKeyboard(int)));
548 // Setup menu entries for colour schemes
549 m_keyboardColorAction = new KSelectAction(i18n("Keyboards &Color Schemes"), 0, this, 0, actionCollection(), "keyboard_schemes");
550 QStringList schemes_list;
551 for (unsigned int i=0; i<m_colorSchemes.count(); ++i)
552 schemes_list.append(m_colorSchemes[i].m_name);
553 m_keyboardColorAction->setItems(schemes_list);
554 m_keyboardColorAction->setCurrentItem(Prefs::colorScheme());
555 connect (m_keyboardColorAction, SIGNAL(activated(int)), this, SLOT(changeColor(int)));
558 /// This function updates the font used in the sliding line of a font suggestions was
559 /// made for the current lecture.
560 void KTouch::updateFontFromLecture() {
561 // if the lecture requires a font, try this
562 if (!m_lecture.m_fontSuggestions.isEmpty()) {
563 QFont f;
564 // TODO : if multiple font suggestions are given, try one after another until a
565 // suggested font is found
566 if (f.fromString(m_lecture.m_fontSuggestions)) m_slideLineWidget->setFont(f);
567 else if (f.fromString("Courier 10 Pitch")) m_slideLineWidget->setFont(f);
571 /// This function populates the file lists with the installed training, keyboard and
572 /// examination files.
573 void KTouch::updateFileLists() {
574 KStandardDirs *dirs = KGlobal::dirs();
576 // first search for all installed keyboard files
577 // TODO : search in i18n() directories
578 QStringList keyboardFiles = dirs->findAllResources("data","ktouch/*.keyboard");
579 // TODO : extract titles from keyboard files and store them in the m_keyboardTitles string list
580 m_keyboardFiles = keyboardFiles;
582 // remove the number layout, since this is the necessary default layout and will be
583 // added anyway
584 QStringList::iterator it = m_keyboardFiles.find("number.keyboard");
585 if (it!=m_keyboardFiles.end()) m_keyboardFiles.remove(it);
586 m_keyboardFiles.push_front("number.keyboard");
587 m_keyboardTitles.push_front(i18n("Keypad/Number block"));
589 // Now lets find the lecture files.
590 // TODO : search in i18n() directories
591 QStringList lectureFiles = dirs->findAllResources("data","ktouch/*.ktouch.xml");
592 // Now extract the titles of the lecture files and populate the string lists used in the program
593 m_lectureFiles.clear();
594 m_lectureTitles.clear();
595 if (!lectureFiles.isEmpty()) {
596 // extract the prefixes
597 for (QStringList::iterator it=lectureFiles.begin(); it!=lectureFiles.end(); ++it) {
598 KURL url(*it);
599 KTouchLecture l;
600 // only add lecture if we can actually load it
601 if (l.loadXML(this, url)) {
602 // since we could read the lecture, we remember the URL
603 m_lectureFiles.push_back(*it);
604 // store the title of the lecture
605 if (l.m_title.isEmpty())
606 m_lectureTitles.push_back(i18n("untitled lecture") + " - (" + url.fileName() + ")");
607 else
608 m_lectureTitles.push_back(l.m_title);
613 // Now find predefined files with colour schemes
614 QStringList colour_schemes = dirs->findAllResources("data","ktouch/*.colour_scheme");
615 // TODO : read in colour schemes and populate QValueList<KTouchColorScheme>
618 void KTouch::createDefaultColorSchemes() {
619 KTouchColorScheme color;
621 color.m_name = "Black'n White";
622 color.m_frame = Qt::black;
623 for (int i=0; i<8; ++i)
624 color.m_background[i] = Qt::white;
625 color.m_text = Qt::black;
626 color.m_backgroundH = Qt::black;
627 color.m_textH = Qt::white;
628 color.m_cBackground = Qt::gray;
629 color.m_cText = Qt::black;
630 color.m_cBackgroundH = Qt::white;
631 color.m_cTextH = Qt::black;
632 m_colorSchemes.push_back(color);
634 color.m_name = "Classic";
635 color.m_frame = Qt::black;
636 color.m_background[0] = QColor(255,238, 7); color.m_background[4] = QColor(247,138,247);
637 color.m_background[1] = QColor( 14,164,239); color.m_background[5] = QColor(158,255,155);
638 color.m_background[2] = QColor(158,255,155); color.m_background[6] = QColor( 14,164,239);
639 color.m_background[3] = QColor(252,138,138); color.m_background[7] = QColor(255,238, 7);
640 color.m_text = Qt::black;
641 color.m_backgroundH = Qt::darkBlue;
642 color.m_textH = Qt::white;
643 color.m_cBackground = Qt::gray;
644 color.m_cText = Qt::black;
645 color.m_cBackgroundH = Qt::white;
646 color.m_cTextH = Qt::black;
647 m_colorSchemes.push_back(color);
649 color.m_name = "Deep Blue";
650 color.m_frame = QColor(220,220,220);
651 color.m_background[0] = QColor( 0, 39, 80); color.m_background[4] = QColor( 24, 19, 72);
652 color.m_background[1] = QColor( 39, 59,127); color.m_background[5] = QColor( 8, 44,124);
653 color.m_background[2] = QColor( 4, 39, 53); color.m_background[6] = QColor( 10, 82,158);
654 color.m_background[3] = QColor( 40, 32,121); color.m_background[7] = QColor( 43, 60,124);
655 color.m_text = Qt::white;
656 color.m_backgroundH = QColor(125,180,255);
657 color.m_textH = Qt::darkBlue;
658 color.m_cBackground = Qt::black;
659 color.m_cText = Qt::white;
660 color.m_cBackgroundH = QColor(111,121,73);
661 color.m_cTextH = Qt::white;
662 m_colorSchemes.push_back(color);
664 color.m_name = "Stripy";
665 color.m_frame = Qt::black;
666 for (int i=0; i<8; i=i+2)
667 color.m_background[i] = QColor( 39, 70, 127);
668 for (int i=1; i<8; i=i+2)
669 color.m_background[i] = Qt::darkGray;
670 color.m_text = Qt::black;
671 color.m_backgroundH = QColor( 39, 70, 227);
672 color.m_textH = Qt::white;
673 color.m_cBackground = Qt::gray;
674 color.m_cText = Qt::black;
675 color.m_cBackgroundH = QColor( 39, 70, 227);
676 color.m_cTextH = Qt::black;
677 m_colorSchemes.push_back(color);
680 /// Updates the check mark in the lecture-quick-selection menu depending on the
681 /// lecture in Prefs::currentLectureFile().
682 void KTouch::updateLectureActionCheck() {
683 int num = 0;
684 QStringList::iterator it = m_lectureFiles.begin();
685 QString fname = Prefs::currentLectureFile();
686 while (it != m_lectureFiles.end() && (*it).find(fname) == -1) {
687 ++it;
688 ++num;
690 if (it == m_lectureFiles.end()) m_defaultLectureAction->setCurrentItem(-1);
691 else m_defaultLectureAction->setCurrentItem(num);