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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 #ifdef PRECOMPILED 27 #include "ui_pch.hxx" 28 #endif 29 30 31 #include <hintids.hxx> 32 #ifndef _VIEW_HXX 33 #include <view.hxx> 34 #endif 35 #include <wrtsh.hxx> 36 #include <swundo.hxx> // fuer Undo-Ids 37 #ifndef _GLOBALS_HRC 38 #include <globals.hrc> 39 #endif 40 #include <splargs.hxx> 41 42 43 #ifndef _MSGBOX_HXX //autogen 44 #include <vcl/msgbox.hxx> 45 #endif 46 #include <editeng/unolingu.hxx> 47 #include <editeng/langitem.hxx> 48 #include <editeng/fontitem.hxx> 49 #include <rtl/ustring.hxx> 50 #include <com/sun/star/text/RubyAdjust.hpp> 51 #include <hhcwrp.hxx> 52 #include <sdrhhcwrap.hxx> 53 #include <doc.hxx> 54 #include <docsh.hxx> 55 #include <txatritr.hxx> 56 #include <mdiexp.hxx> // Progress 57 #include <edtwin.hxx> 58 #include <crsskip.hxx> 59 #include <index.hxx> 60 #include <pam.hxx> 61 #include <swcrsr.hxx> 62 #include <viscrs.hxx> 63 #include <ndtxt.hxx> 64 #include <fmtruby.hxx> 65 #include <breakit.hxx> 66 #include <docsh.hxx> 67 68 #ifndef _OLMENU_HRC 69 #include <olmenu.hrc> 70 #endif 71 72 #include <unomid.h> 73 74 using ::rtl::OUString; 75 using namespace ::com::sun::star; 76 using namespace ::com::sun::star::text; 77 using namespace ::com::sun::star::uno; 78 using namespace ::com::sun::star::linguistic2; 79 using namespace ::com::sun::star::i18n; 80 81 #define CHAR_PAR_BRK ((sal_Char) 0x0D) 82 83 ////////////////////////////////////////////////////////////////////// 84 // Beschreibung: Ggf. Rahmen/Objektshell abschalten 85 86 static void lcl_ActivateTextShell( SwWrtShell & rWrtSh ) 87 { 88 if( rWrtSh.IsSelFrmMode() || rWrtSh.IsObjSelected() ) 89 rWrtSh.EnterStdMode(); 90 } 91 92 ////////////////////////////////////////////////////////////////////// 93 94 class SwKeepConversionDirectionStateContext 95 { 96 public: 97 SwKeepConversionDirectionStateContext() 98 { 99 //!! hack to transport the current conversion direction state settings 100 //!! into the next incarnation that iterates over the drawing objets 101 //!! ( see SwHHCWrapper::~SwHHCWrapper() ) 102 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_True ); 103 } 104 105 ~SwKeepConversionDirectionStateContext() 106 { 107 editeng::HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_False ); 108 } 109 }; 110 111 ////////////////////////////////////////////////////////////////////// 112 113 SwHHCWrapper::SwHHCWrapper( 114 SwView* pSwView, 115 const uno::Reference< lang::XMultiServiceFactory >& rxMSF, 116 LanguageType nSourceLanguage, 117 LanguageType nTargetLanguage, 118 const Font *pTargetFont, 119 sal_Int32 nConvOptions, 120 sal_Bool bIsInteractive, 121 sal_Bool bStart, sal_Bool bOther, sal_Bool bSelection ) : 122 editeng::HangulHanjaConversion( &pSwView->GetEditWin(), rxMSF, 123 SvxCreateLocale( nSourceLanguage ), 124 SvxCreateLocale( nTargetLanguage ), 125 pTargetFont, 126 nConvOptions, 127 bIsInteractive ), 128 rWrtShell( pSwView->GetWrtShell() ) 129 { 130 pConvArgs = 0; 131 nLastPos = 0; 132 nUnitOffset = 0; 133 134 pView = pSwView; 135 pWin = &pSwView->GetEditWin(); 136 bIsDrawObj = sal_False; 137 bIsStart = bStart; 138 bIsOtherCntnt = bStartChk = bOther; 139 bIsConvSpecial = sal_True; 140 bIsSelection = bSelection; 141 bInfoBox = sal_False; 142 bStartDone = bOther || bStart; 143 bEndDone = sal_False; 144 // bLastRet = sal_True; 145 nPageCount = nPageStart = 0; 146 } 147 148 149 SwHHCWrapper::~SwHHCWrapper() 150 { 151 delete pConvArgs; 152 153 rWrtShell.SetCareWin( NULL ); 154 155 // check for existence of a draw view which means that there are 156 // (or previously were) draw objects present in the document. 157 // I.e. we like to check those too. 158 if ( IsDrawObj() /*&& bLastRet*/ && pView->GetWrtShell().HasDrawView() ) 159 { 160 Cursor *pSave = pView->GetWindow()->GetCursor(); 161 { 162 SwKeepConversionDirectionStateContext aContext; 163 164 SdrHHCWrapper aSdrConvWrap( pView, GetSourceLanguage(), 165 GetTargetLanguage(), GetTargetFont(), 166 GetConversionOptions(), IsInteractive() ); 167 aSdrConvWrap.StartTextConversion(); 168 } 169 pView->GetWindow()->SetCursor( pSave ); 170 } 171 172 if( nPageCount ) 173 ::EndProgress( pView->GetDocShell() ); 174 175 // finally for chinese translation we need to change the the documents 176 // default language and font to the new ones to be used. 177 LanguageType nTargetLang = GetTargetLanguage(); 178 if (IsChinese( nTargetLang )) 179 { 180 SwDoc *pDoc = pView->GetDocShell()->GetDoc(); 181 182 //!! Note: This also effects the default language of text boxes (EditEngine/EditView) !! 183 pDoc->SetDefault( SvxLanguageItem( nTargetLang, RES_CHRATR_CJK_LANGUAGE ) ); 184 // 185 const Font *pFont = GetTargetFont(); 186 if (pFont) 187 { 188 SvxFontItem aFontItem( pFont->GetFamily(), pFont->GetName(), 189 pFont->GetStyleName(), pFont->GetPitch(), 190 pFont->GetCharSet(), RES_CHRATR_CJK_FONT ); 191 pDoc->SetDefault( aFontItem ); 192 } 193 194 } 195 196 /* 197 if( bInfoBox ) 198 InfoBox(&pView->GetEditWin(), String(SW_RES(STR_SPELL_OK)) ).Execute(); 199 */ 200 } 201 202 203 void SwHHCWrapper::GetNextPortion( 204 ::rtl::OUString& rNextPortion, 205 LanguageType& rLangOfPortion, 206 sal_Bool bAllowChanges ) 207 { 208 pConvArgs->bAllowImplicitChangesForNotConvertibleText = bAllowChanges; 209 210 FindConvText_impl(); 211 rNextPortion = pConvArgs->aConvText; 212 rLangOfPortion = pConvArgs->nConvTextLang; 213 214 nUnitOffset = 0; 215 216 // build last pos from currently selected text 217 SwPaM* pCrsr = rWrtShell.GetCrsr(); 218 nLastPos = pCrsr->Start()->nContent.GetIndex(); 219 } 220 221 222 void SwHHCWrapper::SelectNewUnit_impl( sal_Int32 nUnitStart, sal_Int32 nUnitEnd ) 223 { 224 SwPaM *pCrsr = rWrtShell.GetCrsr(); 225 pCrsr->GetPoint()->nContent = nLastPos; 226 pCrsr->DeleteMark(); 227 228 rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_False, 229 (sal_uInt16) (nUnitOffset + nUnitStart), sal_True ); 230 pCrsr->SetMark(); 231 rWrtShell.Right( CRSR_SKIP_CHARS, /*bExpand*/ sal_True, 232 (sal_uInt16) (nUnitEnd - nUnitStart), sal_True ); 233 // end selection now. Otherwise SHIFT+HOME (extending the selection) 234 // won't work when the dialog is closed without any replacement. 235 // (see #116346#) 236 rWrtShell.EndSelect(); 237 } 238 239 240 void SwHHCWrapper::HandleNewUnit( 241 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd ) 242 { 243 DBG_ASSERT( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" ); 244 if (!(0 <= nUnitStart && nUnitStart <= nUnitEnd)) 245 return; 246 247 lcl_ActivateTextShell( rWrtShell ); 248 249 rWrtShell.StartAllAction(); 250 251 // select current unit 252 SelectNewUnit_impl( nUnitStart, nUnitEnd ); 253 254 rWrtShell.EndAllAction(); 255 } 256 257 258 void SwHHCWrapper::ChangeText( const String &rNewText, 259 const OUString& rOrigText, 260 const uno::Sequence< sal_Int32 > *pOffsets, 261 SwPaM *pCrsr ) 262 { 263 //!! please see also TextConvWrapper::ChangeText with is a modified 264 //!! copy of this code 265 266 DBG_ASSERT( rNewText.Len() != 0, "unexpected empty string" ); 267 if (rNewText.Len() == 0) 268 return; 269 270 if (pOffsets && pCrsr) // try to keep as much attributation as possible ? 271 { 272 // remember cursor start position for later setting of the cursor 273 const SwPosition *pStart = pCrsr->Start(); 274 const xub_StrLen nStartIndex = pStart->nContent.GetIndex(); 275 const SwNodeIndex aStartNodeIndex = pStart->nNode; 276 SwTxtNode *pStartTxtNode = aStartNodeIndex.GetNode().GetTxtNode(); 277 278 const sal_Int32 nIndices = pOffsets->getLength(); 279 const sal_Int32 *pIndices = pOffsets->getConstArray(); 280 xub_StrLen nConvTextLen = rNewText.Len(); 281 xub_StrLen nPos = 0; 282 xub_StrLen nChgPos = STRING_NOTFOUND; 283 xub_StrLen nChgLen = 0; 284 xub_StrLen nConvChgPos = STRING_NOTFOUND; 285 xub_StrLen nConvChgLen = 0; 286 287 // offset to calculate the position in the text taking into 288 // account that text may have been replaced with new text of 289 // different length. Negative values allowed! 290 long nCorrectionOffset = 0; 291 292 DBG_ASSERT(nIndices == 0 || nIndices == nConvTextLen, 293 "mismatch between string length and sequence length!" ); 294 295 // find all substrings that need to be replaced (and only those) 296 while (sal_True) 297 { 298 // get index in original text that matches nPos in new text 299 xub_StrLen nIndex; 300 if (nPos < nConvTextLen) 301 nIndex = (sal_Int32) nPos < nIndices ? (xub_StrLen) pIndices[nPos] : nPos; 302 else 303 { 304 nPos = nConvTextLen; 305 nIndex = static_cast< xub_StrLen >( rOrigText.getLength() ); 306 } 307 308 if (rOrigText.getStr()[nIndex] == rNewText.GetChar(nPos) || 309 nPos == nConvTextLen /* end of string also terminates non-matching char sequence */) 310 { 311 // substring that needs to be replaced found? 312 if (nChgPos != STRING_NOTFOUND && nConvChgPos != STRING_NOTFOUND) 313 { 314 nChgLen = nIndex - nChgPos; 315 nConvChgLen = nPos - nConvChgPos; 316 #ifdef DEBUG 317 String aInOrig( rOrigText.copy( nChgPos, nChgLen ) ); 318 #endif 319 String aInNew( rNewText.Copy( nConvChgPos, nConvChgLen ) ); 320 321 // set selection to sub string to be replaced in original text 322 xub_StrLen nChgInNodeStartIndex = static_cast< xub_StrLen >( nStartIndex + nCorrectionOffset + nChgPos ); 323 DBG_ASSERT( rWrtShell.GetCrsr()->HasMark(), "cursor misplaced (nothing selected)" ); 324 rWrtShell.GetCrsr()->GetMark()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex ); 325 rWrtShell.GetCrsr()->GetPoint()->nContent.Assign( pStartTxtNode, nChgInNodeStartIndex + nChgLen ); 326 #ifdef DEBUG 327 String aSelTxt1( rWrtShell.GetSelTxt() ); 328 #endif 329 330 // replace selected sub string with the corresponding 331 // sub string from the new text while keeping as 332 // much from the attributes as possible 333 ChangeText_impl( aInNew, sal_True ); 334 335 nCorrectionOffset += nConvChgLen - nChgLen; 336 337 nChgPos = STRING_NOTFOUND; 338 nConvChgPos = STRING_NOTFOUND; 339 } 340 } 341 else 342 { 343 // begin of non-matching char sequence found ? 344 if (nChgPos == STRING_NOTFOUND && nConvChgPos == STRING_NOTFOUND) 345 { 346 nChgPos = nIndex; 347 nConvChgPos = nPos; 348 } 349 } 350 if (nPos >= nConvTextLen) 351 break; 352 ++nPos; 353 } 354 355 // set cursor to the end of all the new text 356 // (as it would happen after ChangeText_impl (Delete and Insert) 357 // of the whole text in the 'else' branch below) 358 rWrtShell.ClearMark(); 359 rWrtShell.GetCrsr()->Start()->nContent.Assign( pStartTxtNode, nStartIndex + nConvTextLen ); 360 } 361 else 362 { 363 ChangeText_impl( rNewText, sal_False ); 364 } 365 } 366 367 368 void SwHHCWrapper::ChangeText_impl( const String &rNewText, sal_Bool bKeepAttributes ) 369 { 370 if (bKeepAttributes) 371 { 372 // get item set with all relevant attributes 373 sal_uInt16 aRanges[] = { 374 RES_CHRATR_BEGIN, RES_FRMATR_END, 375 0, 0, 0 }; 376 SfxItemSet aItemSet( rWrtShell.GetAttrPool(), aRanges ); 377 // get all attributes spanning the whole selection in order to 378 // restore those for the new text 379 rWrtShell.GetCurAttr( aItemSet ); 380 381 #ifdef DEBUG 382 String aSelTxt1( rWrtShell.GetSelTxt() ); 383 #endif 384 rWrtShell.Delete(); 385 rWrtShell.Insert( rNewText ); 386 387 // select new inserted text (currently the Point is right after the new text) 388 if (!rWrtShell.GetCrsr()->HasMark()) 389 rWrtShell.GetCrsr()->SetMark(); 390 SwPosition *pMark = rWrtShell.GetCrsr()->GetMark(); 391 pMark->nContent = pMark->nContent.GetIndex() - rNewText.Len(); 392 #ifdef DEBUG 393 String aSelTxt2( rWrtShell.GetSelTxt() ); 394 #endif 395 396 // since 'SetAttr' below functions like merging with the attributes 397 // from the itemset with any existing ones we have to get rid of all 398 // all attributes now. (Those attributes that may take effect left 399 // to the position where the new text gets inserted after the old text 400 // was deleted) 401 rWrtShell.ResetAttr(); 402 // apply previously saved attributes to new text 403 rWrtShell.SetAttr( aItemSet ); 404 } 405 else 406 { 407 rWrtShell.Delete(); 408 rWrtShell.Insert( rNewText ); 409 } 410 } 411 412 413 void SwHHCWrapper::ReplaceUnit( 414 const sal_Int32 nUnitStart, const sal_Int32 nUnitEnd, 415 const ::rtl::OUString& rOrigText, 416 const OUString& rReplaceWith, 417 const uno::Sequence< sal_Int32 > &rOffsets, 418 ReplacementAction eAction, 419 LanguageType *pNewUnitLanguage ) 420 { 421 static OUString aBracketedStart( C2U( "(" ) ); 422 static OUString aBracketedEnd( C2U( ")" ) ); 423 424 DBG_ASSERT( nUnitStart >= 0 && nUnitEnd >= nUnitStart, "wrong arguments" ); 425 if (!(nUnitStart >= 0 && nUnitEnd >= nUnitStart)) 426 return; 427 428 lcl_ActivateTextShell( rWrtShell ); 429 430 // Das aktuelle Wort austauschen 431 rWrtShell.StartAllAction(); 432 433 // select current unit 434 SelectNewUnit_impl( nUnitStart, nUnitEnd ); 435 436 OUString aOrigTxt( rWrtShell.GetSelTxt() ); 437 OUString aNewTxt( rReplaceWith ); 438 DBG_ASSERT( aOrigTxt == rOrigText, "!! text mismatch !!" ); 439 SwFmtRuby *pRuby = 0; 440 sal_Bool bRubyBelow = sal_False; 441 String aNewOrigText; 442 switch (eAction) 443 { 444 case eExchange : 445 break; 446 case eReplacementBracketed : 447 { 448 (((aNewTxt = aOrigTxt) += aBracketedStart) += rReplaceWith) += aBracketedEnd; 449 } 450 break; 451 case eOriginalBracketed : 452 { 453 (((aNewTxt = rReplaceWith) += aBracketedStart) += aOrigTxt) += aBracketedEnd; 454 } 455 break; 456 case eReplacementAbove : 457 { 458 pRuby = new SwFmtRuby( rReplaceWith ); 459 } 460 break; 461 case eOriginalAbove : 462 { 463 pRuby = new SwFmtRuby( aOrigTxt ); 464 aNewOrigText = rReplaceWith; 465 } 466 break; 467 case eReplacementBelow : 468 { 469 pRuby = new SwFmtRuby( rReplaceWith ); 470 bRubyBelow = sal_True; 471 } 472 break; 473 case eOriginalBelow : 474 { 475 pRuby = new SwFmtRuby( aOrigTxt ); 476 aNewOrigText = rReplaceWith; 477 bRubyBelow = sal_True; 478 } 479 break; 480 default: 481 DBG_ERROR( "unexpected case" ); 482 } 483 nUnitOffset += nUnitStart + aNewTxt.getLength(); 484 485 if (pRuby) 486 { 487 rWrtShell.StartUndo( UNDO_SETRUBYATTR ); 488 if (aNewOrigText.Len()) 489 { 490 // according to FT we currently should not bother about keeping 491 // attributes in Hangul/Hanja conversion 492 ChangeText( aNewOrigText, rOrigText, NULL, NULL ); 493 494 //!! since Delete, Insert in 'ChangeText' do not set the WrtShells 495 //!! bInSelect flag 496 //!! back to false we do it now manually in order for the selection 497 //!! to be done properly in the following call to Left. 498 // We didn't fix it in Delete and Insert since it is currently 499 // unclear if someone depends on this incorrect behvaiour 500 // of the flag. 501 rWrtShell.EndSelect(); 502 503 rWrtShell.Left( 0, sal_True, aNewOrigText.Len(), sal_True, sal_True ); 504 } 505 506 pRuby->SetPosition( bRubyBelow ); 507 pRuby->SetAdjustment( RubyAdjust_CENTER ); 508 //!! the following seem not to be needed 509 //pRuby->SetCharFmtName( const String& rNm ); 510 //pRuby->SetCharFmtId( sal_uInt16 nNew ); 511 #ifdef DEBUG 512 SwPaM *pPaM = rWrtShell.GetCrsr(); 513 (void)pPaM; 514 #endif 515 rWrtShell.SetAttr(*pRuby); 516 delete pRuby; 517 rWrtShell.EndUndo( UNDO_SETRUBYATTR ); 518 } 519 else 520 { 521 rWrtShell.StartUndo( UNDO_OVERWRITE ); 522 523 // according to FT we should currently not bother about keeping 524 // attributes in Hangul/Hanja conversion and leave that untouched. 525 // Thus we do this only for Chinese translation... 526 sal_Bool bIsChineseConversion = IsChinese( GetSourceLanguage() ); 527 if (bIsChineseConversion) 528 ChangeText( aNewTxt, rOrigText, &rOffsets, rWrtShell.GetCrsr() ); 529 else 530 ChangeText( aNewTxt, rOrigText, NULL, NULL ); 531 532 // change language and font if necessary 533 if (bIsChineseConversion) 534 { 535 rWrtShell.SetMark(); 536 rWrtShell.GetCrsr()->GetMark()->nContent -= (xub_StrLen) aNewTxt.getLength(); 537 538 DBG_ASSERT( GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED || GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL, 539 "SwHHCWrapper::ReplaceUnit : unexpected target language" ); 540 541 sal_uInt16 aRanges[] = { 542 RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, 543 RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONT, 544 0, 0, 0 }; 545 546 SfxItemSet aSet( rWrtShell.GetAttrPool(), aRanges ); 547 if (pNewUnitLanguage) 548 { 549 //DBG_ASSERT(!IsSimilarChinese( *pNewUnitLanguage, nOldLang ), 550 // "similar language should not be changed!"); 551 aSet.Put( SvxLanguageItem( *pNewUnitLanguage, RES_CHRATR_CJK_LANGUAGE ) ); 552 } 553 554 const Font *pTargetFont = GetTargetFont(); 555 DBG_ASSERT( pTargetFont, "target font missing?" ); 556 if (pTargetFont && pNewUnitLanguage) 557 { 558 SvxFontItem aFontItem = (SvxFontItem&) aSet.Get( RES_CHRATR_CJK_FONT ); 559 aFontItem.SetFamilyName( pTargetFont->GetName()); 560 aFontItem.SetFamily( pTargetFont->GetFamily()); 561 aFontItem.SetStyleName( pTargetFont->GetStyleName()); 562 aFontItem.SetPitch( pTargetFont->GetPitch()); 563 aFontItem.SetCharSet( pTargetFont->GetCharSet() ); 564 aSet.Put( aFontItem ); 565 } 566 567 rWrtShell.SetAttr( aSet ); 568 569 rWrtShell.ClearMark(); 570 } 571 572 rWrtShell.EndUndo( UNDO_OVERWRITE ); 573 } 574 575 rWrtShell.EndAllAction(); 576 } 577 578 579 sal_Bool SwHHCWrapper::HasRubySupport() const 580 { 581 return sal_True; 582 } 583 584 585 void SwHHCWrapper::Convert() 586 { 587 DBG_ASSERT( pConvArgs == 0, "NULL pointer expected" ); 588 { 589 SwPaM *pCrsr = pView->GetWrtShell().GetCrsr(); 590 SwPosition* pSttPos = pCrsr->Start(); 591 SwPosition* pEndPos = pCrsr->End(); 592 593 594 if (pSttPos->nNode.GetNode().IsTxtNode() && 595 pEndPos->nNode.GetNode().IsTxtNode()) 596 { 597 pConvArgs = new SwConversionArgs( GetSourceLanguage(), 598 pSttPos->nNode.GetNode().GetTxtNode(), pSttPos->nContent, 599 pEndPos->nNode.GetNode().GetTxtNode(), pEndPos->nContent ); 600 } 601 else // we are not in the text (maybe a graphic or OLE object is selected) let's start from the top 602 { 603 // get PaM that points to the start of the document 604 SwNode& rNode = pView->GetDocShell()->GetDoc()->GetNodes().GetEndOfContent(); 605 SwPaM aPam(rNode); 606 aPam.Move( fnMoveBackward, fnGoDoc ); // move to start of document 607 608 pSttPos = aPam.GetPoint(); //! using a PaM here makes sure we will get only text nodes 609 SwTxtNode *pTxtNode = pSttPos->nNode.GetNode().GetTxtNode(); 610 // just in case we check anyway... 611 if (!pTxtNode || !pTxtNode->IsTxtNode()) 612 return; 613 pConvArgs = new SwConversionArgs( GetSourceLanguage(), 614 pTxtNode, pSttPos->nContent, 615 pTxtNode, pSttPos->nContent ); 616 } 617 DBG_ASSERT( pConvArgs->pStartNode && pConvArgs->pStartNode->IsTxtNode(), 618 "failed to get proper start text node" ); 619 DBG_ASSERT( pConvArgs->pEndNode && pConvArgs->pEndNode->IsTxtNode(), 620 "failed to get proper end text node" ); 621 622 // chinese conversion specific settings 623 DBG_ASSERT( IsChinese( GetSourceLanguage() ) == IsChinese( GetTargetLanguage() ), 624 "source and target language mismatch?" ); 625 if (IsChinese( GetTargetLanguage() )) 626 { 627 pConvArgs->nConvTargetLang = GetTargetLanguage(); 628 pConvArgs->pTargetFont = GetTargetFont(); 629 pConvArgs->bAllowImplicitChangesForNotConvertibleText = sal_True; 630 } 631 632 // if it is not just a selection and we are about to begin 633 // with the current conversion for the very first time 634 // we need to find the start of the current (initial) 635 // convertible unit in order for the text conversion to give 636 // the correct result for that. Since it is easier to obtain 637 // the start of the word we use that though. 638 if (!pCrsr->HasMark()) // is not a selection? 639 { 640 // since #118246 / #117803 still occurs if the cursor is placed 641 // between the two chinese characters to be converted (because both 642 // of them are words on their own!) using the word boundary here does 643 // not work. Thus since chinese conversion is not interactive we start 644 // at the begin of the paragraph to solve the problem, i.e. have the 645 // TextConversion service get those charcters together in the same call. 646 xub_StrLen nStartIdx = STRING_MAXLEN; 647 if (editeng::HangulHanjaConversion::IsChinese( GetSourceLanguage() ) ) 648 nStartIdx = 0; 649 else 650 { 651 OUString aText( pConvArgs->pStartNode->GetTxt() ); 652 long nPos = pConvArgs->pStartIdx->GetIndex(); 653 Boundary aBoundary( pBreakIt->GetBreakIter()-> 654 getWordBoundary( aText, nPos, pBreakIt->GetLocale( pConvArgs->nConvSrcLang ), 655 WordType::DICTIONARY_WORD, sal_True ) ); 656 657 // valid result found? 658 if (aBoundary.startPos < aText.getLength() && 659 aBoundary.startPos != aBoundary.endPos) 660 { 661 nStartIdx = static_cast< xub_StrLen >(aBoundary.startPos ); 662 } 663 } 664 665 if (STRING_MAXLEN != nStartIdx) 666 *pConvArgs->pStartIdx = nStartIdx; 667 } 668 } 669 670 if ( bIsOtherCntnt ) 671 ConvStart_impl( pConvArgs, SVX_SPELL_OTHER ); 672 else 673 { 674 bStartChk = sal_False; 675 ConvStart_impl( pConvArgs, SVX_SPELL_BODY_END ); 676 } 677 678 ConvertDocument(); 679 680 ConvEnd_impl( pConvArgs ); 681 } 682 683 684 sal_Bool SwHHCWrapper::ConvNext_impl( ) 685 { 686 //! modified version of SvxSpellWrapper::SpellNext 687 688 // Keine Richtungsaenderung, also ist der gewuenschte Bereich ( bStartChk ) 689 // vollstaendig abgearbeitet. 690 if( bStartChk ) 691 bStartDone = sal_True; 692 else 693 bEndDone = sal_True; 694 695 if( bIsOtherCntnt && bStartDone && bEndDone ) // Dokument komplett geprueft? 696 { 697 bInfoBox = sal_True; 698 return sal_False; 699 } 700 701 //ResMgr* pMgr = DIALOG_MGR(); 702 sal_Bool bGoOn = sal_False; 703 704 if ( bIsOtherCntnt ) 705 { 706 bStartChk = sal_False; 707 ConvStart_impl( pConvArgs, SVX_SPELL_BODY ); 708 bGoOn = sal_True; 709 } 710 else if ( bStartDone && bEndDone ) 711 { 712 // Bodybereich erledigt, Frage nach Sonderbereich 713 if( bIsConvSpecial && HasOtherCnt_impl() ) 714 { 715 ConvStart_impl( pConvArgs, SVX_SPELL_OTHER ); 716 bIsOtherCntnt = bGoOn = sal_True; 717 } 718 else 719 bInfoBox = sal_True; 720 } 721 else 722 { 723 // Ein BODY_Bereich erledigt, Frage nach dem anderen BODY_Bereich 724 /* 725 //pWin->LeaveWait(); 726 727 sal_uInt16 nResId = RID_SVXQB_CONTINUE; 728 QueryBox aBox( pWin, ResId( nResId, pMgr ) ); 729 if ( aBox.Execute() != RET_YES ) 730 { 731 // Verzicht auf den anderen Bereich, ggf. Frage nach Sonderbereich 732 //pWin->EnterWait(); 733 bStartDone = bEndDone = sal_True; 734 return SpellNext(); 735 } 736 else 737 { 738 */ 739 bStartChk = !bStartDone; 740 ConvStart_impl( pConvArgs, bStartChk ? SVX_SPELL_BODY_START : SVX_SPELL_BODY_END ); 741 bGoOn = sal_True; 742 /* 743 } 744 pWin->EnterWait(); 745 */ 746 } 747 return bGoOn; 748 } 749 750 751 sal_Bool SwHHCWrapper::FindConvText_impl() 752 { 753 //! modified version of SvxSpellWrapper::FindSpellError 754 755 //ShowLanguageErrors(); 756 757 sal_Bool bFound = sal_False; 758 759 pWin->EnterWait(); 760 sal_Bool bConv = sal_True; 761 762 while ( bConv ) 763 { 764 bFound = ConvContinue_impl( pConvArgs ); 765 if (bFound) 766 { 767 bConv = sal_False; 768 } 769 else 770 { 771 ConvEnd_impl( pConvArgs ); 772 bConv = ConvNext_impl(); 773 } 774 } 775 pWin->LeaveWait(); 776 return bFound; 777 } 778 779 780 sal_Bool SwHHCWrapper::HasOtherCnt_impl() 781 { 782 return bIsSelection ? sal_False : rWrtShell.HasOtherCnt(); 783 } 784 785 786 void SwHHCWrapper::ConvStart_impl( SwConversionArgs /* [out] */ *pConversionArgs, SvxSpellArea eArea ) 787 { 788 SetDrawObj( SVX_SPELL_OTHER == eArea ); 789 pView->SpellStart( eArea, bStartDone, bEndDone, /* [out] */ pConversionArgs ); 790 } 791 792 793 void SwHHCWrapper::ConvEnd_impl( SwConversionArgs *pConversionArgs ) 794 { 795 pView->SpellEnd( pConversionArgs ); 796 //ShowLanguageErrors(); 797 } 798 799 800 sal_Bool SwHHCWrapper::ConvContinue_impl( SwConversionArgs *pConversionArgs ) 801 { 802 sal_Bool bProgress = !bIsDrawObj && !bIsSelection; 803 // bLastRet = aConvText.getLength() == 0; 804 pConversionArgs->aConvText = OUString(); 805 pConversionArgs->nConvTextLang = LANGUAGE_NONE; 806 uno::Any aRet = bProgress ? 807 pView->GetWrtShell().SpellContinue( &nPageCount, &nPageStart, pConversionArgs ) : 808 pView->GetWrtShell().SpellContinue( &nPageCount, NULL, pConversionArgs ); 809 //aRet >>= aConvText; 810 return pConversionArgs->aConvText.getLength() != 0; 811 } 812 813 ////////////////////////////////////////////////////////////////////// 814 815