Skip to content

Commit

Permalink
V2409.11 : TB 128, Escape from empty message list, message list info …
Browse files Browse the repository at this point in the history
…with filtered number
  • Loading branch information
RPTools-org committed Sep 12, 2024
1 parent e766814 commit 757a395
Show file tree
Hide file tree
Showing 18 changed files with 773 additions and 810 deletions.
29 changes: 29 additions & 0 deletions 2409.10.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"addonId": "thunderbirdPlusG5",
"displayName": "Thunderbird+G5 (TB 115 & 128 ESR)\u0003",
"URL": "",
"description": "This add-on significantly increases the efficiency and comfort of using Thunderbird 115 with NVDA.\nFor more information, visit :\nhttps://www.rptools.org/NVDA-Thunderbird/get.php?pg=manual&v=g5&lang=en",
"sha256": "70b4020d5379b5a3e879812ab7e66f58bd8c36868bcfd71bfee95a582bbcf6c9",
"homepage": "https://www.rptools.org/NVDA-Thunderbird/index.html",
"addonVersionName": "2409.10.00",
"addonVersionNumber": {
"major": 2409,
"minor": 10,
"patch": 0
},
"minNVDAVersion": {
"major": 2021,
"minor": 1,
"patch": 0
},
"lastTestedVersion": {
"major": 2024,
"minor": 1,
"patch": 0
},
"channel": "None",
"publisher": "",
"sourceURL": "https://github.com/RPTools-org/thunderbirdPlusG5",
"license": null,
"licenseURL": null
}
29 changes: 29 additions & 0 deletions 2409.11.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"addonId": "thunderbirdPlusG5",
"displayName": "Thunderbird+G5 (TB 115 & 128 ESR)\u0003",
"URL": "",
"description": "This add-on significantly increases the efficiency and comfort of using Thunderbird 115 with NVDA.\nFor more information, visit :\nhttps://www.rptools.org/NVDA-Thunderbird/get.php?pg=manual&v=g5&lang=en",
"sha256": "e58ce1f06a6cedd4418df760b9855233886c8aeeb5ba5e19c5d0ea22e6532009",
"homepage": "https://www.rptools.org/NVDA-Thunderbird/index.html",
"addonVersionName": "2409.11.00",
"addonVersionNumber": {
"major": 2409,
"minor": 11,
"patch": 0
},
"minNVDAVersion": {
"major": 2021,
"minor": 1,
"patch": 0
},
"lastTestedVersion": {
"major": 2024,
"minor": 1,
"patch": 0
},
"channel": "None",
"publisher": "",
"sourceURL": "https://github.com/RPTools-org/thunderbirdPlusG5",
"license": null,
"licenseURL": null
}
2 changes: 1 addition & 1 deletion addon/appModules/shared/sharedVars.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
virtualSpellChk = False
delayFocusDoc = 20
testMode = False
debugLog = ""
debugLog = ""

import quoteNav
def initQuoteNav() :
Expand Down
102 changes: 98 additions & 4 deletions addon/appModules/shared/utils115.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ def isFolderTreeItem(fti, ID="") :
if gRegFTI.findall(ID) : return True
return False

def currentTree(o, role) :
if role not in (controlTypes.Role.TREEVIEWITEM, controlTypes.Role.LISTITEM, controlTypes.Role.TABLE) :
return ""
o = o.parent
while o :
r = o.role
if r == controlTypes.Role.TEXTFRAME :
if hasID(o, "threadTree") :
return "t"
if r == controlTypes.Role.TREEVIEW :
if hasID(o, "folderTree") :
return "f"
o = o.parent
return""

def isQuickfilterBar(o) :
try : o = o.parent
except : return False
Expand Down Expand Up @@ -376,7 +391,7 @@ def getThreadTreeFromFG(focus=False, nextGesture="", getThreadPane=False, pp=Non
# finally :
# sharedVars.objLooping = prevLooping

def getMessageStatus(infoIdx=-1) :
def getMessageStatus115(infoIdx=-1) :
try : # finally
prevLooping = sharedVars.objLooping
sharedVars.objLooping = True
Expand All @@ -386,13 +401,15 @@ def getMessageStatus(infoIdx=-1) :
# level 9, 2 of 3, name : 11 messages sélectionnés, Role.STATICTEXT, left:359, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i2, Role-STATICTEXT,
# level 9, 3 of 3, Role.STATICTEXT, left:493, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i3, Role-STATICTEXT,
# get threadPane
o = getThreadTreeFromFG(focus=False, nextGesture="", getThreadPane=True)
threadPane = getThreadTreeFromFG(focus=False, nextGesture="", getThreadPane=True)
# get | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION,
o = o.firstChild.firstChild
o = threadPane.firstChild.firstChild
# get | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer
# the following line is OK in TB 128.
o = findChildByRoleID(o, controlTypes.Role.SECTION, "threadPaneFolderCountContainer")
# return "examine le journal tbp "
# sharedVars.log(o, "threadPaneFolderCountContainer")
if not o : return ""

if infoIdx > -1 and infoIdx < 4 :
try : return o.getChild(infoIdx).name
except : return ""
Expand All @@ -408,6 +425,83 @@ def getMessageStatus(infoIdx=-1) :
finally :
sharedVars.objLooping = prevLooping

def getFilterInfos128(threadPane, infos=False) :
# children of threadPane : | i1, 86, , IA2ID : quick-filter-bar | i0, 86, , IA2ID : quickFilterBarContainer | i7, 91, , IA2ID : qfb-results-label
o = findChildByRoleID(threadPane, controlTypes.Role.SECTION, ID="quick-filter-bar",startIdx=0)
if not o : return "", ""
o = oContainer = findChildByRoleID(o, controlTypes.Role.SECTION, ID="quickFilterBarContainer",startIdx=0)
if not o : return "", ""
o = findChildByRoleID(o, controlTypes.Role.TEXTFRAME, ID="qfb-results-label",startIdx=6)
count = ""
if o and o.firstChild :
count = _("Filtered : ") + str(o.firstChild.name) + " / "
if not infos :
return count, ""
# 2. retrieve filter infos
word = options = ""
# keyword edit : path = | i0, 86, , IA2ID : quickFilterBarContainer | i1, 91, , IA2ID : qfb-qs-textbox | i0, 39, | i0, 8, ,
o = oContainer.getChild(1).firstChild.firstChild # new in TB 128
if o.role == controlTypes.Role.EDITABLETEXT and o.value :
word = str(o.value)
# toggle buttons
o = oContainer.getChild(2) # unread toggle button
while o :
if o.role == controlTypes.Role.TOGGLEBUTTON and controlTypes.State.PRESSED in o.states :
options += o.name + ", "
# # sharedVars.log(o, "child")
o = o.next
# # sharedVars.logte(infos)
filtExpr = ""
if word or options :
filtExpr = ", " + _("Filter : ")
if word :
filtExpr += word + ", "
if options :
filtExpr += options
return count, filtExpr
def getMessageStatus128(infoIdx=-1) :
# returns total messages, filter infos
try : # finally
prevLooping = sharedVars.objLooping
sharedVars.objLooping = True
# level 8, 1 of 1, Role.SECTION, IA2ID : threadPaneFolderCountContainer, left:272 Tag: div, States : , childCount : 4 Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer
# level 9, 0 of 3, name : 13 messages, Role.STATICTEXT, left:281, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i0, Role-STATICTEXT,
# level 9, 1 of 3, Role.STATICTEXT, left:347, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i1, Role-STATICTEXT,
# level 9, 2 of 3, name : 11 messages sélectionnés, Role.STATICTEXT, left:359, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i2, Role-STATICTEXT,
# level 9, 3 of 3, Role.STATICTEXT, left:493, States : Path : Role-FRAME| i31, Role-GROUPING, , IA2ID : tabpanelcontainer | i2, Role-PROPERTYPAGE, , IA2ID : mail3PaneTab1 | i0, Role-INTERNALFRAME, , IA2ID : mail3PaneTabBrowser1 | i0, Role-GROUPING, | i2, Role-SECTION, , IA2ID : threadPane | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION, | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer | i3, Role-STATICTEXT,
# get threadPane
threadPane = getThreadTreeFromFG(focus=False, nextGesture="", getThreadPane=True)
# get | i0, Role-SECTION, , IA2ID : threadPaneHeaderBar | i0, Role-SECTION,
o = threadPane.firstChild.firstChild
# get | i1, Role-SECTION, , IA2ID : threadPaneFolderCountContainer
# the following line is OK in TB 128.
o = findChildByRoleID(o, controlTypes.Role.SECTION, "threadPaneFolderCountContainer")
# sharedVars.log(o, "threadPaneFolderCountContainer")
if not o : return ""
# 128 specific
if infoIdx > -1 and infoIdx < 4 :
try : return o.getChild(infoIdx).name
except : return ""
# all fields
# filtered message count
t, filterInfos = getFilterInfos128(threadPane, infos=True)
o = o.firstChild
while o :
# sharedVars.log(o, "Nombre ")
if o.name :
t += o.name + ", "
o = o.next
if t : t = t[:-2]
return t + filterInfos
finally :
sharedVars.objLooping = prevLooping

def getMessageStatus(infoIdx=-1) :
if sharedVars.TBMajor < 128 :
return getMessageStatus115(infoIdx)
else :
return getMessageStatus128(infoIdx)

def silentSendKey(key) :
KeyboardInputGesture.fromName (key).send()
setSpeechMode(prevSpeechMode)
Expand Down
86 changes: 45 additions & 41 deletions addon/appModules/thunderbird.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,17 +463,22 @@ def script_sharedTab(self, gesture) :
def script_sharedEscape(self, gesture) :
o=api.getFocusObject()
role = o.role
curTreeType = utils.currentTree(o, role)
if curTreeType == "f" :
return KeyboardInputGesture.fromName ("f6").send()

ID = str(utils.getIA2Attr(o))
if ID.startswith("threadTree-row") :
if hasFilter(o, ID) :
wx.CallAfter(ui.message, _("Filter removed"))
return gesture.send()
return utils.getFolderTreeFromFG(True)
elif utils.isFolderTreeItem(o, ID) :
if utils.getIA2Attr(o, "2", "level") :
return utis.sendKey("tab", 1)
else :
return utils.getThreadTreeFromFG(True)
if curTreeType == "t" : # threadTree
if ID.startswith("threadTree-row") :
if hasFilter(o, ID) :
wx.CallAfter(ui.message, _("Filter removed"))
return gesture.send()
return KeyboardInputGesture.fromName ("shift+f6").send() # utils.getFolderTreeFromFG(True)
# elif utils.isFolderTreeItem(o, ID) :
# if utils.getIA2Attr(o, "2", "level") :
# return utis.sendKey("tab", 1)
# else :
# return utils.getThreadTreeFromFG(True)
elif "Recipient" in ID or "expandedsubjectBox" in ID or "Recipient" in str(utils.getIA2Attr(o.parent)) : # header pane
return KeyboardInputGesture.fromName ("shift+f6").send()
elif role in (controlTypes.Role.BUTTON, controlTypes.Role.TOGGLEBUTTON) and ID.startswith("attachment") :
Expand Down Expand Up @@ -508,7 +513,7 @@ def script_sharedEscape(self, gesture) :
elif role == controlTypes.Role.EDITABLETEXT and utils.hasID(o.parent, "MsgHeadersToolbar") : # write window
if sharedVars.oSettings.getOption("compose", "closeMessageWithEscape") :
return KeyboardInputGesture.fromName ("control+w").send ()
elif role in (controlTypes.Role.LIST, controlTypes.Role.TREEVIEW) and utils.hasID(o.parent.parent, "threadTree") :
elif role in (controlTypes.Role.LIST, controlTypes.Role.TREEVIEW, controlTypes.Role.TABLE) and utils.hasID(o.parent.parent, "threadTree") : # 2024.09.08 added Role.TABLE
if hasFilter(o, "threadTree-row") :
wx.CallAfter(ui.message, _("Filter removed"))
return gesture.send()
Expand All @@ -526,7 +531,6 @@ def script_sharedEscape(self, gesture) :
def script_sharedAltEnd(self, gesture) :
o = api.getFocusObject()
if utils.hasID(o, "threadTree") or utils.hasID(o.parent, "quickFilterBarContainer") :
# utils.sayQFBInfos(o)
msg = utils.getMessageStatus()
if not msg : msg = _("Blank")
ui.message(msg)
Expand Down Expand Up @@ -848,35 +852,27 @@ def script_showHelp(self, gesture) :
script_showHelp.category = sharedVars.scriptCategory

def script_displayDebug(self, gesture) :
# import versionInfo
# text = str(versionInfo.version_year)[2:] +"." + str(versionInfo.version_major) + "." + str(versionInfo.version_minor)
# api.copyToClip(text)

# text = langUtils.getPHPTable()
# api.copyToClip(text)
# return
# utis.listGestFromScanCodes()
# return
# winVerAlert()
# if sharedVars.curFrame == "messengerWindow" :
# utis.isChichi()
# sharedVars.debugLog += "\nChichi : " + str(sharedVars.chichi)
# # sharedVars.debugLog += "\nObjLooping : " + str(sharedVars.objLooping) + "\n"
# # sharedVars.debugLog += "\nvirtualSpellChk : " + str(sharedVars.virtualSpellChk) + "\n"
debugShow(self, False)

def script_initDebug(self, gesture) :
# disabModes : 0 nothing, 1 choose overlay, 2 : object init, 3 gainFocus
self.disabMode +=1
if self.disabMode > 3 : self.disabMode = 0
if self.disabMode == 0 : mode = u"Aucune désactivation"
elif self.disabMode == 1 : mode = u"Désactivation de l'intercepteur."
elif self.disabMode == 2 : mode = u"Désactivation de l'initialisation des objets NVDA."
elif self.disabMode == 3 : mode = u"Désactivation de gain focus."
else : mode = "disabMode = " + str(self.disabMode)

ui.message(mode)

if sharedVars.debug :
sharedVars.debug = False
ui.message("Debug mode is disabled")
else :
sharedVars.debug = True
ui.message("Debug mode is enabled")

# # disabModes : 0 nothing, 1 choose overlay, 2 : object init, 3 gainFocus
# self.disabMode +=1
# if self.disabMode > 3 : self.disabMode = 0
# if self.disabMode == 0 : mode = u"Aucune désactivation"
# elif self.disabMode == 1 : mode = u"Désactivation de l'intercepteur."
# elif self.disabMode == 2 : mode = u"Désactivation de l'initialisation des objets NVDA."
# elif self.disabMode == 3 : mode = u"Désactivation de gain focus."
# else : mode = "disabMode = " + str(self.disabMode)

# ui.message(mode)

__gestures = {
# utis.gestureFromScanCode(41, "kb:") :"showContextMenu", # 41 is the scancode of the key above Tab
# utis.gestureFromScanCode(41, "kb:shift+") :"showOptionMenu",
Expand Down Expand Up @@ -944,7 +940,8 @@ def script_initDebug(self, gesture) :
}

def debugShow(appMod, auto) :
# sharedVars.logte("curWinTitle=" + sharedVars.curWinTitle)
sharedVars.debugLog = "Debug mode : {}, TB branch : {}".format(str(sharedVars.debug), sharedVars.TBMajor) + "\n" + "\n" + sharedVars.debugLog
# sharedredVars.logte("curWinTitle=" + sharedVars.curWinTitle)
# nom = utils.getColValue(api.getFocusObject(), "subjectcol")
# sharedVars.logte("Valeur colonne=" + nom)
# oRow = api.getFocusObject()
Expand All @@ -956,14 +953,14 @@ def debugShow(appMod, auto) :
# textDialog.showText(title="Log", text=sharedVars.debugLog)
# return
# provisoire
textDialog.showText(title="Log", text=sharedVars.debugLog)
# textDialog.showText(title="Log", text=sharedVars.debugLog)
# sharedVars.log(no, "Nav object")
fo = api.getFocusObject()
if utils.hasID(fo, "threadTree-row" ) :
# sharedVars.logte("Current row original name :\n" + sharedVars.curTTRow)
utils.listAscendants(-6)
utils.listDescendants(fo, 0, "* List of descendants")
utils.listColumnNames(fo)
# utils.listColumnNames(fo)
else :
utils.listAscendants(-6)
utils.listDescendants(fo, 0, "* List of descendants")
Expand Down Expand Up @@ -1016,6 +1013,13 @@ def removeResponseMention (appMod,s,mode):
return s

def hasFilter(o, ID=None) :
if sharedVars.TBMajor > 127 :
tp = utis.findParentByID(o,controlTypes.Role.SECTION, "threadPane")
if not tp : return False
cnt, inf = utils.getFilterInfos128(tp)
return True if cnt else False

# TB 115
if not ID :
ID = str(utils.getIA2Attr(o))
if ID.startswith("threadTree-row") :
Expand Down
6 changes: 3 additions & 3 deletions addon/doc/en/readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Thunderbird+G5 for Thunderbird >= 115
# Thunderbird+G5 for Thunderbird 115 and 128 ESR

* Authors: Pierre-Louis Renaud (From Thunderbird 78 to 115) & Cyrille Bougot (TB 102), Daniel Poiraud (From TB 78 to 91), Yannick (TB 45 to 60);
* URL: [thunderbird+ G5 and G4 add-ons home page][4] ;
[History of changes at RPTools.org][5] ;
[History of changes and additional documentation][5] ;
[Contact in French or English][6] ;
* Download [stable version][3]
* Installation: NVDA menu / Tools / Add-on store / available extensions or updates tab;;
* Download [Latest version from RPTools.org][3] ;
* NVDA compatibility: 2021.1 and later;
* [Source code on gitHub][2]
Expand Down
6 changes: 3 additions & 3 deletions addon/doc/fr/readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Thunderbird+G5 pour Thunderbird >= 115
# Thunderbird+G5 pour Thunderbird 115 et 128 ESR

* Auteurs: Pierre-Louis Renaud (de Thunderbird 78 à 115) & Cyrille Bougot (TB 102), Daniel Poiraud (de TB 78 à 91), Yannick (TB 45 à 60);
* URL: [Page d'accueil des extensions thunderbird+ G5 et G4][4] ;
[Historique des changements][5] ;
[Historique des changements et compléments de documentation][5] ;
[Contact][6] ;
* Télécharger : [Version stable][3]
* Installation : menu NVDA / Outils / Add-on store / onglet extensions disponibles ou mises à jour ;;
* Télécharger : [Dernière version sur RPTools.org][3] ;
* Ccompatibilité NVDA : 2021.1 et ultérieures ;
* [Code Source sur gitHub][2]
Expand Down
Loading

0 comments on commit 757a395

Please sign in to comment.