Repository: nvaccess/nvda

Issue:
Word announces section breaks as page breaks
When you insert a section break (new page), NVDA identifies it as simply a "page break".  When you insert a section break (continuous), no identification is given by NVDA.  Column breaks are also not identified.

With formatting symbols displayed, column, page and section breaks are all displayed as a dotted line (different types of dots between the three types) across the page with the type of break in (what appears visually as) text identifying "Page break (continuous)", "Column break" etc.



Discussion:
I think a similar issue can be seen with column breaks, and using the 
arrow keys, no method is given to move to the next column. I might e 
wrong, I only saw this once on a test.

On 5/13/2016 5:04 AM, Quentin Christensen wrote:

> When you insert a section break (new page), NVDA identifies it as 
> simply a "page break". When you insert a section break (continuous), 
> no identification is given by NVDA. Column breaks are also not identified.
> 
> With formatting symbols displayed, column, page and section breaks are 
> all displayed as a dotted line (different types of dots between the 
> three types) across the page with the type of break in (what appears 
> visually as) text identifying "Page break (continuous)", "Column 
> break" etc.
> 
> —
> You are receiving this because you are subscribed to this thread.
> Reply to this email directly or view it on GitHub 
> https://github.com/nvaccess/nvda/issues/5946

## 

---

```
Derek Riemer
```
- Department of computer science, third year undergraduate student.
- Proud user of the NVDA screen reader.
- Open source enthusiast.
- Member of Bridge Cu
- Avid skiier.

Websites:
Honors portfolio http://derekriemer.com
Awesome little hand built weather app! 
http://django.derekriemer.com/weather/

email me at derek.riemer@colorado.edu mailto:derek.riemer@colorado.edu
Phone: (303) 906-2194

You're right, there are other issues with columns which I've been pondering as well.  I just mentioned the issue with column breaks as I wasn't sure if this specific aspect was related to the section break identification.

Microsoft Word exposes all breaks as page break characters (0x12)
However We could announce section changes like we do for page changes. I.e. when arrowing anywhere if the section changes we could say "section x" before the text, where x is the new section number. We can get this with selection.sections(1).index 


Resolving patch:
diff --git a/source/NVDAObjects/window/winword.py b/source/NVDAObjects/window/winword.py
--- a/source/NVDAObjects/window/winword.py
+++ b/source/NVDAObjects/window/winword.py
@@ -617,6 +617,8 @@ def getTextWithFields(self,formatConfig=None):
 			formatConfigFlags+=formatConfigFlag_includeLayoutTables
 		if self.obj.ignoreEditorRevisions:
 			formatConfigFlags&=~formatConfigFlagsMap['reportRevisions']
+		if self.obj.ignorePageNumbers:
+			formatConfigFlags&=~formatConfigFlagsMap['reportPage']
 		res=NVDAHelper.localLib.nvdaInProcUtils_winword_getTextInRange(self.obj.appModule.helperLocalBindingHandle,self.obj.documentWindowHandle,startOffset,endOffset,formatConfigFlags,ctypes.byref(text))
 		if res or not text:
 			log.debugWarning("winword_getTextInRange failed with %d"%res)
@@ -1086,6 +1088,9 @@ def _get_ignoreEditorRevisions(self):
 		self.ignoreEditorRevisions=ignore
 		return ignore
 
+	#: True if page numbers (as well as section numbers and column numbers) should be ignored. Such as in outlook.
+	ignorePageNumbers = False
+
 	#: True if formatting should be ignored (text only) such as for spellCheck error field
 	ignoreFormatting=False
 
diff --git a/source/appModules/outlook.py b/source/appModules/outlook.py
--- a/source/appModules/outlook.py
+++ b/source/appModules/outlook.py
@@ -175,7 +175,7 @@ def _get_shouldAllowIAccessibleFocusEvent(self):
 		if winUser.getGUIThreadInfo(self.windowThreadID).hwndFocus!=self.windowHandle:
 			return False
 		return super(SuperGridClient2010,self).shouldAllowIAccessibleFocusEvent
-
+
 	def event_gainFocus(self):
 		# #3834: UIA has a much better implementation for rows, so use it if available.
 		if self.appModule.outlookVersion<14 or not UIAHandler.handler:
@@ -191,7 +191,7 @@ def event_gainFocus(self):
 			return super(SuperGridClient2010,self).event_gainFocus()
 		obj.parent=self.parent
 		eventHandler.executeEvent("gainFocus",obj)
-
+
 class MessageList_pre2003(IAccessible):
 
 	def _get_name(self):
@@ -366,7 +366,7 @@ def reportFocus(self):
 				ui.message(timeSlotText)
 		else:
 			self.event_valueChange()
-
+
 class UIAGridRow(RowWithFakeNavigation,UIA):
 
 	rowHeaderText=None
@@ -513,3 +513,4 @@ def _get_role(self):
 		return controlTypes.ROLE_DOCUMENT if self.isReadonlyViewer else super(OutlookWordDocument,self).role
 
 	ignoreEditorRevisions=True
+	ignorePageNumbers=True # This includes page sections, and page columns. None of which are appropriate for outlook.
\ No newline at end of file
diff --git a/source/speech.py b/source/speech.py
--- a/source/speech.py
+++ b/source/speech.py
@@ -1131,7 +1131,7 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,unit=None,extra
 		text=getTableInfoSpeech(tableInfo,oldTableInfo,extraDetail=extraDetail)
 		if text:
 			textList.append(text)
-	if  formatConfig["reportPage"]:
+	if formatConfig["reportPage"]:
 		pageNumber=attrs.get("page-number")
 		oldPageNumber=attrsCache.get("page-number") if attrsCache is not None else None
 		if pageNumber and pageNumber!=oldPageNumber:
@@ -1139,6 +1139,56 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,unit=None,extra
 			# %s will be replaced with the page number.
 			text=_("page %s")%pageNumber
 			textList.append(text)
+		sectionNumber=attrs.get("section-number")
+		oldSectionNumber=attrsCache.get("section-number") if attrsCache is not None else None
+		if sectionNumber and sectionNumber!=oldSectionNumber:
+			# Translators: Indicates the section number in a document.
+			# %s will be replaced with the section number.
+			text=_("section %s")%sectionNumber
+			textList.append(text)
+
+		textColumnCount=attrs.get("text-column-count")
+		oldTextColumnCount=attrsCache.get("text-column-count") if attrsCache is not None else None
+		textColumnNumber=attrs.get("text-column-number")
+		oldTextColumnNumber=attrsCache.get("text-column-number") if attrsCache is not None else None
+
+		# Because we do not want to report the number of columns when a document is just opened and there is only 
+		# one column. This would be verbose, in the standard case.
+		# column number has changed, or the columnCount has changed
+		# but not if the columnCount is 1 or less and there is no old columnCount.
+		if (((textColumnNumber and textColumnNumber!=oldTextColumnNumber) or
+			(textColumnCount and textColumnCount!=oldTextColumnCount)) and not
+			(textColumnCount and int(textColumnCount) <=1 and oldTextColumnCount == None)) :
+			if textColumnNumber and textColumnCount:
+				# Translators: Indicates the text column number in a document.
+				# {0} will be replaced with the text column number.
+				# {1} will be replaced with the number of text columns.
+				text=_("column {0} of {1}").format(textColumnNumber,textColumnCount)
+				textList.append(text)
+			elif textColumnCount:
+				# Translators: Indicates the text column number in a document.
+				# %s will be replaced with the number of text columns.
+				text=_("%s columns")%(textColumnCount)
+				textList.append(text)
+
+	sectionBreakType=attrs.get("section-break")
+	if sectionBreakType:
+		if sectionBreakType == "0" : # Continuous section break.
+			text=_("continuous section break")
+		elif sectionBreakType == "1" : # New column section break.
+			text=_("new column section break")
+		elif sectionBreakType == "2" : # New page section break.
+			text=_("new page section break")
+		elif sectionBreakType == "3" : # Even pages section break.
+			text=_("even pages section break")
+		elif sectionBreakType == "4" : # Odd pages section break.
+			text=_("odd pages section break")
+		else:
+			text=""
+		textList.append(text)
+	columnBreakType=attrs.get("column-break")
+	if columnBreakType:
+		textList.append(_("column break"))
 	if  formatConfig["reportHeadings"]:
 		headingLevel=attrs.get("heading-level")
 		oldHeadingLevel=attrsCache.get("heading-level") if attrsCache is not None else None


Test patch: