Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / lingu / hhcwrp.cxx
blob813f9d043c8b08ffd641599dee19df018675c12e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hintids.hxx>
21 #include <view.hxx>
22 #include <wrtsh.hxx>
23 #include <swundo.hxx>
24 #include <splargs.hxx>
26 #include <editeng/langitem.hxx>
27 #include <editeng/fontitem.hxx>
28 #include <rtl/ustring.hxx>
29 #include <com/sun/star/text/RubyAdjust.hpp>
30 #include <com/sun/star/i18n/XBreakIterator.hpp>
31 #include <osl/diagnose.h>
32 #include <hhcwrp.hxx>
33 #include "sdrhhcwrap.hxx"
34 #include <doc.hxx>
35 #include <docsh.hxx>
36 #include <mdiexp.hxx>
37 #include <edtwin.hxx>
38 #include <contentindex.hxx>
39 #include <pam.hxx>
40 #include <swcrsr.hxx>
41 #include <ndtxt.hxx>
42 #include <fmtruby.hxx>
43 #include <breakit.hxx>
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::text;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::linguistic2;
49 using namespace ::com::sun::star::i18n;
51 // Description: Turn off frame/object shell if applicable
53 static void lcl_ActivateTextShell( SwWrtShell & rWrtSh )
55 if( rWrtSh.IsSelFrameMode() || rWrtSh.IsObjSelected() )
56 rWrtSh.EnterStdMode();
59 namespace {
61 class SwKeepConversionDirectionStateContext
63 public:
64 SwKeepConversionDirectionStateContext()
66 //!! hack to transport the current conversion direction state settings
67 //!! into the next incarnation that iterates over the drawing objects
68 //!! ( see SwHHCWrapper::~SwHHCWrapper() )
69 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( true );
72 ~SwKeepConversionDirectionStateContext()
74 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( false );
80 SwHHCWrapper::SwHHCWrapper(
81 SwView* pSwView,
82 const uno::Reference< uno::XComponentContext >& rxContext,
83 LanguageType nSourceLanguage,
84 LanguageType nTargetLanguage,
85 const vcl::Font *pTargetFont,
86 sal_Int32 nConvOptions,
87 bool bIsInteractive,
88 bool bStart, bool bOther, bool bSelection )
89 : editeng::HangulHanjaConversion(pSwView->GetEditWin().GetFrameWeld(), rxContext,
90 LanguageTag::convertToLocale( nSourceLanguage ),
91 LanguageTag::convertToLocale( nTargetLanguage ),
92 pTargetFont,
93 nConvOptions,
94 bIsInteractive )
95 , m_pView( pSwView )
96 , m_rWrtShell( pSwView->GetWrtShell() )
97 , m_nLastPos( 0 )
98 , m_nUnitOffset( 0 )
99 , m_nPageCount( 0 )
100 , m_nPageStart( 0 )
101 , m_bIsDrawObj( false )
102 , m_bIsOtherContent( bOther )
103 , m_bStartChk( bOther )
104 , m_bIsSelection( bSelection )
105 , m_bStartDone( bOther || bStart )
106 , m_bEndDone( false )
110 SwHHCWrapper::~SwHHCWrapper() COVERITY_NOEXCEPT_FALSE
112 m_pConvArgs.reset();
114 SwViewShell::SetCareDialog(nullptr);
116 // check for existence of a draw view which means that there are
117 // (or previously were) draw objects present in the document.
118 // I.e. we like to check those too.
119 if ( m_bIsDrawObj /*&& bLastRet*/ && m_pView->GetWrtShell().HasDrawView() )
121 vcl::Cursor *pSave = m_pView->GetWindow()->GetCursor();
123 SwKeepConversionDirectionStateContext aContext;
125 SdrHHCWrapper aSdrConvWrap( m_pView, GetSourceLanguage(),
126 GetTargetLanguage(), GetTargetFont(),
127 GetConversionOptions(), IsInteractive() );
128 aSdrConvWrap.StartTextConversion();
130 m_pView->GetWindow()->SetCursor( pSave );
133 if( m_nPageCount )
134 ::EndProgress( m_pView->GetDocShell() );
136 // finally for chinese translation we need to change the documents
137 // default language and font to the new ones to be used.
138 LanguageType nTargetLang = GetTargetLanguage();
139 if (!IsChinese( nTargetLang ))
140 return;
142 SwDoc *pDoc = m_pView->GetDocShell()->GetDoc();
144 //!! Note: This also effects the default language of text boxes (EditEngine/EditView) !!
145 pDoc->SetDefault( SvxLanguageItem( nTargetLang, RES_CHRATR_CJK_LANGUAGE ) );
147 const vcl::Font *pFont = GetTargetFont();
148 if (pFont)
150 SvxFontItem aFontItem( pFont->GetFamilyType(), pFont->GetFamilyName(),
151 pFont->GetStyleName(), pFont->GetPitch(),
152 pFont->GetCharSet(), RES_CHRATR_CJK_FONT );
153 pDoc->SetDefault( aFontItem );
157 void SwHHCWrapper::GetNextPortion(
158 OUString& rNextPortion,
159 LanguageType& rLangOfPortion,
160 bool bAllowChanges )
162 m_pConvArgs->bAllowImplicitChangesForNotConvertibleText = bAllowChanges;
164 FindConvText_impl();
165 rNextPortion = m_pConvArgs->aConvText;
166 rLangOfPortion = m_pConvArgs->nConvTextLang;
168 m_nUnitOffset = 0;
170 // build last pos from currently selected text
171 SwPaM* pCursor = m_rWrtShell.GetCursor();
172 m_nLastPos = pCursor->Start()->GetContentIndex();
175 void SwHHCWrapper::SelectNewUnit_impl( sal_Int32 nUnitStart, sal_Int32 nUnitEnd )
177 SwPaM *pCursor = m_rWrtShell.GetCursor();
178 pCursor->GetPoint()->SetContent( m_nLastPos );
179 pCursor->DeleteMark();
181 m_rWrtShell.Right( SwCursorSkipMode::Chars, /*bExpand*/ false,
182 o3tl::narrowing<sal_uInt16>(m_nUnitOffset + nUnitStart), true );
183 pCursor->SetMark();
184 m_rWrtShell.Right( SwCursorSkipMode::Chars, /*bExpand*/ true,
185 o3tl::narrowing<sal_uInt16>(nUnitEnd - nUnitStart), true );
186 // end selection now. Otherwise SHIFT+HOME (extending the selection)
187 // won't work when the dialog is closed without any replacement.
188 // (see #116346#)
189 m_rWrtShell.EndSelect();
192 void SwHHCWrapper::HandleNewUnit(
193 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd )
195 OSL_ENSURE( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" );
196 if (0 > nUnitStart || nUnitStart > nUnitEnd)
197 return;
199 lcl_ActivateTextShell( m_rWrtShell );
201 m_rWrtShell.StartAllAction();
203 // select current unit
204 SelectNewUnit_impl( nUnitStart, nUnitEnd );
206 m_rWrtShell.EndAllAction();
209 void SwHHCWrapper::ChangeText( const OUString &rNewText,
210 std::u16string_view aOrigText,
211 const uno::Sequence< sal_Int32 > *pOffsets,
212 SwPaM *pCursor )
214 //!! please see also TextConvWrapper::ChangeText with is a modified
215 //!! copy of this code
217 OSL_ENSURE( !rNewText.isEmpty(), "unexpected empty string" );
218 if (rNewText.isEmpty())
219 return;
221 if (pOffsets && pCursor) // try to keep as much attributation as possible ?
223 // remember cursor start position for later setting of the cursor
224 const SwPosition *pStart = pCursor->Start();
225 const sal_Int32 nStartIndex = pStart->GetContentIndex();
226 SwTextNode *pStartTextNode = pStart->GetNode().GetTextNode();
228 const sal_Int32 nIndices = pOffsets->getLength();
229 const sal_Int32 *pIndices = pOffsets->getConstArray();
230 sal_Int32 nConvTextLen = rNewText.getLength();
231 sal_Int32 nPos = 0;
232 sal_Int32 nChgPos = -1;
233 sal_Int32 nChgLen = 0;
234 sal_Int32 nConvChgPos = -1;
235 sal_Int32 nConvChgLen = 0;
237 // offset to calculate the position in the text taking into
238 // account that text may have been replaced with new text of
239 // different length. Negative values allowed!
240 tools::Long nCorrectionOffset = 0;
242 OSL_ENSURE(nIndices == 0 || nIndices == nConvTextLen,
243 "mismatch between string length and sequence length!" );
245 // find all substrings that need to be replaced (and only those)
246 while (true)
248 // get index in original text that matches nPos in new text
249 sal_Int32 nIndex;
250 if (nPos < nConvTextLen)
251 nIndex = nPos < nIndices ? pIndices[nPos] : nPos;
252 else
254 nPos = nConvTextLen;
255 nIndex = aOrigText.size();
258 if (nPos == nConvTextLen || /* end of string also terminates non-matching char sequence */
259 aOrigText[nIndex] == rNewText[nPos])
261 // substring that needs to be replaced found?
262 if (nChgPos != -1 && nConvChgPos != -1)
264 nChgLen = nIndex - nChgPos;
265 nConvChgLen = nPos - nConvChgPos;
266 OUString aInNew( rNewText.copy( nConvChgPos, nConvChgLen ) );
268 // set selection to sub string to be replaced in original text
269 sal_Int32 nChgInNodeStartIndex = nStartIndex + nCorrectionOffset + nChgPos;
270 OSL_ENSURE( m_rWrtShell.GetCursor()->HasMark(), "cursor misplaced (nothing selected)" );
271 m_rWrtShell.GetCursor()->GetMark()->Assign( *pStartTextNode, nChgInNodeStartIndex );
272 m_rWrtShell.GetCursor()->GetPoint()->Assign( *pStartTextNode, nChgInNodeStartIndex + nChgLen );
274 // replace selected sub string with the corresponding
275 // sub string from the new text while keeping as
276 // much from the attributes as possible
277 ChangeText_impl( aInNew, true );
279 nCorrectionOffset += nConvChgLen - nChgLen;
281 nChgPos = -1;
282 nConvChgPos = -1;
285 else
287 // begin of non-matching char sequence found ?
288 if (nChgPos == -1 && nConvChgPos == -1)
290 nChgPos = nIndex;
291 nConvChgPos = nPos;
294 if (nPos >= nConvTextLen)
295 break;
296 ++nPos;
299 // set cursor to the end of all the new text
300 // (as it would happen after ChangeText_impl (Delete and Insert)
301 // of the whole text in the 'else' branch below)
302 m_rWrtShell.ClearMark();
303 m_rWrtShell.GetCursor()->Start()->Assign( *pStartTextNode, nStartIndex + nConvTextLen );
305 else
307 ChangeText_impl( rNewText, false );
311 void SwHHCWrapper::ChangeText_impl( const OUString &rNewText, bool bKeepAttributes )
313 if (bKeepAttributes)
315 // get item set with all relevant attributes
316 SfxItemSetFixed<RES_CHRATR_BEGIN, RES_FRMATR_END> aItemSet( m_rWrtShell.GetAttrPool() );
317 // get all attributes spanning the whole selection in order to
318 // restore those for the new text
319 m_rWrtShell.GetCurAttr( aItemSet );
321 m_rWrtShell.Delete(true);
322 m_rWrtShell.Insert( rNewText );
324 // select new inserted text (currently the Point is right after the new text)
325 if (!m_rWrtShell.GetCursor()->HasMark())
326 m_rWrtShell.GetCursor()->SetMark();
327 SwPosition *pMark = m_rWrtShell.GetCursor()->GetMark();
328 pMark->SetContent( pMark->GetContentIndex() - rNewText.getLength() );
330 // since 'SetAttr' below functions like merging with the attributes
331 // from the itemset with any existing ones we have to get rid of all
332 // all attributes now. (Those attributes that may take effect left
333 // to the position where the new text gets inserted after the old text
334 // was deleted)
335 m_rWrtShell.ResetAttr();
336 // apply previously saved attributes to new text
337 m_rWrtShell.SetAttrSet( aItemSet );
339 else
341 m_rWrtShell.Delete(true);
342 m_rWrtShell.Insert( rNewText );
346 void SwHHCWrapper::ReplaceUnit(
347 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd,
348 const OUString& rOrigText,
349 const OUString& rReplaceWith,
350 const uno::Sequence< sal_Int32 > &rOffsets,
351 ReplacementAction eAction,
352 LanguageType *pNewUnitLanguage )
354 OSL_ENSURE( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" );
355 if (nUnitStart < 0 || nUnitEnd < nUnitStart)
356 return;
358 lcl_ActivateTextShell( m_rWrtShell );
360 // replace the current word
361 m_rWrtShell.StartAllAction();
363 // select current unit
364 SelectNewUnit_impl( nUnitStart, nUnitEnd );
366 OUString aOrigText( m_rWrtShell.GetSelText() );
367 OUString aNewText( rReplaceWith );
368 OSL_ENSURE( aOrigText == rOrigText, "!! text mismatch !!" );
369 std::unique_ptr<SwFormatRuby> pRuby;
370 bool bRubyBelow = false;
371 OUString aNewOrigText;
372 switch (eAction)
374 case eExchange :
375 break;
376 case eReplacementBracketed :
378 aNewText = aOrigText + "(" + rReplaceWith + ")";
380 break;
381 case eOriginalBracketed :
383 aNewText = rReplaceWith + "(" + aOrigText + ")";
385 break;
386 case eReplacementAbove :
388 pRuby.reset(new SwFormatRuby( rReplaceWith ));
390 break;
391 case eOriginalAbove :
393 pRuby.reset(new SwFormatRuby( aOrigText ));
394 aNewOrigText = rReplaceWith;
396 break;
397 case eReplacementBelow :
399 pRuby.reset(new SwFormatRuby( rReplaceWith ));
400 bRubyBelow = true;
402 break;
403 case eOriginalBelow :
405 pRuby.reset(new SwFormatRuby( aOrigText ));
406 aNewOrigText = rReplaceWith;
407 bRubyBelow = true;
409 break;
410 default:
411 OSL_FAIL("unexpected case" );
413 m_nUnitOffset += nUnitStart + aNewText.getLength();
415 if (pRuby)
417 m_rWrtShell.StartUndo( SwUndoId::SETRUBYATTR );
418 if (!aNewOrigText.isEmpty())
420 // according to FT we currently should not bother about keeping
421 // attributes in Hangul/Hanja conversion
422 ChangeText( aNewOrigText, rOrigText, nullptr, nullptr );
424 //!! since Delete, Insert in 'ChangeText' do not set the WrtShells
425 //!! bInSelect flag
426 //!! back to false we do it now manually in order for the selection
427 //!! to be done properly in the following call to Left.
428 // We didn't fix it in Delete and Insert since it is currently
429 // unclear if someone depends on this incorrect behaviour
430 // of the flag.
431 m_rWrtShell.EndSelect();
433 m_rWrtShell.Left( SwCursorSkipMode::Chars, true, aNewOrigText.getLength(), true, true );
436 pRuby->SetPosition( o3tl::narrowing<sal_uInt16>(bRubyBelow) );
437 pRuby->SetAdjustment( RubyAdjust_CENTER );
439 m_rWrtShell.SetAttrItem(*pRuby);
440 pRuby.reset();
441 m_rWrtShell.EndUndo( SwUndoId::SETRUBYATTR );
443 else
445 m_rWrtShell.StartUndo( SwUndoId::OVERWRITE );
447 // according to FT we should currently not bother about keeping
448 // attributes in Hangul/Hanja conversion and leave that untouched.
449 // Thus we do this only for Chinese translation...
450 const bool bIsChineseConversion = IsChinese( GetSourceLanguage() );
451 if (bIsChineseConversion)
452 ChangeText( aNewText, rOrigText, &rOffsets, m_rWrtShell.GetCursor() );
453 else
454 ChangeText( aNewText, rOrigText, nullptr, nullptr );
456 // change language and font if necessary
457 if (bIsChineseConversion)
459 m_rWrtShell.SetMark();
460 m_rWrtShell.GetCursor()->GetMark()->AdjustContent( -aNewText.getLength() );
462 OSL_ENSURE( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL,
463 "SwHHCWrapper::ReplaceUnit : unexpected target language" );
465 SfxItemSetFixed<
466 RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT,
467 RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE>
468 aSet( m_rWrtShell.GetAttrPool() );
469 if (pNewUnitLanguage)
471 aSet.Put( SvxLanguageItem( *pNewUnitLanguage, RES_CHRATR_CJK_LANGUAGE ) );
474 const vcl::Font *pTargetFont = GetTargetFont();
475 OSL_ENSURE( pTargetFont, "target font missing?" );
476 if (pTargetFont && pNewUnitLanguage)
478 SvxFontItem aFontItem( aSet.Get( RES_CHRATR_CJK_FONT ) );
479 aFontItem.SetFamilyName( pTargetFont->GetFamilyName());
480 aFontItem.SetFamily( pTargetFont->GetFamilyType());
481 aFontItem.SetStyleName( pTargetFont->GetStyleName());
482 aFontItem.SetPitch( pTargetFont->GetPitch());
483 aFontItem.SetCharSet( pTargetFont->GetCharSet() );
484 aSet.Put( aFontItem );
487 m_rWrtShell.SetAttrSet( aSet );
489 m_rWrtShell.ClearMark();
492 m_rWrtShell.EndUndo( SwUndoId::OVERWRITE );
495 m_rWrtShell.EndAllAction();
498 bool SwHHCWrapper::HasRubySupport() const
500 return true;
503 void SwHHCWrapper::Convert()
505 OSL_ENSURE( m_pConvArgs == nullptr, "NULL pointer expected" );
507 SwPaM *pCursor = m_pView->GetWrtShell().GetCursor();
508 auto [pSttPos, pEndPos] = pCursor->StartEnd(); // SwPosition*
510 if (pSttPos->GetNode().IsTextNode() &&
511 pEndPos->GetNode().IsTextNode())
513 m_pConvArgs.reset( new SwConversionArgs( GetSourceLanguage(), *pSttPos, *pEndPos ) );
515 else // we are not in the text (maybe a graphic or OLE object is selected) let's start from the top
517 // get PaM that points to the start of the document
518 SwNode& rNode = m_pView->GetDocShell()->GetDoc()->GetNodes().GetEndOfContent();
519 SwPaM aPam(rNode);
520 aPam.Move( fnMoveBackward, GoInDoc ); // move to start of document
522 pSttPos = aPam.GetPoint(); //! using a PaM here makes sure we will get only text nodes
523 SwTextNode *pTextNode = pSttPos->GetNode().GetTextNode();
524 // just in case we check anyway...
525 if (!pTextNode || !pTextNode->IsTextNode())
526 return;
527 m_pConvArgs.reset( new SwConversionArgs( GetSourceLanguage(), *pSttPos, *pSttPos ) );
529 OSL_ENSURE( m_pConvArgs->pStartPos && m_pConvArgs->pStartPos->GetNode().IsTextNode(),
530 "failed to get proper start text node" );
531 OSL_ENSURE( m_pConvArgs->pEndPos && m_pConvArgs->pEndPos->GetNode().IsTextNode(),
532 "failed to get proper end text node" );
534 // chinese conversion specific settings
535 OSL_ENSURE( IsChinese( GetSourceLanguage() ) == IsChinese( GetTargetLanguage() ),
536 "source and target language mismatch?" );
537 if (IsChinese( GetTargetLanguage() ))
539 m_pConvArgs->nConvTargetLang = GetTargetLanguage();
540 m_pConvArgs->pTargetFont = GetTargetFont();
541 m_pConvArgs->bAllowImplicitChangesForNotConvertibleText = true;
544 // if it is not just a selection and we are about to begin
545 // with the current conversion for the very first time
546 // we need to find the start of the current (initial)
547 // convertible unit in order for the text conversion to give
548 // the correct result for that. Since it is easier to obtain
549 // the start of the word we use that though.
550 if (!pCursor->HasMark()) // is not a selection?
552 // since #118246 / #117803 still occurs if the cursor is placed
553 // between the two chinese characters to be converted (because both
554 // of them are words on their own!) using the word boundary here does
555 // not work. Thus since chinese conversion is not interactive we start
556 // at the begin of the paragraph to solve the problem, i.e. have the
557 // TextConversion service get those characters together in the same call.
558 sal_Int32 nStartIdx = -1;
559 if (editeng::HangulHanjaConversion::IsChinese( GetSourceLanguage() ) )
560 nStartIdx = 0;
561 else
563 OUString aText( m_pConvArgs->pStartPos->GetNode().GetTextNode()->GetText() );
564 const sal_Int32 nPos = m_pConvArgs->pStartPos->GetContentIndex();
565 Boundary aBoundary( g_pBreakIt->GetBreakIter()->
566 getWordBoundary( aText, nPos, g_pBreakIt->GetLocale( m_pConvArgs->nConvSrcLang ),
567 WordType::DICTIONARY_WORD, true ) );
569 // valid result found?
570 if (aBoundary.startPos < aText.getLength() &&
571 aBoundary.startPos != aBoundary.endPos)
573 nStartIdx = aBoundary.startPos;
577 if (nStartIdx != -1)
578 m_pConvArgs->pStartPos->SetContent( nStartIdx );
582 if ( m_bIsOtherContent )
583 ConvStart_impl( m_pConvArgs.get(), SvxSpellArea::Other );
584 else
586 m_bStartChk = false;
587 ConvStart_impl( m_pConvArgs.get(), SvxSpellArea::BodyEnd );
590 ConvertDocument();
592 ConvEnd_impl( m_pConvArgs.get() );
595 bool SwHHCWrapper::ConvNext_impl( )
597 //! modified version of SvxSpellWrapper::SpellNext
599 // no change of direction so the desired region is fully processed
600 if( m_bStartChk )
601 m_bStartDone = true;
602 else
603 m_bEndDone = true;
605 if( m_bIsOtherContent && m_bStartDone && m_bEndDone ) // document completely checked?
607 return false;
610 bool bGoOn = false;
612 if ( m_bIsOtherContent )
614 m_bStartChk = false;
615 ConvStart_impl( m_pConvArgs.get(), SvxSpellArea::Body );
616 bGoOn = true;
618 else if ( m_bStartDone && m_bEndDone )
620 // body region done, ask about special region
621 if( !m_bIsSelection && m_rWrtShell.HasOtherCnt() )
623 ConvStart_impl( m_pConvArgs.get(), SvxSpellArea::Other );
624 m_bIsOtherContent = bGoOn = true;
627 else
629 m_bStartChk = !m_bStartDone;
630 ConvStart_impl( m_pConvArgs.get(), m_bStartChk ? SvxSpellArea::BodyStart : SvxSpellArea::BodyEnd );
631 bGoOn = true;
633 return bGoOn;
636 void SwHHCWrapper::FindConvText_impl()
638 //! modified version of SvxSpellWrapper::FindSpellError
640 bool bFound = false;
642 weld::WaitObject aWait(GetUIParent());
643 bool bConv = true;
645 while ( bConv )
647 bFound = ConvContinue_impl( m_pConvArgs.get() );
648 if (bFound)
650 bConv = false;
652 else
654 ConvEnd_impl( m_pConvArgs.get() );
655 bConv = ConvNext_impl();
660 void SwHHCWrapper::ConvStart_impl( SwConversionArgs /* [out] */ *pConversionArgs, SvxSpellArea eArea )
662 m_bIsDrawObj = SvxSpellArea::Other == eArea;
663 m_pView->SpellStart( eArea, m_bStartDone, m_bEndDone, /* [out] */ pConversionArgs );
666 void SwHHCWrapper::ConvEnd_impl( SwConversionArgs const *pConversionArgs )
668 m_pView->SpellEnd( pConversionArgs );
671 bool SwHHCWrapper::ConvContinue_impl( SwConversionArgs *pConversionArgs )
673 bool bProgress = !m_bIsDrawObj && !m_bIsSelection;
674 pConversionArgs->aConvText.clear();
675 pConversionArgs->nConvTextLang = LANGUAGE_NONE;
676 m_pView->GetWrtShell().SpellContinue( &m_nPageCount, bProgress ? &m_nPageStart : nullptr, pConversionArgs );
677 return !pConversionArgs->aConvText.isEmpty();
680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */