/***************************************************** vim:set ts=4 sw=4 sts=4: Description: A dialog for user to select a Talker, either by specifying selected Talker attributes, or by specifying all attributes of an existing configured Talker. Copyright: (C) 2005 by Gary Cramblitt ------------------- Original author: Gary Cramblitt 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ******************************************************************************/ // TQt includes. #include #include #include #include // KDE includes. #include #include #include #include #include #include #include // KTTS includes. #include "utils.h" #include "selecttalkerdlg.h" #include "selecttalkerdlg.moc" SelectTalkerDlg::SelectTalkerDlg( TQWidget* parent, const char* name, const TQString& caption, const TQString& talkerCode, bool runningTalkers) : KDialogBase( parent, name, true, caption, KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok) { m_widget = new SelectTalkerWidget( this ); // TODO: How do I do this in a general way and still get KDialogBase to properly resize? m_widget->setMinimumSize( TQSize(700,500) ); // setInitialSize( TQSize(700,600) ); setMainWidget( m_widget ); m_runningTalkers = runningTalkers; m_talkerCode = TalkerCode( talkerCode, false ); // Fill combo boxes. KComboBox* cb = m_widget->genderComboBox; cb->insertItem( TQString() ); cb->insertItem( TalkerCode::translatedGender("male") ); cb->insertItem( TalkerCode::translatedGender("female") ); cb->insertItem( TalkerCode::translatedGender("neutral") ); cb = m_widget->volumeComboBox; cb->insertItem( TQString() ); cb->insertItem( TalkerCode::translatedVolume("medium") ); cb->insertItem( TalkerCode::translatedVolume("loud") ); cb->insertItem( TalkerCode::translatedVolume("soft") ); cb = m_widget->rateComboBox; cb->insertItem( TQString() ); cb->insertItem( TalkerCode::translatedRate("medium") ); cb->insertItem( TalkerCode::translatedRate("fast") ); cb->insertItem( TalkerCode::translatedRate("slow") ); cb = m_widget->synthComboBox; cb->insertItem( TQString() ); TDETrader::OfferList offers = TDETrader::self()->query("KTTSD/SynthPlugin"); for(unsigned int i=0; i < offers.count() ; ++i) cb->insertItem(offers[i]->name()); // Fill List View with list of Talkers. m_widget->talkersListView->setSorting( -1 ); loadTalkers( m_runningTalkers ); // Set initial radio button state. if ( talkerCode.isEmpty() ) m_widget->useDefaultRadioButton->setChecked(true); else { TQString dummy; if (talkerCode == TalkerCode::normalizeTalkerCode(talkerCode, dummy)) m_widget->useSpecificTalkerRadioButton->setChecked(true); else m_widget->useClosestMatchRadioButton->setChecked(true); } applyTalkerCodeToControls(); enableDisableControls(); connect(m_widget->useDefaultRadioButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); connect(m_widget->useClosestMatchRadioButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); connect(m_widget->useSpecificTalkerRadioButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(configChanged())); connect(m_widget->languageBrowseButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotLanguageBrowseButton_clicked())); connect(m_widget->synthComboBox, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(configChanged())); connect(m_widget->genderComboBox, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(configChanged())); connect(m_widget->volumeComboBox, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(configChanged())); connect(m_widget->rateComboBox, TQT_SIGNAL(activated(const TQString&)), this, TQT_SLOT(configChanged())); connect(m_widget->synthCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(configChanged())); connect(m_widget->genderCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(configChanged())); connect(m_widget->volumeCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(configChanged())); connect(m_widget->rateCheckBox, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(configChanged())); connect(m_widget->talkersListView, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotTalkersListView_selectionChanged())); m_widget->talkersListView->setMinimumHeight( 120 ); } SelectTalkerDlg::~SelectTalkerDlg() { } TQString SelectTalkerDlg::getSelectedTalkerCode() { return m_talkerCode.getTalkerCode(); } TQString SelectTalkerDlg::getSelectedTranslatedDescription() { return m_talkerCode.getTranslatedDescription(); } void SelectTalkerDlg::slotLanguageBrowseButton_clicked() { // Create a TQHBox to host TDEListView. TQHBox* hBox = new TQHBox(m_widget, "SelectLanguage_hbox"); // Create a TDEListView and fill with all known languages. TDEListView* langLView = new TDEListView(hBox, "SelectLanguage_lview"); langLView->addColumn(i18n("Language")); langLView->addColumn(i18n("Code")); langLView->setSelectionMode(TQListView::Single); TQStringList allLocales = TDEGlobal::locale()->allLanguagesTwoAlpha(); TQString locale; TQString language; // Blank line so user can select no language. // Note: Don't use TQString(), which gets displayed at bottom of list, rather than top. TQListViewItem* item = new TDEListViewItem(langLView, "", ""); if (m_talkerCode.languageCode().isEmpty()) item->setSelected(true); int allLocalesCount = allLocales.count(); for (int ndx=0; ndx < allLocalesCount; ++ndx) { locale = allLocales[ndx]; language = TalkerCode::languageCodeToLanguage(locale); item = new TDEListViewItem(langLView, language, locale); if (m_talkerCode.fullLanguageCode() == locale) item->setSelected(true); } // Sort by language. langLView->setSorting(0); langLView->sort(); // Display the box in a dialog. KDialogBase* dlg = new KDialogBase( KDialogBase::Swallow, i18n("Select Languages"), KDialogBase::Help|KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Cancel, m_widget, "SelectLanguage_dlg", true, true); dlg->setMainWidget(hBox); dlg->setHelp("", "kttsd"); dlg->setInitialSize(TQSize(300, 500), false); // TODO: This isn't working. Furthermore, item appears selected but is not. langLView->ensureItemVisible(langLView->selectedItem()); int dlgResult = dlg->exec(); language = TQString(); if (dlgResult == TQDialog::Accepted) { if (langLView->selectedItem()) { language = langLView->selectedItem()->text(0); m_talkerCode.setFullLanguageCode( langLView->selectedItem()->text(1) ); } } delete dlg; m_widget->languageLineEdit->setText(language); m_widget->languageCheckBox->setChecked( !language.isEmpty() ); configChanged(); } void SelectTalkerDlg::slotTalkersListView_selectionChanged() { TQListViewItem* item = m_widget->talkersListView->selectedItem(); if ( !item ) return; if (!m_widget->useSpecificTalkerRadioButton->isChecked()) return; configChanged(); } void SelectTalkerDlg::configChanged() { applyControlsToTalkerCode(); applyTalkerCodeToControls(); enableDisableControls(); } void SelectTalkerDlg::applyTalkerCodeToControls() { bool preferred = false; TQString code = m_talkerCode.getTalkerCode(); // TODO: Need to display translated Synth names. KttsUtils::setCbItemFromText(m_widget->synthComboBox, TalkerCode::stripPrefer( m_talkerCode.plugInName(), preferred) ); m_widget->synthCheckBox->setEnabled( !m_talkerCode.plugInName().isEmpty() ); m_widget->synthCheckBox->setChecked( preferred ); KttsUtils::setCbItemFromText(m_widget->genderComboBox, TalkerCode::translatedGender( TalkerCode::stripPrefer( m_talkerCode.gender(), preferred ) ) ); m_widget->genderCheckBox->setEnabled( !m_talkerCode.gender().isEmpty() ); m_widget->genderCheckBox->setChecked( preferred ); KttsUtils::setCbItemFromText(m_widget->volumeComboBox, TalkerCode::translatedVolume( TalkerCode::stripPrefer( m_talkerCode.volume(), preferred ) ) ); m_widget->volumeCheckBox->setEnabled( !m_talkerCode.volume().isEmpty() ); m_widget->volumeCheckBox->setChecked( preferred ); KttsUtils::setCbItemFromText(m_widget->rateComboBox, TalkerCode::translatedRate( TalkerCode::stripPrefer( m_talkerCode.rate(), preferred ) ) ); m_widget->rateCheckBox->setEnabled( !m_talkerCode.rate().isEmpty() ); m_widget->rateCheckBox->setChecked( preferred ); // Select closest matching specific Talker. int talkerIndex = TalkerCode::findClosestMatchingTalker(m_talkers, m_talkerCode.getTalkerCode(), false); TDEListView* lv = m_widget->talkersListView; TQListViewItem* item = lv->firstChild(); if ( item ) { while ( talkerIndex > 0 ) { item = item->nextSibling(); --talkerIndex; } lv->setSelected( item, true ); } } void SelectTalkerDlg::applyControlsToTalkerCode() { if ( m_widget->useDefaultRadioButton->isChecked() ) m_talkerCode = TalkerCode(TQString(), false); else if ( m_widget->useClosestMatchRadioButton->isChecked() ) { // Language already stored in talker code. TQString t = m_widget->synthComboBox->currentText(); if ( !t.isEmpty() && m_widget->synthCheckBox->isChecked() ) t.prepend("*"); m_talkerCode.setPlugInName( t ); t = TalkerCode::untranslatedGender( m_widget->genderComboBox->currentText() ); if ( !t.isEmpty() && m_widget->genderCheckBox->isChecked() ) t.prepend("*"); m_talkerCode.setGender( t ); t = TalkerCode::untranslatedVolume( m_widget->volumeComboBox->currentText() ); if ( !t.isEmpty() && m_widget->volumeCheckBox->isChecked() ) t.prepend("*"); m_talkerCode.setVolume( t ); t = TalkerCode::untranslatedRate( m_widget->rateComboBox->currentText() ); if ( !t.isEmpty() && m_widget->rateCheckBox->isChecked() ) t.prepend("*"); m_talkerCode.setRate( t ); } else if (m_widget->useSpecificTalkerRadioButton->isChecked() ) { TQListViewItem* item = m_widget->talkersListView->selectedItem(); if ( item ) { int itemIndex = -1; while ( item ) { item = item->itemAbove(); itemIndex++; } m_talkerCode = TalkerCode( &(m_talkers[itemIndex]), false ); } } } void SelectTalkerDlg::loadTalkers(bool /*runningTalkers*/) { m_talkers.clear(); TDEListView* lv = m_widget->talkersListView; lv->clear(); TQListViewItem* item; TDEConfig* config = new TDEConfig("kttsdrc"); config->setGroup("General"); TQStringList talkerIDsList = config->readListEntry("TalkerIDs", ','); if (!talkerIDsList.isEmpty()) { TQStringList::ConstIterator itEnd(talkerIDsList.constEnd()); for( TQStringList::ConstIterator it = talkerIDsList.constBegin(); it != itEnd; ++it ) { TQString talkerID = *it; config->setGroup("Talker_" + talkerID); TQString talkerCode = config->readEntry("TalkerCode", TQString()); // Parse and normalize the talker code. TalkerCode talker = TalkerCode(talkerCode, true); m_talkers.append(talker); TQString desktopEntryName = config->readEntry("DesktopEntryName", TQString()); TQString synthName = TalkerCode::TalkerDesktopEntryNameToName(desktopEntryName); // Display in List View using translated strings. item = new TDEListViewItem(lv, item); TQString fullLanguageCode = talker.fullLanguageCode(); TQString language = TalkerCode::languageCodeToLanguage(fullLanguageCode); item->setText(tlvcLanguage, language); // Don't update the Synthesizer name with plugInName. The former is a translated // name; the latter an English name. // if (!plugInName.isEmpty()) talkerItem->setText(tlvcSynthName, plugInName); if (!synthName.isEmpty()) item->setText(tlvcSynthName, synthName); if (!talker.voice().isEmpty()) item->setText(tlvcVoice, talker.voice()); if (!talker.gender().isEmpty()) item->setText(tlvcGender, TalkerCode::translatedGender(talker.gender())); if (!talker.volume().isEmpty()) item->setText(tlvcVolume, TalkerCode::translatedVolume(talker.volume())); if (!talker.rate().isEmpty()) item->setText(tlvcRate, TalkerCode::translatedRate(talker.rate())); } } delete config; } void SelectTalkerDlg::enableDisableControls() { bool enableClosest = ( m_widget->useClosestMatchRadioButton->isChecked() ); bool enableSpecific = ( m_widget->useSpecificTalkerRadioButton->isChecked() ); m_widget->closestMatchGroupBox->setEnabled( enableClosest ); m_widget->talkersListView->setEnabled( enableSpecific ); }