mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 02:42:48 +00:00
generic: drop text-to-speech support
Katana (or any interface designed around key and mouse events) is not for blind people, trying to slap text-to-speech on top of it was the wrong thing to do to begin with side note: speech-dispatcher tends to hang if the output device is not configured properly (i.e. editing /etc/speech-dispatcher/speechd.conf manually) Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
c728d46d16
commit
4dbb501d25
26 changed files with 4 additions and 845 deletions
|
@ -299,14 +299,6 @@ set_package_properties(Libmicrohttpd PROPERTIES
|
||||||
PURPOSE "HTTP(S) server"
|
PURPOSE "HTTP(S) server"
|
||||||
)
|
)
|
||||||
|
|
||||||
kde4_optional_find_package(Speechd)
|
|
||||||
set_package_properties(Speechd PROPERTIES
|
|
||||||
DESCRIPTION "Speech Dispatcher provides a high-level device independent layer for speech synthesis"
|
|
||||||
URL "https://freebsoft.org/speechd"
|
|
||||||
TYPE RECOMMENDED
|
|
||||||
PURPOSE "Text-To-Speech"
|
|
||||||
)
|
|
||||||
|
|
||||||
kde4_optional_find_package(LibArchive 3.0.3)
|
kde4_optional_find_package(LibArchive 3.0.3)
|
||||||
set_package_properties(LibArchive PROPERTIES
|
set_package_properties(LibArchive PROPERTIES
|
||||||
DESCRIPTION "Multi-format archive and compression library"
|
DESCRIPTION "Multi-format archive and compression library"
|
||||||
|
|
|
@ -24,7 +24,6 @@ kde4_bool_to_01(EXIV2_FOUND HAVE_EXIV2) # kexiv2
|
||||||
kde4_bool_to_01(LIBMICROHTTPD_FOUND HAVE_LIBMICROHTTPD) # khttp
|
kde4_bool_to_01(LIBMICROHTTPD_FOUND HAVE_LIBMICROHTTPD) # khttp
|
||||||
kde4_bool_to_01(MPV_FOUND HAVE_MPV) # kmediaplayer
|
kde4_bool_to_01(MPV_FOUND HAVE_MPV) # kmediaplayer
|
||||||
kde4_bool_to_01(OPENSSL_FOUND HAVE_OPENSSL) # kpasswdstore
|
kde4_bool_to_01(OPENSSL_FOUND HAVE_OPENSSL) # kpasswdstore
|
||||||
kde4_bool_to_01(SPEECHD_FOUND HAVE_SPEECHD) # kspeech
|
|
||||||
kde4_bool_to_01(ACL_FOUND HAVE_POSIX_ACL) # kio
|
kde4_bool_to_01(ACL_FOUND HAVE_POSIX_ACL) # kio
|
||||||
|
|
||||||
check_include_files(fstab.h HAVE_FSTAB_H) # kio, kdecore
|
check_include_files(fstab.h HAVE_FSTAB_H) # kio, kdecore
|
||||||
|
|
|
@ -14,7 +14,6 @@ set(cmakeFilesDontInstall
|
||||||
FindLibCDIO.cmake
|
FindLibCDIO.cmake
|
||||||
FindDevinfo.cmake
|
FindDevinfo.cmake
|
||||||
FindFFmpeg.cmake
|
FindFFmpeg.cmake
|
||||||
FindSpeechd.cmake
|
|
||||||
FindLibRaw.cmake
|
FindLibRaw.cmake
|
||||||
FindLibJPEG.cmake
|
FindLibJPEG.cmake
|
||||||
FindOpenJPEG.cmake
|
FindOpenJPEG.cmake
|
||||||
|
|
|
@ -62,8 +62,7 @@
|
||||||
# KDE4_KPOWERMANAGER_LIBS - the kpowermanager library and all depending libraries
|
# KDE4_KPOWERMANAGER_LIBS - the kpowermanager library and all depending libraries
|
||||||
# KDE4_KDNSSD_LIBS - the kdnssd library and all depending libraries
|
# KDE4_KDNSSD_LIBS - the kdnssd library and all depending libraries
|
||||||
# KDE4_KHTTP_LIBS - the khttp library and all depending libraries
|
# KDE4_KHTTP_LIBS - the khttp library and all depending libraries
|
||||||
# KDE4_KSPEECH_LIBS - the kspeech library and all depending libraries
|
# KDE4_KARCHIVE_LIBS - the karchive library and all depending libraries
|
||||||
# KDE4_KARCHIVE_LIBS - the kspeech library and all depending libraries
|
|
||||||
#
|
#
|
||||||
# The variable INSTALL_TARGETS_DEFAULT_ARGS can be used when installing libraries
|
# The variable INSTALL_TARGETS_DEFAULT_ARGS can be used when installing libraries
|
||||||
# or executables into the default locations.
|
# or executables into the default locations.
|
||||||
|
@ -243,7 +242,6 @@ set(_kde_libraries
|
||||||
kpowermanager
|
kpowermanager
|
||||||
kdnssd
|
kdnssd
|
||||||
khttp
|
khttp
|
||||||
kspeech
|
|
||||||
karchive
|
karchive
|
||||||
kemail
|
kemail
|
||||||
kfile
|
kfile
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Try to find speech-dispatcher, once done this will define:
|
|
||||||
#
|
|
||||||
# SPEECHD_FOUND - system has speech-dispatcher
|
|
||||||
# SPEECHD_INCLUDE_DIR - the speech-dispatcher include directory
|
|
||||||
# SPEECHD_LIBRARIES - the libraries needed to use speech-dispatcher
|
|
||||||
#
|
|
||||||
# Copyright (c) 2020 Ivailo Monev <xakepa10@gmail.com>
|
|
||||||
#
|
|
||||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
|
||||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
|
||||||
pkg_check_modules(PC_SPEECHD QUIET speech-dispatcher)
|
|
||||||
|
|
||||||
set(SPEECHD_INCLUDE_DIR ${PC_SPEECHD_INCLUDE_DIRS})
|
|
||||||
set(SPEECHD_LIBRARIES ${PC_SPEECHD_LIBRARIES})
|
|
||||||
set(SPEECHD_VERSION ${PC_SPEECHD_VERSION})
|
|
||||||
|
|
||||||
if(NOT SPEECHD_INCLUDE_DIR OR NOT SPEECHD_LIBRARIES)
|
|
||||||
find_path(SPEECHD_INCLUDE_DIR
|
|
||||||
NAMES libspeechd.h
|
|
||||||
PATH_SUFFIXES speech-dispatcher
|
|
||||||
HINTS $ENV{SPEECHDDIR}/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(SPEECHD_LIBRARIES
|
|
||||||
NAMES speechd
|
|
||||||
HINTS $ENV{SPEECHDDIR}/lib
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(Speechd
|
|
||||||
VERSION_VAR SPEECHD_VERSION
|
|
||||||
REQUIRED_VARS SPEECHD_INCLUDE_DIR SPEECHD_LIBRARIES
|
|
||||||
)
|
|
||||||
|
|
||||||
mark_as_advanced(SPEECHD_INCLUDE_DIR SPEECHD_LIBRARIES)
|
|
|
@ -65,9 +65,6 @@
|
||||||
/* Define to 1 if you have OpenSSL */
|
/* Define to 1 if you have OpenSSL */
|
||||||
#cmakedefine HAVE_OPENSSL 1
|
#cmakedefine HAVE_OPENSSL 1
|
||||||
|
|
||||||
/* Define to 1 if you have Speech Dispatcher */
|
|
||||||
#cmakedefine HAVE_SPEECHD 1
|
|
||||||
|
|
||||||
/* Define to 1 if getmntinfo() uses statvfs struct */
|
/* Define to 1 if getmntinfo() uses statvfs struct */
|
||||||
#cmakedefine GETMNTINFO_USES_STATVFS 1
|
#cmakedefine GETMNTINFO_USES_STATVFS 1
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,6 @@ install(
|
||||||
KShortcutWidget
|
KShortcutWidget
|
||||||
KSortableItem
|
KSortableItem
|
||||||
KSortableList
|
KSortableList
|
||||||
KSpeech
|
|
||||||
KSplashScreen
|
KSplashScreen
|
||||||
KSqueezedTextLabel
|
KSqueezedTextLabel
|
||||||
KStandardDirs
|
KStandardDirs
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#include "../kspeech.h"
|
|
|
@ -70,7 +70,6 @@
|
||||||
51005 kpowermanager
|
51005 kpowermanager
|
||||||
51006 kdnssd
|
51006 kdnssd
|
||||||
51007 khttp
|
51007 khttp
|
||||||
51008 kspeech
|
|
||||||
51009 karchive
|
51009 karchive
|
||||||
51010 kemail
|
51010 kemail
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ include_directories(
|
||||||
${CMAKE_SOURCE_DIR}/interfaces/kregexpeditor
|
${CMAKE_SOURCE_DIR}/interfaces/kregexpeditor
|
||||||
${CMAKE_SOURCE_DIR}/kdecore/sonnet
|
${CMAKE_SOURCE_DIR}/kdecore/sonnet
|
||||||
${CMAKE_SOURCE_DIR}/kdeui
|
${CMAKE_SOURCE_DIR}/kdeui
|
||||||
${CMAKE_SOURCE_DIR}/kutils/kspeech
|
|
||||||
${CMAKE_BINARY_DIR}/kutils/kspeech
|
|
||||||
${KDE4_KDECORE_INCLUDES}
|
${KDE4_KDECORE_INCLUDES}
|
||||||
actions
|
actions
|
||||||
colors
|
colors
|
||||||
|
@ -335,7 +333,6 @@ target_link_libraries(kdeui PRIVATE
|
||||||
|
|
||||||
target_link_libraries(kdeui PUBLIC
|
target_link_libraries(kdeui PUBLIC
|
||||||
${KDE4_KDECORE_LIBS}
|
${KDE4_KDECORE_LIBS}
|
||||||
${KDE4_KSPEECH_LIBS}
|
|
||||||
${QT_QTGUI_LIBRARY}
|
${QT_QTGUI_LIBRARY}
|
||||||
${QT_QTXML_LIBRARY}
|
${QT_QTXML_LIBRARY}
|
||||||
${QT_QTNETWORK_LIBRARY}
|
${QT_QTNETWORK_LIBRARY}
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
* Action is the string representing the action. Actions can be added to
|
* Action is the string representing the action. Actions can be added to
|
||||||
* the KNotify daemon as plugins, by deriving from KNotifyPlugin.
|
* the KNotify daemon as plugins, by deriving from KNotifyPlugin.
|
||||||
* At the time of writing, the following actions are available: Taskbar,
|
* At the time of writing, the following actions are available: Taskbar,
|
||||||
* Sound, Popup, Logfile, KTTS, Execute.
|
* Sound, Popup, Logfile, Execute.
|
||||||
* Actions can be combined by seperating them with '|'.
|
* Actions can be combined by seperating them with '|'.
|
||||||
*
|
*
|
||||||
* Contexts is a comma separated list of possible context for this event.
|
* Contexts is a comma separated list of possible context for this event.
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include <dialog.h>
|
#include <dialog.h>
|
||||||
#include "backgroundchecker.h"
|
#include "backgroundchecker.h"
|
||||||
#include <kdebug.h>
|
#include <kdebug.h>
|
||||||
#include <kspeech.h>
|
|
||||||
#include <kaction.h>
|
#include <kaction.h>
|
||||||
#include <kcursor.h>
|
#include <kcursor.h>
|
||||||
#include <kglobalsettings.h>
|
#include <kglobalsettings.h>
|
||||||
|
@ -573,27 +572,9 @@ QMenu *KTextEdit::mousePopupMenu()
|
||||||
popup->addAction(replaceAction);
|
popup->addAction(replaceAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (KSpeech::isSupported()) {
|
|
||||||
popup->addSeparator();
|
|
||||||
QAction *speakAction = popup->addAction(i18n("Speak Text"));
|
|
||||||
speakAction->setIcon(KIcon("preferences-desktop-text-to-speech"));
|
|
||||||
speakAction->setEnabled(!emptyDocument );
|
|
||||||
connect( speakAction, SIGNAL(triggered(bool)), this, SLOT(slotSpeakText()) );
|
|
||||||
}
|
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KTextEdit::slotSpeakText()
|
|
||||||
{
|
|
||||||
QString text;
|
|
||||||
if(textCursor().hasSelection())
|
|
||||||
text = textCursor().selectedText();
|
|
||||||
else
|
|
||||||
text = toPlainText();
|
|
||||||
KSpeech kspeech(this);
|
|
||||||
kspeech.say(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KTextEdit::contextMenuEvent(QContextMenuEvent *event)
|
void KTextEdit::contextMenuEvent(QContextMenuEvent *event)
|
||||||
{
|
{
|
||||||
// Obtain the cursor at the mouse position and the current cursor
|
// Obtain the cursor at the mouse position and the current cursor
|
||||||
|
|
|
@ -326,10 +326,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
|
||||||
void slotFind();
|
void slotFind();
|
||||||
void slotFindNext();
|
void slotFindNext();
|
||||||
void slotReplace();
|
void slotReplace();
|
||||||
/**
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
void slotSpeakText();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,8 +4,6 @@ include_directories(
|
||||||
${KDE4_KIO_INCLUDES}
|
${KDE4_KIO_INCLUDES}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/kutils/kspeech
|
|
||||||
${CMAKE_BINARY_DIR}/kutils/kspeech
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_TESTING)
|
if(ENABLE_TESTING)
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
#include <kstandarddirs.h>
|
#include <kstandarddirs.h>
|
||||||
#include <kiconloader.h>
|
#include <kiconloader.h>
|
||||||
#include <kspeech.h>
|
|
||||||
|
|
||||||
KNotifyConfigActionsWidget::KNotifyConfigActionsWidget( QWidget * parent )
|
KNotifyConfigActionsWidget::KNotifyConfigActionsWidget( QWidget * parent )
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
@ -40,26 +39,16 @@ KNotifyConfigActionsWidget::KNotifyConfigActionsWidget( QWidget * parent )
|
||||||
m_ui.Logfile_check->setIcon(KIcon("text-x-generic"));
|
m_ui.Logfile_check->setIcon(KIcon("text-x-generic"));
|
||||||
m_ui.Execute_check->setIcon(KIcon("system-run"));
|
m_ui.Execute_check->setIcon(KIcon("system-run"));
|
||||||
m_ui.Taskbar_check->setIcon(KIcon("services"));
|
m_ui.Taskbar_check->setIcon(KIcon("services"));
|
||||||
m_ui.KTTS_check->setIcon(KIcon("text-speak"));
|
|
||||||
|
|
||||||
connect(m_ui.Execute_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
connect(m_ui.Execute_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Sound_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
connect(m_ui.Sound_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Popup_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
connect(m_ui.Popup_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Logfile_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
connect(m_ui.Logfile_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Taskbar_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
connect(m_ui.Taskbar_check,SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.KTTS_check,SIGNAL(toggled(bool)), this, SLOT(slotKTTSComboChanged()));
|
|
||||||
connect(m_ui.Execute_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
connect(m_ui.Execute_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Sound_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
connect(m_ui.Sound_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Logfile_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
connect(m_ui.Logfile_select,SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
|
||||||
connect(m_ui.Sound_play,SIGNAL(clicked()), this, SLOT(slotPlay()));
|
connect(m_ui.Sound_play,SIGNAL(clicked()), this, SLOT(slotPlay()));
|
||||||
connect(m_ui.KTTS_combo,SIGNAL(currentIndexChanged(int)), this, SLOT(slotKTTSComboChanged()));
|
|
||||||
m_ui.KTTS_combo->setEnabled(false);
|
|
||||||
if(!KNotifyConfigElement::have_kttsd())
|
|
||||||
{
|
|
||||||
m_ui.KTTS_check->setVisible(false);
|
|
||||||
m_ui.KTTS_select->setVisible(false);
|
|
||||||
m_ui.KTTS_combo->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,18 +67,10 @@ void KNotifyConfigActionsWidget::setConfigElement( KNotifyConfigElement * config
|
||||||
m_ui.Logfile_check->setChecked( actions.contains("Logfile") );
|
m_ui.Logfile_check->setChecked( actions.contains("Logfile") );
|
||||||
m_ui.Execute_check->setChecked( actions.contains("Execute") );
|
m_ui.Execute_check->setChecked( actions.contains("Execute") );
|
||||||
m_ui.Taskbar_check->setChecked( actions.contains("Taskbar") );
|
m_ui.Taskbar_check->setChecked( actions.contains("Taskbar") );
|
||||||
m_ui.KTTS_check->setChecked( actions.contains("KTTS") );
|
|
||||||
|
|
||||||
m_ui.Sound_select->setUrl( KUrl( config->readEntry( "Sound" , true ) ) );
|
m_ui.Sound_select->setUrl( KUrl( config->readEntry( "Sound" , true ) ) );
|
||||||
m_ui.Logfile_select->setUrl( KUrl( config->readEntry( "Logfile" , true ) ) );
|
m_ui.Logfile_select->setUrl( KUrl( config->readEntry( "Logfile" , true ) ) );
|
||||||
m_ui.Execute_select->setUrl( KUrl( config->readEntry( "Execute" ) ) );
|
m_ui.Execute_select->setUrl( KUrl( config->readEntry( "Execute" ) ) );
|
||||||
m_ui.KTTS_select->setText( config->readEntry( "KTTS" ) );
|
|
||||||
if(m_ui.KTTS_select->text() == QLatin1String("%e"))
|
|
||||||
m_ui.KTTS_combo->setCurrentIndex(1);
|
|
||||||
else if(m_ui.KTTS_select->text() == QLatin1String("%m") || m_ui.KTTS_select->text() == QLatin1String("%s"))
|
|
||||||
m_ui.KTTS_combo->setCurrentIndex(0);
|
|
||||||
else
|
|
||||||
m_ui.KTTS_combo->setCurrentIndex(2);
|
|
||||||
blockSignals(blocked);
|
blockSignals(blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,26 +87,12 @@ void KNotifyConfigActionsWidget::save( KNotifyConfigElement * config )
|
||||||
actions << "Execute";
|
actions << "Execute";
|
||||||
if(m_ui.Taskbar_check->isChecked())
|
if(m_ui.Taskbar_check->isChecked())
|
||||||
actions << "Taskbar";
|
actions << "Taskbar";
|
||||||
if(m_ui.KTTS_check->isChecked())
|
|
||||||
actions << "KTTS";
|
|
||||||
|
|
||||||
config->writeEntry( "Action" , actions.join("|") );
|
config->writeEntry( "Action" , actions.join("|") );
|
||||||
|
|
||||||
config->writeEntry( "Sound" , m_ui.Sound_select->url().url() );
|
config->writeEntry( "Sound" , m_ui.Sound_select->url().url() );
|
||||||
config->writeEntry( "Logfile" , m_ui.Logfile_select->url().url() );
|
config->writeEntry( "Logfile" , m_ui.Logfile_select->url().url() );
|
||||||
config->writeEntry( "Execute" , m_ui.Execute_select->url().path() );
|
config->writeEntry( "Execute" , m_ui.Execute_select->url().path() );
|
||||||
switch(m_ui.KTTS_combo->currentIndex())
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
config->writeEntry( "KTTS" , "%s" );
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
config->writeEntry( "KTTS" , "%e" );
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
default:
|
|
||||||
config->writeEntry( "KTTS" , m_ui.KTTS_select->text() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KNotifyConfigActionsWidget::slotPlay( )
|
void KNotifyConfigActionsWidget::slotPlay( )
|
||||||
|
@ -145,10 +112,4 @@ void KNotifyConfigActionsWidget::slotPlay( )
|
||||||
kaudioplayer.call("play", soundURL.prettyUrl(), QString::fromLatin1("knotify"));
|
kaudioplayer.call("play", soundURL.prettyUrl(), QString::fromLatin1("knotify"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KNotifyConfigActionsWidget::slotKTTSComboChanged()
|
|
||||||
{
|
|
||||||
m_ui.KTTS_select->setEnabled(m_ui.KTTS_check->isChecked() && m_ui.KTTS_combo->currentIndex() == 2);
|
|
||||||
emit changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_knotifyconfigactionswidget.cpp"
|
#include "moc_knotifyconfigactionswidget.cpp"
|
||||||
|
|
|
@ -44,7 +44,6 @@ class KNotifyConfigActionsWidget : public QWidget
|
||||||
void changed();
|
void changed();
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void slotPlay();
|
void slotPlay();
|
||||||
void slotKTTSComboChanged();
|
|
||||||
private:
|
private:
|
||||||
Ui::KNotifyConfigActionsWidgetBase m_ui;
|
Ui::KNotifyConfigActionsWidgetBase m_ui;
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,48 +100,6 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" >
|
|
||||||
<widget class="QCheckBox" name="KTTS_check" >
|
|
||||||
<property name="text" >
|
|
||||||
<string>Sp&eech</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1" colspan="2" >
|
|
||||||
<widget class="KComboBox" name="KTTS_combo" >
|
|
||||||
<property name="sizePolicy" >
|
|
||||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="whatsThis" >
|
|
||||||
<string><qt>Specifies how Text-To-Speech should speak the event when received. If you select "Speak custom text", enter the text in the box. You may use the following substitution strings in the text:<dl><dt>%e</dt><dd>Name of the event</dd><dt>%a</dt><dd>Application that sent the event</dd><dt>%m</dt><dd>The message sent by the application</dd></dl></qt></string>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text" >
|
|
||||||
<string>Speak Event Message</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text" >
|
|
||||||
<string>Speak Event Name</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text" >
|
|
||||||
<string>Speak Custom Text</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="3" >
|
|
||||||
<widget class="KLineEdit" name="KTTS_select" >
|
|
||||||
<property name="whatsThis" >
|
|
||||||
<string><qt>Specifies how Text-To-Speech should speak the event when received. If you select "Speak custom text", enter the text in the box. You may use the following substitution strings in the text:<dl><dt>%e</dt><dd>Name of the event</dd><dt>%a</dt><dd>Application that sent the event</dd><dt>%m</dt><dd>The message sent by the application</dd></dl></qt></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -222,21 +180,5 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
<connection>
|
|
||||||
<sender>KTTS_check</sender>
|
|
||||||
<signal>toggled(bool)</signal>
|
|
||||||
<receiver>KTTS_combo</receiver>
|
|
||||||
<slot>setEnabled(bool)</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel" >
|
|
||||||
<x>48</x>
|
|
||||||
<y>169</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel" >
|
|
||||||
<x>131</x>
|
|
||||||
<y>169</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include <kdebug.h>
|
#include <kdebug.h>
|
||||||
#include <kstandarddirs.h>
|
#include <kstandarddirs.h>
|
||||||
#include <kservice.h>
|
#include <kservice.h>
|
||||||
#include <kspeech.h>
|
|
||||||
|
|
||||||
KNotifyConfigElement::KNotifyConfigElement(const QString &eventid, KConfig *config)
|
KNotifyConfigElement::KNotifyConfigElement(const QString &eventid, KConfig *config)
|
||||||
: m_config( new KConfigGroup(config , "Event/" + eventid) )
|
: m_config( new KConfigGroup(config , "Event/" + eventid) )
|
||||||
|
@ -60,9 +59,3 @@ void KNotifyConfigElement::save( )
|
||||||
}
|
}
|
||||||
m_config->sync();
|
m_config->sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool KNotifyConfigElement::have_kttsd() //[static]
|
|
||||||
{
|
|
||||||
return KSpeech::isSupported();
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,11 +41,6 @@ class KNotifyConfigElement
|
||||||
|
|
||||||
void save();
|
void save();
|
||||||
|
|
||||||
/**
|
|
||||||
* return wither kttsd is installed or not.
|
|
||||||
*/
|
|
||||||
static bool have_kttsd();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString,QString> m_cache;
|
QMap<QString,QString> m_cache;
|
||||||
KConfigGroup* m_config;
|
KConfigGroup* m_config;
|
||||||
|
|
|
@ -69,8 +69,6 @@ void KNotifyEventList::KNotifyEventListDelegate::paint( QPainter* painter,
|
||||||
iconList << ( optionsList.contains("Logfile") ? KIcon("text-x-generic") : KIcon() );
|
iconList << ( optionsList.contains("Logfile") ? KIcon("text-x-generic") : KIcon() );
|
||||||
iconList << ( optionsList.contains("Taskbar") ? KIcon("services") : KIcon() );
|
iconList << ( optionsList.contains("Taskbar") ? KIcon("services") : KIcon() );
|
||||||
iconList << ( optionsList.contains("Execute") ? KIcon("system-run") : KIcon() );
|
iconList << ( optionsList.contains("Execute") ? KIcon("system-run") : KIcon() );
|
||||||
if( KNotifyConfigElement::have_kttsd() )
|
|
||||||
iconList << ( optionsList.contains("KTTS") ? KIcon("text-speak") : KIcon() );
|
|
||||||
|
|
||||||
int mc_x=0;
|
int mc_x=0;
|
||||||
|
|
||||||
|
@ -103,7 +101,7 @@ KNotifyEventList::KNotifyEventList(QWidget *parent)
|
||||||
setIconSize( QSize(iconWidth, iconWidth) );
|
setIconSize( QSize(iconWidth, iconWidth) );
|
||||||
|
|
||||||
header()->setResizeMode( 0, QHeaderView::Fixed );
|
header()->setResizeMode( 0, QHeaderView::Fixed );
|
||||||
header()->resizeSection( 0, KNotifyConfigElement::have_kttsd() ? (iconWidth+4)*6: (iconWidth+4)*5 );
|
header()->resizeSection( 0, (iconWidth + 4) * 5 );
|
||||||
header()->setResizeMode( 1, QHeaderView::ResizeToContents );
|
header()->setResizeMode( 1, QHeaderView::ResizeToContents );
|
||||||
|
|
||||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)) , this , SLOT(slotSelectionChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
|
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)) , this , SLOT(slotSelectionChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
|
||||||
|
|
|
@ -13,7 +13,6 @@ add_subdirectory(kpasswdstore)
|
||||||
add_subdirectory(kpowermanager)
|
add_subdirectory(kpowermanager)
|
||||||
add_subdirectory(kdnssd)
|
add_subdirectory(kdnssd)
|
||||||
add_subdirectory(khttp)
|
add_subdirectory(khttp)
|
||||||
add_subdirectory(kspeech)
|
|
||||||
add_subdirectory(karchive)
|
add_subdirectory(karchive)
|
||||||
add_subdirectory(kemail)
|
add_subdirectory(kemail)
|
||||||
|
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
if(SPEECHD_FOUND)
|
|
||||||
include_directories(${SPEECHD_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=51008)
|
|
||||||
|
|
||||||
set(kspeech_LIB_SRCS
|
|
||||||
kspeech.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(kspeech ${LIBRARY_TYPE} ${kspeech_LIB_SRCS})
|
|
||||||
|
|
||||||
target_link_libraries(kspeech PUBLIC
|
|
||||||
${KDE4_KDECORE_LIBS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(SPEECHD_FOUND)
|
|
||||||
target_link_libraries(kspeech PRIVATE ${SPEECHD_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(kspeech PROPERTIES
|
|
||||||
VERSION ${GENERIC_LIB_VERSION}
|
|
||||||
SOVERSION ${GENERIC_LIB_SOVERSION}
|
|
||||||
)
|
|
||||||
|
|
||||||
generate_export_header(kspeech)
|
|
||||||
|
|
||||||
install(
|
|
||||||
FILES
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/kspeech_export.h
|
|
||||||
kspeech.h
|
|
||||||
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}
|
|
||||||
COMPONENT Devel
|
|
||||||
)
|
|
||||||
|
|
||||||
install(
|
|
||||||
TARGETS kspeech
|
|
||||||
EXPORT kdelibsLibraryTargets
|
|
||||||
${INSTALL_TARGETS_DEFAULT_ARGS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(ENABLE_TESTING)
|
|
||||||
add_subdirectory(tests)
|
|
||||||
endif()
|
|
|
@ -1,411 +0,0 @@
|
||||||
/* This file is part of the KDE libraries
|
|
||||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License version 2, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This library 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
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "kspeech.h"
|
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <kdebug.h>
|
|
||||||
#include <kconfig.h>
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
# include <speech-dispatcher/libspeechd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef QMap<int, KSpeechPrivate*> KSpeechMap;
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(QMutex, globalKSpeechInstancesMutex)
|
|
||||||
Q_GLOBAL_STATIC(KSpeechMap, globalKSpeechInstances)
|
|
||||||
|
|
||||||
// NOTE: the callback function is not called in the same thread as the object that opens the
|
|
||||||
// connection
|
|
||||||
class KSpeechPrivate : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
KSpeechPrivate(QObject *parent);
|
|
||||||
~KSpeechPrivate();
|
|
||||||
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
void openSpeechD();
|
|
||||||
void closeSpeechD();
|
|
||||||
static void speechCallback(size_t msg_id, size_t client_id, SPDNotificationType state);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void signalJobStateChanged(int jobNum, int state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend KSpeech;
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
SPDConnection* m_speechd;
|
|
||||||
int m_speechdid;
|
|
||||||
QByteArray m_voice;
|
|
||||||
#endif
|
|
||||||
QByteArray m_speechid;
|
|
||||||
};
|
|
||||||
|
|
||||||
KSpeechPrivate::KSpeechPrivate(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
, m_speechd(nullptr),
|
|
||||||
m_speechdid(0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
m_speechid = QCoreApplication::applicationName().toLocal8Bit();
|
|
||||||
}
|
|
||||||
|
|
||||||
KSpeechPrivate::~KSpeechPrivate()
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
Q_ASSERT(!m_speechd);
|
|
||||||
Q_ASSERT(m_speechdid == 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
void KSpeechPrivate::openSpeechD()
|
|
||||||
{
|
|
||||||
Q_ASSERT(!m_speechd);
|
|
||||||
m_speechd = spd_open(m_speechid.constData(), "main", NULL, SPD_MODE_THREADED);
|
|
||||||
if (Q_UNLIKELY(!m_speechd)) {
|
|
||||||
kWarning() << "Could not open speech-dispatcher connection";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_speechdid = spd_get_client_id(m_speechd);
|
|
||||||
{
|
|
||||||
QMutexLocker locker(globalKSpeechInstancesMutex());
|
|
||||||
globalKSpeechInstances()->insert(m_speechdid, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_speechd->callback_begin = KSpeechPrivate::speechCallback;
|
|
||||||
m_speechd->callback_end = KSpeechPrivate::speechCallback;
|
|
||||||
m_speechd->callback_cancel = KSpeechPrivate::speechCallback;
|
|
||||||
|
|
||||||
spd_set_notification_on(m_speechd, SPD_BEGIN);
|
|
||||||
spd_set_notification_on(m_speechd, SPD_END);
|
|
||||||
spd_set_notification_on(m_speechd, SPD_CANCEL);
|
|
||||||
|
|
||||||
KConfig kconfig("kspeechrc", KConfig::SimpleConfig);
|
|
||||||
KConfigGroup kconfiggroup = kconfig.group(m_speechid);
|
|
||||||
const int volume = kconfiggroup.readEntry("volume", 100);
|
|
||||||
const int pitch = kconfiggroup.readEntry("pitch", 0);
|
|
||||||
const QByteArray voice = kconfiggroup.readEntry("voice", QByteArray());
|
|
||||||
KSpeech* kspeech = qobject_cast<KSpeech*>(parent());
|
|
||||||
Q_ASSERT(kspeech);
|
|
||||||
kspeech->setVolume(volume);
|
|
||||||
kspeech->setPitch(pitch);
|
|
||||||
if (!voice.isEmpty()) {
|
|
||||||
kspeech->setVoice(voice);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechPrivate::closeSpeechD()
|
|
||||||
{
|
|
||||||
if (m_speechd) {
|
|
||||||
spd_close(m_speechd);
|
|
||||||
m_speechd = nullptr;
|
|
||||||
|
|
||||||
QMutexLocker locker(globalKSpeechInstancesMutex());
|
|
||||||
globalKSpeechInstances()->remove(m_speechdid);
|
|
||||||
m_speechdid = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechPrivate::speechCallback(size_t msg_id, size_t client_id, SPDNotificationType state)
|
|
||||||
{
|
|
||||||
QMutexLocker locker(globalKSpeechInstancesMutex());
|
|
||||||
KSpeechPrivate* kspeechprivate = globalKSpeechInstances()->value(static_cast<int>(client_id), 0);
|
|
||||||
if (Q_UNLIKELY(!kspeechprivate)) {
|
|
||||||
kWarning() << "Null kspeech private pointer";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int jobNum = msg_id;
|
|
||||||
switch (state) {
|
|
||||||
case SPD_EVENT_BEGIN: {
|
|
||||||
emit kspeechprivate->signalJobStateChanged(jobNum, KSpeech::JobStarted);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPD_EVENT_END: {
|
|
||||||
emit kspeechprivate->signalJobStateChanged(jobNum, KSpeech::JobFinished);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SPD_EVENT_CANCEL: {
|
|
||||||
emit kspeechprivate->signalJobStateChanged(jobNum, KSpeech::JobCanceled);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // HAVE_SPEECHD
|
|
||||||
|
|
||||||
|
|
||||||
KSpeech::KSpeech(QObject* parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new KSpeechPrivate(this))
|
|
||||||
{
|
|
||||||
connect(
|
|
||||||
d, SIGNAL(signalJobStateChanged(int,int)),
|
|
||||||
this, SLOT(_jobStateChanged(int,int))
|
|
||||||
);
|
|
||||||
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
d->openSpeechD();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
KSpeech::~KSpeech()
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
d->closeSpeechD();
|
|
||||||
#endif
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::isSupported()
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeech::setSpeechID(const QString &id)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
d->closeSpeechD();
|
|
||||||
#endif
|
|
||||||
d->m_speechid = id.toUtf8();
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
d->openSpeechD();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int KSpeech::volume() const
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return spd_get_volume(d->m_speechd);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::setVolume(const int volume)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Q_UNLIKELY(volume < -100 || volume > 100)) {
|
|
||||||
kWarning() << "Invalid volume value" << volume;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int speechdresult = spd_set_volume(d->m_speechd, volume);
|
|
||||||
if (Q_UNLIKELY(speechdresult < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher set volume failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int KSpeech::pitch() const
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return spd_get_voice_pitch(d->m_speechd);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::setPitch(const int pitch)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Q_UNLIKELY(pitch < -100 || pitch > 100)) {
|
|
||||||
kWarning() << "Invalid pitch value" << pitch;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int speechdresult = spd_set_voice_pitch(d->m_speechd, pitch);
|
|
||||||
if (Q_UNLIKELY(speechdresult < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher set pitch failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray KSpeech::voice() const
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
return d->m_voice;
|
|
||||||
#else
|
|
||||||
return QByteArray();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QByteArray> KSpeech::voices() const
|
|
||||||
{
|
|
||||||
QList<QByteArray> result;
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPDVoice** speechdvoices = spd_list_synthesis_voices(d->m_speechd);
|
|
||||||
if (Q_UNLIKELY(!speechdvoices)) {
|
|
||||||
kWarning() << "Null speech-dispatcher voices pointer";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
int i = 0;
|
|
||||||
while (speechdvoices[i]) {
|
|
||||||
result.append(speechdvoices[i]->name);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
free_spd_voices(speechdvoices);
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::setVoice(const QByteArray &voice)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// could be empty if not set in kspeechrc
|
|
||||||
if (voice.isEmpty()) {
|
|
||||||
kWarning() << "Empty voice" << voice;
|
|
||||||
return false;
|
|
||||||
} else if (Q_UNLIKELY(!KSpeech::voices().contains(voice))) {
|
|
||||||
// NOTE: if voice is invalid speech-dispatcher will not dispatch anything
|
|
||||||
kWarning() << "Invalid voice value" << voice;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int speechdresult = spd_set_synthesis_voice(d->m_speechd, voice.constData());
|
|
||||||
if (Q_UNLIKELY(speechdresult < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher set voice failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
d->m_voice = voice;
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int KSpeech::say(const QString &text)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray textbytes = text.toUtf8();
|
|
||||||
const int jobNum = spd_say(d->m_speechd, SPD_TEXT, textbytes.constData());
|
|
||||||
if (Q_UNLIKELY(jobNum < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher say failed";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return jobNum;
|
|
||||||
#else
|
|
||||||
kWarning() << "KSpeech is a stub";
|
|
||||||
return 0;
|
|
||||||
#endif // HAVE_SPEECHD
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::removeAllJobs()
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kDebug() << "Null speech-dispatcher pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int speechdresult = spd_stop(d->m_speechd);
|
|
||||||
if (Q_UNLIKELY(speechdresult < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher stop failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
kWarning() << "KSpeech is a stub";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KSpeech::removeJob(int jobNum)
|
|
||||||
{
|
|
||||||
#if defined(HAVE_SPEECHD)
|
|
||||||
if (Q_UNLIKELY(!d->m_speechd)) {
|
|
||||||
kWarning() << "Null speech-dispatcher pointer";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int speechdresult = spd_stop_uid(d->m_speechd, jobNum);
|
|
||||||
if (Q_UNLIKELY(speechdresult < 0)) {
|
|
||||||
kWarning() << "Speech-dispatcher stop uid failed";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
kWarning() << "KSpeech is a stub";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeech::_jobStateChanged(int jobNum, int state)
|
|
||||||
{
|
|
||||||
emit jobStateChanged(jobNum, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "kspeech.moc"
|
|
|
@ -1,77 +0,0 @@
|
||||||
/* This file is part of the KDE libraries
|
|
||||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License version 2, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This library 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
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef KSPEECH_H
|
|
||||||
#define KSPEECH_H
|
|
||||||
|
|
||||||
#include "kspeech_export.h"
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
class KSpeechPrivate;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Class for Text-To-Speech.
|
|
||||||
|
|
||||||
@since 4.22
|
|
||||||
*/
|
|
||||||
class KSPEECH_EXPORT KSpeech : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum KSpeechState {
|
|
||||||
JobStarted = 0,
|
|
||||||
JobFinished = 1,
|
|
||||||
JobCanceled = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
KSpeech(QObject* parent = nullptr);
|
|
||||||
~KSpeech();
|
|
||||||
|
|
||||||
static bool isSupported();
|
|
||||||
|
|
||||||
void setSpeechID(const QString &id);
|
|
||||||
|
|
||||||
int volume() const;
|
|
||||||
bool setVolume(const int volume);
|
|
||||||
|
|
||||||
int pitch() const;
|
|
||||||
bool setPitch(const int pitch);
|
|
||||||
|
|
||||||
QByteArray voice() const;
|
|
||||||
QList<QByteArray> voices() const;
|
|
||||||
bool setVoice(const QByteArray &voice);
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
int say(const QString &text);
|
|
||||||
|
|
||||||
bool removeAllJobs();
|
|
||||||
bool removeJob(int jobNum);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void jobStateChanged(int jobNum, int state);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void _jobStateChanged(int jobNum, int state);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_DISABLE_COPY(KSpeech);
|
|
||||||
KSpeechPrivate* const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // KSPEECH_H
|
|
|
@ -1,9 +0,0 @@
|
||||||
include_directories(
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/..
|
|
||||||
)
|
|
||||||
|
|
||||||
kde4_add_test(kspeech-kspeechtest
|
|
||||||
kspeechtest.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(kspeech-kspeechtest ${KDE4_KSPEECH_LIBS} ${QT_QTTEST_LIBRARY})
|
|
|
@ -1,103 +0,0 @@
|
||||||
/* This file is part of the KDE libraries
|
|
||||||
Copyright (C) 2022 Ivailo Monev <xakepa10@gmail.com>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License version 2, as published by the Free Software Foundation.
|
|
||||||
|
|
||||||
This library 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
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "qtest_kde.h"
|
|
||||||
#include "kspeech.h"
|
|
||||||
#include "kdebug.h"
|
|
||||||
|
|
||||||
#include <QSignalSpy>
|
|
||||||
|
|
||||||
class KSpeechTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private Q_SLOTS:
|
|
||||||
void initTestCase();
|
|
||||||
void cleanupTestCase();
|
|
||||||
|
|
||||||
void say_data();
|
|
||||||
void say();
|
|
||||||
|
|
||||||
void setters_and_getters_data();
|
|
||||||
void setters_and_getters();
|
|
||||||
};
|
|
||||||
|
|
||||||
QTEST_KDEMAIN_CORE(KSpeechTest)
|
|
||||||
|
|
||||||
void KSpeechTest::initTestCase()
|
|
||||||
{
|
|
||||||
if (!KSpeech::isSupported()) {
|
|
||||||
QSKIP("Built without speech-dispatcher", SkipAll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechTest::cleanupTestCase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechTest::say_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("saystr");
|
|
||||||
QTest::newRow("US-ASCII") << QString::fromAscii("foobar");
|
|
||||||
QTest::newRow("UTF-8") << QString::fromUtf8("лорем ипсум");
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechTest::say()
|
|
||||||
{
|
|
||||||
QFETCH(QString, saystr);
|
|
||||||
|
|
||||||
KSpeech kspeech(this);
|
|
||||||
QSignalSpy spyJobStateChanged(&kspeech, SIGNAL(jobStateChanged(int,int)));
|
|
||||||
QVERIFY(kspeech.say(saystr) != 0);
|
|
||||||
QTest::qWait(3000);
|
|
||||||
QVERIFY(spyJobStateChanged.count() == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechTest::setters_and_getters_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<int>("volume");
|
|
||||||
QTest::addColumn<int>("pitch");
|
|
||||||
QTest::addColumn<QByteArray>("voice");
|
|
||||||
QTest::addColumn<bool>("valid");
|
|
||||||
// check `spd-say -L` for valid voice
|
|
||||||
QTest::newRow("valid") << int(10) << int(2) << QByteArray("Slovak") << bool(true);
|
|
||||||
QTest::newRow("invalid") << int(-123) << int(321) << QByteArray("foobar") << bool(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KSpeechTest::setters_and_getters()
|
|
||||||
{
|
|
||||||
QFETCH(int, volume);
|
|
||||||
QFETCH(int, pitch);
|
|
||||||
QFETCH(QByteArray, voice);
|
|
||||||
QFETCH(bool, valid);
|
|
||||||
|
|
||||||
KSpeech kspeech(this);
|
|
||||||
QCOMPARE(kspeech.setVolume(volume), valid);
|
|
||||||
QCOMPARE(kspeech.setPitch(pitch), valid);
|
|
||||||
QCOMPARE(kspeech.setVoice(voice), valid);
|
|
||||||
if (valid) {
|
|
||||||
QCOMPARE(kspeech.volume(), volume);
|
|
||||||
QCOMPARE(kspeech.pitch(), pitch);
|
|
||||||
QCOMPARE(kspeech.voice(), voice);
|
|
||||||
} else {
|
|
||||||
QCOMPARE(kspeech.volume(), 100);
|
|
||||||
QCOMPARE(kspeech.pitch(), 0);
|
|
||||||
QCOMPARE(kspeech.voice(), QByteArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "kspeechtest.moc"
|
|
Loading…
Add table
Reference in a new issue