1# Orca 2# 3# Copyright 2016 Igalia, S.L. 4# 5# Author: Joanmarie Diggs <jdiggs@igalia.com> 6# 7# This library is free software; you can redistribute it and/or 8# modify it under the terms of the GNU Lesser General Public 9# License as published by the Free Software Foundation; either 10# version 2.1 of the License, or (at your option) any later version. 11# 12# This library is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15# Lesser General Public License for more details. 16# 17# You should have received a copy of the GNU Lesser General Public 18# License along with this library; if not, write to the 19# Free Software Foundation, Inc., Franklin Street, Fifth Floor, 20# Boston MA 02110-1301 USA. 21 22"""Utilities for obtaining sounds to be presented for objects.""" 23 24__id__ = "$Id:$" 25__version__ = "$Revision:$" 26__date__ = "$Date:$" 27__copyright__ = "Copyright (c) 2016 Igalia, S.L." 28__license__ = "LGPL" 29 30import pyatspi 31 32from orca import settings_manager 33from orca import sound_generator 34 35_settingsManager = settings_manager.getManager() 36 37 38class SoundGenerator(sound_generator.SoundGenerator): 39 40 def __init__(self, script): 41 super().__init__(script) 42 43 def _generateClickable(self, obj, **args): 44 """Returns an array of sounds indicating obj is clickable.""" 45 46 if not _settingsManager.getSetting('playSoundForState'): 47 return [] 48 49 if not self._script.utilities.inDocumentContent(obj): 50 return [] 51 52 if not args.get('mode', None): 53 args['mode'] = self._mode 54 55 args['stringType'] = 'clickable' 56 if self._script.utilities.isClickableElement(obj): 57 filenames = [self._script.formatting.getString(**args)] 58 result = list(map(self._convertFilenameToIcon, filenames)) 59 if result: 60 return result 61 62 return [] 63 64 def _generateHasLongDesc(self, obj, **args): 65 """Returns an array of sounds indicating obj has a longdesc.""" 66 67 if not _settingsManager.getSetting('playSoundForState'): 68 return [] 69 70 if not self._script.utilities.inDocumentContent(obj): 71 return [] 72 73 if not args.get('mode', None): 74 args['mode'] = self._mode 75 76 args['stringType'] = 'haslongdesc' 77 if self._script.utilities.hasLongDesc(obj): 78 filenames = [self._script.formatting.getString(**args)] 79 result = list(map(self._convertFilenameToIcon, filenames)) 80 if result: 81 return result 82 83 return [] 84 85 def generateSound(self, obj, **args): 86 """Returns an array of sounds for the complete presentation of obj.""" 87 88 if not self._script.utilities.inDocumentContent(obj): 89 return super().generateSound(obj, **args) 90 91 result = [] 92 if args.get('formatType') == 'detailedWhereAmI': 93 oldRole = self._overrideRole('default', args) 94 elif self._script.utilities.isLink(obj): 95 oldRole = self._overrideRole(pyatspi.ROLE_LINK, args) 96 elif self._script.utilities.treatAsDiv(obj): 97 oldRole = self._overrideRole(pyatspi.ROLE_SECTION, args) 98 else: 99 oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args) 100 101 result.extend(super().generateSound(obj, **args)) 102 result = list(filter(lambda x: x, result)) 103 self._restoreRole(oldRole, args) 104 105 return result 106 107 def generateContents(self, contents, **args): 108 """Returns an array of an array of sounds for the contents.""" 109 110 if not len(contents): 111 return [] 112 113 result = [] 114 contents = self._script.utilities.filterContentsForPresentation(contents, False) 115 for i, content in enumerate(contents): 116 obj, start, end, string = content 117 icon = self.generateSound( 118 obj, startOffset=start, endOffset=end, string=string, 119 index=i, total=len(contents), **args) 120 result.append(icon) 121 122 return result 123