From 6a4e6bcfef7aed0d9063c02a6c6ee8cc7f9b627a Mon Sep 17 00:00:00 2001 From: Muflone Date: Sat, 20 Jun 2009 18:27:52 +0000 Subject: [PATCH] --- copyright | 17 ----- gespeaker.desktop | 10 --- gespeaker.png | Bin 4049 -> 0 bytes gespeakerUI.py | 184 ++++++++++++++++++++++++++++++++++------------ locale/fr.po | 44 +++++------ locale/i18n-3.sh | 0 locale/it.po | 2 +- 7 files changed, 161 insertions(+), 96 deletions(-) delete mode 100644 copyright delete mode 100644 gespeaker.desktop delete mode 100644 gespeaker.png mode change 100755 => 100644 locale/i18n-3.sh diff --git a/copyright b/copyright deleted file mode 100644 index 26511d8..0000000 --- a/copyright +++ /dev/null @@ -1,17 +0,0 @@ -Copyright 2009 by Muflone - -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; version 2 of the License. - -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. - -The full text of the GNU General Public License is available on Debian -systems in /usr/share/common-licenses/GPL-2. diff --git a/gespeaker.desktop b/gespeaker.desktop deleted file mode 100644 index 1afb024..0000000 --- a/gespeaker.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Version=1.0 -Name=Gespeaker -Comment=A frontend for espeak -Type=Application -Comment[it_IT]=Un frontend per espeak -Exec=/usr/bin/gespeaker -Icon=/usr/share/gespeaker/gespeaker.png -Terminal=false -Categories=AudioVideo;Audio;Player;GTK; diff --git a/gespeaker.png b/gespeaker.png deleted file mode 100644 index baaaefa4c080eba0ca5dec0bf9d4164d92e96314..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4049 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 diff --git a/gespeakerUI.py b/gespeakerUI.py index 23a170e..6b33748 100644 --- a/gespeakerUI.py +++ b/gespeakerUI.py @@ -6,26 +6,36 @@ import gtk import gtk.glade import pygtk +import gobject pygtk.require("2.0") -import subprocess +# No more used +# import TempfileWrapper +import tempfile +import os from gettext import gettext as _ from DialogYesNo import DialogYesNo from DialogFileOpenSave import DialogFileOpen, DialogFileSave from DialogSimpleMessages import * from DialogAbout import DialogAbout +from EspeakFrontend import EspeakFrontend -espeakcmd = '/usr/bin/espeak' -espeakargs = '--stdout -a %d -p %d -s %d -g %d -v %s "%s" | aplay 2> /dev/null' +cmdEspeak = '/usr/bin/espeak' +cmdPlayer = 'aplay' +argsEspeak = '--stdout -a %d -p %d -s %d -g %d -v %s -f %s' -class gespeakerUI(): +class gespeakerUI(object): def __init__(self, app_name, app_title, app_version): print 'starting gespeaker' + self.espeak = EspeakFrontend() + # Create temporary filename + self.tempFilename = tempfile.mkstemp(prefix='gespeaker')[1] gladeUI = 'gespeaker.glade' self.app_name = app_name self.app_title = app_title self.app_version = app_version + self.timeoutCheck = None print 'loading interface from %s' % gladeUI self.gladeFile = gtk.glade.XML(fname=gladeUI, domain=self.app_name) # Signals handler @@ -35,6 +45,10 @@ def __init__(self, app_name, app_title, app_version): 'on_imgmenuFileNew_activate': self.on_imgmenuFileNew_activate, 'on_imgmenuFileOpen_activate': self.on_imgmenuFileOpen_activate, 'on_imgmenuFileSaveAs_activate': self.on_imgmenuFileSaveAs_activate, + 'on_imgmenuEditStop_activate': self.on_imgmenuEditStop_activate, + 'on_btnPlayStop_toggled': self.on_btnPlayStop_toggled, + 'on_btnPause_toggled': self.on_btnPause_toggled, + 'on_imgmenuEditPause_activate': self.on_imgmenuEditPause_activate, 'on_imgmenuEditResetSettings_activate': self.on_imgmenuEditResetSettings_activate, 'on_imgmenuHelpAbout_activate': self.on_imgmenuHelpAbout_activate } @@ -42,22 +56,33 @@ def __init__(self, app_name, app_title, app_version): # Load window and controls self.loadControls() self.winMain.show() + # Play default message + self.btnPlayStop.set_active(True) gtk.main() def loadControls(self): "Load controls and other values" # Load controls from gladeFile print 'loading controls from UI' - self.winMain = self.gladeFile.get_widget('winMain') + gw = self.gladeFile.get_widget + self.winMain = gw('winMain') self.winMain.set_title(self.app_title) - self.winMain.set_icon_from_file('gespeaker.png') - self.winMain.set_focus(self.gladeFile.get_widget('txvText')) - self.txvBuffer = self.gladeFile.get_widget('txvText').get_buffer() - self.hscVolume = self.gladeFile.get_widget('hscVolume') - self.hscPitch = self.gladeFile.get_widget('hscPitch') - self.hscSpeed = self.gladeFile.get_widget('hscSpeed') - self.hscDelay = self.gladeFile.get_widget('hscDelay') - self.cboLanguages = self.gladeFile.get_widget('cboLanguages') + self.winMain.set_icon_from_file('gespeaker.svg') + self.winMain.set_focus(gw('txvText')) + self.txvBuffer = gw('txvText').get_buffer() + self.hscVolume = gw('hscVolume') + self.hscPitch = gw('hscPitch') + self.hscSpeed = gw('hscSpeed') + self.hscDelay = gw('hscDelay') + self.cboLanguages = gw('cboLanguages') + self.radioVoiceMale = gw('radioVoiceMale') + self.radioVoiceFemale = gw('radioVoiceFemale') + self.imgmenuEditPlay = gw('imgmenuEditPlay') + self.imgmenuEditStop = gw('imgmenuEditStop') + self.tlbStop = gw('tlbStop') + self.btnPlayStop = gw('btnPlayStop') + self.btnPause = gw('btnPause') + self.imgmenuEditPause = gw('imgmenuEditPause') # Useful lambda to get txvBuffer's text self.getText = lambda buffer=self.txvBuffer: buffer.get_text( buffer.get_start_iter(), buffer.get_end_iter() @@ -69,10 +94,8 @@ def loadControls(self): self.cboLanguages.pack_start(cell, True) self.cboLanguages.add_attribute(cell, 'text', 0) # Load languages list from espeak --voices - print 'loading languages from %s --voices' % espeakcmd - p = subprocess.Popen((espeakcmd, '--voices'), stdout=subprocess.PIPE) self.defaultLanguage = 0 - for langs in p.communicate()[0].split('\n')[1:-1]: + for langs in self.espeak.loadLanguages(cmdEspeak): lang = langs[22:52].rsplit(None, 1) listLanguages.append(lang) if lang[0] == _('default language'): @@ -83,28 +106,14 @@ def loadControls(self): def on_imgmenuFileQuit_activate(self, widget, data=None): "Close the program" print 'quitting' + if self.tempFilename and os.path.exists(self.tempFilename): + os.remove(self.tempFilename) gtk.main_quit() return 0 def on_imgmenuEditPlay_activate(self, widget, data=None): - "Play whole text" - text = self.getText(self.txvBuffer) - text = text.replace('\\', '\\\\') - text = text.replace('`', '\\`') - text = text.replace('"', '\\"') - text = text.replace('$', '\\$') - if text: - cmd = '%s %s' % (espeakcmd, espeakargs % ( - self.hscVolume.get_value(), - self.hscPitch.get_value(), - self.hscSpeed.get_value(), - self.hscDelay.get_value(), - self.cboLanguages.get_model()[self.cboLanguages.get_active()][1], - text - ) - ) - print cmd - processPlay = subprocess.Popen(cmd, shell=True) + "Press button to start play, indirect cause button style" + self.btnPlayStop.set_active(True) def on_imgmenuFileNew_activate(self, widget, data=None): "Clears the whole text" @@ -113,7 +122,7 @@ def on_imgmenuFileNew_activate(self, widget, data=None): message=_('Do you want to delete the current text?'), default_button=gtk.RESPONSE_NO ) - dialog.set_icon_from_file('gespeaker.png') + dialog.set_icon_from_file('gespeaker.svg') dialog.show() if dialog.responseIsYes(): self.txvBuffer.set_text('') @@ -122,7 +131,7 @@ def on_imgmenuFileNew_activate(self, widget, data=None): def on_imgmenuFileOpen_activate(self, widget, data=None): "Loads an external file" dialog = DialogFileOpen(title=_('Please select the file to open')) - dialog.set_icon_from_file('gespeaker.png') + dialog.set_icon_from_file('gespeaker.svg') if dialog.show(): file = None try: @@ -140,14 +149,13 @@ def on_imgmenuFileOpen_activate(self, widget, data=None): except: ShowDialogError(text=_('Error opening the file'), showOk=True) print 'error loading %s' % dialog.filename - finally: - if file: - file.close() + if file: + file.close() def on_imgmenuFileSaveAs_activate(self, widget, data=None): "Saves the whole text in the specified filename" dialog = DialogFileSave(title=_('Please select where to save the file')) - dialog.set_icon_from_file('gespeaker.png') + dialog.set_icon_from_file('gespeaker.svg') if dialog.show(): print 'saving text in %s' % dialog.filename file = None @@ -166,9 +174,8 @@ def on_imgmenuFileSaveAs_activate(self, widget, data=None): except: ShowDialogError(text=_('Error saving the file'), showOk=True) print 'error saving %s' % dialog.filename - finally: - if file: - file.close() + if file: + file.close() def on_imgmenuEditResetSettings_activate(self, widget, data=None): "Restore default settings" @@ -176,13 +183,14 @@ def on_imgmenuEditResetSettings_activate(self, widget, data=None): message=_('Do you want to reset the default settings?'), default_button=gtk.RESPONSE_NO ) - dialog.set_icon_from_file('gespeaker.png') + dialog.set_icon_from_file('gespeaker.svg') dialog.show() if dialog.responseIsYes(): self.hscVolume.set_value(100) self.hscPitch.set_value(50) self.hscSpeed.set_value(170) self.hscDelay.set_value(10) + self.radioVoiceMale.set_active(True) if self.defaultLanguage: self.cboLanguages.set_active(self.defaultLanguage) print 'restored default settings' @@ -200,6 +208,90 @@ def on_imgmenuHelpAbout_activate(self, widget, data=None): website_label='Ubuntu Trucchi', authors=['Muflone '], translation=_('translation'), - logo='gespeaker.png', - icon='gespeaker.png' + logo='gespeaker.svg', + icon='gespeaker.svg' ) + + def on_imgmenuEditStop_activate(self, widget, data=None): + "Press button to stop play, indirect cause button style" + self.btnPlayStop.set_active(False) + + def on_imgmenuEditPause_activate(self, widget, data=None): + "Press button to pause or continue" + self.btnPause.set_active(not self.btnPause.get_active()) + + def checkIfPlaying(self): + "Check if a process is still running" + if self.espeak.isPlaying(): + # Still running + return True + else: + # Disable stop buttons on menu and toolbar + self.btnPlayStop.set_active(False) + return False + + def setStopCheck(self, active): + "Set/unset timeout check for running processes" + if active: + self.timeoutCheck = gobject.timeout_add(500, self.checkIfPlaying) + else: + gobject.source_remove(self.timeoutCheck) + self.timeoutCheck = None + + def on_btnPlayStop_toggled(self, widget, data=None): + "Play and stop by pressing and releasing the button" + if self.btnPlayStop.get_active(): + # Button active so we have to start to play + self.startPlaying() + else: + # If Pause button is active then we have to continue before to kill + if self.btnPause.get_active(): + self.btnPause.set_active(False) + # Button inactive so we have to stop the playing + self.stopPlaying() + + def on_btnPause_toggled(self, widget, data=None): + "Pause and unpause espeak and player by signals STOP/CONT" + self.espeak.pauseOrResume(self.btnPause.get_active()) + + def startPlaying(self): + "Play whole text" + self.playText(self.getText(self.txvBuffer)) + + def playText(self, text): + if text: + # Save buffer text on temporary filename and play it + tmpFile = open(self.tempFilename, mode='w') + tmpFile.write(text) + tmpFile.close() + cmd = '%s %s' % (cmdEspeak, argsEspeak % ( + self.hscVolume.get_value(), + self.hscPitch.get_value(), + self.hscSpeed.get_value(), + self.hscDelay.get_value(), + self.cboLanguages.get_model()[self.cboLanguages.get_active()][1] + + (self.radioVoiceFemale.get_active() and '+12' or ''), + self.tempFilename + ) + ) + print cmd + self.espeak.play(cmd, cmdPlayer) + # Enable stop buttons on menu and toolbar + self.imgmenuEditPlay.set_sensitive(False) + self.imgmenuEditStop.set_sensitive(True) + self.imgmenuEditPause.set_sensitive(True) + self.btnPause.set_sensitive(True) + self.btnPlayStop.set_label('gtk-media-stop') + # Enable check for running processes + self.setStopCheck(True) + + def stopPlaying(self): + if self.espeak.stop(): + # If stopped then disable buttons and menus + self.setStopCheck(False) + self.imgmenuEditPlay.set_sensitive(True) + self.imgmenuEditStop.set_sensitive(False) + self.imgmenuEditPause.set_sensitive(False) + self.btnPause.set_sensitive(False) + self.btnPlayStop.set_label('gtk-media-play') + diff --git a/locale/fr.po b/locale/fr.po index 859542d..ec44dd9 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -19,59 +19,59 @@ msgstr "" #: gespeaker.glade.h:1 msgid "Insert text to play" -msgstr "" +msgstr "Insérer le texte à jouer" #: gespeaker.glade.h:2 msgid "Settings" -msgstr "" +msgstr "Préférences" #: gespeaker.glade.h:3 msgid "Dela_y:" -msgstr "" +msgstr "Déla_i:" #: gespeaker.glade.h:4 msgid "Fem_ale" -msgstr "" +msgstr "Fémini_ne" #: gespeaker.glade.h:5 msgid "P_itch:" -msgstr "" +msgstr "_Tonalité:" #: gespeaker.glade.h:6 msgid "Spee_d:" -msgstr "" +msgstr "Vite_sse:" #: gespeaker.glade.h:7 msgid "Voice:" -msgstr "" +msgstr "Voix:" #: gespeaker.glade.h:8 msgid "Welcome in Gespeaker" -msgstr "" +msgstr "Bienvenu dans Gespeaker" #: gespeaker.glade.h:9 msgid "_Edit" -msgstr "" +msgstr "É_dition" #: gespeaker.glade.h:10 msgid "_File" -msgstr "" +msgstr "_Fichier" #: gespeaker.glade.h:11 msgid "_Help" -msgstr "" +msgstr "Aid_e" #: gespeaker.glade.h:12 msgid "_Language:" -msgstr "" +msgstr "Lang_ue:" #: gespeaker.glade.h:13 msgid "_Male" -msgstr "" +msgstr "_Masculine" #: gespeaker.glade.h:14 msgid "_Volume:" -msgstr "" +msgstr "_Volume:" #: gespeakerUI.py:101 msgid "default language" @@ -79,32 +79,32 @@ msgstr "french" #: gespeakerUI.py:122 msgid "Do you want to delete the current text?" -msgstr "" +msgstr "Voulez-vous effacer le texte courant?" #: gespeakerUI.py:133 msgid "Please select the file to open" -msgstr "" +msgstr "Choisir le fichier à ouvrir" #: gespeakerUI.py:143 gespeakerUI.py:150 msgid "Error opening the file" -msgstr "" +msgstr "Erreur en ouvrant le fichier" #: gespeakerUI.py:157 msgid "Please select where to save the file" -msgstr "" +msgstr "Choisir où enregistrer le fichier" #: gespeakerUI.py:168 gespeakerUI.py:175 msgid "Error saving the file" -msgstr "" +msgstr "Erreur en enregistrant le fichier" #: gespeakerUI.py:183 msgid "Do you want to reset the default settings?" -msgstr "" +msgstr "Voulez-vous rétablir les paramètres par défaut?" #: gespeakerUI.py:204 msgid "A GTK frontend for espeak" -msgstr "" +msgstr "Une interface GTK pour espeak" #: gespeakerUI.py:210 msgid "translation" -msgstr "" +msgstr "Traduction française par Emmanuel " diff --git a/locale/i18n-3.sh b/locale/i18n-3.sh old mode 100755 new mode 100644 diff --git a/locale/it.po b/locale/it.po index 23017c7..6d05c49 100644 --- a/locale/it.po +++ b/locale/it.po @@ -63,7 +63,7 @@ msgstr "A_iuto" #: gespeaker.glade.h:12 msgid "_Language:" -msgstr "_Lingua:" +msgstr "Li_ngua:" #: gespeaker.glade.h:13 msgid "_Male"