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