Repository: nvaccess/nvda

Issue:
Have ability to show line number of document on Braille display
It is possible to have NVDA read line numbers in Word and other documents, however this information is not displayed on a connected Braille display and there is currently no setting to allow this information to be displayed.  (Feature request).



Discussion:
Hi,

@DKager: Any ideas on what we can do? Thanks.

hi
 happy to find some help at last
it can be related to pref. document reporting
as a marked V
please please support this feature
noelia from nvda addons suggested that 
perhaps modifying two functions of brailleHandler this can be reported automatically 
using a flag from pref. document reporting

its already 7 years avilable in  jaws so no reason not to add this.
in jaws it just adds the line number to the beginning of the line
like a seeing person would see in notepad++ like so:
1 blah blah some code and very long line even 
2 another line of code funny you reading it
3 well guess whats its more code hope this was enought
4 just kidding this is it i guess you got it

I expect NVDA can figure out line numbers in some way. So in that sense it can be done, though doing it only because another screen reader can do it is probably not good enough. For example, I find that I can get along by checking what line I'm on in Notepad++ through the status bar.

Technically it should be possible by extending braille.TextInfoRegion. It may require some work to make this compatible with braille.Region.focusToHardLeft, because presumably the line number should be visible at the very start of the line without being part of the text.

Hi Ilan and participants, I meant that perhaps these two functions of braille.py can be modified:
getBrailleTextForProperties and getControlFieldBraille.
This would be to report line numbers automatically.
Though imo it would be better to give the possibility of ask this information on request, for instance pressing NVDA+f twice, since other formatting changes can be useful too, or information as page numbers.
Thanks.

hi

imagine asking every time what is the line number 
your mind goes nuts because you loose focus
its not possible to create anything like that 

i mentioned jaws because thats what i'm used to as a programmer .
its hard to read and program code while using debugger
if you cant read the line number while coding i need to search for it
imagine if you will that as a blind person you would not be able to hear nvda say the line number while coding.
or as a seeing person seeing one line at a time not knowing where you are
and as general debugger can jump through huge ammount of lines 
back and forth its impossible right??
so thats my point

When I'm programing, I'm not looking at the line number each time.
I think it's not difficult to implement, or it seems not to be difficult.
If it's not implemented in NVDA, I don't know if it is so much risk 
developing an add-on monkey patching the mentioned functions.

El 10/05/2016 a las 17:56, shevetonline escribió:

> hi
> 
> imagine asking every time what is the line number
> your mind goes nuts because you loose focus
> its not possible to create anything like that
> 
> i mentioned jaws because thats what i'm used to as a programmer .
> its hard to read and program code while using debugger
> if you cant read the line number while coding i need to search for it
> imagine if you will that as a blind person you would not be able to hear
> nvda say the line number while coding.
> or as a seeing person seeing one line at a time not knowing where you are
> and as general debugger can jump through huge ammount of lines
> back and forth its impossible right??
> so thats my point
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub
> https://github.com/nvaccess/nvda/issues/5941#issuecomment-218203855

Back when I used a screen reader that showed the line numbers in Notepad++ if enabled, I actually disabled them because it got in the way. So my question was if there are people who do want to see all line numbers all the time, or if it would be enough to manually query for this. If you personally find this useful then I would welcome the additional functionality.

Let's simplify here.

If "Report line numbers" is enabled in Document Formatting preferences, line numbers get spoken at the start of the line (if the application supports retrieving this info). I don't personally find this useful--even as a programmer myself, I prefer to query the line on demand in the status bar--but the point is that it is included as an option for speech. We should just present the same information in braille depending on the same setting. The only change I'd suggest is that we should just braille the number with no "line" prefix as we have for speech.

Addressing a specific point:

> Technically it should be possible by extending braille.TextInfoRegion. It may require some work to make this compatible with braille.Region.focusToHardLeft, because presumably the line number should be visible at the very start of the line without being part of the text.

IMO, we shouldn't worry about focusToHardLeft for this. Those that want this probably do always want to see the line number without having to scroll back. It also gets ugly when you scroll to the next or previous line: should we skip the line number or not? And scrolling back is even worse, since it'd be very asymmetric.

Hi, replying to Jamie, imo your suggestion makes sense since it 
simplifies things and makes code consistent.
I don't like looking this on status bar since they can contain other 
info or be different between programs.
I don't know if the scope of this issue should be changed to cover page 
numbers, and include mor information in browseable message when pressing 
NVDA+f twice.
Hope this can be implement.
Thanks.

El 11/05/2016 a las 0:40, James Teh escribió:

> Let's simplify here.
> 
> If "Report line numbers" is enabled in Document Formatting preferences,
> line numbers get spoken at the start of the line (if the application
> supports retrieving this info). I don't personally find this
> useful--even as a programmer myself, I prefer to query the line on
> demand in the status bar--but the point is that it is included as an
> option for speech. We should just present the same information in
> braille depending on the same setting. The only change I'd suggest is
> that we should just braille the number with no "line" prefix as we have
> for speech.
> 
> Addressing a specific point:
> 
> ```
> Technically it should be possible by extending
> braille.TextInfoRegion. It may require some work to make this
> compatible with braille.Region.focusToHardLeft, because presumably
> the line number should be visible at the very start of the line
> without being part of the text.
> ```
> 
> IMO, we shouldn't worry about focusToHardLeft for this. Those that want
> this probably do always want to see the line number without having to
> scroll back. It also gets ugly when you scroll to the next or previous
> line: should we skip the line number or not? And scrolling back is even
> worse, since it'd be very asymmetric.
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub
> https://github.com/nvaccess/nvda/issues/5941#issuecomment-218313224

Let's keep the scope narrow here, since this seems to be quite important 
to the original reporter and broadening scope introduces more complexity.

OK, I can create a branch for this if it would be faster, not instead.
I don¡t know when to ask this, for instance, when regio isMultiline or 
when obj.role == controlTypes.ROLE_DOCUMENT.
Thanks.

El 11/05/2016 a las 7:43, James Teh escribió:

> Let's keep the scope narrow here, since this seems to be quite important
> to the original reporter and broadening scope introduces more complexity.
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub
> https://github.com/nvaccess/nvda/issues/5941#issuecomment-218367134

You don't need to worry about isMultiline or the like, since this applies to any TextInfoRegion. It's actually a FormatField attribute, not a ControlField attribute, so you'll want to do this in getFormatFieldBraille. There's a snag, though: you only want to do it for the first format field on the line. getFormatFieldBraille doesn't currently know about that, so that'll require an additional argument.

Hi, thanks for the explanation. I'm looking this.

El 11/05/2016 a las 8:12, James Teh escribió:

> You don't need to worry about isMultiline or the like, since this
> applies to any TextInfoRegion. It's actually a FormatField attribute,
> not a ControlField attribute, so you'll want to do this in
> getFormatFieldBraille. There's a snag, though: you only want to do it
> for the first format field on the line. getFormatFieldBraille doesn't
> currently know about that, so that'll require an additional argument.
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub
> https://github.com/nvaccess/nvda/issues/5941#issuecomment-218370913

Hi, unfortunately, I can't test this at home since I don't have a 
braille display.
Taking care to your comments, I have added a cormatConfig parameter to 
the function, so:

def getFormatFieldBraille(field, formatConfig):
    linePrefix = field.get("line-prefix")
    if linePrefix:
        return linePrefix
    if formatConfig["reportLineNumber"]:
        return field.get("line-number")
    return None
After, I have added the argument to this other function of 
TextInfoRegion class. The function is
_addTextWithFields
Thanks.

El 11/05/2016 a las 8:12, James Teh escribió:

> You don't need to worry about isMultiline or the like, since this
> applies to any TextInfoRegion. It's actually a FormatField attribute,
> not a ControlField attribute, so you'll want to do this in
> getFormatFieldBraille. There's a snag, though: you only want to do it
> for the first format field on the line. getFormatFieldBraille doesn't
> currently know about that, so that'll require an additional argument.
> 
> —
> You are receiving this because you commented.
> Reply to this email directly or view it on GitHub
> https://github.com/nvaccess/nvda/issues/5941#issuecomment-218370913

Hi, finally I have designed the code as follows, and it works for me:
1. In the getFormatFieldBraille (field) function, I have added a textList variable to hold the line number when the reporting of this is activated in document format settings, and then the line prefix. This is based on getBrailleTextForProperties, where a textList is used too.
2. In the TextInfoRegion class, I have added a self._skipFormatWithTextFields variable, set to false in the update function, and to True when the first format field is found, in _addTextWithFields. When True, text is set to None. This is based on self._skipFieldsNotAtStartOfNode variable.
I have tested this in Notepad++, Word and other programs.
I think we don't need to document this in the user guide; just in What's new.
If there are no objection, I will create a pull request soon.
Thanks.


Resolving patch:
diff --git a/source/braille.py b/source/braille.py
--- a/source/braille.py
+++ b/source/braille.py
@@ -2,7 +2,7 @@
 #A part of NonVisual Desktop Access (NVDA)
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
-#Copyright (C) 2008-2015 NV Access Limited
+#Copyright (C) 2008-2016 NV Access Limited
 
 import sys
 import itertools
@@ -739,11 +739,17 @@ def getControlFieldBraille(info, field, ancestors, reportStart, formatConfig):
 		return (_("%s end") %
 			getBrailleTextForProperties(role=role))
 
-def getFormatFieldBraille(field):
-	linePrefix = field.get("line-prefix")
-	if linePrefix:
-		return linePrefix
-	return None
+def getFormatFieldBraille(field, isAtStart, formatConfig):
+	textList = []
+	if isAtStart:
+		if formatConfig["reportLineNumber"]:
+			lineNumber = field.get("line-number")
+			if lineNumber:
+				textList.append("%s" % lineNumber)
+		linePrefix = field.get("line-prefix")
+		if linePrefix:
+			textList.append(linePrefix)
+	return " ".join([x for x in textList if x])
 
 class TextInfoRegion(Region):
 
@@ -818,6 +824,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False):
 		typeform = louis.plain_text
 		for command in info.getTextWithFields(formatConfig=formatConfig):
 			if isinstance(command, basestring):
+				self._isFormatFieldAtStart = False
 				if not command:
 					continue
 				if self._endsWithField:
@@ -849,7 +856,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False):
 				field = command.field
 				if cmd == "formatChange":
 					typeform = self._getTypeformFromFormatField(field)
-					text = getFormatFieldBraille(field)
+					text = getFormatFieldBraille(field, self._isFormatFieldAtStart, formatConfig)
 					if not text:
 						continue
 					# Map this field text to the start of the field's content.
@@ -920,9 +927,10 @@ def update(self):
 		self._rawToContentPos = []
 		self._currentContentPos = 0
 		self.selectionStart = self.selectionEnd = None
+		self._isFormatFieldAtStart = True
 		self._skipFieldsNotAtStartOfNode = False
-		self._endsWithField = False
 
+		self._endsWithField = False
 		# Not all text APIs support offsets, so we can't always get the offset of the selection relative to the start of the reading unit.
 		# Therefore, grab the reading unit in three parts.
 		# First, the chunk from the start of the reading unit to the start of the selection.


Test patch: