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 #include <algorithm>
25 
26 #include <com/sun/star/text/TextMarkupType.hpp>
27 #include <com/sun/star/accessibility/TextSegment.hpp>
28 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <com/sun/star/lang/IllegalArgumentException.hpp>
30 
31 #include <comphelper/sequence.hxx>
32 #include <osl/diagnose.h>
33 #include <ndtxt.hxx>
34 #include <wrong.hxx>
35 
36 using namespace com::sun::star;
37 
38 // helper functions
39 namespace {
42  SwWrongList const* (SwTextNode::*
43  getTextMarkupFunc(const sal_Int32 nTextMarkupType))() const
44  {
45  switch ( nTextMarkupType )
46  {
47  case text::TextMarkupType::SPELLCHECK:
48  {
49  return &SwTextNode::GetWrong;
50  }
51  break;
52  case text::TextMarkupType::PROOFREADING:
53  {
54  // support not implemented yet
55  return nullptr;
56  }
57  break;
58  case text::TextMarkupType::SMARTTAG:
59  {
60  // support not implemented yet
61  return nullptr;
62  }
63  break;
64  default:
65  {
66  throw lang::IllegalArgumentException();
67  }
68  }
69  }
70 }
71 
72 // implementation of class <SwTextMarkupoHelper>
74  const SwTextFrame& rTextFrame)
75  : mrPortionData( rPortionData )
76  , m_pTextFrame(&rTextFrame)
77  , mpTextMarkupList( nullptr )
78 {
79 }
80 
81 // #i108125#
83  const SwWrongList& rTextMarkupList )
84  : mrPortionData( rPortionData )
85  , m_pTextFrame( nullptr )
86  , mpTextMarkupList( &rTextMarkupList )
87 {
88 }
89 
90 sal_Int32 SwTextMarkupHelper::getTextMarkupCount( const sal_Int32 nTextMarkupType )
91 {
92  sal_Int32 nTextMarkupCount( 0 );
93 
94  if (mpTextMarkupList)
95  {
96  nTextMarkupCount = mpTextMarkupList->Count();
97  }
98  else
99  {
101  SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
102  if (pGetWrongList)
103  {
104  sw::WrongListIteratorCounter iter(*m_pTextFrame, pGetWrongList);
105  nTextMarkupCount = iter.GetElementCount();
106  }
107  }
108 
109  return nTextMarkupCount;
110 }
111 
112 css::accessibility::TextSegment
113  SwTextMarkupHelper::getTextMarkup( const sal_Int32 nTextMarkupIndex,
114  const sal_Int32 nTextMarkupType )
115 {
116  if ( nTextMarkupIndex >= getTextMarkupCount( nTextMarkupType ) ||
117  nTextMarkupIndex < 0 )
118  {
119  throw lang::IndexOutOfBoundsException();
120  }
121 
122  css::accessibility::TextSegment aTextMarkupSegment;
123  aTextMarkupSegment.SegmentStart = -1;
124  aTextMarkupSegment.SegmentEnd = -1;
125 
126  std::unique_ptr<sw::WrongListIteratorCounter> pIter;
127  if (mpTextMarkupList)
128  {
130  }
131  else
132  {
134  SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
135  if (pGetWrongList)
136  {
137  pIter.reset(new sw::WrongListIteratorCounter(*m_pTextFrame, pGetWrongList));
138  }
139  }
140 
141  if (pIter)
142  {
143  auto const oElement(pIter->GetElementAt(nTextMarkupIndex));
144  if (oElement)
145  {
146  const OUString& rText = mrPortionData.GetAccessibleString();
147  const sal_Int32 nStartPos =
148  mrPortionData.GetAccessiblePosition(oElement->first);
149  const sal_Int32 nEndPos =
150  mrPortionData.GetAccessiblePosition(oElement->second);
151  aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
152  aTextMarkupSegment.SegmentStart = nStartPos;
153  aTextMarkupSegment.SegmentEnd = nEndPos;
154  }
155  else
156  {
157  OSL_FAIL( "<SwTextMarkupHelper::getTextMarkup(..)> - missing <SwWrongArea> instance" );
158  }
159  }
160 
161  return aTextMarkupSegment;
162 }
163 
164 css::uno::Sequence< css::accessibility::TextSegment >
165  SwTextMarkupHelper::getTextMarkupAtIndex( const sal_Int32 nCharIndex,
166  const sal_Int32 nTextMarkupType )
167 {
168  // assumption:
169  // value of <nCharIndex> is in range [0..length of accessible text)
170 
171  const TextFrameIndex nCoreCharIndex = mrPortionData.GetCoreViewPosition(nCharIndex);
172  // Handling of portions with core length == 0 at the beginning of the
173  // paragraph - e.g. numbering portion.
174  if ( mrPortionData.GetAccessiblePosition( nCoreCharIndex ) > nCharIndex )
175  {
176  return uno::Sequence< css::accessibility::TextSegment >();
177  }
178 
179  std::unique_ptr<sw::WrongListIteratorCounter> pIter;
180  if (mpTextMarkupList)
181  {
183  }
184  else
185  {
187  SwWrongList const* (SwTextNode::*const pGetWrongList)() const = getTextMarkupFunc(nTextMarkupType);
188  if (pGetWrongList)
189  {
190  pIter.reset(new sw::WrongListIteratorCounter(*m_pTextFrame, pGetWrongList));
191  }
192  }
193 
194  std::vector< css::accessibility::TextSegment > aTmpTextMarkups;
195  if (pIter)
196  {
197  const OUString& rText = mrPortionData.GetAccessibleString();
198  sal_uInt16 count(pIter->GetElementCount());
199  for (sal_uInt16 i = 0; i < count; ++i)
200  {
201  auto const oElement(pIter->GetElementAt(i));
202  if (oElement &&
203  oElement->first <= nCoreCharIndex &&
204  nCoreCharIndex < oElement->second)
205  {
206  const sal_Int32 nStartPos =
207  mrPortionData.GetAccessiblePosition(oElement->first);
208  const sal_Int32 nEndPos =
209  mrPortionData.GetAccessiblePosition(oElement->second);
210  css::accessibility::TextSegment aTextMarkupSegment;
211  aTextMarkupSegment.SegmentText = rText.copy( nStartPos, nEndPos - nStartPos );
212  aTextMarkupSegment.SegmentStart = nStartPos;
213  aTextMarkupSegment.SegmentEnd = nEndPos;
214  aTmpTextMarkups.push_back( aTextMarkupSegment );
215  }
216  }
217  }
218 
219  return comphelper::containerToSequence(aTmpTextMarkups );
220 }
221 
222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const OUString & GetAccessibleString() const
get the text string, as presented by the layout
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
const size_t count(pCandidateA->getBorderLines().size())
SwTextFrame const * m_pTextFrame
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_Int32 getTextMarkupCount(const sal_Int32 nTextMarkupType)
sal_uInt16 Count() const
Definition: wrong.hxx:323
int i
SwTextMarkupHelper(const SwAccessiblePortionData &rPortionData, const SwTextFrame &rTextFrame)
TextFrameIndex GetCoreViewPosition(sal_Int32 nPos) const
get the position in the core view string for a given (accessibility) position
collect text portion data from the layout through SwPortionHandler interface
Definition: accportions.hxx:39
const SwAccessiblePortionData & mrPortionData
css::uno::Sequence< css::accessibility::TextSegment > getTextMarkupAtIndex(const sal_Int32 nCharIndex, const sal_Int32 nTextMarkupType)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:80
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
SwWrongList * GetWrong()
Definition: txtedt.cxx:2158
css::accessibility::TextSegment getTextMarkup(const sal_Int32 nTextMarkupIndex, const sal_Int32 nTextMarkupType)
sal_uInt16 GetElementCount()
Definition: wrong.cxx:834
const SwWrongList * mpTextMarkupList
sal_Int32 GetAccessiblePosition(TextFrameIndex nPos) const
get the position in the accessibility string for a given view position