commit 565afb783dc50d4ec7c9d1d6caf486c26f47d1fe
Author: nalin.x.linux <nalin.x.linux@gmail.com>
Date:   Sun Aug 28 15:27:27 2022 +0530

    Preferences dialog startup fixed, speech person selection enabled, set default speech module and language using user's language

---
 lios/main.py        |   10 ++++-
 lios/preferences.py |  104 +++++++++++++++++++++++++++++++++++++++++++++++-----
 lios/speech.py      |   13 +++++-
 3 files changed, 112 insertions(+), 15 deletions(-)

--- a/lios/main.py
+++ b/lios/main.py
@@ -181,6 +181,7 @@ class linux_intelligent_ocr_solution():
 		#Load Preferences
 		self.preferences = preferences.lios_preferences()
 		self.preferences.set_from_file(macros.preferences_file_path)
+		self.preferences.set_default_speech_module_and_language()
 		self.preferences.set_avalable_scanner_drivers([ item.name for item in self.available_scanner_driver_list])
 		self.preferences.set_avalable_ocr_engines([ (item.name,item.get_available_languages())
 												for item in self.available_ocr_engine_list ])
@@ -1379,6 +1380,7 @@ pacman -S aspell-fr"""))
 
 	def restore_preferences(self,*data):
 		self.preferences.__init__()
+		self.preferences.set_default_speech_module_and_language()
 		self.make_preferences_effective()
 		self.notify_information(_("Preferences Restored"),0)
 	
@@ -1441,8 +1443,12 @@ pacman -S aspell-fr"""))
 			self.is_reading = True
 			speaker = speech.Speech()
 			speaker.set_output_module(speaker.list_output_modules()[self.preferences.speech_module])
-			if(self.preferences.speech_module != -1 and len(speaker.list_voices()) > 1):
-				speaker.set_synthesis_voice(speaker.list_voices()[self.preferences.speech_language])
+			language_person_dict = speaker.get_language_person_dict()
+
+			if(self.preferences.speech_module != -1 and len(language_person_dict.keys()) > 1):
+				voice = language_person_dict[list(language_person_dict)[self.preferences.speech_language]][self.preferences.speech_person]
+				speaker.set_synthesis_voice(voice)
+
 			speaker.set_volume(self.preferences.speech_volume)
 			speaker.set_pitch(self.preferences.speech_pitch)
 			while(not self.textview.is_cursor_at_end()):
--- a/lios/preferences.py
+++ b/lios/preferences.py
@@ -39,7 +39,7 @@ class lios_preferences:
 		self.background_color="#000";self.font_color="#fff";
 		self.highlight_color="#1572ffff0000";
 		self.background_highlight_color="#00000bacffff";
-		self.speech_module=0;self.speech_language=10;
+		self.speech_module=-1;self.speech_language=-1;self.speech_person=-1;
 		self.speech_rate=0;self.speech_pitch=0;self.speech_volume=100;
 		self.time_between_repeated_scanning=0;self.scan_resolution=300;
 		self.scan_driver=1;self.scanner_cache_calibration=0;
@@ -72,6 +72,7 @@ class lios_preferences:
 				self.language=int(config.get('cfg',"language"))
 				self.speech_module=int(config.get('cfg',"speech_module"))
 				self.speech_language=int(config.get('cfg',"speech_language"))
+				self.speech_person=int(config.get('cfg',"speech_person"))
 				self.speech_rate=int(config.get('cfg',"speech_rate"))
 				self.speech_volume=int(config.get('cfg',"speech_volume"))
 				self.speech_pitch=int(config.get('cfg',"speech_pitch"))
@@ -96,6 +97,34 @@ class lios_preferences:
 		else:
 			self.__init__()
 
+	# Set speech module, language and person if speech_module is not set
+	def set_default_speech_module_and_language(self):
+		if(self.speech_module == -1):
+			test = speech.Speech()
+			output_modules_list = test.list_output_modules()
+			if("espeak-ng" in output_modules_list):
+				self.speech_module = output_modules_list.index('espeak-ng')
+				test.set_output_module('espeak-ng')
+			elif("espeak" in output_modules_list):
+				self.speech_module = output_modules_list.index('espeak')
+				test.set_output_module('espeak')
+
+			# if espeak or espeak-ng set language
+			if(self.speech_module != -1):
+				import locale
+				language_code, encoding = locale.getdefaultlocale()
+				localeValues = language_code.split('_')
+				language = localeValues[0]
+				language_person_dict = test.get_language_person_dict()
+				if(language in language_person_dict.keys()):
+					self.speech_language = list(language_person_dict.keys()).index(language)
+					self.speech_person=0;
+			else:
+				self.speech_module=0;self.speech_language=0;self.speech_person=0;
+
+			#Closing
+			test.close()
+
 	def save_to_file(self,filename):
 		#Removing old configuration file
 		try:
@@ -114,6 +143,7 @@ class lios_preferences:
 		config.set('cfg',"language",str(self.language))
 		config.set('cfg',"speech_module",str(self.speech_module))
 		config.set('cfg',"speech_language",str(self.speech_language))
+		config.set('cfg',"speech_person",str(self.speech_person))
 		config.set('cfg',"speech_pitch",str(self.speech_pitch))
 		config.set('cfg',"speech_volume",str(self.speech_volume))
 		config.set('cfg',"speech_rate",str(self.speech_rate))
@@ -161,14 +191,62 @@ class lios_preferences:
 			combobox_language.set_active(self.language)
 
 		def change_speech_module(*data):
-			index_engine = combobox_speech_module.get_active()
-			combobox_speech_language.clear()
+			module_index = combobox_speech_module.get_active()
+
 			test = speech.Speech()
-			list = test.list_output_modules()
-			test.set_output_module(list[index_engine])
-			for item in test.list_voices():
-				combobox_speech_language.add_item(item)
-			combobox_speech_language.set_active(self.speech_language)
+			output_modules_list = test.list_output_modules()
+			test.set_output_module(output_modules_list[module_index])
+
+			self.speech_language_person_dict = test.get_language_person_dict()
+			test.close()
+
+			# Disconnecting for preventng function calls while clearing
+			# combobox_speech_language or adding each language to the same
+			try:
+				combobox_speech_language.disconnect_by_func(change_speech_language)
+			except(TypeError):
+				pass
+
+			combobox_speech_language.clear()
+
+			if(len(self.speech_language_person_dict.keys()) == 0):
+				combobox_speech_language.add_item(_("Default"))
+				self.speech_language = 0
+			else:
+				for item in self.speech_language_person_dict.keys():
+					combobox_speech_language.add_item(item)
+
+			combobox_speech_language.connect_change_callback_function(change_speech_language)
+
+
+			if(self.speech_language < len(self.speech_language_person_dict.keys())):
+				combobox_speech_language.set_active(self.speech_language)
+			else:
+				combobox_speech_language.set_active(0)
+				self.speech_language = 0
+
+		def change_speech_language(*data):
+			combobox_speech_person.clear()
+
+			# For users having preferences from old version
+			if(self.speech_person == -1):
+				self.speech_person = 0
+
+			if(len(list(self.speech_language_person_dict.keys())) == 0):
+				combobox_speech_person.add_item(_("Default"))
+				combobox_speech_person.set_active(0)
+				self.speech_person = 0
+				return
+
+			index_language = combobox_speech_language.get_active()
+			language = list(self.speech_language_person_dict.keys())[index_language]
+
+			for item in self.speech_language_person_dict[language]:
+				combobox_speech_person.add_item(item)
+
+			if(self.speech_person >= len(self.speech_language_person_dict[language])):
+				self.speech_person = 0
+			combobox_speech_person.set_active(self.speech_person)
 
 		def change_mode_of_rotation(*data):
 			if(combobox_mode_of_rotation.get_active() == 2):
@@ -227,10 +305,14 @@ class lios_preferences:
 
 		label_speech_language = widget.Label(_("Speech-Language"))
 		combobox_speech_language = widget.ComboBox()
-		combobox_speech_module.set_active(self.speech_module)
-		combobox_speech_language.set_active(self.speech_language)
 		label_speech_language.set_mnemonic_widget(combobox_speech_language)
 
+		label_speech_person = widget.Label(_("Speech Person"))
+		combobox_speech_person = widget.ComboBox()
+		label_speech_person.set_mnemonic_widget(combobox_speech_person)
+
+		combobox_speech_module.set_active(self.speech_module)
+
 		label_speech_rate = widget.Label(_("Speech-Rate"))
 		spin_speech_rate = widget.SpinButton(self.speech_rate,-100,100,1,10,0)
 		label_speech_rate.set_mnemonic_widget(spin_speech_rate)
@@ -252,6 +334,7 @@ class lios_preferences:
 			(label_highlight_background,1,1),(colorbutton_highlight_background,1,1),containers.Grid.NEW_ROW,
 			(label_speech_module,1,1),(combobox_speech_module,1,1),containers.Grid.NEW_ROW,
 			(label_speech_language,1,1),(combobox_speech_language,1,1),containers.Grid.NEW_ROW,
+			(label_speech_person,1,1),(combobox_speech_person,1,1),containers.Grid.NEW_ROW,
 			(label_speech_rate,1,1),(spin_speech_rate,1,1),containers.Grid.NEW_ROW,
 			(label_speech_pitch,1,1),(spin_speech_pitch,1,1),containers.Grid.NEW_ROW,
 			(label_speech_volume,1,1),(spin_speech_volume,1,1)])
@@ -436,6 +519,7 @@ class lios_preferences:
 			self.language=combobox_language.get_active()
 			self.speech_module=combobox_speech_module.get_active()
 			self.speech_language=combobox_speech_language.get_active()
+			self.speech_person=combobox_speech_person.get_active()
 			self.speech_rate=spin_speech_rate.get_value()
 			self.speech_pitch=spin_speech_pitch.get_value()
 			self.speech_volume=spin_speech_volume.get_value()
--- a/lios/speech.py
+++ b/lios/speech.py
@@ -23,9 +23,16 @@ class Speech(speechd.SSIPClient):
 	def __init__(self,client_name="lios"):
 		super(Speech,self).__init__(client_name)
 		self.status = False
-	
-	def list_voices(self):
-		return [ x[0] for x in self.list_synthesis_voices()]
+
+	def get_language_person_dict(self):
+		dictionary = {}
+		voices = self.list_synthesis_voices()
+		for item in voices:
+			if(item[1] not in dictionary):
+				dictionary[item[1]] = [item[0]]
+			else:
+				dictionary[item[1]].append(item[0])
+		return dictionary
 	
 	def say(self,text):
 		self.status = True
