1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sw.hxx"
25
26 #include <textmarkuphelper.hxx>
27 #include <accportions.hxx>
28
29 #include <vector>
30 #include <algorithm>
31 #include <comphelper/stlunosequence.hxx>
32
33 #include <errhdl.hxx>
34
35 #include <com/sun/star/text/TextMarkupType.hpp>
36 #include <com/sun/star/accessibility/TextSegment.hpp>
37
38 #include <ndtxt.hxx>
39 #include <wrong.hxx>
40
41 using namespace com::sun::star;
42
43 // helper functions
44 namespace {
getTextMarkupList(const SwTxtNode & rTxtNode,const sal_Int32 nTextMarkupType)45 const SwWrongList* getTextMarkupList( const SwTxtNode& rTxtNode,
46 const sal_Int32 nTextMarkupType )
47 throw (::com::sun::star::lang::IllegalArgumentException,
48 ::com::sun::star::uno::RuntimeException)
49 {
50 const SwWrongList* pTextMarkupList( 0 );
51 switch ( nTextMarkupType )
52 {
53 case text::TextMarkupType::SPELLCHECK:
54 {
55 pTextMarkupList = rTxtNode.GetWrong();
56 }
57 break;
58 case text::TextMarkupType::PROOFREADING:
59 {
60 // support not implemented yet
61 pTextMarkupList = 0;
62 }
63 break;
64 case text::TextMarkupType::SMARTTAG:
65 {
66 // support not implemented yet
67 pTextMarkupList = 0;
68 }
69 break;
70 default:
71 {
72 throw lang::IllegalArgumentException();
73 }
74 }
75
76 return pTextMarkupList;
77 }
78 }
79
80 // implementation of class <SwTextMarkupoHelper>
SwTextMarkupHelper(const SwAccessiblePortionData & rPortionData,const SwTxtNode & rTxtNode)81 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData,
82 const SwTxtNode& rTxtNode )
83 : mrPortionData( rPortionData )
84 // --> OD 2010-02-19 #i108125#
85 , mpTxtNode( &rTxtNode )
86 , mpTextMarkupList( 0 )
87 // <--
88 {
89 }
90
91 // --> OD 2010-02-19 #i108125#
SwTextMarkupHelper(const SwAccessiblePortionData & rPortionData,const SwWrongList & rTextMarkupList)92 SwTextMarkupHelper::SwTextMarkupHelper( const SwAccessiblePortionData& rPortionData,
93 const SwWrongList& rTextMarkupList )
94 : mrPortionData( rPortionData )
95 , mpTxtNode( 0 )
96 , mpTextMarkupList( &rTextMarkupList )
97 {
98 }
99 // <--
100
getTextMarkupCount(const sal_Int32 nTextMarkupType)101 sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupType )
102 throw (::com::sun::star::lang::IllegalArgumentException,
103 ::com::sun::star::uno::RuntimeException)
104 {
105 sal_Int32 nTextMarkupCount( 0 );
106
107 // --> OD 2010-02-19 #i108125#
108 const SwWrongList* pTextMarkupList =
109 mpTextMarkupList
110 ? mpTextMarkupList
111 : getTextMarkupList( *mpTxtNode, nTextMarkupType );
112 // <--
113 if ( pTextMarkupList )
114 {
115 nTextMarkupCount = pTextMarkupList->Count();
116 }
117
118 return nTextMarkupCount;
119 }
120 ::com::sun::star::accessibility::TextSegment
getTextMarkup(const sal_Int32 nTextMarkupIndex,const sal_Int32 nTextMarkupType)121 SwTextMarkupHelper::getTextMarkup( const sal_Int32 nTextMarkupIndex,
122 const sal_Int32 nTextMarkupType )
123 throw (::com::sun::star::lang::IndexOutOfBoundsException,
124 ::com::sun::star::lang::IllegalArgumentException,
125 ::com::sun::star::uno::RuntimeException)
126 {
127 if ( nTextMarkupIndex >= getTextMarkupCount( nTextMarkupType ) ||
128 nTextMarkupIndex < 0 )
129 {
130 throw lang::IndexOutOfBoundsException();
131 }
132
133 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment;
134 aTextMarkupSegment.SegmentStart = -1;
135 aTextMarkupSegment.SegmentEnd = -1;
136
137 // --> OD 2010-02-19 #i108125#
138 const SwWrongList* pTextMarkupList =
139 mpTextMarkupList
140 ? mpTextMarkupList
141 : getTextMarkupList( *mpTxtNode, nTextMarkupType );
142 // <--
143 if ( pTextMarkupList )
144 {
145 const SwWrongArea* pTextMarkup =
146 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIndex) );
147 if ( pTextMarkup )
148 {
149 const ::rtl::OUString rText = mrPortionData.GetAccessibleString();
150 const sal_Int32 nStartPos =
151 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos );
152 const sal_Int32 nEndPos =
153 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen );
154 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
155 aTextMarkupSegment.SegmentStart = nStartPos;
156 aTextMarkupSegment.SegmentEnd = nEndPos;
157 }
158 else
159 {
160 ASSERT( false,
161 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" );
162 }
163 }
164
165 return aTextMarkupSegment;
166 }
167
168 ::com::sun::star::uno::Sequence< ::com::sun::star::accessibility::TextSegment >
getTextMarkupAtIndex(const sal_Int32 nCharIndex,const sal_Int32 nTextMarkupType)169 SwTextMarkupHelper::getTextMarkupAtIndex( const sal_Int32 nCharIndex,
170 const sal_Int32 nTextMarkupType )
171 throw (::com::sun::star::lang::IndexOutOfBoundsException,
172 ::com::sun::star::lang::IllegalArgumentException,
173 ::com::sun::star::uno::RuntimeException)
174 {
175 // assumption:
176 // value of <nCharIndex> is in range [0..length of accessible text)
177
178 const sal_uInt16 nCoreCharIndex = mrPortionData.GetModelPosition( nCharIndex );
179 // Handling of portions with core length == 0 at the beginning of the
180 // paragraph - e.g. numbering portion.
181 if ( mrPortionData.GetAccessiblePosition( nCoreCharIndex ) > nCharIndex )
182 {
183 return uno::Sequence< ::com::sun::star::accessibility::TextSegment >();
184 }
185
186 // --> OD 2010-02-19 #i108125#
187 const SwWrongList* pTextMarkupList =
188 mpTextMarkupList
189 ? mpTextMarkupList
190 : getTextMarkupList( *mpTxtNode, nTextMarkupType );
191 // <--
192 ::std::vector< ::com::sun::star::accessibility::TextSegment > aTmpTextMarkups;
193 if ( pTextMarkupList )
194 {
195 const ::rtl::OUString rText = mrPortionData.GetAccessibleString();
196
197 const sal_uInt16 nTextMarkupCount = pTextMarkupList->Count();
198 for ( sal_uInt16 nTextMarkupIdx = 0; nTextMarkupIdx < nTextMarkupCount; ++nTextMarkupIdx )
199 {
200 const SwWrongArea* pTextMarkup =
201 pTextMarkupList->GetElement( static_cast<sal_uInt16>(nTextMarkupIdx) );
202 ASSERT( pTextMarkup,
203 "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" );
204 if ( pTextMarkup &&
205 pTextMarkup->mnPos <= nCoreCharIndex &&
206 nCoreCharIndex < ( pTextMarkup->mnPos + pTextMarkup->mnLen ) )
207 {
208 const sal_Int32 nStartPos =
209 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos );
210 const sal_Int32 nEndPos =
211 mrPortionData.GetAccessiblePosition( pTextMarkup->mnPos + pTextMarkup->mnLen );
212 ::com::sun::star::accessibility::TextSegment aTextMarkupSegment;
213 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
214 aTextMarkupSegment.SegmentStart = nStartPos;
215 aTextMarkupSegment.SegmentEnd = nEndPos;
216 aTmpTextMarkups.push_back( aTextMarkupSegment );
217 }
218 }
219 }
220
221 uno::Sequence< ::com::sun::star::accessibility::TextSegment > aTextMarkups(
222 aTmpTextMarkups.size() );
223 ::std::copy( aTmpTextMarkups.begin(), aTmpTextMarkups.end(),
224 ::comphelper::stl_begin( aTextMarkups ) );
225
226 return aTextMarkups;
227 }
228