Skip to content

Commit

Permalink
Read notifications added also to Thunderbird. Create a separate modul…
Browse files Browse the repository at this point in the history
…e for code shared for both appmodules. Updated localizations. Minor fixes.
  • Loading branch information
javidominguez committed Dec 3, 2017
1 parent 1e388b6 commit a4beedb
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 128 deletions.
87 changes: 16 additions & 71 deletions addon/appModules/firefox.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Mozilla Firefox Scripts version 1.0.4 (Oct 2016)
# Mozilla Firefox Scripts version 1.4 (Dec-2017)
# Author Javi Dominguez <fjavids@gmail.com>
# License GNU GPL

Expand All @@ -14,8 +14,9 @@
import speech
import gui
import wx
from datetime import datetime, timedelta
from datetime import datetime
from threading import Timer
import shared

addonHandler.initTranslation()

Expand All @@ -26,23 +27,14 @@ class AppModule(firefox.AppModule):

scriptCategory = _("mozilla Firefox")

def chooseNVDAObjectOverlayClasses(self, obj, clsList):
if obj.role == controlTypes.ROLE_ALERT:
alertText = ""
for child in obj.recursiveDescendants:
if child.name:
if not child.isFocusable and child.name not in alertText:
alertText = "%s %s" % (alertText, child.name)
obj.description = alertText
clsList.insert(0, alertPopup)

def event_alert(self, obj, nextHandler):
alertText = obj.name if obj.name else obj.description if obj.description else obj.displayText if obj.displayText else _("Couldn't capture the text of this notification")
alertText = shared.getAlertText(obj)
alertText = _("Couldn't capture the text of this notification") if not alertText else alertText
if self.inMainWindow():
if self.focusAlertPopup(obj):
Timer(0.5, nextHandler)
if shared.focusAlertPopup(obj):
Timer(0.75, nextHandler)
return
self.notificationHistory.append((datetime.now(), alertText))
self.notificationHistory.append((datetime.now(), alertText.replace("\n", "\t")))
nextHandler()

def script_status(self, gesture):
Expand Down Expand Up @@ -108,47 +100,24 @@ def script_toolsBar(self, gesture):
script_toolsBar.__doc__ = _("Shows a list of opened tabs. If pressed twice quickly, shows buttons of tool bar.")


def script_openNotification(self, gesture):
if not self.inMainWindow():
ui.message(_("Not available here"))
return
def script_notifications(self, gesture):
obj = api.getForegroundObject().simpleFirstChild
if obj.role == controlTypes.ROLE_ALERT:
if api.getFocusObject().parent == obj: # Already focused
ui.message(obj.description)
speech.speakObject(obj)
speech.speakObject(api.getFocusObject())
return
if self.focusAlertPopup(obj):
if shared.focusAlertPopup(obj):
speech.speakObject(api.getFocusObject())
return
if self.notificationHistory:
def elapsedFromTimestamp(timestamp):
delta = datetime.now()-timestamp
d = -delta.days
h, r = divmod(delta.seconds, 3600)
m, s = divmod(r, 60)
if d == 1:
return "Yesterday"
if d > 1:
return "%d days ago" % d
if h == 1:
return _("About an hour ago")
elif h > 1:
return _("About %d hours ago") % h
if m == 1:
return _("About a minute ago")
elif m > 1:
return _("About %d minutes ago") % m
if s == 1:
return _("a second ago")
elif s > 1:
return _("%d seconds ago") % s
if scriptHandler.getLastScriptRepeatCount() == 1:
ui.browseableMessage("\n".join(["%s: %s" % (elapsedFromTimestamp(notification[0]), notification[1]) for notification in self.notificationHistory]), _("Notification History"))
ui.browseableMessage("\n".join(["%s: %s" % (shared.elapsedFromTimestamp(notification[0]), notification[1]) for notification in self.notificationHistory]), "%s - Firefox" % _("Notification History"))
else:
ui.message(_("Last alert, %s: %s") % (elapsedFromTimestamp(self.notificationHistory[-1][0]), self.notificationHistory[-1][1]))
ui.message(_("Last alert, %s: %s") % (shared.elapsedFromTimestamp(self.notificationHistory[-1][0]), self.notificationHistory[-1][1]))
else:
ui.message(_("There is no notification"))
script_openNotification.__doc__ = _("Reads the last notification and it takes the system focus to it if it is possible. By pressing two times quickly shows the history of notifications.")
script_notifications.__doc__ = _("Reads the last notification and it takes the system focus to it if it is possible. By pressing two times quickly shows the history of notifications.")

def script_focusDocument(self, gesture):
if not self.inMainWindow():
Expand All @@ -173,18 +142,6 @@ def script_focusDocument(self, gesture):
pass
script_focusDocument.__doc__ = _("Brings the focus to the document")

def focusAlertPopup(self, alertPopup):
if True:
obj = alertPopup.firstChild
while obj and not obj.isFocusable:
obj = obj.next
if obj:
obj.scrollIntoView()
obj.setFocus()
Timer(0.1, speech.cancelSpeech)
return True
return False

def getTabsDialog(self):
tabs = ""
fg = api.getForegroundObject()
Expand Down Expand Up @@ -241,7 +198,7 @@ def inMainWindow(self):
"kb:NVDA+F8": "toolsBar",
"kb(desktop):NVDA+A": "url",
"kb(laptop):NVDA+Control+A": "url",
"kb:NVDA+Control+N": "openNotification",
"kb:NVDA+Control+N": "notifications",
"kb:NVDA+F6": "focusDocument"
}

Expand Down Expand Up @@ -313,15 +270,3 @@ def moveMouseToObj(self):
return (True)
return(False)

class alertPopup(Dialog):
pass

class alertPopupChild(IAccessible):

def script_title(self, gesture):
ui.message("titulo de la alerta")
ui.message(self.container.description)

__gestures = {
filter(lambda g: g[1].__name__ == "script_title", globalCommands.commands._gestureMap.iteritems())[0][0]: "title"
}
62 changes: 62 additions & 0 deletions addon/appModules/shared/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Mozilla Scripts version 1.4 (Dec-2017)
# Shared code for both appmodules
# Author Javi Dominguez <fjavids@gmail.com>
# License GNU GPL

from datetime import datetime, timedelta
from threading import Timer
import speech
import controlTypes
import api
import addonHandler

addonHandler.initTranslation()

def focusAlertPopup(alertPopup, SETFOCUS = True):
if alertPopup.role != controlTypes.ROLE_ALERT:
return False
obj = alertPopup.firstChild
while obj and not obj.isFocusable:
obj = obj.next
if obj:
if api.getFocusObject() == obj:
return True
if SETFOCUS: # Else returns True to indicate that popup is focusable but does not perform the action.
obj.scrollIntoView()
obj.setFocus()
api.setFocusObject(obj)
speech.speakObject(alertPopup)
Timer(0.05, speech.cancelSpeech)
return True
return False

def elapsedFromTimestamp(timestamp):
delta = datetime.now()-timestamp
d = -delta.days
h, r = divmod(delta.seconds, 3600)
m, s = divmod(r, 60)
if d == 1:
return "Yesterday"
if d > 1:
return "%d days ago" % d
if h == 1:
return _("About an hour ago")
elif h > 1:
return _("About %d hours ago") % h
if m == 1:
return _("About a minute ago")
elif m > 1:
return _("About %d minutes ago") % m
if s == 1:
return _("a second ago")
elif s > 1:
return _("%d seconds ago") % s

def getAlertText(alertPopup):
alertText = alertPopup.name if alertPopup.name else alertPopup.description if alertPopup.description else alertPopup.displayText if alertPopup.displayText else ""
for obj in alertPopup.recursiveDescendants:
objText = obj.name if obj.name else obj.description if obj.description else obj.displayText if obj.displayText else ""
if not obj.isFocusable and objText not in alertText:
alertText = "%s %s" % (alertText, objText)
return alertText

36 changes: 34 additions & 2 deletions addon/appModules/thunderbird.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Mozilla Thunderbird Scripts version 1.1.0 (apr 2017)
# Mozilla Thunderbird Scripts version 1.4 (Dec-2017)
# Author Javi Dominguez <fjavids@gmail.com>
# License GNU GPL

from nvdaBuiltin.appModules import thunderbird
from time import time
from datetime import datetime
from NVDAObjects.IAccessible.mozilla import BrokenFocusedState
from tones import beep
import addonHandler
Expand All @@ -16,13 +17,17 @@
import gui
import wx
import globalCommands
import shared

addonHandler.initTranslation()

class AppModule(thunderbird.AppModule):

scriptCategory = _("mozilla Thunderbird")

lastIndex = 0
Dialog = None
notificationHistory = []

def chooseNVDAObjectOverlayClasses(self, obj, clsList):
# Overlay search box in fast filtering bar
Expand All @@ -48,6 +53,14 @@ def chooseNVDAObjectOverlayClasses(self, obj, clsList):
except AttributeError:
pass

def event_alert(self, obj, nextHandler):
alertText = obj.name if obj.name else obj.description if obj.description else obj.displayText if obj.displayText else ""
if shared.focusAlertPopup(obj,
SETFOCUS = False if controlTypes.STATE_EDITABLE in api.getFocusObject().states else True):
return
self.notificationHistory.append((datetime.now(), alertText.replace("\n", "\t")))
nextHandler()

def script_readAddressField(self, gesture):
try:
index = int(gesture.keyName[-1])-1
Expand Down Expand Up @@ -129,6 +142,24 @@ def script_focusDocument(self, gesture):
pass
script_focusDocument.__doc__ = _("Brings the focus to the text of the open message.")

def script_notifications(self, gesture):
obj = self.getPropertyPage().simpleLastChild.simplePrevious
if obj.role == controlTypes.ROLE_ALERT:
if api.getFocusObject().parent == obj: # Already focused
ui.message(shared.getAlertText(obj))
speech.speakObject(api.getFocusObject())
return
if shared.focusAlertPopup(obj):
return
if self.notificationHistory:
if scriptHandler.getLastScriptRepeatCount() == 1:
ui.browseableMessage("\n".join(["%s: %s" % (shared.elapsedFromTimestamp(notification[0]), notification[1]) for notification in self.notificationHistory]), "%s - Thunderbird" % _("Notification History"))
else:
ui.message(_("Last alert, %s: %s") % (shared.elapsedFromTimestamp(self.notificationHistory[-1][0]), self.notificationHistory[-1][1]))
else:
ui.message(_("There is no notification"))
script_notifications.__doc__ = _("Reads the last notification and it takes the system focus to it if it is possible. By pressing two times quickly shows the history of notifications.")

def addressField(self, index, rightClick):
if self.isDocument():
fields = []
Expand Down Expand Up @@ -179,7 +210,8 @@ def getPropertyPage(self):
"kb:Control+Shift+6": "messageDate",
"kb:NVDA+H": "manageColumns",
"kb:Control+Shift+A": "attachments",
"kb:NVDA+F6": "focusDocument"
"kb:NVDA+F6": "focusDocument",
"kb:NVDA+Control+N": "notifications"
}

class SearchBox(BrokenFocusedState):
Expand Down
2 changes: 1 addition & 1 deletion addon/doc/pt_BR/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* NVDA + A (desktop) ou NVDA + Control + A (laptop) Lê o endereço da página. Se pressionado duas vezes rapidamente, copia-o para a área de transferência.
* NVDA + End (desktop) ou NVDA + Shift + End (laptop) Lê a barra de estado. Se pressionado duas vezes rapidamente, copia-a para a área de transferência.
* NVDA + F8 Mostra uma lista de separadores abertos. Se pressionado duas vezes rapidamente, mostra os botões da barra de ferramentas.
* NVDA + Control + N Mostra a notificação se houver alguma.
* NVDA + Control + N a última notificação e leva para lá o foco do sistema se for possível. Pressionando duas vezes rapidamente mostra o histórico das notificações.
* NVDA + F6 Traz o foco para o documento.

## Thunderbird
Expand Down
4 changes: 2 additions & 2 deletions addon/doc/pt_PT/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* NVDA + A (desktop) ou NVDA + Control + A (laptop) Lê o endereço da página. Se pressionado duas vezes rapidamente, copia-o para a área de transferência.
* NVDA + End (desktop) ou NVDA + Shift + End (laptop) Lê a barra de estado. Se pressionado duas vezes rapidamente, copia-a para a área de transferência.
* NVDA + F8 Mostra uma lista de separadores abertos. Se pressionado duas vezes rapidamente, mostra os botões da barra de ferramentas.
* NVDA + Control + N Mostra a notificação se houver alguma.
* NVDA + Control + N a última notificação e leva para lá o foco do sistema se for possível. Pressionando duas vezes rapidamente mostra o histórico das notificações.
* NVDA + F6 Traz o foco para o documento.

## Thunderbird
Expand All @@ -17,7 +17,7 @@
* Controle + Shift + 5 Lê o assunto da mensagem.
* Controle + Shift + 6 Lê a data da mensagem.
* Controle + Shift + A Traz o foco para a lista de anexos, se houver algum.
(Estes scripts também estão disponíveis na lista de mensagens se você ativar o painel de visualização).
(Estes scripts também estão disponíveis na lista de mensagens se activar o painel de visualização).
* Na barra de filtragem rápida:
* Pressione seta para baixo para mostrar mais opções, enter para marcar / desmarcar a opção seleccionada.
* Na lista de mensagens:
Expand Down
Loading

0 comments on commit a4beedb

Please sign in to comment.