-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Changed the strecture of the code, added the ability to wrap in nvda …
…find, and added a setting to turn off the beeps caused by wrapping.
- Loading branch information
1 parent
2c917c0
commit 4fa67f6
Showing
5 changed files
with
245 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# screenWrapping | ||
# Copyright 2018 Hamada Trichine, released under GPLv2. | ||
|
||
import config | ||
from speech import cancelSpeech | ||
from ui import message | ||
from tones import beep | ||
|
||
|
||
DIRECTION_NEXT = "next" | ||
DIRECTION_PREV = "previous" | ||
|
||
def playBeep(hz, length): | ||
if config.conf["screenWrapping"]["turnOnBeeps"]: | ||
beep(hz, length) | ||
|
||
def alertWrp(direction): | ||
cancelSpeech() | ||
if direction == DIRECTION_PREV: | ||
# Translators: Text spoken when screen wrapping to bottom. | ||
message(_("wrapping to bottom")) | ||
playBeep(100, 80) | ||
else: | ||
# Translators: Text spoken when screen wrapping to top. | ||
message(_("wrapping to top")) | ||
playBeep(500, 80) | ||
|
||
def alertToggleFunctionality(state): | ||
if state: | ||
message( | ||
# Translators: Text spoken when screen rapping is turned off. | ||
_("Screen wrapping off.")) | ||
playBeep(100,150) | ||
else: | ||
message( | ||
# Translators: Text spoken when screen rapping is turned on. | ||
_("Screen wrapping on.")) | ||
playBeep(400,150) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# screenWrapping | ||
# Copyright 2018 Hamada Trichine, released under GPLv2. | ||
|
||
import wx | ||
import textInfos | ||
import speech | ||
import controlTypes | ||
from core import callLater | ||
from cursorManager import CursorManager | ||
from gui import guiHelper, messageBox | ||
from gui.contextHelp import ContextHelpMixin | ||
from . import wrappingAlerts | ||
|
||
|
||
class CustomFindDialog(ContextHelpMixin, wx.Dialog, ): | ||
helpId = "SearchingForText" | ||
def __init__(self, parent, cursorManager, text, isCaseSensitive, reverse=False): | ||
# Translators: the title of the find dialog | ||
super().__init__(parent=parent, title=_("Find")) | ||
self.currentCursorManager = cursorManager | ||
self.reverse = reverse | ||
|
||
dialogSizer = wx.BoxSizer(wx.VERTICAL) | ||
helperSizer = guiHelper.BoxSizerHelper(self, orientation=wx.VERTICAL) | ||
# Translators: a label for the edit text box where you type your search query | ||
editTextLabel = _("Type the text you wish to find") | ||
self.findTextField = helperSizer.addLabeledControl(editTextLabel, wx.TextCtrl, value=text) | ||
self.caseSensitiveCheckBox = wx.CheckBox(self, wx.ID_ANY, label=_("Case &sensitive")) | ||
self.caseSensitiveCheckBox.SetValue(isCaseSensitive) | ||
# Translators: An option in the find dialog to allow wrapping on search. | ||
self.wrapAroundCheckBox = wx.CheckBox(self, wx.ID_ANY, label=_("&Wrap around")) | ||
self.wrapAroundCheckBox.SetValue(self.currentCursorManager._wrapFind) | ||
helperSizer.addItem(self.caseSensitiveCheckBox) | ||
helperSizer.addItem(self.wrapAroundCheckBox) | ||
helperSizer.addDialogDismissButtons(self.CreateButtonSizer(wx.OK|wx.CANCEL)) | ||
dialogSizer.Add(helperSizer.sizer, border=guiHelper.BORDER_FOR_DIALOGS, flag=wx.ALL) | ||
dialogSizer.Fit(self) | ||
|
||
self.SetSizer(dialogSizer) | ||
self.CentreOnScreen() | ||
self.SetFocus() | ||
self.findTextField.SetFocus() | ||
|
||
self.Bind(wx.EVT_BUTTON, self.onOk, id=wx.ID_OK) | ||
self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL) | ||
|
||
def onOk(self, event): | ||
searchQuery = self.findTextField.GetValue() | ||
isCaseSensitive = self.caseSensitiveCheckBox.GetValue() | ||
CursorManager._wrapFind = self.wrapAroundCheckBox.GetValue() | ||
callLater(100, self.currentCursorManager.doFindText, searchQuery, caseSensitive=isCaseSensitive, reverse=self.reverse) | ||
self.Destroy() | ||
|
||
def onCancel(self, event): | ||
self.Destroy() | ||
|
||
|
||
def speakFindResult(currentCursorManager, textInfoRange, result, willSayAllResume): | ||
currentCursorManager.selection = textInfoRange | ||
textInfoRange.move(textInfos.UNIT_LINE,1,endPoint="end") | ||
if not willSayAllResume: | ||
speech.speakTextInfo(textInfoRange, reason=controlTypes.OutputReason.CARET) | ||
|
||
def customDoFindText(cursorManagerInst, text, reverse=False, caseSensitive=False, willSayAllResume=False): | ||
if not text: | ||
return | ||
textInfoRange = cursorManagerInst.makeTextInfo(textInfos.POSITION_CARET) | ||
result = textInfoRange.find(text, reverse=reverse, caseSensitive=caseSensitive) | ||
if result: | ||
speech.cancelSpeech() | ||
speakFindResult(cursorManagerInst, textInfoRange, result, willSayAllResume) | ||
else: | ||
textInfoRange=cursorManagerInst.makeTextInfo(textInfos.POSITION_LAST if reverse else textInfos.POSITION_FIRST) | ||
result = textInfoRange.find(text,reverse=reverse,caseSensitive=caseSensitive) | ||
if not cursorManagerInst._wrapFind or not result: | ||
wx.CallAfter(messageBox, _('text "%s" not found') % text, _("Find Error"), wx.OK|wx.ICON_ERROR) | ||
else: | ||
wrappingAlerts.alertWrp(wrappingAlerts.DIRECTION_NEXT if not reverse else wrappingAlerts.DIRECTION_PREV) | ||
speakFindResult(cursorManagerInst, textInfoRange, result, willSayAllResume) | ||
|
||
CursorManager._lastFindText = text | ||
CursorManager._lastCaseSensitivity = caseSensitive |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# screenWrapping | ||
# Copyright 2018 Hamada Trichine, released under GPLv2. | ||
|
||
import textInfos | ||
from core import callLater | ||
from ui import message | ||
from scriptHandler import willSayAllResume | ||
from speech import cancelSpeech | ||
from tones import beep | ||
from . import wrappingAlerts | ||
|
||
|
||
def getCurrentPos(treeInterceptor): | ||
posDelta = treeInterceptor.makeTextInfo(textInfos.POSITION_FIRST) | ||
posDelta.setEndPoint(treeInterceptor.makeTextInfo(textInfos.POSITION_CARET), "endToStart") | ||
return len(posDelta.text) | ||
|
||
def resetPosition(treeInterceptor, offset, errorMessage): | ||
cursor = treeInterceptor.makeTextInfo(textInfos.POSITION_FIRST) | ||
cursor.move(textInfos.UNIT_CHARACTER, offset) | ||
if hasattr(treeInterceptor, "selection"): | ||
treeInterceptor.selection = cursor | ||
else: | ||
cursor.updateCaret() | ||
cancelSpeech() | ||
cursor.move(textInfos.UNIT_LINE,1,endPoint="end") | ||
message(errorMessage) | ||
|
||
def updatePosition(treeInterceptor, position): | ||
cursor = treeInterceptor.makeTextInfo(position) | ||
cursor.updateCaret() | ||
cancelSpeech() | ||
|
||
def initNavItemsGenerator(treeInterceptor, itemType): | ||
if itemType=="notLinkBlock": | ||
return treeInterceptor._iterNotLinkBlock | ||
else: | ||
return lambda direction, info: treeInterceptor._iterNodesByType(itemType, direction, info) | ||
|
||
def screenWrapping(treeInterceptor, itemType, readUnit, wrp2, reverse="previous", direction="next"): | ||
updatePosition(treeInterceptor, wrp2) | ||
navItems = initNavItemsGenerator(treeInterceptor, itemType) | ||
try: | ||
wrapping = next(navItems(direction, treeInterceptor.selection)) | ||
wrappingAlerts.alertWrp(direction) | ||
wrapping.moveTo() | ||
try: | ||
wrapping = next(navItems(reverse, treeInterceptor.selection)) | ||
callLater(300,wrapping.moveTo) | ||
except StopIteration: | ||
pass | ||
wrapping.report(readUnit=readUnit) | ||
return True | ||
except StopIteration: | ||
pass | ||
|
||
def quickNavWrapping(treeInterceptor, gesture, itemType, direction, errorMessage, readUnit): | ||
iterFactory = initNavItemsGenerator(treeInterceptor, itemType) | ||
try: | ||
item = next(iterFactory(direction, treeInterceptor.selection)) | ||
except NotImplementedError: | ||
# Translators: a message when a particular quick nav command is not supported in the current document. | ||
message(_("Not supported in this document")) | ||
return | ||
except StopIteration: | ||
if direction == "next": | ||
lastPos = getCurrentPos(treeInterceptor) | ||
if not screenWrapping(treeInterceptor, itemType, readUnit, wrp2=textInfos.POSITION_FIRST): | ||
resetPosition(treeInterceptor, lastPos, errorMessage) | ||
else: | ||
lastPos = getCurrentPos(treeInterceptor) | ||
if not screenWrapping(treeInterceptor, itemType, readUnit, wrp2=textInfos.POSITION_LAST, reverse="next", direction="previous"): | ||
resetPosition(treeInterceptor, lastPos, errorMessage) | ||
return | ||
|
||
item.moveTo() | ||
if not gesture or not willSayAllResume(gesture): | ||
item.report(readUnit=readUnit) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# screenWrapping | ||
# Copyright 2018 Hamada Trichine, released under GPLv2. | ||
|
||
import wx, gui, config | ||
|
||
class ScreenWrappingSettings(gui.SettingsPanel): | ||
# Translators: The name of the addon. | ||
title = _("Screen Wrapping") | ||
|
||
def makeSettings(self, sizer): | ||
self.sizer = gui.guiHelper.BoxSizerHelper(self, sizer=sizer) | ||
# Translators: Text for the check box in the settings that turns on or off the beeps when wrapping. | ||
self.beepsCheckBox = self.sizer.addItem(wx.CheckBox(self, id=wx.ID_ANY, label=_("&Play a beep when wrapping"))) | ||
self.beepsCheckBox.SetValue(config.conf["screenWrapping"]["turnOnBeeps"]) | ||
|
||
def onSave(self): | ||
config.conf["screenWrapping"]["turnOnBeeps"] = self.beepsCheckBox.GetValue() | ||
|
||
def onDiscard(self): | ||
return |