summaryrefslogtreecommitdiffstats
path: root/kttsd/libkttsd/selecttalkerdlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kttsd/libkttsd/selecttalkerdlg.cpp')
-rw-r--r--kttsd/libkttsd/selecttalkerdlg.cpp365
1 files changed, 365 insertions, 0 deletions
diff --git a/kttsd/libkttsd/selecttalkerdlg.cpp b/kttsd/libkttsd/selecttalkerdlg.cpp
new file mode 100644
index 0000000..d74339e
--- /dev/null
+++ b/kttsd/libkttsd/selecttalkerdlg.cpp
@@ -0,0 +1,365 @@
+/***************************************************** 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 <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.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.
+
+ 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.
+ ******************************************************************************/
+
+// Qt includes.
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qhbox.h>
+#include <qgroupbox.h>
+
+// KDE includes.
+#include <kcombobox.h>
+#include <ktrader.h>
+#include <kpushbutton.h>
+#include <klistview.h>
+#include <klineedit.h>
+#include <kconfig.h>
+#include <kdebug.h>
+
+// KTTS includes.
+#include "utils.h"
+#include "selecttalkerdlg.h"
+#include "selecttalkerdlg.moc"
+
+SelectTalkerDlg::SelectTalkerDlg(
+ QWidget* parent,
+ const char* name,
+ const QString& caption,
+ const QString& 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( QSize(700,500) );
+ // setInitialSize( QSize(700,600) );
+ setMainWidget( m_widget );
+ m_runningTalkers = runningTalkers;
+ m_talkerCode = TalkerCode( talkerCode, false );
+
+ // Fill combo boxes.
+ KComboBox* cb = m_widget->genderComboBox;
+ cb->insertItem( QString::null );
+ cb->insertItem( TalkerCode::translatedGender("male") );
+ cb->insertItem( TalkerCode::translatedGender("female") );
+ cb->insertItem( TalkerCode::translatedGender("neutral") );
+
+ cb = m_widget->volumeComboBox;
+ cb->insertItem( QString::null );
+ cb->insertItem( TalkerCode::translatedVolume("medium") );
+ cb->insertItem( TalkerCode::translatedVolume("loud") );
+ cb->insertItem( TalkerCode::translatedVolume("soft") );
+
+ cb = m_widget->rateComboBox;
+ cb->insertItem( QString::null );
+ cb->insertItem( TalkerCode::translatedRate("medium") );
+ cb->insertItem( TalkerCode::translatedRate("fast") );
+ cb->insertItem( TalkerCode::translatedRate("slow") );
+
+ cb = m_widget->synthComboBox;
+ cb->insertItem( QString::null );
+ KTrader::OfferList offers = KTrader::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
+ {
+ QString dummy;
+ if (talkerCode == TalkerCode::normalizeTalkerCode(talkerCode, dummy))
+ m_widget->useSpecificTalkerRadioButton->setChecked(true);
+ else
+ m_widget->useClosestMatchRadioButton->setChecked(true);
+ }
+
+ applyTalkerCodeToControls();
+ enableDisableControls();
+
+ connect(m_widget->useDefaultRadioButton, SIGNAL(clicked()),
+ this, SLOT(configChanged()));
+ connect(m_widget->useClosestMatchRadioButton, SIGNAL(clicked()),
+ this, SLOT(configChanged()));
+ connect(m_widget->useSpecificTalkerRadioButton, SIGNAL(clicked()),
+ this, SLOT(configChanged()));
+
+ connect(m_widget->languageBrowseButton, SIGNAL(clicked()),
+ this, SLOT(slotLanguageBrowseButton_clicked()));
+
+ connect(m_widget->synthComboBox, SIGNAL(activated(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->genderComboBox, SIGNAL(activated(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->volumeComboBox, SIGNAL(activated(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->rateComboBox, SIGNAL(activated(const QString&)),
+ this, SLOT(configChanged()));
+
+ connect(m_widget->synthCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(configChanged()));
+ connect(m_widget->genderCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(configChanged()));
+ connect(m_widget->volumeCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(configChanged()));
+ connect(m_widget->rateCheckBox, SIGNAL(toggled(bool)),
+ this, SLOT(configChanged()));
+
+ connect(m_widget->talkersListView, SIGNAL(selectionChanged()),
+ this, SLOT(slotTalkersListView_selectionChanged()));
+
+ m_widget->talkersListView->setMinimumHeight( 120 );
+}
+
+SelectTalkerDlg::~SelectTalkerDlg() { }
+
+QString SelectTalkerDlg::getSelectedTalkerCode()
+{
+ return m_talkerCode.getTalkerCode();
+}
+
+QString SelectTalkerDlg::getSelectedTranslatedDescription()
+{
+ return m_talkerCode.getTranslatedDescription();
+}
+
+void SelectTalkerDlg::slotLanguageBrowseButton_clicked()
+{
+ // Create a QHBox to host KListView.
+ QHBox* hBox = new QHBox(m_widget, "SelectLanguage_hbox");
+ // Create a KListView and fill with all known languages.
+ KListView* langLView = new KListView(hBox, "SelectLanguage_lview");
+ langLView->addColumn(i18n("Language"));
+ langLView->addColumn(i18n("Code"));
+ langLView->setSelectionMode(QListView::Single);
+ QStringList allLocales = KGlobal::locale()->allLanguagesTwoAlpha();
+ QString locale;
+ QString language;
+ // Blank line so user can select no language.
+ // Note: Don't use QString::null, which gets displayed at bottom of list, rather than top.
+ QListViewItem* item = new KListViewItem(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 KListViewItem(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(QSize(300, 500), false);
+ // TODO: This isn't working. Furthermore, item appears selected but is not.
+ langLView->ensureItemVisible(langLView->selectedItem());
+ int dlgResult = dlg->exec();
+ language = QString::null;
+ if (dlgResult == QDialog::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()
+{
+ QListViewItem* 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;
+ QString 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);
+ KListView* lv = m_widget->talkersListView;
+ QListViewItem* 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(QString::null, false);
+ else if ( m_widget->useClosestMatchRadioButton->isChecked() )
+ {
+ // Language already stored in talker code.
+
+ QString 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() )
+ {
+ QListViewItem* 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();
+ KListView* lv = m_widget->talkersListView;
+ lv->clear();
+ QListViewItem* item;
+ KConfig* config = new KConfig("kttsdrc");
+ config->setGroup("General");
+ QStringList talkerIDsList = config->readListEntry("TalkerIDs", ',');
+ if (!talkerIDsList.isEmpty())
+ {
+ QStringList::ConstIterator itEnd(talkerIDsList.constEnd());
+ for( QStringList::ConstIterator it = talkerIDsList.constBegin(); it != itEnd; ++it )
+ {
+ QString talkerID = *it;
+ config->setGroup("Talker_" + talkerID);
+ QString talkerCode = config->readEntry("TalkerCode", QString::null);
+ // Parse and normalize the talker code.
+ TalkerCode talker = TalkerCode(talkerCode, true);
+ m_talkers.append(talker);
+ QString desktopEntryName = config->readEntry("DesktopEntryName", QString::null);
+ QString synthName = TalkerCode::TalkerDesktopEntryNameToName(desktopEntryName);
+ // Display in List View using translated strings.
+ item = new KListViewItem(lv, item);
+ QString fullLanguageCode = talker.fullLanguageCode();
+ QString 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 );
+}