LibreOffice Module sw (master) 1
textmarkuphelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "textmarkuphelper.hxx"
21#include "accportions.hxx"
22
23#include <vector>
24
25#include <com/sun/star/text/TextMarkupType.hpp>
26#include <com/sun/star/accessibility/TextSegment.hpp>
27#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28#include <com/sun/star/lang/IllegalArgumentException.hpp>
29
31#include <osl/diagnose.h>
32#include <ndtxt.hxx>
33#include <wrong.hxx>
34
35using namespace com::sun::star;
36
37// helper functions
38namespace {
41 SwWrongList const* (SwTextNode::*
42 getTextMarkupFunc(const sal_Int32 nTextMarkupType))() const
43 {
44 switch ( nTextMarkupType )
45 {
46 case text::TextMarkupType::SPELLCHECK:
47 {
49 }
50 break;
51 case text::TextMarkupType::PROOFREADING:
52 {
53 // support not implemented yet
54 return nullptr;
55 }
56 break;
57 case text::TextMarkupType::SMARTTAG:
58 {
59 // support not implemented yet
60 return nullptr;
61 }
62 break;
63 default:
64 {
65 throw lang::IllegalArgumentException();
66 }
67 }
68 }
69}
70
71// implementation of class <SwTextMarkupoHelper>
73 const SwTextFrame& rTextFrame)
74 : mrPortionData( rPortionData )
75 , m_pTextFrame(&rTextFrame)
76 , mpTextMarkupList( nullptr )
77{
78}
79
80// #i108125#
82 const SwWrongList& rTextMarkupList )
83 : mrPortionData( rPortionData )
84 , m_pTextFrame( nullptr )
85 , mpTextMarkupList( &rTextMarkupList )
86{
87}
88
89sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupType )
90{
91 sal_Int32 nTextMarkupCount( 0 );
92
94 {
95 nTextMarkupCount = mpTextMarkupList->Count();
96 }
97 else
98 {
99 assert(m_pTextFrame);
100 SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
101 if (pGetWrongList)
102 {
103 sw::WrongListIteratorCounter iter(*m_pTextFrame, pGetWrongList);
104 nTextMarkupCount = iter.GetElementCount();
105 }
106 }
107
108 return nTextMarkupCount;
109}
110
111css::accessibility::TextSegment
112 SwTextMarkupHelper::getTextMarkup( const sal_Int32 nTextMarkupIndex,
113 const sal_Int32 nTextMarkupType )
114{
115 if ( nTextMarkupIndex >= getTextMarkupCount( nTextMarkupType ) ||
116 nTextMarkupIndex < 0 )
117 {
118 throw lang::IndexOutOfBoundsException();
119 }
120
121 css::accessibility::TextSegment aTextMarkupSegment;
122 aTextMarkupSegment.SegmentStart = -1;
123 aTextMarkupSegment.SegmentEnd = -1;
124
125 std::unique_ptr<sw::WrongListIteratorCounter> pIter;
127 {
129 }
130 else
131 {
132 assert(m_pTextFrame);
133 SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
134 if (pGetWrongList)
135 {
136 pIter.reset(new sw::WrongListIteratorCounter(*m_pTextFrame, pGetWrongList));
137 }
138 }
139
140 if (pIter)
141 {
142 auto const oElement(pIter->GetElementAt(nTextMarkupIndex));
143 if (oElement)
144 {
145 const OUString& rText = mrPortionData.GetAccessibleString();
146 const sal_Int32 nStartPos =
147 mrPortionData.GetAccessiblePosition(oElement->first);
148 const sal_Int32 nEndPos =
149 mrPortionData.GetAccessiblePosition(oElement->second);
150 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
151 aTextMarkupSegment.SegmentStart = nStartPos;
152 aTextMarkupSegment.SegmentEnd = nEndPos;
153 }
154 else
155 {
156 OSL_FAIL( "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" );
157 }
158 }
159
160 return aTextMarkupSegment;
161}
162
163css::uno::Sequence< css::accessibility::TextSegment >
164 SwTextMarkupHelper::getTextMarkupAtIndex( const sal_Int32 nCharIndex,
165 const sal_Int32 nTextMarkupType )
166{
167 // assumption:
168 // value of <nCharIndex> is in range [0..length of accessible text)
169
170 const TextFrameIndex nCoreCharIndex = mrPortionData.GetCoreViewPosition(nCharIndex);
171 // Handling of portions with core length == 0 at the beginning of the
172 // paragraph - e.g. numbering portion.
173 if ( mrPortionData.GetAccessiblePosition( nCoreCharIndex ) > nCharIndex )
174 {
175 return uno::Sequence< css::accessibility::TextSegment >();
176 }
177
178 std::unique_ptr<sw::WrongListIteratorCounter> pIter;
180 {
182 }
183 else
184 {
185 assert(m_pTextFrame);
186 SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
187 if (pGetWrongList)
188 {
189 pIter.reset(new sw::WrongListIteratorCounter(*m_pTextFrame, pGetWrongList));
190 }
191 }
192
193 std::vector< css::accessibility::TextSegment > aTmpTextMarkups;
194 if (pIter)
195 {
196 const OUString& rText = mrPortionData.GetAccessibleString();
197 sal_uInt16 count(pIter->GetElementCount());
198 for (sal_uInt16 i = 0; i < count; ++i)
199 {
200 auto const oElement(pIter->GetElementAt(i));
201 if (oElement &&
202 oElement->first <= nCoreCharIndex &&
203 nCoreCharIndex < oElement->second)
204 {
205 const sal_Int32 nStartPos =
206 mrPortionData.GetAccessiblePosition(oElement->first);
207 const sal_Int32 nEndPos =
208 mrPortionData.GetAccessiblePosition(oElement->second);
209 css::accessibility::TextSegment aTextMarkupSegment;
210 aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
211 aTextMarkupSegment.SegmentStart = nStartPos;
212 aTextMarkupSegment.SegmentEnd = nEndPos;
213 aTmpTextMarkups.push_back( aTextMarkupSegment );
214 }
215 }
216 }
217
218 return comphelper::containerToSequence(aTmpTextMarkups );
219}
220
221/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
collect text portion data from the layout through SwPortionHandler interface
Definition: accportions.hxx:40
TextFrameIndex GetCoreViewPosition(sal_Int32 nPos) const
get the position in the core view string for a given (accessibility) position
const OUString & GetAccessibleString() const
get the text string, as presented by the layout
sal_Int32 GetAccessiblePosition(TextFrameIndex nPos) const
get the position in the accessibility string for a given view position
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextFrame const * m_pTextFrame
const SwAccessiblePortionData & mrPortionData
SwTextMarkupHelper(const SwAccessiblePortionData &rPortionData, const SwTextFrame &rTextFrame)
sal_Int32 getTextMarkupCount(const sal_Int32 nTextMarkupType)
css::uno::Sequence< css::accessibility::TextSegment > getTextMarkupAtIndex(const sal_Int32 nCharIndex, const sal_Int32 nTextMarkupType)
css::accessibility::TextSegment getTextMarkup(const sal_Int32 nTextMarkupIndex, const sal_Int32 nTextMarkupType)
const SwWrongList * mpTextMarkupList
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:86
SwWrongList * GetWrong()
Definition: txtedt.cxx:2226
sal_uInt16 Count() const
Definition: wrong.hxx:323
sal_uInt16 GetElementCount()
Definition: wrong.cxx:835
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
int i