LibreOffice Module sw (master) 1
unotextmarkup.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 <unotextmarkup.hxx>
21
23#include <o3tl/safeint.hxx>
24#include <osl/diagnose.h>
25#include <svl/listener.hxx>
26#include <utility>
27#include <vcl/svapp.hxx>
28#include <SwSmartTagMgr.hxx>
29#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30#include <com/sun/star/text/TextMarkupType.hpp>
31#include <com/sun/star/text/TextMarkupDescriptor.hpp>
32#include <com/sun/star/container/ElementExistException.hpp>
33#include <com/sun/star/container/XStringKeyMap.hpp>
34#include <ndtxt.hxx>
35#include <SwGrammarMarkUp.hxx>
36#include <TextCursorHelper.hxx>
37#include <GrammarContact.hxx>
38
39#include <com/sun/star/lang/XUnoTunnel.hpp>
40#include <com/sun/star/text/XTextRange.hpp>
41
42#include <pam.hxx>
43
44#include <unotextrange.hxx>
45#include <modeltoviewhelper.hxx>
46
47using namespace ::com::sun::star;
48
50 : public SvtListener
51{
54
55 Impl(SwTextNode* const pTextNode, ModelToViewHelper aMap)
56 : m_pTextNode(pTextNode)
57 , m_ConversionMap(std::move(aMap))
58 {
59 if(m_pTextNode)
60 StartListening(pTextNode->GetNotifier());
61 }
62
63 virtual void Notify(const SfxHint& rHint) override;
64};
65
67 SwTextNode *const pTextNode, const ModelToViewHelper& rMap)
68 : m_pImpl(new Impl(pTextNode, rMap))
69{
71
73{
74}
75
77{
78 return m_pImpl->m_pTextNode;
79}
80
82{
83 m_pImpl->m_pTextNode = nullptr;
84 m_pImpl->EndListeningAll();
85}
86
88{
89 return m_pImpl->m_ConversionMap;
90}
91
92uno::Reference< container::XStringKeyMap > SAL_CALL SwXTextMarkup::getMarkupInfoContainer()
93{
94 return new SwXStringKeyMap;
95}
96
97void SAL_CALL SwXTextMarkup::commitTextRangeMarkup(::sal_Int32 nType, const OUString & aIdentifier, const uno::Reference< text::XTextRange> & xRange,
98 const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
99{
100 SolarMutexGuard aGuard;
101
102 if (auto pRange = dynamic_cast<SwXTextRange*>(xRange.get()))
103 {
104 SwDoc& rDoc = pRange->GetDoc();
105
106 SwUnoInternalPaM aPam(rDoc);
107
108 ::sw::XTextRangeToSwPaM(aPam, xRange);
109
110 auto [startPos, endPos] = aPam.StartEnd(); // SwPosition*
111
112 commitStringMarkup (nType, aIdentifier, startPos->GetContentIndex(), endPos->GetContentIndex() - startPos->GetContentIndex(), xMarkupInfoContainer);
113 }
114 else if (auto pCursor = dynamic_cast<OTextCursorHelper*>(xRange.get()))
115 {
116 SwPaM & rPam(*pCursor->GetPaM());
117
118 auto [startPos, endPos] = rPam.StartEnd(); // SwPosition*
119
120 commitStringMarkup (nType, aIdentifier, startPos->GetContentIndex(), endPos->GetContentIndex() - startPos->GetContentIndex(), xMarkupInfoContainer);
121 }
122}
123
125 ::sal_Int32 nType,
126 const OUString & rIdentifier,
127 ::sal_Int32 nStart,
128 ::sal_Int32 nLength,
129 const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
130{
131 SolarMutexGuard aGuard;
132
133 // paragraph already dead or modified?
134 if (!m_pImpl->m_pTextNode || nLength <= 0)
135 return;
136
137 if ( nType == text::TextMarkupType::SMARTTAG &&
138 !SwSmartTagMgr::Get().IsSmartTagTypeEnabled( rIdentifier ) )
139 return;
140
141 // get appropriate list to use...
142 SwWrongList* pWList = nullptr;
143 bool bRepaint = false;
144 if ( nType == text::TextMarkupType::SPELLCHECK )
145 {
146 pWList = m_pImpl->m_pTextNode->GetWrong();
147 if ( !pWList )
148 {
149 pWList = new SwWrongList( WRONGLIST_SPELL );
150 m_pImpl->m_pTextNode->SetWrong( std::unique_ptr<SwWrongList>(pWList) );
151 }
152 }
153 else if ( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
154 {
155 sw::GrammarContact* pGrammarContact = sw::getGrammarContactFor(*m_pImpl->m_pTextNode);
156 if( pGrammarContact )
157 {
158 pWList = pGrammarContact->getGrammarCheck(*m_pImpl->m_pTextNode, true);
159 OSL_ENSURE( pWList, "GrammarContact _has_ to deliver a wrong list" );
160 }
161 else
162 {
163 pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
164 if ( !pWList )
165 {
166 m_pImpl->m_pTextNode->SetGrammarCheck( std::make_unique<SwGrammarMarkUp>() );
167 pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
168 }
169 }
170 bRepaint = pWList == m_pImpl->m_pTextNode->GetGrammarCheck();
171 if( pWList->GetBeginInv() < COMPLETE_STRING )
172 static_cast<SwGrammarMarkUp*>(pWList)->ClearGrammarList();
173 }
174 else if ( nType == text::TextMarkupType::SMARTTAG )
175 {
176 pWList = m_pImpl->m_pTextNode->GetSmartTags();
177 if ( !pWList )
178 {
179 pWList = new SwWrongList( WRONGLIST_SMARTTAG );
180 m_pImpl->m_pTextNode->SetSmartTags( std::unique_ptr<SwWrongList>(pWList) );
181 }
182 }
183 else
184 {
185 OSL_FAIL( "Unknown mark-up type" );
186 return;
187 }
188
189 const ModelToViewHelper::ModelPosition aStartPos =
190 m_pImpl->m_ConversionMap.ConvertToModelPosition( nStart );
192 m_pImpl->m_ConversionMap.ConvertToModelPosition( nStart + nLength - 1);
193
194 const bool bStartInField = aStartPos.mbIsField;
195 const bool bEndInField = aEndPos.mbIsField;
196 bool bCommit = false;
197
198 if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
199 {
200 nStart = aStartPos.mnSubPos;
201 const sal_Int32 nFieldPosModel = aStartPos.mnPos;
202 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
203
204 SwWrongList* pSubList = pWList->SubList( nInsertPos );
205 if ( !pSubList )
206 {
207 if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
208 pSubList = new SwGrammarMarkUp();
209 else
210 pSubList = new SwWrongList( pWList->GetWrongListType() );
211 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
212 }
213
214 pWList = pSubList;
215 bCommit = true;
216 }
217 else if ( !bStartInField && !bEndInField )
218 {
219 nStart = aStartPos.mnPos;
220 bCommit = true;
221 nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
222 }
223 else if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
224 {
225 bCommit = true;
226 nStart = aStartPos.mnPos;
227 sal_Int32 nEnd = aEndPos.mnPos;
228 if( bStartInField && nType != text::TextMarkupType::SENTENCE )
229 {
230 const sal_Int32 nFieldPosModel = aStartPos.mnPos;
231 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
232 SwWrongList* pSubList = pWList->SubList( nInsertPos );
233 if ( !pSubList )
234 {
235 pSubList = new SwGrammarMarkUp();
236 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
237 }
238 const sal_Int32 nTmpStart =
239 m_pImpl->m_ConversionMap.ConvertToViewPosition(aStartPos.mnPos);
240 const sal_Int32 nTmpLen =
241 m_pImpl->m_ConversionMap.ConvertToViewPosition(aStartPos.mnPos + 1)
242 - nTmpStart - aStartPos.mnSubPos;
243 if( nTmpLen > 0 )
244 {
245 pSubList->Insert( rIdentifier, xMarkupInfoContainer, aStartPos.mnSubPos, nTmpLen );
246 }
247 ++nStart;
248 }
249 if( bEndInField && nType != text::TextMarkupType::SENTENCE )
250 {
251 const sal_Int32 nFieldPosModel = aEndPos.mnPos;
252 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
253 SwWrongList* pSubList = pWList->SubList( nInsertPos );
254 if ( !pSubList )
255 {
256 pSubList = new SwGrammarMarkUp();
257 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
258 }
259 const sal_Int32 nTmpLen = aEndPos.mnSubPos + 1;
260 pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, nTmpLen );
261 }
262 else
263 ++nEnd;
264 if( nEnd > nStart )
265 nLength = nEnd - nStart;
266 else
267 bCommit = false;
268 }
269
270 if ( bCommit )
271 {
272 if( nType == text::TextMarkupType::SENTENCE )
273 static_cast<SwGrammarMarkUp*>(pWList)->setSentence( nStart );
274 else
275 pWList->Insert( rIdentifier, xMarkupInfoContainer, nStart, nLength );
276 }
277
278 if( bRepaint )
279 sw::finishGrammarCheckFor(*m_pImpl->m_pTextNode);
280}
281
283 const ModelToViewHelper& rConversionMap,
284 SwGrammarMarkUp* pWList,
285 ::sal_Int32 nType,
286 const OUString & rIdentifier,
287 ::sal_Int32 nStart,
288 ::sal_Int32 nLength,
289 const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
290{
291 OSL_ENSURE( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE, "Wrong mark-up type" );
292 const ModelToViewHelper::ModelPosition aStartPos =
293 rConversionMap.ConvertToModelPosition( nStart );
295 rConversionMap.ConvertToModelPosition( nStart + nLength - 1);
296
297 const bool bStartInField = aStartPos.mbIsField;
298 const bool bEndInField = aEndPos.mbIsField;
299 bool bCommit = false;
300
301 if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
302 {
303 nStart = aStartPos.mnSubPos;
304 const sal_Int32 nFieldPosModel = aStartPos.mnPos;
305 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
306
307 SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
308 if ( !pSubList )
309 {
310 pSubList = new SwGrammarMarkUp();
311 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
312 }
313
314 pWList = pSubList;
315 bCommit = true;
316 }
317 else if ( !bStartInField && !bEndInField )
318 {
319 nStart = aStartPos.mnPos;
320 bCommit = true;
321 nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
322 }
323 else
324 {
325 bCommit = true;
326 nStart = aStartPos.mnPos;
327 sal_Int32 nEnd = aEndPos.mnPos;
328 if( bStartInField && nType != text::TextMarkupType::SENTENCE )
329 {
330 const sal_Int32 nFieldPosModel = aStartPos.mnPos;
331 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
332 SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
333 if ( !pSubList )
334 {
335 pSubList = new SwGrammarMarkUp();
336 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
337 }
338 const sal_Int32 nTmpStart = rConversionMap.ConvertToViewPosition( aStartPos.mnPos );
339 const sal_Int32 nTmpLen = rConversionMap.ConvertToViewPosition( aStartPos.mnPos + 1 )
340 - nTmpStart - aStartPos.mnSubPos;
341 if( nTmpLen > 0 )
342 pSubList->Insert( rIdentifier, xMarkupInfoContainer, aStartPos.mnSubPos, nTmpLen );
343 ++nStart;
344 }
345 if( bEndInField && nType != text::TextMarkupType::SENTENCE )
346 {
347 const sal_Int32 nFieldPosModel = aEndPos.mnPos;
348 const sal_uInt16 nInsertPos = pWList->GetWrongPos( nFieldPosModel );
349 SwGrammarMarkUp* pSubList = static_cast<SwGrammarMarkUp*>(pWList->SubList( nInsertPos ));
350 if ( !pSubList )
351 {
352 pSubList = new SwGrammarMarkUp();
353 pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
354 }
355 const sal_Int32 nTmpLen = aEndPos.mnSubPos + 1;
356 pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, nTmpLen );
357 }
358 else
359 ++nEnd;
360 if( nEnd > nStart )
361 nLength = nEnd - nStart;
362 else
363 bCommit = false;
364 }
365
366 if ( bCommit )
367 {
368 if( nType == text::TextMarkupType::SENTENCE )
369 pWList->setSentence( nStart+nLength );
370 else
371 pWList->Insert( rIdentifier, xMarkupInfoContainer, nStart, nLength );
372 }
373}
374
376 const uno::Sequence< text::TextMarkupDescriptor > &rMarkups )
377{
378 SolarMutexGuard aGuard;
379
380 // paragraph already dead or modified?
381 if (!m_pImpl->m_pTextNode)
382 return;
383
384 // for grammar checking there should be exactly one sentence markup
385 // and 0..n grammar markups.
386 // Different markups are not expected but may be applied anyway since
387 // that should be no problem...
388 // but it has to be implemented, at the moment only this function is for
389 // grammar markups and sentence markup only!
390 const text::TextMarkupDescriptor *pSentenceMarkUp = nullptr;
391 for( const text::TextMarkupDescriptor &rDesc : rMarkups )
392 {
393 if (rDesc.nType == text::TextMarkupType::SENTENCE)
394 {
395 if (pSentenceMarkUp != nullptr)
396 throw lang::IllegalArgumentException(); // there is already one sentence markup
397 pSentenceMarkUp = &rDesc;
398 }
399 else if( rDesc.nType != text::TextMarkupType::PROOFREADING )
400 return;
401 }
402
403 if( pSentenceMarkUp == nullptr )
404 return;
405
406 // get appropriate list to use...
407 SwGrammarMarkUp* pWList = nullptr;
408 bool bRepaint = false;
409 sw::GrammarContact* pGrammarContact = sw::getGrammarContactFor(*m_pImpl->m_pTextNode);
410 if( pGrammarContact )
411 {
412 pWList = pGrammarContact->getGrammarCheck(*m_pImpl->m_pTextNode, true);
413 OSL_ENSURE( pWList, "GrammarContact _has_ to deliver a wrong list" );
414 }
415 else
416 {
417 pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
418 if ( !pWList )
419 {
420 m_pImpl->m_pTextNode->SetGrammarCheck( std::make_unique<SwGrammarMarkUp>() );
421 pWList = m_pImpl->m_pTextNode->GetGrammarCheck();
422 pWList->SetInvalid( 0, COMPLETE_STRING );
423 }
424 }
425 bRepaint = pWList == m_pImpl->m_pTextNode->GetGrammarCheck();
426
427 bool bAcceptGrammarError = false;
428 if( pWList->GetBeginInv() < COMPLETE_STRING )
429 {
430 const ModelToViewHelper::ModelPosition aSentenceEnd =
431 m_pImpl->m_ConversionMap.ConvertToModelPosition(
432 pSentenceMarkUp->nOffset + pSentenceMarkUp->nLength );
433 bAcceptGrammarError = aSentenceEnd.mnPos > pWList->GetBeginInv();
434 pWList->ClearGrammarList( aSentenceEnd.mnPos );
435 }
436
437 if( bAcceptGrammarError )
438 {
439 for( const text::TextMarkupDescriptor &rDesc : rMarkups )
440 {
441 lcl_commitGrammarMarkUp(m_pImpl->m_ConversionMap, pWList, rDesc.nType,
442 rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
443 }
444 }
445 else
446 {
447 bRepaint = false;
448 const text::TextMarkupDescriptor &rDesc = *pSentenceMarkUp;
449 lcl_commitGrammarMarkUp(m_pImpl->m_ConversionMap, pWList, rDesc.nType,
450 rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
451 }
452
453 if( bRepaint )
454 sw::finishGrammarCheckFor(*m_pImpl->m_pTextNode);
455}
456
458{
460 if(rHint.GetId() == SfxHintId::Dying)
461 {
462 m_pTextNode = nullptr;
463 }
464}
465
467{
468}
469
470uno::Any SAL_CALL SwXStringKeyMap::getValue(const OUString & aKey)
471{
472 std::map< OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
473 if ( aIter == maMap.end() )
474 throw container::NoSuchElementException();
475
476 return (*aIter).second;
477}
478
479sal_Bool SAL_CALL SwXStringKeyMap::hasValue(const OUString & aKey)
480{
481 return maMap.find( aKey ) != maMap.end();
482}
483
484void SAL_CALL SwXStringKeyMap::insertValue(const OUString & aKey, const uno::Any & aValue)
485{
486 std::map< OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
487 if ( aIter != maMap.end() )
488 throw container::ElementExistException();
489
490 maMap[ aKey ] = aValue;
491}
492
493::sal_Int32 SAL_CALL SwXStringKeyMap::getCount()
494{
495 return maMap.size();
496}
497
498OUString SAL_CALL SwXStringKeyMap::getKeyByIndex(::sal_Int32 nIndex)
499{
500 if ( o3tl::make_unsigned(nIndex) >= maMap.size() )
501 throw lang::IndexOutOfBoundsException();
502
503 return OUString();
504}
505
506uno::Any SAL_CALL SwXStringKeyMap::getValueByIndex(::sal_Int32 nIndex)
507{
508 if ( o3tl::make_unsigned(nIndex) >= maMap.size() )
509 throw lang::IndexOutOfBoundsException();
510
511 return uno::Any();
512}
513
514/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
ModelPosition ConvertToModelPosition(sal_Int32 nViewPos) const
Converts a view position into a model position.
sal_Int32 ConvertToViewPosition(sal_Int32 nModelPos) const
Converts a model position into a view position.
SfxHintId GetId() const
bool StartListening(SvtBroadcaster &rBroadcaster)
Definition: doc.hxx:197
void ClearGrammarList(sal_Int32 nSentenceEnd=COMPLETE_STRING)
void setSentence(sal_Int32 nStart)
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
std::pair< const SwPosition *, const SwPosition * > StartEnd() const
Because sometimes the cost of the operator<= can add up.
Definition: pam.hxx:269
static SwSmartTagMgr & Get()
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
WrongListType GetWrongListType() const
Definition: wrong.hxx:287
void InsertSubList(sal_Int32 nNewPos, sal_Int32 nNewLen, sal_uInt16 nWhere, SwWrongList *pSubList)
Definition: wrong.cxx:523
sal_uInt16 GetWrongPos(sal_Int32 nValue) const
Find the first position that is greater or equal to the given value.
Definition: wrong.cxx:191
void SetInvalid(sal_Int32 nBegin, sal_Int32 nEnd)
Definition: wrong.cxx:254
SwWrongList * SubList(sal_uInt16 nIdx) const
Definition: wrong.hxx:342
void Insert(sal_uInt16 nWhere, std::vector< SwWrongArea >::iterator startPos, std::vector< SwWrongArea >::iterator const &endPos)
Definition: wrong.cxx:538
sal_Int32 GetBeginInv() const
Definition: wrong.hxx:288
Implementation of the css::container::XStringKeyMap interface.
virtual sal_Bool SAL_CALL hasValue(const OUString &aKey) override
virtual css::uno::Any SAL_CALL getValue(const OUString &aKey) override
virtual ::sal_Int32 SAL_CALL getCount() override
virtual css::uno::Any SAL_CALL getValueByIndex(::sal_Int32 nIndex) override
virtual OUString SAL_CALL getKeyByIndex(::sal_Int32 nIndex) override
virtual void SAL_CALL insertValue(const OUString &aKey, const css::uno::Any &aValue) override
virtual void SAL_CALL commitStringMarkup(::sal_Int32 nType, const OUString &aIdentifier, ::sal_Int32 nStart, ::sal_Int32 nLength, const css::uno::Reference< css::container::XStringKeyMap > &xMarkupInfoContainer) override
::sw::UnoImplPtr< Impl > m_pImpl
virtual css::uno::Reference< css::container::XStringKeyMap > SAL_CALL getMarkupInfoContainer() override
const ModelToViewHelper & GetConversionMap() const
virtual void SAL_CALL commitMultiTextMarkup(const css::uno::Sequence< css::text::TextMarkupDescriptor > &aMarkups) override
SwXTextMarkup(SwTextNode *const rTextNode, const ModelToViewHelper &rConversionMap)
virtual ~SwXTextMarkup() override
virtual void SAL_CALL commitTextRangeMarkup(::sal_Int32 nType, const OUString &aIdentifier, const css::uno::Reference< css::text::XTextRange > &xRange, const css::uno::Reference< css::container::XStringKeyMap > &xMarkupInfoContainer) override
void ClearTextNode()
SwTextNode * GetTextNode()
This class is responsible for the delayed display of grammar checks when a paragraph is edited It's a...
SwGrammarMarkUp * getGrammarCheck(SwTextNode &rTextNode, bool bCreate)
getGrammarCheck checks if the given text node is blocked by the current cursor if not,...
#define DBG_TESTSOLARMUTEX()
sal_Int32 nIndex
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sw::GrammarContact * getGrammarContactFor(const SwTextNode &rTextNode)
getGrammarContact() delivers the grammar contact of the document (for a given textnode)
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange, ::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1108
void finishGrammarCheckFor(SwTextNode &rTextNode)
finishGrammarCheck() calls the same function of the grammar contact of the document (for a given text...
HashMap_OWString_Interface aMap
QPRO_FUNC_TYPE nType
This struct defines a position in the model string.
virtual void Notify(const SfxHint &rHint) override
SwTextNode * m_pTextNode
Impl(SwTextNode *const pTextNode, ModelToViewHelper aMap)
ModelToViewHelper const m_ConversionMap
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
unsigned char sal_Bool
static void lcl_commitGrammarMarkUp(const ModelToViewHelper &rConversionMap, SwGrammarMarkUp *pWList, ::sal_Int32 nType, const OUString &rIdentifier, ::sal_Int32 nStart, ::sal_Int32 nLength, const uno::Reference< container::XStringKeyMap > &xMarkupInfoContainer)
@ WRONGLIST_SPELL
Definition: wrong.hxx:58
@ WRONGLIST_SMARTTAG
Definition: wrong.hxx:60
sal_Int32 nLength