/*************************************************************************** * ktouch.cpp * * ---------- * * Copyright (C) 2000 by Håvard Frøiland, 2004 by Andreas Nicolai * * ghorwin@users.sourceforge.net * * * * 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 "ktouch.h" #include "ktouch.moc" // Standard files #include // QT Header #include #include #include #include #include //#include // KDE Header #include #include #include #include #include #include #include #include #include #include #include #include #include // Own header files #include "ktouchlecture.h" #include "ktouchlectureeditor.h" #include "ktouchstatus.h" #include "ktouchslideline.h" #include "ktouchkeyboardwidget.h" #include "ktouchcoloreditor.h" #include "ktouchtrainer.h" #include "ktouchstatistics.h" #include "ktouchprefgenerallayout.h" #include "ktouchpreftraininglayout.h" #include "ktouchprefkeyboardlayout.h" #include "ktouchprefcolorslayout.h" #include "ktouchutils.h" #include "prefs.h" #include "ktouchcolorscheme.h" KTouch * KTouchPtr = NULL; KTouch::KTouch() : KMainWindow( 0, "KTouch" ), m_statusWidget(NULL), m_keyboardWidget(NULL), m_trainer(NULL) { setFocusPolicy(TQ_StrongFocus); setInputMethodEnabled(true); // Set global KTouchPtr to the main KTouch Object KTouchPtr = this; // General initialization of the program, common for all start modes init(); // Setup our actions and connections setupActions(); // create the GUI reading the ui.rc file if (!initialGeometrySet()) resize( TQSize(700, 510).expandedTo(tqminimumSizeHint())); setupGUI(ToolBar | Keys | StatusBar | Create); setAutoSaveSettings(); // Read user statistics KURL stat_file = KGlobal::dirs()->findResource("data", "ktouch/statistics.xml"); //kdDebug() << "[KTouch::KTouch] readings statistics from file '" << stat_file << "'" << endl; if (!m_stats.read(this, stat_file)) m_stats.clear(); // if we can't read it, start with empty statistics // Init a training session initTrainingSession(); // If session was restored, the function readProperties() was already called if (kapp->isRestored()) { kdDebug() << "[KTouch::KTouch] restoring session..." << endl; /// \todo Rewrite all the session management stuff. /// For now we just do the same as for the standard startup. } // else { //kdDebug() << "[KTouch::KTouch] starting standard training..." << endl; // A note about safety: In this function there are a lot of things that might go // wrong. What happens if the training file can't be found? What if the // file cannot be opened or is corrupt? Whatever happens, the function loadXML() // ensures, that there is at least the default mini-level in the lecture // so that the training won't crash. // Load statistics data from statistics-file // Reload the last used training file. if (Prefs::currentLectureFile().isNull() || !m_lecture.loadXML(this, Prefs::currentLectureFile() )) { Prefs::setCurrentLectureFile(TQString()); m_defaultLectureAction->setCurrentItem(-1); } else { updateFontFromLecture(); // adjust check marks in quick-select menus updateLectureActionCheck(); //kdDebug() << "[KTouch::KTouch] lecture file = " << Prefs::currentLectureFile() << endl; } // Adjust check mark for the keyboard file updateKeyboardActionCheck(); // If the user doesn't want to restart with his old level, start from 0 (level 1) if (!Prefs::rememberLevel()) m_trainer->m_level = 0; else m_trainer->m_level = Prefs::currentTrainingLevel(); // now let's start the training in the current level m_trainer->startTraining(true); // } } // ---------------------------------------------------------------------------- // Free memory of objects that are not owned by the main KTouch object KTouch::~KTouch() { delete m_trainer; m_trainer = NULL; } // ---------------------------------------------------------------------------- KTouchLectureStats& KTouch::getCurrentLectureStats() { // kdDebug() << "[KTouch::getCurrentLectureStats] " << endl; KURL lectureURL = Prefs::currentLectureFile(); if (lectureURL.url().isEmpty()) lectureURL = "default"; // kdDebug() << " lectureURL = '" << lectureURL << "'" << endl; KTouchLectureStats& stat = m_stats.m_lectureStats[lectureURL]; // add additional info to the statistics if (stat.m_lectureURL.isEmpty()) stat.m_lectureURL = lectureURL; if (stat.m_lectureTitle.isEmpty()) stat.m_lectureTitle = m_lecture.m_title; return stat; } // ---------------------------------------------------------------------------- void KTouch::clearStatistics() { m_stats.clear(); } // ---------------------------------------------------------------------------- // ******************** // *** Public slots *** // ******************** void KTouch::applyPreferences() { // This applies a new color scheme for the keyboard and also updates all other // changes for the keyboard widget changeColor(Prefs::currentColorScheme()); m_slideLineWidget->applyPreferences(); m_statusWidget->applyPreferences(); } // ---------------------------------------------------------------------------- void KTouch::keyPressEvent(TQKeyEvent *keyEvent) { if (keyEvent->text().isEmpty()) return; // if we the training session is paused, continue training now if (m_trainer->m_trainingPaused) { m_trainingPause->setEnabled(true); m_trainer->continueTraining(); } if (keyEvent->text().length() > 1) { kdDebug() << "[KTouch::keyPressEvent] text = '" << keyEvent->text().ascii() << "'" << endl; } TQChar key = keyEvent->text().at(0); // get first tqunicode character // HACK : manually filter out known dead keys // bool has_dead_key = true; switch (key.tqunicode()) { case 94 : m_lastDeadKey = TQChar(uint(94)); break; case 176 : m_lastDeadKey = TQChar(uint(176)); break; case 180 : m_lastDeadKey = TQChar(uint(180)); break; case 96 : m_lastDeadKey = TQChar(uint(96)); break; case 126 : m_lastDeadKey = TQChar(uint(126)); break; default : m_lastDeadKey = TQChar(uint(0)); } if (m_lastDeadKey != TQChar(uint(0)) && key == m_lastDeadKey) { // kdDebug() << "Got dead key = " << m_lastDeadKey << endl; //keyEvent->accept(); // return; } if (key.isPrint()) m_trainer->keyPressed(key); else if (key==TQChar(8)) m_trainer->backspacePressed(); else if (key==TQChar(13)) m_trainer->enterPressed(); else return; // unrecognised char -> don't accept it! Maybe the key is for somebody else? keyEvent->accept(); } // ---------------------------------------------------------------------------- void KTouch::imEndEvent ( TQIMEvent * e ){ m_trainer->keyPressed(e->text().at(0)); e->accept(); } void KTouch::configOverrideLectureFontToggled(bool on) { if (on) { m_pageGeneral->fontTextLabel->setEnabled(true); m_pageGeneral->kcfg_Font->setEnabled(true); } else { m_pageGeneral->fontTextLabel->setEnabled(false); m_pageGeneral->kcfg_Font->setEnabled(false); } } // ---------------------------------------------------------------------------- void KTouch::configOverrideKeyboardFontToggled(bool on) { if (on) { m_pageKeyboard->textLabel1->setEnabled(true); m_pageKeyboard->kcfg_KeyboardFont->setEnabled(true); } else { m_pageKeyboard->textLabel1->setEnabled(false); m_pageKeyboard->kcfg_KeyboardFont->setEnabled(false); } } // ---------------------------------------------------------------------------- void KTouch::configAutoLevelChangeToggled(bool on) { if (on) { m_pageTraining->l1->setEnabled(true); m_pageTraining->l2->setEnabled(true); m_pageTraining->l3->setEnabled(true); m_pageTraining->l4->setEnabled(true); m_pageTraining->l5->setEnabled(true); m_pageTraining->l6->setEnabled(true); m_pageTraining->l7->setEnabled(true); m_pageTraining->l8->setEnabled(true); m_pageTraining->l9->setEnabled(true); m_pageTraining->l10->setEnabled(true); m_pageTraining->kcfg_UpSpeedLimit->setEnabled(true); m_pageTraining->kcfg_UpCorrectLimit->setEnabled(true); m_pageTraining->kcfg_DownSpeedLimit->setEnabled(true); m_pageTraining->kcfg_DownCorrectLimit->setEnabled(true); m_pageTraining->kcfg_DisableManualLevelChange->setEnabled(true); } else { m_pageTraining->l1->setEnabled(false); m_pageTraining->l2->setEnabled(false); m_pageTraining->l3->setEnabled(false); m_pageTraining->l4->setEnabled(false); m_pageTraining->l5->setEnabled(false); m_pageTraining->l6->setEnabled(false); m_pageTraining->l7->setEnabled(false); m_pageTraining->l8->setEnabled(false); m_pageTraining->l9->setEnabled(false); m_pageTraining->l10->setEnabled(false); m_pageTraining->kcfg_UpSpeedLimit->setEnabled(false); m_pageTraining->kcfg_UpCorrectLimit->setEnabled(false); m_pageTraining->kcfg_DownSpeedLimit->setEnabled(false); m_pageTraining->kcfg_DownCorrectLimit->setEnabled(false); m_pageTraining->kcfg_DisableManualLevelChange->setEnabled(false); } } // ---------------------------------------------------------------------------- void KTouch::configCommonColorsToggled(bool on) { m_pageColors->colorsGroup->setEnabled(on); } // ---------------------------------------------------------------------------- // The action File->Open lecture... void KTouch::fileOpenLecture() { trainingPause(); KURL tmp = KFileDialog::getOpenURL(TQString(), TQString(), this, i18n("Select Training Lecture File") ); if (!tmp.isEmpty()) { // first store training statistics m_trainer->storeTrainingStatistics(); Prefs::setCurrentLectureFile(tmp.url()); m_lecture.loadXML(this, Prefs::currentLectureFile() ); updateFontFromLecture(); // adjust check marks in quick-select menus updateLectureActionCheck(); } // restart training session from level 1 here... m_trainer->startTraining(false); m_trainingPause->setEnabled(true); } // ---------------------------------------------------------------------------- // The action File->Edit lecture... void KTouch::fileEditLecture() { trainingPause(); m_trainer->storeTrainingStatistics(); // Create and execute editor KTouchLectureEditor dlg(this); dlg.startEditor( Prefs::currentLectureFile() ); // Reload lecture in case it was modified m_lecture.loadXML(this, Prefs::currentLectureFile() ); updateFontFromLecture(); // adjust check marks in quick-select menus updateLectureActionCheck(); // restart training session here (keep level)... m_trainer->startTraining(true); m_trainingPause->setEnabled(true); } // ---------------------------------------------------------------------------- // The action File->Edit colors... void KTouch::fileEditColors() { trainingPause(); // Create a copy of the currently editable color schemes. TQValueList tmp_list; int default_schemes = 0; for (TQValueVector::const_iterator it = KTouchColorScheme::m_colorSchemes.constBegin(); it != KTouchColorScheme::m_colorSchemes.constEnd(); ++it) { if (!it->m_default) tmp_list.append(*it); else ++default_schemes; } KTouchColorEditor dlg(this); // Create editor // start editor int selected; dlg.startEditor( tmp_list, Prefs::currentColorScheme() - default_schemes, selected); KTouchColorScheme::createDefaults(); for (TQValueList::const_iterator it = tmp_list.constBegin(); it != tmp_list.constEnd(); ++it) { KTouchColorScheme::m_colorSchemes.append(*it); } // update the quick select menu TQStringList schemes_list; for (unsigned int i=0; isetItems(schemes_list); int index = selected + default_schemes; if (index >=0 && index < static_cast(KTouchColorScheme::m_colorSchemes.count())) { Prefs::setCurrentColorScheme(index); } else { Prefs::setCurrentColorScheme(1); // fall back on default in case active was deleted } m_keyboardColorAction->setCurrentItem(Prefs::currentColorScheme()); applyPreferences(); } // ---------------------------------------------------------------------------- // The action File->Edit keyboard... void KTouch::fileEditKeyboard() { trainingPause(); // Create and execute editor // KTouchKeyboardEditor dlg(this); // dlg.startEditor( Prefs::currentKeyboardFile() ); // Reload lecture in case it was modified //m_keyboard.loadXML(this, Prefs::currentKeyboardFile() ); //updateFontFromLecture(); // adjust check marks in quick-select menus //updateKeyboardActionCheck(); } // ---------------------------------------------------------------------------- void KTouch::fileQuit() { kapp->quit(); } // ---------------------------------------------------------------------------- void KTouch::trainingNewSession() { trainingPause(); int result = KMessageBox::questionYesNoCancel(this, i18n("Would you like to keep the current level for the new training session?"), i18n("Start New Training Session"),i18n("Keep Current Level"),i18n("Do Not Keep")); if (result == KMessageBox::Cancel) return; // store the statistics obtained so far in the trainer object m_trainer->storeTrainingStatistics(); // start new training session here m_trainer->startTraining(result == KMessageBox::Yes); m_trainingPause->setEnabled(true); } // ---------------------------------------------------------------------------- void KTouch::trainingPause() { m_trainingPause->setEnabled(false); m_trainer->pauseTraining(); } // ---------------------------------------------------------------------------- void KTouch::trainingStatistics() { trainingPause(); KTouchStatistics dlg(this); // TODO : this is somewhat messy: we have to get the words in the // current line (since they are not stored in the current // level and session stats, because the student may delete // the whole line again) and add them manually to copies // of the currents stats KTouchSessionStats kss = m_trainer->m_sessionStats; KTouchLevelStats kls = m_trainer->m_levelStats; kss.m_words += m_trainer->wordsInCurrentLine(); kls.m_words += m_trainer->wordsInCurrentLine(); // by calling getCurrentLectureStats we ensure that there is // data for the current lecture present for the dialog to function // properly getCurrentLectureStats(); dlg.run(Prefs::currentLectureFile(), m_stats, kls, kss); } // ---------------------------------------------------------------------------- void KTouch::optionsPreferences() { trainingPause(); if ( KConfigDialog::showDialog( "settings" ) ) return; // KConfigDialog didn't find an instance of this dialog, so lets create it : KConfigDialog* dialog = new KConfigDialog( this, "settings", Prefs::self() ); m_pageGeneral = new KTouchPrefGeneralLayout(0, "General"); dialog->addPage(m_pageGeneral, i18n("General Options"), "style"); m_pageTraining = new KTouchPrefTrainingLayout(0, "Training"); dialog->addPage(m_pageTraining, i18n("Training Options"), "kalarm"); m_pageKeyboard = new KTouchPrefKeyboardLayout(0, "Keyboard"); dialog->addPage(m_pageKeyboard, i18n("Keyboard Settings"), "keyboard_layout"); m_pageColors = new KTouchPrefColorsLayout(0, "Colors"); dialog->addPage(m_pageColors, i18n("Color Settings"), "package_graphics"); connect(dialog, TQT_SIGNAL(settingsChanged()), TQT_TQOBJECT(this), TQT_SLOT(applyPreferences())); // TODO : Connect some other buttons/check boxes of the dialog connect(m_pageGeneral->kcfg_OverrideLectureFont, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(configOverrideLectureFontToggled(bool))); connect(m_pageKeyboard->kcfg_OverrideKeyboardFont, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(configOverrideKeyboardFontToggled(bool))); connect(m_pageTraining->kcfg_AutoLevelChange, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(configAutoLevelChangeToggled(bool))); connect(m_pageColors->kcfg_CommonTypingLineColors, TQT_SIGNAL(toggled(bool)), TQT_TQOBJECT(this), TQT_SLOT(configCommonColorsToggled(bool))); // call the functions to enable/disable controls depending on settings configOverrideLectureFontToggled(Prefs::overrideLectureFont()); configOverrideKeyboardFontToggled(Prefs::overrideKeyboardFont()); configAutoLevelChangeToggled(Prefs::autoLevelChange()); configCommonColorsToggled(Prefs::commonTypingLineColors()); dialog->show(); } // ---------------------------------------------------------------------------- void KTouch::changeStatusbarMessage(const TQString& text) { statusBar()->message(text); } // ---------------------------------------------------------------------------- void KTouch::changeStatusbarStats(unsigned int level_correct, unsigned int level_total, unsigned int level_words, unsigned int session_correct, unsigned int session_total, unsigned int session_words) { statusBar()->changeItem(i18n( "Level: Correct/Total chars: %1/%2 Words: %3") .tqarg(level_correct).tqarg(level_total).tqarg(level_words), 1); statusBar()->changeItem(i18n( "Session: Correct/Total chars: %1/%2 Words: %3") .tqarg(session_correct).tqarg(session_total).tqarg(session_words), 2); } // ---------------------------------------------------------------------------- void KTouch::changeKeyboard(int num) { if (static_cast(num)>=m_keyboardFiles.count()) return; Prefs::setCurrentKeyboardFile( m_keyboardFiles[num] ); // kdDebug() << "[KTouch::changeKeyboard] new keyboard tqlayout = " << Prefs::currentKeyboardFile() << endl; m_keyboardLayoutAction->setCurrentItem(num); // call Apply-Preferenzes in "noisy"-mode, pop up an error if the chosen tqlayout file is corrupt m_keyboardWidget->applyPreferences(this, false); } // ---------------------------------------------------------------------------- void KTouch::changeColor(int num) { if (static_cast(num)>=KTouchColorScheme::m_colorSchemes.count()) return; Prefs::setCurrentColorScheme(num); m_keyboardWidget->applyPreferences(this, false); m_slideLineWidget->applyPreferences(); } // ---------------------------------------------------------------------------- void KTouch::changeLecture(int num) { if (static_cast(num)>=m_lectureFiles.count()) return; trainingPause(); KTouchLecture l; TQString fileName = m_lectureFiles[num]; if (!l.loadXML(this, KURL::fromPathOrURL(fileName))) { KMessageBox::sorry(0, i18n("Could not tqfind/open the lecture file '%1'.").tqarg(fileName) ); m_defaultLectureAction->setCurrentItem(-1); } else { // store the statistics obtained so far in the trainer object m_trainer->storeTrainingStatistics(); // set new lecture as current Prefs::setCurrentLectureFile( fileName ); m_lecture = l; updateFontFromLecture(); m_defaultLectureAction->setCurrentItem(num); // now let's start the training in the first level of the training lecture m_trainer->startTraining(false); m_trainingPause->setEnabled(true); } } // ---------------------------------------------------------------------------- // ********************************* // *** Protected member function *** // ********************************* bool KTouch::queryExit() { // store config data Prefs::setCurrentTrainingLevel( m_trainer->m_level ); Prefs::writeConfig(); // update and save statistics m_trainer->storeTrainingStatistics(); KURL stat_file = KGlobal::dirs()->saveLocation("data","ktouch", true) + "statistics.xml"; //kdDebug() << "[KTouch::queryExit] Writing statistics to file: '" << stat_file << "'" << endl; m_stats.write(this, stat_file); KURL color_file = KGlobal::dirs()->saveLocation("data","ktouch", true) + "color_schemes.xml"; KTouchColorScheme::writeList(this, color_file); return true; } // ---------------------------------------------------------------------------- void KTouch::resizeEvent(TQResizeEvent * event) { changeStatusbarStats(m_trainer->m_levelStats.m_correctChars, m_trainer->m_levelStats.m_totalChars, m_trainer->m_levelStats.m_words, m_trainer->m_sessionStats.m_correctChars, m_trainer->m_sessionStats.m_totalChars, m_trainer->m_sessionStats.m_words); KMainWindow::resizeEvent(event); } // ---------------------------------------------------------------------------- // ******************************* // *** Private member function *** // ******************************* // Will be called when this app is restored due to session management. // This function only stored the temperary data of the last session. All permanent // settings should be handled by the KTouchConfiguration object. void KTouch::readProperties(KConfig *config) { kdDebug() << "[KTouch::readProperties] Reading session data..." << endl; // TODO : Session management rewrite config->setGroup("TrainingState"); /* // The application is about to be restored due to session management. // Let's read all the stuff that was set when the application was terminated (during KDE logout). TQString session = config->readEntry("Session"); if (!session.isEmpty()) m_trainer->m_session = KTouchTrainingSession(session); m_trainer->m_level = config->readNumEntry("Level", 0); m_trainer->m_line = config->readNumEntry("Line", 0); m_currentLectureFile = config->readPathEntry("Lecture"); m_trainer->readSessionHistory(); // read session history (excluding currently active session) // update the trainer object m_trainer->m_teacherText = m_lecture.level(m_trainer->m_level).line(m_trainer->m_line); m_trainer->m_studentText = config->readEntry("StudentText"); m_trainer->continueTraining(); changeStatusbarMessage( i18n("Restarting training session: Waiting for first keypress...") ); // update the slide line widget m_slideLineWidget->setNewText(m_trainer->m_teacherText, m_trainer->m_studentText); // update all the other widgets m_trainer->updateWidgets(); // Read training state config->setGroup("TrainingState"); m_currentLectureURL = config->readPathEntry("LectureURL"); m_trainer->m_level = config->readNumEntry("Level", 0); */ } // ---------------------------------------------------------------------------- // Will be called when the app should save its state for session management purposes. void KTouch::saveProperties(KConfig *config) { kdDebug() << "[KTouch::saveProperties] Saving session data..." << endl; // We are going down because of session management (most likely because of // KDE logout). Let's save the current status so that we can restore it // next logon. // TODO : Session management rewrite /* config->setGroup("TrainingState"); // first write the current lecture URL and the training position config->writePathEntry("Lecture", m_currentLectureURL.url()); config->writeEntry("Level", m_trainer->m_level); config->writeEntry("Line", m_trainer->m_line); config->writeEntry("StudentText", m_trainer->m_studentText); config->writeEntry("Session", m_trainer->m_session.asString() ); // store the session history so far m_trainer->writeSessionHistory(); config->setGroup("TrainingState"); config->writePathEntry("LectureURL", m_currentLectureURL.url()); config->writeEntry("Level", m_trainer->m_level); // during normal shutdown we finish the session and add it to the session history m_trainer->m_sessionHistory.append( m_trainer->m_session ); m_trainer->writeSessionHistory(); */ } // ---------------------------------------------------------------------------- // Initialises the program during a normal startup void KTouch::init() { //kdDebug() << "[KTouch::init] populating file lists..." << endl; updateFileLists(); // create lists with default lecture/keyboard/examination files/colour scheme files //kdDebug() << "[KTouch::init] " << m_lectureFiles.count() << " lectures available" << endl; //kdDebug() << "[KTouch::init] " << m_keyboardFiles.count() << " keyboard tqlayouts available" << endl; //kdDebug() << "[KTouch::init] " << m_examinationFiles.count() << " examination files available" << endl; if (Prefs::currentLectureFile() == "default") { Prefs::setCurrentLectureFile(TQString()); // /// \todo look up a lecture in the language of the KDE locale /* TQString default_lecture = "default"; if (m_lectureFiles.count() > 0) default_lecture = m_lectureFiles[0]; Prefs::setCurrentLectureFile( default_lecture ); */ } // if keyboard tqlayout (loaded by Prefs is not available (e.g. the // tqlayout file has been deleted) switch to default keyboard if (m_keyboardFiles.tqcontains(Prefs::currentKeyboardFile() )==0) { TQString default_keyboard; // determine locale TQString lang = KGlobal::locale()->language(); TQString fname = lang + ".keyboard"; // try to find keyboard with current locale TQStringList::const_iterator it = m_keyboardFiles.constBegin(); while (it != m_keyboardFiles.constEnd() && (*it).tqfind(fname) == -1) ++it; if (it == m_keyboardFiles.constEnd()) { fname = lang.left(2) + ".keyboard"; // try to find more general version it = m_keyboardFiles.constBegin(); while (it != m_keyboardFiles.constEnd() && (*it).tqfind(fname) == -1) ++it; } if (it != m_keyboardFiles.constEnd()) default_keyboard = *it; else default_keyboard = "number.keyboard"; Prefs::setCurrentKeyboardFile ( default_keyboard ); } // create some default colour schemes KTouchColorScheme::createDefaults(); // read additional color schemes KURL color_file = KGlobal::dirs()->findResource("data", "ktouch/color_schemes.xml"); KTouchColorScheme::readList(this, color_file); } // ---------------------------------------------------------------------------- // Creates the tqlayout and GUI setup for a practice session void KTouch::initTrainingSession() { //kdDebug() << "[KTouch::initTrainingSession] setting up tqlayouts and widgets for new training session..." << endl; // Build the training area. The status widget has a fixed vertical size, the slide line and the // keyboard grow according to their vertical stretch factors (see last argument in the constructors // of TQSizePolicy) TQVBox * mainLayout = new TQVBox( this ); m_statusWidget = new KTouchtqStatus( mainLayout ); m_slideLineWidget = new KTouchSlideLine( mainLayout ); m_slideLineWidget->tqsetSizePolicy( TQSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding, 0, 1) ); m_keyboardWidget = new KTouchKeyboardWidget( mainLayout ); m_keyboardWidget->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Expanding, 0, 3) ); setCentralWidget(mainLayout); // apply the settings to the widgets m_slideLineWidget->applyPreferences(); m_keyboardWidget->applyPreferences(this, true); // set preferences silently here // create our trainer, the master object for the training stuff... if (m_trainer != NULL) delete m_trainer; m_trainer = new KTouchTrainer(m_statusWidget, m_slideLineWidget, m_keyboardWidget, &m_lecture); // Setup status bar statusBar()->show(); statusBar()->insertItem("Level", 1, 0, true); statusBar()->insertItem("Session", 2, 0, true); } // ---------------------------------------------------------------------------- // Creates the (standard) actions and entries in the menu. void KTouch::setupActions() { // *** File menu *** new KAction(i18n("&Open lecture..."), "open_lecture", 0, TQT_TQOBJECT(this), TQT_SLOT(fileOpenLecture()), actionCollection(), "file_openlecture"); new KAction(i18n("&Edit lecture..."), "edit_lecture", 0, TQT_TQOBJECT(this), TQT_SLOT(fileEditLecture()), actionCollection(), "file_editlecture"); new KAction(i18n("&Edit color scheme..."), "edit_colors", 0, TQT_TQOBJECT(this), TQT_SLOT(fileEditColors()), actionCollection(), "file_editcolors"); // new KAction(i18n("&Edit Keyboard..."), "edit_keyboard", 0, // TQT_TQOBJECT(this), TQT_SLOT(fileEditKeyboard()), actionCollection(), "file_editkeyboard"); KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(fileQuit()), actionCollection()); // *** Training menu *** new KAction(i18n("&Start New Session"), "launch", 0, TQT_TQOBJECT(this), TQT_SLOT(trainingNewSession()), actionCollection(), "training_newsession"); m_trainingPause = new KAction(i18n("&Pause Session"), "player_pause", 0, TQT_TQOBJECT(this), TQT_SLOT(trainingPause()), actionCollection(), "training_pause"); new KAction(i18n("&Lecture Statistics"), "kalarm", 0, TQT_TQOBJECT(this), TQT_SLOT(trainingStatistics()), actionCollection(), "training_stats"); // Setup menu entries for the training lectures m_defaultLectureAction = new KSelectAction(i18n("Default &Lectures"), 0, TQT_TQOBJECT(this), 0, actionCollection(), "default_lectures"); m_defaultLectureAction->setMenuAccelsEnabled(false); m_defaultLectureAction->setItems(m_lectureTitles); m_defaultLectureAction->setCurrentItem(0); connect (m_defaultLectureAction, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changeLecture(int))); // *** Settings menu *** KStdAction::preferences(TQT_TQOBJECT(this), TQT_SLOT(optionsPreferences()), actionCollection()); // Setup menu entries for keyboard tqlayouts m_keyboardLayoutAction= new KSelectAction(i18n("&Keyboard Layouts"), 0, TQT_TQOBJECT(this), 0, actionCollection(), "keyboard_layouts"); m_keyboardLayoutAction->setMenuAccelsEnabled(false); m_keyboardLayoutAction->setItems(m_keyboardTitles); connect (m_keyboardLayoutAction, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changeKeyboard(int))); // Setup menu entries for colour schemes m_keyboardColorAction = new KSelectAction(i18n("&Color Schemes"), 0, TQT_TQOBJECT(this), 0, actionCollection(), "keyboard_schemes"); TQStringList schemes_list; for (unsigned int i=0; isetMenuAccelsEnabled(false); m_keyboardColorAction->setItems(schemes_list); if (static_cast(Prefs::currentColorScheme()) >= schemes_list.count()) Prefs::setCurrentColorScheme(1); m_keyboardColorAction->setCurrentItem(Prefs::currentColorScheme()); connect (m_keyboardColorAction, TQT_SIGNAL(activated(int)), TQT_TQOBJECT(this), TQT_SLOT(changeColor(int))); } // ---------------------------------------------------------------------------- // This function updates the font used in the sliding line of a font suggestions was // made for the current lecture. void KTouch::updateFontFromLecture() { // if the lecture requires a font, try this if (!m_lecture.m_fontSuggestions.isEmpty()) { TQFont f; // TODO : if multiple font suggestions are given, try one after another until a // suggested font is found if (f.fromString(m_lecture.m_fontSuggestions)) m_slideLineWidget->setFont(f); else if (f.fromString("Monospace")) m_slideLineWidget->setFont(f); } } // ---------------------------------------------------------------------------- // This function populates the file lists with the installed training, keyboard and // examination files. void KTouch::updateFileLists() { KStandardDirs *dirs = KGlobal::dirs(); // first search for all installed keyboard files // TODO : search in i18n() directories m_keyboardFiles = dirs->findAllResources("data","ktouch/*.keyboard"); // remove the number tqlayout, since this is the necessary default tqlayout and will be // added anyway TQStringList::iterator it = m_keyboardFiles.tqfind("number.keyboard"); if (it!=m_keyboardFiles.end()) m_keyboardFiles.remove(it); m_keyboardTitles.clear(); for (TQStringList::const_iterator cit = m_keyboardFiles.constBegin(); cit != m_keyboardFiles.constEnd(); ++cit) { // extract titles from keyboard files and store them in the // m_keyboardTitles string list // get the filename alone TQString fname = KURL(*cit).fileName(); // get the filename without the .keyboard fname.truncate(fname.length() - 9); // get everything in front of the first . TQString lang_iso = fname.section('.',0,0); // get language description of file names TQString lang_name = KGlobal::locale()->twoAlphaToLanguageName(lang_iso); // kdDebug() << fname << " | " << lang_iso << " | " << lang_name << endl; if (lang_name.isEmpty()) lang_name = KGlobal::locale()->twoAlphaToCountryName(lang_iso); if (!lang_name.isEmpty()) lang_name += " (" + fname + ")"; else lang_name = fname; m_keyboardTitles.append( lang_name ); // kdDebug() << m_keyboardTitles.back() << endl; } // now sort the files and titles accordingly sort_lists(m_keyboardTitles, m_keyboardFiles); // and add the number keypad to the front m_keyboardFiles.push_front("number.keyboard"); m_keyboardTitles.push_front(i18n("Keypad/Number block")); // Now lets find the lecture files. // TODO : search in i18n() directories TQStringList lectureFiles = dirs->findAllResources("data","ktouch/*.ktouch.xml"); // Now extract the titles of the lecture files and populate the string lists used in the program m_lectureFiles.clear(); m_lectureTitles.clear(); if (!lectureFiles.isEmpty()) { // extract the prefixes for (TQStringList::iterator it=lectureFiles.begin(); it!=lectureFiles.end(); ++it) { KURL url(*it); KTouchLecture l; // only add lecture if we can actually load it if (l.loadXML(this, url)) { // since we could read the lecture, we remember the URL m_lectureFiles.push_back(*it); // store the title of the lecture if (l.m_title.isEmpty()) m_lectureTitles.push_back(i18n("untitled lecture") + " - (" + url.fileName() + ")"); else m_lectureTitles.push_back(l.m_title); } } sort_lists(m_lectureTitles, m_lectureFiles); } // Now find predefined files with colour schemes TQStringList colour_schemes = dirs->findAllResources("data","ktouch/*.colour_scheme"); // TODO : read in colour schemes and populate TQValueList } // ---------------------------------------------------------------------------- void KTouch::updateLectureActionCheck() { int num = 0; TQStringList::iterator it = m_lectureFiles.begin(); TQString fname = Prefs::currentLectureFile(); while (it != m_lectureFiles.end() && (*it).tqfind(fname) == -1) { ++it; ++num; } if (it == m_lectureFiles.end()) m_defaultLectureAction->setCurrentItem(-1); else m_defaultLectureAction->setCurrentItem(num); } // ---------------------------------------------------------------------------- void KTouch::updateKeyboardActionCheck() { int num = 0; TQStringList::iterator it = m_keyboardFiles.begin(); TQString fname = Prefs::currentKeyboardFile(); while (it != m_keyboardFiles.end() && (*it).tqfind(fname) == -1) { ++it; ++num; } if (it == m_keyboardFiles.end()) m_keyboardLayoutAction->setCurrentItem(-1); else m_keyboardLayoutAction->setCurrentItem(num); } // ---------------------------------------------------------------------------- /* void KTouch::imStartEvent(TQIMEvent *e) { kdDebug() << "[KTouch::imStartEvent] text = '" << e->text() << "'" << endl; e->accept(); } // ---------------------------------------------------------------------------- void KTouch::imComposeEvent(TQIMEvent *e) { kdDebug() << "[KTouch::imComposeEvent] text = '" << e->text() << "'" << endl; e->accept(); } // ---------------------------------------------------------------------------- void KTouch::imEndEvent(TQIMEvent *e) { kdDebug() << "[KTouch::imEndEvent] text = '" << e->text() << "'" << endl; if (!e->text().isEmpty()) { if (e->text() == "^") { TQKeyEvent *ev = new TQKeyEvent (TQEvent::KeyPress, TQt::Key_AsciiCircum, '^', 0, TQString("^")); keyPressEvent(ev); delete ev; } } e->accept(); } // ---------------------------------------------------------------------------- */