OSDN Git Service

More improvements to handling footnotes and endnotes in MS Word. Now they are always...
authorMichael Curran <mick@kulgan.net>
Thu, 23 Feb 2012 02:34:47 +0000 (12:34 +1000)
committerMichael Curran <mick@kulgan.net>
Thu, 23 Feb 2012 02:34:47 +0000 (12:34 +1000)
Specific changes:
* Force a new chunk (range) before and after individual footnotes and endnotes (i.e. a footnote or endnote is always in its own range in the loop).
* Again provide real text content inside the controlField tag for a footnote/endnote, but just use a space for now (still better on braille displays).

nvdaHelper/remote/winword.cpp

index 87aab91..1b440b7 100644 (file)
@@ -91,6 +91,7 @@ using namespace std;
 \r
 #define wdCommentsStory 4\r
 \r
+#define wdCharacter 1\r
 #define wdWord 2\r
 #define wdLine 5\r
 #define wdCharacterFormatting 13\r
@@ -390,26 +391,25 @@ void generateXMLAttribsForFormatting(IDispatch* pDispatchRange, int startOffset,
        } \r
 }\r
 \r
-inline void generateFootnoteEndnoteXML(IDispatch* pDispatchRange, wostringstream& XMLStream, bool footnote) {\r
+inline bool generateFootnoteEndnoteXML(IDispatch* pDispatchRange, wostringstream& XMLStream, bool footnote) {\r
        IDispatchPtr pDispatchNotes=NULL;\r
        IDispatchPtr pDispatchNote=NULL;\r
        int count=0;\r
        int index=0;\r
        if(_com_dispatch_raw_propget(pDispatchRange,(footnote?wdDISPID_RANGE_FOOTNOTES:wdDISPID_RANGE_ENDNOTES),VT_DISPATCH,&pDispatchNotes)!=S_OK||!pDispatchNotes) {\r
-               return;\r
+               return false;\r
        }\r
        if(_com_dispatch_raw_propget(pDispatchNotes,wdDISPID_FOOTNOTES_COUNT,VT_I4,&count)!=S_OK||count<=0) {\r
-               return;\r
+               return false;\r
        }\r
-       for(int i=1;i<=count;++i) {\r
-               if(_com_dispatch_raw_method(pDispatchNotes,wdDISPID_FOOTNOTES_ITEM,DISPATCH_METHOD,VT_DISPATCH,&pDispatchNote,L"\x0003",i)!=S_OK||!pDispatchNote) {\r
-                       continue;\r
-               }\r
-               if(_com_dispatch_raw_propget(pDispatchNote,wdDISPID_FOOTNOTE_INDEX,VT_I4,&index)!=S_OK) {\r
-                       continue;\r
-               }\r
-               XMLStream<<L"<control _startOfNode=\"1\" role=\""<<(footnote?L"footnote":L"endnote")<<L"\" value=\""<<index<<L"\" />";\r
+       if(_com_dispatch_raw_method(pDispatchNotes,wdDISPID_FOOTNOTES_ITEM,DISPATCH_METHOD,VT_DISPATCH,&pDispatchNote,L"\x0003",1)!=S_OK||!pDispatchNote) {\r
+               return false;\r
+       }\r
+       if(_com_dispatch_raw_propget(pDispatchNote,wdDISPID_FOOTNOTE_INDEX,VT_I4,&index)!=S_OK) {\r
+               return false;\r
        }\r
+       XMLStream<<L"<control _startOfNode=\"1\" role=\""<<(footnote?L"footnote":L"endnote")<<L"\" value=\""<<index<<L"\">";\r
+       return true;\r
 }\r
 \r
 UINT wm_winword_getTextInRange=0;\r
@@ -478,42 +478,57 @@ void winword_getTextInRange_helper(HWND hwnd, winword_getTextInRange_args* args)
                        _com_dispatch_raw_propput(pDispatchRange,wdDISPID_RANGE_END,VT_I4,args->endOffset);\r
                        chunkEndOffset=args->endOffset;\r
                }\r
-               if(firstLoop) {\r
-                       if(initialFormatConfig&formatConfig_reportTables) {\r
-                               neededClosingControlTagCount+=generateTableXML(pDispatchRange,args->startOffset,args->endOffset,XMLStream);\r
-                       }\r
-                       if(initialFormatConfig&formatConfig_reportHeadings) {\r
-                               neededClosingControlTagCount+=generateHeadingXML(pDispatchRange,XMLStream);\r
-                       }\r
-                       generateXMLAttribsForFormatting(pDispatchRange,chunkStartOffset,chunkEndOffset,initialFormatConfig,initialFormatAttribsStream);\r
-               }\r
                _com_dispatch_raw_propget(pDispatchRange,wdDISPID_RANGE_TEXT,VT_BSTR,&text);\r
-               bool hasNoteChars=false;\r
-               XMLStream<<L"<text ";\r
-               XMLStream<<initialFormatAttribsStream.str();\r
-               generateXMLAttribsForFormatting(pDispatchRange,chunkStartOffset,chunkEndOffset,formatConfig,XMLStream);\r
-               XMLStream<<L">";\r
-               if(firstLoop) {\r
-                       formatConfig&=(~formatConfig_reportLists);\r
-                       firstLoop=false;\r
-               }\r
                if(text) {\r
-                       wstring tempText;\r
+                       //Force a new chunk before and after control+b (note characters)\r
+                       int noteCharOffset=-1;\r
                        for(int i=0;text[i]!=L'\0';++i) {\r
                                if(text[i]==L'\x0002') {\r
-                                       hasNoteChars=true;\r
-                                       continue;\r
+                                       noteCharOffset=i;\r
+                                       if(i==0) text[i]=L' ';\r
+                                       break;\r
                                }\r
+                       }\r
+                       bool isNoteChar=(noteCharOffset==0);\r
+                       if(noteCharOffset==0) noteCharOffset=1;\r
+                       if(noteCharOffset>0) {\r
+                               text[noteCharOffset]=L'\0';\r
+                               _com_dispatch_raw_method(pDispatchRange,wdDISPID_RANGE_COLLAPSE,DISPATCH_METHOD,VT_EMPTY,NULL,L"\x0003",wdCollapseStart);\r
+                               if(_com_dispatch_raw_method(pDispatchRange,wdDISPID_RANGE_MOVEEND,DISPATCH_METHOD,VT_I4,&unitsMoved,L"\x0003\x0003",wdCharacter,noteCharOffset)!=S_OK||unitsMoved<=0) {\r
+                                       break;\r
+                               }\r
+                               _com_dispatch_raw_propget(pDispatchRange,wdDISPID_RANGE_END,VT_I4,&chunkEndOffset);\r
+                       }\r
+                       if(firstLoop) {\r
+                               if(initialFormatConfig&formatConfig_reportTables) {\r
+                                       neededClosingControlTagCount+=generateTableXML(pDispatchRange,args->startOffset,args->endOffset,XMLStream);\r
+                               }\r
+                               if(initialFormatConfig&formatConfig_reportHeadings) {\r
+                                       neededClosingControlTagCount+=generateHeadingXML(pDispatchRange,XMLStream);\r
+                               }\r
+                               generateXMLAttribsForFormatting(pDispatchRange,chunkStartOffset,chunkEndOffset,initialFormatConfig,initialFormatAttribsStream);\r
+                       }\r
+                       if(isNoteChar) {\r
+                               isNoteChar=generateFootnoteEndnoteXML(pDispatchRange,XMLStream,true);\r
+                               if(!isNoteChar) isNoteChar=generateFootnoteEndnoteXML(pDispatchRange,XMLStream,false);\r
+                       }\r
+                       XMLStream<<L"<text ";\r
+                       XMLStream<<initialFormatAttribsStream.str();\r
+                       generateXMLAttribsForFormatting(pDispatchRange,chunkStartOffset,chunkEndOffset,formatConfig,XMLStream);\r
+                       XMLStream<<L">";\r
+                       if(firstLoop) {\r
+                               formatConfig&=(~formatConfig_reportLists);\r
+                               firstLoop=false;\r
+                       }\r
+                       wstring tempText;\r
+                       for(int i=0;text[i]!=L'\0';++i) {\r
                                appendCharToXML(text[i],tempText);\r
                        }\r
                        XMLStream<<tempText;\r
                        SysFreeString(text);\r
                        text=NULL;\r
-               }\r
-               XMLStream<<L"</text>";\r
-               if(hasNoteChars) {\r
-                       generateFootnoteEndnoteXML(pDispatchRange,XMLStream,true);\r
-                       generateFootnoteEndnoteXML(pDispatchRange,XMLStream,false);\r
+                       XMLStream<<L"</text>";\r
+                       if(isNoteChar) XMLStream<<L"</control>";\r
                }\r
                _com_dispatch_raw_method(pDispatchRange,wdDISPID_RANGE_COLLAPSE,DISPATCH_METHOD,VT_EMPTY,NULL,L"\x0003",wdCollapseEnd);\r
                chunkStartOffset=chunkEndOffset;\r