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_editeng.hxx" 26 #include <editeng/hangulhanja.hxx> 27 #include <vcl/msgbox.hxx> 28 #include <vcl/button.hxx> 29 #include <unotools/lingucfg.hxx> 30 #include <unotools/linguprops.hxx> 31 32 #include <set> 33 #include <map> 34 #include <com/sun/star/uno/Sequence.hxx> 35 #include <com/sun/star/i18n/XBreakIterator.hpp> 36 #include <com/sun/star/i18n/ScriptType.hpp> 37 #include <com/sun/star/i18n/UnicodeScript.hpp> 38 #include <com/sun/star/i18n/XTextConversion.hpp> 39 #include <com/sun/star/i18n/XExtendedTextConversion.hpp> 40 #include <com/sun/star/i18n/TextConversionType.hpp> 41 #include <com/sun/star/i18n/TextConversionOption.hpp> 42 #include <com/sun/star/i18n/WordType.hpp> 43 #include <vcl/stdtext.hxx> 44 #include <unotools/charclass.hxx> 45 46 #include <editeng/edtdlg.hxx> 47 #include <editeng/editrids.hrc> 48 #include <editeng/unolingu.hxx> 49 50 #define HHC HangulHanjaConversion 51 52 //............................................................................. 53 namespace editeng 54 { 55 //............................................................................. 56 57 using namespace ::com::sun::star::uno; 58 using namespace ::com::sun::star::i18n; 59 using namespace ::com::sun::star::i18n::TextConversionOption; 60 using namespace ::com::sun::star::i18n::TextConversionType; 61 using namespace ::com::sun::star::lang; 62 /* 63 using HangulHanjaConversion::ReplacementAction; 64 using HangulHanjaConversion::eExchange; 65 using HangulHanjaConversion::eReplacementBracketed; 66 using HangulHanjaConversion::eOriginalBracketed; 67 using HangulHanjaConversion::eReplacementAbove; 68 using HangulHanjaConversion::eOriginalAbove; 69 using HangulHanjaConversion::eReplacementBelow; 70 using HangulHanjaConversion::eOriginalBelow; 71 72 using HangulHanjaConversion::eHangulToHanja; 73 using HangulHanjaConversion::eHanjaToHangul; 74 75 using HangulHanjaConversion::eSimpleConversion; 76 using HangulHanjaConversion::eHangulBracketed; 77 using HangulHanjaConversion::eHanjaBracketed; 78 using HangulHanjaConversion::eRubyHanjaAbove; 79 using HangulHanjaConversion::eRubyHanjaBelow; 80 using HangulHanjaConversion::eRubyHangulAbove; 81 using HangulHanjaConversion::eRubyHangulBelow; 82 83 using ::com::sun::star::i18n::TextConversionType::TO_HANJA; 84 using ::com::sun::star::i18n::TextConversionType::TO_HANGUL; 85 using ::com::sun::star::i18n::TextConversionOption::CHARACTER_BY_CHARACTER; 86 using ::com::sun::star::i18n::TextConversionOption::NONE; 87 */ 88 //========================================================================= 89 //= HangulHanjaConversion_Impl 90 //========================================================================= 91 //using HangulHanjaConversion::ConversionFormat; 92 93 class HangulHanjaConversion_Impl 94 { 95 private: 96 typedef ::std::set< ::rtl::OUString, ::std::less< ::rtl::OUString > > StringBag; 97 typedef ::std::map< ::rtl::OUString, ::rtl::OUString, ::std::less< ::rtl::OUString > > StringMap; 98 99 private: 100 StringBag m_sIgnoreList; 101 StringMap m_aChangeList; 102 static StringMap m_aRecentlyUsedList; 103 104 // general 105 AbstractHangulHanjaConversionDialog* //CHINA001 HangulHanjaConversionDialog* 106 m_pConversionDialog; // the dialog to display for user interaction 107 Window* m_pUIParent; // the parent window for any UI we raise 108 Reference< XMultiServiceFactory > 109 m_xORB; // the service factory to use 110 Reference< XTextConversion > 111 m_xConverter; // the text conversion service 112 Locale m_aSourceLocale; // the locale we're working with 113 114 // additions for Chinese simplified / traditional conversion 115 HHC::ConversionType m_eConvType; // conversion type (Hangul/Hanja, simplified/traditional Chinese,...) 116 LanguageType m_nSourceLang; // just a 'copy' of m_aSourceLocale in order in order to 117 // save the applications from always converting to this 118 // type in their implementations 119 LanguageType m_nTargetLang; // target language of new replacement text 120 const Font* m_pTargetFont; // target font of new replacement text 121 sal_Int32 m_nConvOptions; // text conversion options (as used by 'getConversions') 122 sal_Bool m_bIsInteractive; // specifies if the conversion requires user interaction 123 // (and likeley a specialised dialog) or if it is to run 124 // automatically without any user interaction. 125 // True for Hangul / Hanja conversion 126 // False for Chinese simlified / traditional conversion 127 128 HangulHanjaConversion* m_pAntiImpl; // our "anti-impl" instance 129 130 // options 131 sal_Bool m_bByCharacter; // are we in "by character" mode currently? 132 HHC::ConversionFormat m_eConversionFormat; // the current format for the conversion 133 HHC::ConversionDirection m_ePrimaryConversionDirection; // the primary conversion direction 134 HHC::ConversionDirection m_eCurrentConversionDirection; // the primary conversion direction 135 136 //options from Hangul/Hanja Options dialog (also saved to configuration) 137 bool m_bIgnorePostPositionalWord; 138 bool m_bShowRecentlyUsedFirst; 139 bool m_bAutoReplaceUnique; 140 141 // state 142 ::rtl::OUString m_sCurrentPortion; // the text which we are currently working on 143 LanguageType m_nCurrentPortionLang; // language of m_sCurrentPortion found 144 sal_Int32 m_nCurrentStartIndex; // the start index within m_sCurrentPortion of the current convertible portion 145 sal_Int32 m_nCurrentEndIndex; // the end index (excluding) within m_sCurrentPortion of the current convertible portion 146 sal_Int32 m_nReplacementBaseIndex;// index which ReplaceUnit-calls need to be relative to 147 sal_Int32 m_nCurrentConversionOption; 148 sal_Int16 m_nCurrentConversionType; 149 Sequence< ::rtl::OUString > 150 m_aCurrentSuggestions; // the suggestions for the current unit 151 // (means for the text [m_nCurrentStartIndex, m_nCurrentEndIndex) in m_sCurrentPortion) 152 sal_Bool m_bTryBothDirections; // specifies if other conversion directions should be tried when looking for convertible characters 153 154 155 public: 156 HangulHanjaConversion_Impl( 157 Window* _pUIParent, 158 const Reference< XMultiServiceFactory >& _rxORB, 159 const Locale& _rSourceLocale, 160 const Locale& _rTargetLocale, 161 const Font* _pTargetFont, 162 sal_Int32 _nConvOptions, 163 sal_Bool _bIsInteractive, 164 HangulHanjaConversion* _pAntiImpl ); 165 166 public: 167 168 static void SetUseSavedConversionDirectionState( sal_Bool bVal ); 169 170 void DoDocumentConversion( ); 171 IsByCharacter() const172 inline sal_Bool IsByCharacter( ) const { return m_bByCharacter; } 173 IsValid() const174 inline sal_Bool IsValid() const { return m_xConverter.is(); } 175 GetSourceLang() const176 inline LanguageType GetSourceLang() const { return m_nSourceLang; } GetTargetLang() const177 inline LanguageType GetTargetLang() const { return m_nTargetLang; } GetTargetFont() const178 inline const Font * GetTargetFont() const { return m_pTargetFont; } GetConvOptions() const179 inline sal_Int32 GetConvOptions() const { return m_nConvOptions; } IsInteractive() const180 inline sal_Bool IsInteractive() const { return m_bIsInteractive; } 181 182 protected: 183 void createDialog(); 184 185 /** continue with the conversion, return <TRUE/> if and only if the complete conversion is done 186 @param _bRepeatCurrentUnit 187 if <TRUE/>, an implNextConvertible will be called initially to advance to the next convertible. 188 if <FALSE/>, the method will initially work with the current convertible unit 189 */ 190 sal_Bool ContinueConversion( bool _bRepeatCurrentUnit ); 191 192 private: 193 DECL_LINK( OnOptionsChanged, void* ); 194 DECL_LINK( OnIgnore, void* ); 195 DECL_LINK( OnIgnoreAll, void* ); 196 DECL_LINK( OnChange, void* ); 197 DECL_LINK( OnChangeAll, void* ); 198 DECL_LINK( OnByCharClicked, CheckBox* ); 199 DECL_LINK( OnConversionTypeChanged, void* ); 200 DECL_LINK( OnFind, void* ); 201 202 /** proceed, after the current convertible has been handled 203 204 <p><b>Attention:</b> 205 When returning from this method, the dialog may have been deleted!</p> 206 207 @param _bRepeatCurrentUnit 208 will be passed to the <member>ContinueConversion</member> call 209 */ 210 void implProceed( bool _bRepeatCurrentUnit ); 211 212 // change the current convertible, and do _not_ proceed 213 void implChange( const ::rtl::OUString& _rChangeInto ); 214 215 /** find the next convertible piece of text, with possibly advancing to the next portion 216 217 @see HangulHanjaConversion::GetNextPortion 218 */ 219 sal_Bool implNextConvertible( bool _bRepeatUnit ); 220 221 /** find the next convertible unit within the current portion 222 @param _bRepeatUnit 223 if <TRUE/>, the search will start at the beginning of the current unit, 224 if <FALSE/>, it will start at the end of the current unit 225 */ 226 bool implNextConvertibleUnit( const sal_Int32 _nStartAt ); 227 228 /** retrieves the next portion, with setting the index members properly 229 @return 230 <TRUE/> if and only if there is a next portion 231 */ 232 bool implRetrieveNextPortion( ); 233 234 /** determine the ConversionDirection for m_sCurrentPortion 235 @return 236 <FALSE/> if and only if something went wrong 237 */ 238 bool implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection ); 239 240 /** member m_aCurrentSuggestions and m_nCurrentEndIndex are updated according to the other settings and current dictionaries 241 242 if _bAllowSearchNextConvertibleText is true _nStartAt is used as starting point to search the next 243 convertible text portion. This may result in changing of the member m_nCurrentStartIndex additionally. 244 245 @return 246 <TRUE/> if Suggestions were found 247 */ 248 bool implUpdateSuggestions( const bool _bAllowSearchNextConvertibleText=false, const sal_Int32 _nStartAt=-1 ); 249 250 /** reads the options from Hangul/Hanja Options dialog that are saved to configuration 251 */ 252 void implReadOptionsFromConfiguration(); 253 254 /** get the string currently considered to be replaced or ignored 255 */ 256 ::rtl::OUString GetCurrentUnit() const; 257 258 /** read options from configuration, update suggestion list and dialog content 259 */ 260 void implUpdateData(); 261 262 /** get the conversion direction dependent from m_eConvType and m_eCurrentConversionDirection 263 in case of switching the direction is allowed this can be triggered with parameter bSwitchDirection 264 */ 265 sal_Int16 implGetConversionType( bool bSwitchDirection=false ) const; 266 }; 267 268 //========================================================================= 269 //= HangulHanjaConversion_Impl 270 //========================================================================= 271 //------------------------------------------------------------------------- 272 // static member initialization 273 HangulHanjaConversion_Impl::StringMap HangulHanjaConversion_Impl::m_aRecentlyUsedList = HangulHanjaConversion_Impl::StringMap(); 274 275 //------------------------------------------------------------------------- HangulHanjaConversion_Impl(Window * _pUIParent,const Reference<XMultiServiceFactory> & _rxORB,const Locale & _rSourceLocale,const Locale & _rTargetLocale,const Font * _pTargetFont,sal_Int32 _nOptions,sal_Bool _bIsInteractive,HangulHanjaConversion * _pAntiImpl)276 HangulHanjaConversion_Impl::HangulHanjaConversion_Impl( Window* _pUIParent, 277 const Reference< XMultiServiceFactory >& _rxORB, 278 const Locale& _rSourceLocale, 279 const Locale& _rTargetLocale, 280 const Font* _pTargetFont, 281 sal_Int32 _nOptions, 282 sal_Bool _bIsInteractive, 283 HangulHanjaConversion* _pAntiImpl ) 284 : m_pConversionDialog( NULL ) 285 , m_pUIParent( _pUIParent ) 286 , m_xORB( _rxORB ) 287 , m_aSourceLocale( _rSourceLocale ) 288 , m_nSourceLang( SvxLocaleToLanguage( _rSourceLocale ) ) 289 , m_nTargetLang( SvxLocaleToLanguage( _rTargetLocale ) ) 290 , m_pTargetFont( _pTargetFont ) 291 , m_bIsInteractive( _bIsInteractive ) 292 , m_pAntiImpl( _pAntiImpl ) 293 , m_nCurrentPortionLang( LANGUAGE_NONE ) 294 , m_nCurrentStartIndex( 0 ) 295 , m_nCurrentEndIndex( 0 ) 296 , m_nReplacementBaseIndex( 0 ) 297 , m_nCurrentConversionOption( TextConversionOption::NONE ) 298 , m_nCurrentConversionType( -1 ) // not yet known 299 , m_bTryBothDirections( sal_True ) 300 { 301 implReadOptionsFromConfiguration(); 302 303 DBG_ASSERT( m_xORB.is(), "HangulHanjaConversion_Impl::HangulHanjaConversion_Impl: no ORB!" ); 304 305 // determine conversion type 306 if (m_nSourceLang == LANGUAGE_KOREAN && m_nTargetLang == LANGUAGE_KOREAN) 307 m_eConvType = HHC::eConvHangulHanja; 308 else if ( (m_nSourceLang == LANGUAGE_CHINESE_TRADITIONAL && m_nTargetLang == LANGUAGE_CHINESE_SIMPLIFIED) || 309 (m_nSourceLang == LANGUAGE_CHINESE_SIMPLIFIED && m_nTargetLang == LANGUAGE_CHINESE_TRADITIONAL) ) 310 m_eConvType = HHC::eConvSimplifiedTraditional; 311 else 312 { 313 DBG_ERROR( "failed to determine conversion type from languages" ); 314 } 315 316 // set remaining conversion parameters to their default values 317 m_nConvOptions = _nOptions; 318 m_bByCharacter = 0 != (_nOptions & CHARACTER_BY_CHARACTER); 319 m_eConversionFormat = HHC::eSimpleConversion; 320 m_ePrimaryConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja 321 m_eCurrentConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja 322 323 if ( m_xORB.is() ) 324 { 325 ::rtl::OUString sTextConversionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.TextConversion" ) ); 326 m_xConverter = m_xConverter.query( m_xORB->createInstance( sTextConversionService ) ); 327 if ( !m_xConverter.is() ) 328 ShowServiceNotAvailableError( m_pUIParent, sTextConversionService, sal_True ); 329 } 330 331 } 332 333 //------------------------------------------------------------------------- createDialog()334 void HangulHanjaConversion_Impl::createDialog() 335 { 336 DBG_ASSERT( m_bIsInteractive, "createDialog when the conversion should not be interactive?" ); 337 if ( m_bIsInteractive && !m_pConversionDialog ) 338 { 339 EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create(); 340 if(pFact) 341 { 342 m_pConversionDialog = pFact->CreateHangulHanjaConversionDialog(m_pUIParent, m_ePrimaryConversionDirection ); 343 DBG_ASSERT(m_pConversionDialog, "Dialogdiet fail!");//CHINA001 344 345 m_pConversionDialog->EnableRubySupport( m_pAntiImpl->HasRubySupport() ); 346 347 m_pConversionDialog->SetByCharacter( m_bByCharacter ); 348 m_pConversionDialog->SetConversionFormat( m_eConversionFormat ); 349 m_pConversionDialog->SetConversionDirectionState( m_bTryBothDirections, m_ePrimaryConversionDirection ); 350 351 // the handlers 352 m_pConversionDialog->SetOptionsChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnOptionsChanged ) ); 353 m_pConversionDialog->SetIgnoreHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnore ) ); 354 m_pConversionDialog->SetIgnoreAllHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnoreAll ) ); 355 m_pConversionDialog->SetChangeHdl( LINK( this, HangulHanjaConversion_Impl, OnChange ) ); 356 m_pConversionDialog->SetChangeAllHdl( LINK( this, HangulHanjaConversion_Impl, OnChangeAll ) ); 357 m_pConversionDialog->SetClickByCharacterHdl( LINK( this, HangulHanjaConversion_Impl, OnByCharClicked ) ); 358 m_pConversionDialog->SetConversionFormatChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnConversionTypeChanged ) ); 359 m_pConversionDialog->SetFindHdl( LINK( this, HangulHanjaConversion_Impl, OnFind ) ); 360 } 361 } 362 } 363 364 //------------------------------------------------------------------------- implGetConversionType(bool bSwitchDirection) const365 sal_Int16 HangulHanjaConversion_Impl::implGetConversionType( bool bSwitchDirection ) const 366 { 367 sal_Int16 nConversionType = -1; 368 if (m_eConvType == HHC::eConvHangulHanja) 369 nConversionType = HHC::eHangulToHanja == ( m_eCurrentConversionDirection && !bSwitchDirection ) ? TO_HANJA : TO_HANGUL; 370 else if (m_eConvType == HHC::eConvSimplifiedTraditional) 371 nConversionType = LANGUAGE_CHINESE_SIMPLIFIED == m_nTargetLang ? TO_SCHINESE : TO_TCHINESE; 372 DBG_ASSERT( nConversionType != -1, "unexpected conversion type" ); 373 return nConversionType; 374 } 375 376 //------------------------------------------------------------------------- implUpdateSuggestions(bool _bAllowSearchNextConvertibleText,const sal_Int32 _nStartAt)377 bool HangulHanjaConversion_Impl::implUpdateSuggestions( bool _bAllowSearchNextConvertibleText, const sal_Int32 _nStartAt ) 378 { 379 // parameters for the converter 380 sal_Int32 nStartSearch = m_nCurrentStartIndex; 381 if( _bAllowSearchNextConvertibleText ) 382 nStartSearch = _nStartAt; 383 384 sal_Int32 nLength = m_sCurrentPortion.getLength() - nStartSearch; 385 m_nCurrentConversionType = implGetConversionType(); 386 m_nCurrentConversionOption = IsByCharacter() ? CHARACTER_BY_CHARACTER : NONE; 387 if( m_bIgnorePostPositionalWord ) 388 m_nCurrentConversionOption = m_nCurrentConversionOption | IGNORE_POST_POSITIONAL_WORD; 389 390 // no need to check both directions for chinese conversion (saves time) 391 if (m_eConvType == HHC::eConvSimplifiedTraditional) 392 m_bTryBothDirections = sal_False; 393 394 sal_Bool bFoundAny = sal_True; 395 try 396 { 397 TextConversionResult aResult = m_xConverter->getConversions( 398 m_sCurrentPortion, 399 nStartSearch, 400 nLength, 401 m_aSourceLocale, 402 m_nCurrentConversionType, 403 m_nCurrentConversionOption 404 ); 405 sal_Bool bFoundPrimary = aResult.Boundary.startPos < aResult.Boundary.endPos; 406 bFoundAny = bFoundPrimary; 407 408 if ( m_bTryBothDirections ) 409 { // see if we find another convertible when assuming the other direction 410 TextConversionResult aSecondResult = m_xConverter->getConversions( 411 m_sCurrentPortion, 412 nStartSearch, 413 nLength, 414 m_aSourceLocale, 415 implGetConversionType( true ), // switched! 416 m_nCurrentConversionOption 417 ); 418 if ( aSecondResult.Boundary.startPos < aSecondResult.Boundary.endPos ) 419 { // we indeed found such a convertible 420 421 // in case the first attempt (with the original conversion direction) 422 // didn't find anything 423 if ( !bFoundPrimary 424 // or if the second location is _before_ the first one 425 || ( aSecondResult.Boundary.startPos < aResult.Boundary.startPos ) 426 ) 427 { 428 // then use the second finding 429 aResult = aSecondResult; 430 431 // our current conversion direction changed now 432 m_eCurrentConversionDirection = ( HHC::eHangulToHanja == m_eCurrentConversionDirection ) 433 ? HHC::eHanjaToHangul : HHC::eHangulToHanja; 434 bFoundAny = sal_True; 435 } 436 } 437 } 438 439 if( _bAllowSearchNextConvertibleText ) 440 { 441 //this might change the current position 442 m_aCurrentSuggestions = aResult.Candidates; 443 m_nCurrentStartIndex = aResult.Boundary.startPos; 444 m_nCurrentEndIndex = aResult.Boundary.endPos; 445 } 446 else 447 { 448 //the change of starting position is not allowed 449 if( m_nCurrentStartIndex == aResult.Boundary.startPos 450 && aResult.Boundary.endPos != aResult.Boundary.startPos ) 451 { 452 m_aCurrentSuggestions = aResult.Candidates; 453 m_nCurrentEndIndex = aResult.Boundary.endPos; 454 } 455 else 456 { 457 m_aCurrentSuggestions.realloc( 0 ); 458 if( m_sCurrentPortion.getLength() >= m_nCurrentStartIndex+1 ) 459 m_nCurrentEndIndex = m_nCurrentStartIndex+1; 460 } 461 } 462 463 //put recently used string to front: 464 if( m_bShowRecentlyUsedFirst && m_aCurrentSuggestions.getLength()>1 ) 465 { 466 ::rtl::OUString sCurrentUnit( GetCurrentUnit() ); 467 StringMap::const_iterator aRecentlyUsed = m_aRecentlyUsedList.find( sCurrentUnit ); 468 bool bUsedBefore = aRecentlyUsed != m_aRecentlyUsedList.end(); 469 if( bUsedBefore && m_aCurrentSuggestions[0] != aRecentlyUsed->second ) 470 { 471 sal_Int32 nCount = m_aCurrentSuggestions.getLength(); 472 Sequence< ::rtl::OUString > aTmp(nCount); 473 aTmp[0]=aRecentlyUsed->second; 474 sal_Int32 nDiff = 1; 475 for( sal_Int32 n=1; n<nCount; n++)//we had 0 already 476 { 477 if( nDiff && m_aCurrentSuggestions[n-nDiff]==aRecentlyUsed->second ) 478 nDiff=0; 479 aTmp[n]=m_aCurrentSuggestions[n-nDiff]; 480 } 481 m_aCurrentSuggestions = aTmp; 482 } 483 } 484 } 485 catch( const Exception& ) 486 { 487 DBG_ERROR( "HangulHanjaConversion_Impl::implNextConvertibleUnit: caught an exception!" ); 488 489 //!!! at least we want to move on in the text in order 490 //!!! to avoid an endless loop... 491 return false; 492 } 493 return bFoundAny; 494 } 495 496 //------------------------------------------------------------------------- implNextConvertibleUnit(const sal_Int32 _nStartAt)497 bool HangulHanjaConversion_Impl::implNextConvertibleUnit( const sal_Int32 _nStartAt ) 498 { 499 m_aCurrentSuggestions.realloc( 0 ); 500 501 // ask the TextConversion service for the next convertible piece of text 502 503 // get current values from dialog 504 if( m_eConvType == HHC::eConvHangulHanja && m_pConversionDialog ) 505 { 506 m_bTryBothDirections = m_pConversionDialog->GetUseBothDirections(); 507 HHC::ConversionDirection eDialogDirection = HHC::eHangulToHanja; 508 eDialogDirection = m_pConversionDialog->GetDirection( eDialogDirection ); 509 510 if( !m_bTryBothDirections && eDialogDirection != m_eCurrentConversionDirection ) 511 { 512 m_eCurrentConversionDirection = eDialogDirection; 513 } 514 515 // save currently used value for possible later use 516 m_pAntiImpl->m_bTryBothDirectionsSave = m_bTryBothDirections; 517 m_pAntiImpl->m_ePrimaryConversionDirectionSave = m_eCurrentConversionDirection; 518 } 519 520 bool bFoundAny = implUpdateSuggestions( true, _nStartAt ); 521 522 return bFoundAny && 523 (m_nCurrentStartIndex < m_sCurrentPortion.getLength()); 524 } 525 526 //------------------------------------------------------------------------- implRetrieveNextPortion()527 bool HangulHanjaConversion_Impl::implRetrieveNextPortion( ) 528 { 529 sal_Bool bAllowImplicitChanges = m_eConvType == HHC::eConvSimplifiedTraditional; 530 531 m_sCurrentPortion = ::rtl::OUString(); 532 m_nCurrentPortionLang = LANGUAGE_NONE; 533 m_pAntiImpl->GetNextPortion( m_sCurrentPortion, m_nCurrentPortionLang, bAllowImplicitChanges ); 534 m_nReplacementBaseIndex = 0; 535 m_nCurrentStartIndex = m_nCurrentEndIndex = 0; 536 537 bool bRet = 0 != m_sCurrentPortion.getLength(); 538 539 if (m_eConvType == HHC::eConvHangulHanja && m_bTryBothDirections) 540 implGetConversionDirectionForCurrentPortion( m_eCurrentConversionDirection ); 541 542 return bRet; 543 } 544 545 //------------------------------------------------------------------------- implNextConvertible(bool _bRepeatUnit)546 sal_Bool HangulHanjaConversion_Impl::implNextConvertible( bool _bRepeatUnit ) 547 { 548 if ( _bRepeatUnit || ( m_nCurrentEndIndex < m_sCurrentPortion.getLength() ) ) 549 { 550 if ( implNextConvertibleUnit( 551 _bRepeatUnit 552 ? ( IsByCharacter() ? m_nCurrentStartIndex : m_nCurrentStartIndex ) 553 : m_nCurrentEndIndex 554 ) ) 555 return sal_True; 556 } 557 558 // no convertible text in the current portion anymore 559 // -> advance to the next portion 560 do 561 { 562 // next portion 563 if ( implRetrieveNextPortion( ) ) 564 { // there is a next portion 565 // -> find the next convertible unit in the current portion 566 if ( implNextConvertibleUnit( 0 ) ) 567 return sal_True; 568 } 569 } 570 while ( m_sCurrentPortion.getLength() ); 571 572 // no more portions 573 return sal_False; 574 } 575 576 //------------------------------------------------------------------------- GetCurrentUnit() const577 ::rtl::OUString HangulHanjaConversion_Impl::GetCurrentUnit() const 578 { 579 DBG_ASSERT( m_nCurrentStartIndex < m_sCurrentPortion.getLength(), 580 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" ); 581 DBG_ASSERT( m_nCurrentEndIndex <= m_sCurrentPortion.getLength(), 582 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" ); 583 DBG_ASSERT( m_nCurrentStartIndex <= m_nCurrentEndIndex, 584 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid interval!" ); 585 586 ::rtl::OUString sCurrentUnit = m_sCurrentPortion.copy( m_nCurrentStartIndex, m_nCurrentEndIndex - m_nCurrentStartIndex ); 587 return sCurrentUnit; 588 } 589 590 //------------------------------------------------------------------------- ContinueConversion(bool _bRepeatCurrentUnit)591 sal_Bool HangulHanjaConversion_Impl::ContinueConversion( bool _bRepeatCurrentUnit ) 592 { 593 sal_Bool bNeedUserInteraction = sal_False; // when we leave here, do we need user interaction? 594 sal_Bool bDocumentDone = sal_False; // did we already check the whole document? 595 596 while ( !bDocumentDone && !bNeedUserInteraction && implNextConvertible( _bRepeatCurrentUnit ) ) 597 { 598 ::rtl::OUString sCurrentUnit( GetCurrentUnit() ); 599 600 // do we need to ignore it? 601 sal_Bool bAlwaysIgnoreThis = m_sIgnoreList.end() != m_sIgnoreList.find( sCurrentUnit ); 602 603 // do we need to change it? 604 StringMap::const_iterator aChangeListPos = m_aChangeList.find( sCurrentUnit ); 605 sal_Bool bAlwaysChangeThis = m_aChangeList.end() != aChangeListPos; 606 607 // do we automatically change this? 608 sal_Bool bAutoChange = m_bAutoReplaceUnique && m_aCurrentSuggestions.getLength() == 1; 609 610 if (!m_bIsInteractive) 611 { 612 // silent conversion (e.g. for simplified/traditional Chinese)... 613 if(m_aCurrentSuggestions.getLength()>0) 614 implChange( m_aCurrentSuggestions.getConstArray()[0] ); 615 } 616 else if (bAutoChange) 617 { 618 implChange( m_aCurrentSuggestions.getConstArray()[0] ); 619 } 620 else if ( bAlwaysChangeThis ) 621 { 622 implChange( aChangeListPos->second ); 623 } 624 else if ( !bAlwaysIgnoreThis ) 625 { 626 // here we need to ask the user for what to do with the text 627 // for this, allow derivees to highlight the current text unit in a possible document view 628 m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex ); 629 630 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" ); 631 if( m_pConversionDialog ) 632 m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions ); 633 634 // do not look for the next convertible: We have to wait for the user to interactivly 635 // decide what happens with the current convertible 636 bNeedUserInteraction = sal_True; 637 } 638 } 639 640 /* 641 if ( bDocumentDone ) 642 return sal_True; // we explicitly know that the complete document is done 643 else if ( bNeedUserInteraction ) 644 return sal_False; // the doc is not done, we found a convertible, but need the user to decide 645 else 646 return sal_True; // we did not find a next convertible, so the document is implicitly done 647 */ 648 649 return bDocumentDone || !bNeedUserInteraction; 650 } 651 652 //------------------------------------------------------------------------- implGetConversionDirectionForCurrentPortion(HHC::ConversionDirection & rDirection)653 bool HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection ) 654 { 655 // - For eConvHangulHanja the direction is determined by 656 // the first encountered Korean character. 657 // - For eConvSimplifiedTraditional the conversion direction 658 // is already specified by the source language. 659 660 bool bSuccess = true; 661 662 if (m_eConvType == HHC::eConvHangulHanja) 663 { 664 bSuccess = false; 665 try 666 { 667 // get the break iterator service 668 ::rtl::OUString sBreakIteratorService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) ); 669 Reference< XInterface > xBI( m_xORB->createInstance( ::rtl::OUString( sBreakIteratorService ) ) ); 670 Reference< XBreakIterator > xBreakIter( xBI, UNO_QUERY ); 671 if ( !xBreakIter.is() ) 672 { 673 ShowServiceNotAvailableError( m_pUIParent, sBreakIteratorService, sal_True ); 674 } 675 else 676 { 677 sal_Int32 nNextAsianScript = xBreakIter->beginOfScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN ); 678 if ( -1 == nNextAsianScript ) 679 nNextAsianScript = xBreakIter->nextScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN ); 680 if ( ( nNextAsianScript >= m_nCurrentStartIndex ) && ( nNextAsianScript < m_sCurrentPortion.getLength() ) ) 681 { // found asian text 682 683 // determine if it's Hangul 684 CharClass aCharClassificaton( m_xORB, m_aSourceLocale ); 685 sal_Int16 nScript = aCharClassificaton.getScript( m_sCurrentPortion, sal::static_int_cast< sal_uInt16 >(nNextAsianScript) ); 686 if ( ( UnicodeScript_kHangulJamo == nScript ) 687 || ( UnicodeScript_kHangulCompatibilityJamo == nScript ) 688 || ( UnicodeScript_kHangulSyllable == nScript ) 689 ) 690 { 691 rDirection = HHC::eHangulToHanja; 692 } 693 else 694 { 695 rDirection = HHC::eHanjaToHangul; 696 } 697 698 bSuccess = true; 699 } 700 } 701 } 702 catch( const Exception& ) 703 { 704 DBG_ERROR( "HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion: caught an exception!" ); 705 } 706 } 707 708 return bSuccess; 709 } 710 711 //------------------------------------------------------------------------- DoDocumentConversion()712 void HangulHanjaConversion_Impl::DoDocumentConversion( ) 713 { 714 // clear the change-all list - it's to be re-initialized for every single document 715 { 716 StringMap aEmpty; 717 m_aChangeList.swap( aEmpty ); 718 } 719 720 // first of all, we need to guess the direction of our conversion - it is determined by the first 721 // hangul or hanja character in the first text 722 if ( !implRetrieveNextPortion() ) 723 { 724 DBG_WARNING( "HangulHanjaConversion_Impl::DoDocumentConversion: why did you call me if you do have nothing to convert?" ); 725 // nothing to do 726 return; 727 } 728 if( m_eConvType == HHC::eConvHangulHanja ) 729 { 730 //init conversion direction from saved value 731 HHC::ConversionDirection eDirection = HHC::eHangulToHanja; 732 if(!implGetConversionDirectionForCurrentPortion( eDirection )) 733 // something went wrong, has already been asserted 734 return; 735 736 if (m_pAntiImpl->IsUseSavedConversionDirectionState()) 737 { 738 m_ePrimaryConversionDirection = m_pAntiImpl->m_ePrimaryConversionDirectionSave; 739 m_bTryBothDirections = m_pAntiImpl->m_bTryBothDirectionsSave; 740 if( m_bTryBothDirections ) 741 m_eCurrentConversionDirection = eDirection; 742 else 743 m_eCurrentConversionDirection = m_ePrimaryConversionDirection; 744 } 745 else 746 { 747 m_ePrimaryConversionDirection = eDirection; 748 m_eCurrentConversionDirection = eDirection; 749 } 750 } 751 752 if (m_bIsInteractive && m_eConvType == HHC::eConvHangulHanja) 753 { 754 //always open dialog if at least having a hangul or hanja text portion 755 createDialog(); 756 if(m_pAntiImpl->IsUseSavedConversionDirectionState()) 757 ContinueConversion( sal_False ); 758 else 759 implUpdateData(); 760 m_pConversionDialog->Execute(); 761 DELETEZ( m_pConversionDialog ); 762 } 763 else 764 { 765 #ifdef DBG_UTIL 766 sal_Bool bCompletelyDone = 767 #endif 768 ContinueConversion( sal_False ); 769 DBG_ASSERT( bCompletelyDone, "HangulHanjaConversion_Impl::DoDocumentConversion: ContinueConversion should have returned true here!" ); 770 } 771 } 772 773 //------------------------------------------------------------------------- implProceed(bool _bRepeatCurrentUnit)774 void HangulHanjaConversion_Impl::implProceed( bool _bRepeatCurrentUnit ) 775 { 776 if ( ContinueConversion( _bRepeatCurrentUnit ) ) 777 { // we're done with the whole document 778 DBG_ASSERT( !m_bIsInteractive || m_pConversionDialog, "HangulHanjaConversion_Impl::implProceed: we should not reach this here without dialog!" ); 779 if ( m_pConversionDialog ) 780 m_pConversionDialog->EndDialog( RET_OK ); 781 } 782 } 783 784 //------------------------------------------------------------------------- implChange(const::rtl::OUString & _rChangeInto)785 void HangulHanjaConversion_Impl::implChange( const ::rtl::OUString& _rChangeInto ) 786 { 787 if( !_rChangeInto.getLength() ) 788 return; 789 790 // translate the conversion format into a replacement action 791 // this translation depends on whether we have a Hangul original, or a Hanja original 792 793 HHC::ReplacementAction eAction( HHC::eExchange ); 794 795 if (m_eConvType == HHC::eConvHangulHanja) 796 { 797 // is the original we're about to change in Hangul? 798 sal_Bool bOriginalIsHangul = HHC::eHangulToHanja == m_eCurrentConversionDirection; 799 800 switch ( m_eConversionFormat ) 801 { 802 case HHC::eSimpleConversion: eAction = HHC::eExchange; break; 803 case HHC::eHangulBracketed: eAction = bOriginalIsHangul ? HHC::eOriginalBracketed : HHC::eReplacementBracketed; break; 804 case HHC::eHanjaBracketed: eAction = bOriginalIsHangul ? HHC::eReplacementBracketed : HHC::eOriginalBracketed; break; 805 case HHC::eRubyHanjaAbove: eAction = bOriginalIsHangul ? HHC::eReplacementAbove : HHC::eOriginalAbove; break; 806 case HHC::eRubyHanjaBelow: eAction = bOriginalIsHangul ? HHC::eReplacementBelow : HHC::eOriginalBelow; break; 807 case HHC::eRubyHangulAbove: eAction = bOriginalIsHangul ? HHC::eOriginalAbove : HHC::eReplacementAbove; break; 808 case HHC::eRubyHangulBelow: eAction = bOriginalIsHangul ? HHC::eOriginalBelow : HHC::eReplacementBelow; break; 809 default: 810 DBG_ERROR( "HangulHanjaConversion_Impl::implChange: invalid/unexpected conversion format!" ); 811 } 812 } 813 814 // the proper indices (the wrapper implementation needs indices relative to the 815 // previous replacement) 816 DBG_ASSERT( ( m_nReplacementBaseIndex <= m_nCurrentStartIndex ) && ( m_nReplacementBaseIndex <= m_nCurrentEndIndex ), 817 "HangulHanjaConversion_Impl::implChange: invalid replacement base!" ); 818 819 sal_Int32 nStartIndex = m_nCurrentStartIndex - m_nReplacementBaseIndex; 820 sal_Int32 nEndIndex = m_nCurrentEndIndex - m_nReplacementBaseIndex; 821 822 //remind this decision 823 m_aRecentlyUsedList[ GetCurrentUnit() ] = _rChangeInto; 824 825 LanguageType *pNewUnitLang = 0; 826 LanguageType nNewUnitLang = LANGUAGE_NONE; 827 if (m_eConvType == HHC::eConvSimplifiedTraditional) 828 { 829 // check if language needs to be changed 830 if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL && 831 !m_pAntiImpl->IsTraditional( m_nCurrentPortionLang )) 832 nNewUnitLang = LANGUAGE_CHINESE_TRADITIONAL; 833 else if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED && 834 !m_pAntiImpl->IsSimplified( m_nCurrentPortionLang )) 835 nNewUnitLang = LANGUAGE_CHINESE_SIMPLIFIED; 836 if (nNewUnitLang != LANGUAGE_NONE) 837 pNewUnitLang = &nNewUnitLang; 838 } 839 840 // according to FT we should not (yet) bother about Hangul/Hanja conversion here 841 // 842 // aOffsets is needed in ReplaceUnit below in order to to find out 843 // exactly which characters are really changed in order to keep as much 844 // from attributation for the text as possible. 845 Sequence< sal_Int32 > aOffsets; 846 Reference< XExtendedTextConversion > xExtConverter( m_xConverter, UNO_QUERY ); 847 if (m_eConvType == HHC::eConvSimplifiedTraditional && xExtConverter.is()) 848 { 849 try 850 { 851 ::rtl::OUString aConvText = xExtConverter->getConversionWithOffset( 852 m_sCurrentPortion, 853 m_nCurrentStartIndex, 854 m_nCurrentEndIndex - m_nCurrentStartIndex, 855 m_aSourceLocale, 856 m_nCurrentConversionType, 857 m_nCurrentConversionOption, 858 aOffsets 859 ); 860 } 861 catch( const Exception& ) 862 { 863 DBG_ERROR( "HangulHanjaConversion_Impl::implChange: caught unexpected exception!" ); 864 aOffsets.realloc(0); 865 } 866 } 867 868 // do the replacement 869 m_pAntiImpl->ReplaceUnit( nStartIndex, nEndIndex, m_sCurrentPortion, 870 _rChangeInto, aOffsets, eAction, pNewUnitLang ); 871 872 873 // adjust the replacement base 874 m_nReplacementBaseIndex = m_nCurrentEndIndex; 875 } 876 877 //------------------------------------------------------------------------- implReadOptionsFromConfiguration()878 void HangulHanjaConversion_Impl::implReadOptionsFromConfiguration() 879 { 880 SvtLinguConfig aLngCfg; 881 aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD ) >>= m_bIgnorePostPositionalWord; 882 aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST ) >>= m_bShowRecentlyUsedFirst; 883 aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES ) >>= m_bAutoReplaceUnique; 884 } 885 886 //------------------------------------------------------------------------- implUpdateData()887 void HangulHanjaConversion_Impl::implUpdateData() 888 { 889 implReadOptionsFromConfiguration(); 890 implUpdateSuggestions(); 891 892 if(m_pConversionDialog) 893 { 894 ::rtl::OUString sCurrentUnit( GetCurrentUnit() ); 895 896 m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions ); 897 m_pConversionDialog->FocusSuggestion(); 898 } 899 900 m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex ); 901 } 902 903 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnOptionsChanged,void *,EMPTYARG)904 IMPL_LINK( HangulHanjaConversion_Impl, OnOptionsChanged, void*, EMPTYARG ) 905 { 906 //options and dictionaries might have been changed 907 //-> update our internal settings and the dialog 908 implUpdateData(); 909 910 return 0L; 911 } 912 913 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnIgnore,void *,EMPTYARG)914 IMPL_LINK( HangulHanjaConversion_Impl, OnIgnore, void*, EMPTYARG ) 915 { 916 // simply ignore, and proceed 917 implProceed( sal_False ); 918 return 0L; 919 } 920 921 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnIgnoreAll,void *,EMPTYARG)922 IMPL_LINK( HangulHanjaConversion_Impl, OnIgnoreAll, void*, EMPTYARG ) 923 { 924 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnIgnoreAll: no dialog! How this?" ); 925 926 if ( m_pConversionDialog ) 927 { 928 String sCurrentUnit = m_pConversionDialog->GetCurrentString(); 929 DBG_ASSERT( m_sIgnoreList.end() == m_sIgnoreList.find( sCurrentUnit ), 930 "HangulHanjaConversion_Impl, OnIgnoreAll: shouldn't this have been ignored before" ); 931 932 // put into the "ignore all" list 933 m_sIgnoreList.insert( sCurrentUnit ); 934 935 // and proceed 936 implProceed( sal_False ); 937 } 938 939 return 0L; 940 } 941 942 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnChange,void *,EMPTYARG)943 IMPL_LINK( HangulHanjaConversion_Impl, OnChange, void*, EMPTYARG ) 944 { 945 // change 946 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" ); 947 if( m_pConversionDialog ) 948 implChange( m_pConversionDialog->GetCurrentSuggestion( ) ); 949 // and proceed 950 implProceed( sal_False ); 951 952 return 0L; 953 } 954 955 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnChangeAll,void *,EMPTYARG)956 IMPL_LINK( HangulHanjaConversion_Impl, OnChangeAll, void*, EMPTYARG ) 957 { 958 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnChangeAll: no dialog! How this?" ); 959 if ( m_pConversionDialog ) 960 { 961 ::rtl::OUString sCurrentUnit( m_pConversionDialog->GetCurrentString() ); 962 ::rtl::OUString sChangeInto( m_pConversionDialog->GetCurrentSuggestion( ) ); 963 964 if( sChangeInto.getLength() ) 965 { 966 // change the current occurrence 967 implChange( sChangeInto ); 968 969 // put into the "change all" list 970 m_aChangeList.insert( StringMap::value_type( sCurrentUnit, sChangeInto ) ); 971 } 972 973 // and proceed 974 implProceed( sal_False ); 975 } 976 977 return 0L; 978 } 979 980 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnByCharClicked,CheckBox *,_pBox)981 IMPL_LINK( HangulHanjaConversion_Impl, OnByCharClicked, CheckBox*, _pBox ) 982 { 983 m_bByCharacter = _pBox->IsChecked(); 984 985 // continue conversion, without advancing to the next unit, but instead continuing with the current unit 986 implProceed( sal_True ); 987 return 0L; 988 } 989 990 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnConversionTypeChanged,void *,EMPTYARG)991 IMPL_LINK( HangulHanjaConversion_Impl, OnConversionTypeChanged, void*, EMPTYARG ) 992 { 993 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" ); 994 if( m_pConversionDialog ) 995 m_eConversionFormat = m_pConversionDialog->GetConversionFormat( ); 996 return 0L; 997 } 998 999 //------------------------------------------------------------------------- IMPL_LINK(HangulHanjaConversion_Impl,OnFind,void *,EMPTYARG)1000 IMPL_LINK( HangulHanjaConversion_Impl, OnFind, void*, EMPTYARG ) 1001 { 1002 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnFind: where did this come from?" ); 1003 if ( m_pConversionDialog ) 1004 { 1005 try 1006 { 1007 ::rtl::OUString sNewOriginal( m_pConversionDialog->GetCurrentSuggestion( ) ); 1008 Sequence< ::rtl::OUString > aSuggestions; 1009 1010 DBG_ASSERT( m_xConverter.is(), "HangulHanjaConversion_Impl::OnFind: no converter!" ); 1011 TextConversionResult aToHanja = m_xConverter->getConversions( 1012 sNewOriginal, 1013 0, sNewOriginal.getLength(), 1014 m_aSourceLocale, 1015 TextConversionType::TO_HANJA, 1016 TextConversionOption::NONE 1017 ); 1018 TextConversionResult aToHangul = m_xConverter->getConversions( 1019 sNewOriginal, 1020 0, sNewOriginal.getLength(), 1021 m_aSourceLocale, 1022 TextConversionType::TO_HANGUL, 1023 TextConversionOption::NONE 1024 ); 1025 1026 bool bHaveToHanja = ( aToHanja.Boundary.startPos < aToHanja.Boundary.endPos ); 1027 bool bHaveToHangul = ( aToHangul.Boundary.startPos < aToHangul.Boundary.endPos ); 1028 1029 TextConversionResult* pResult = NULL; 1030 if ( bHaveToHanja && bHaveToHangul ) 1031 { // it found convertibles in both directions -> use the first 1032 if ( aToHangul.Boundary.startPos < aToHanja.Boundary.startPos ) 1033 pResult = &aToHangul; 1034 else 1035 pResult = &aToHanja; 1036 } 1037 else if ( bHaveToHanja ) 1038 { // only found toHanja 1039 pResult = &aToHanja; 1040 } 1041 else 1042 { // only found toHangul 1043 pResult = &aToHangul; 1044 } 1045 if ( pResult ) 1046 aSuggestions = pResult->Candidates; 1047 1048 m_pConversionDialog->SetCurrentString( sNewOriginal, aSuggestions, false ); 1049 m_pConversionDialog->FocusSuggestion(); 1050 } 1051 catch( const Exception& ) 1052 { 1053 DBG_ERROR( "HangulHanjaConversion_Impl::OnFind: caught an exception!" ); 1054 } 1055 } 1056 return 0L; 1057 } 1058 1059 //========================================================================= 1060 //= HangulHanjaConversion 1061 //========================================================================= 1062 //------------------------------------------------------------------------- 1063 1064 // static member initialization 1065 sal_Bool HangulHanjaConversion::m_bUseSavedValues = sal_False; 1066 sal_Bool HangulHanjaConversion::m_bTryBothDirectionsSave = sal_False; 1067 HHC::ConversionDirection HangulHanjaConversion::m_ePrimaryConversionDirectionSave = HHC::eHangulToHanja; 1068 1069 //------------------------------------------------------------------------- HangulHanjaConversion(Window * _pUIParent,const Reference<XMultiServiceFactory> & _rxORB,const Locale & _rSourceLocale,const Locale & _rTargetLocale,const Font * _pTargetFont,sal_Int32 _nOptions,sal_Bool _bIsInteractive)1070 HangulHanjaConversion::HangulHanjaConversion( Window* _pUIParent, 1071 const Reference< XMultiServiceFactory >& _rxORB, 1072 const Locale& _rSourceLocale, const Locale& _rTargetLocale, 1073 const Font* _pTargetFont, 1074 sal_Int32 _nOptions, sal_Bool _bIsInteractive) 1075 :m_pImpl( new HangulHanjaConversion_Impl( _pUIParent, _rxORB, _rSourceLocale, _rTargetLocale, _pTargetFont, _nOptions, _bIsInteractive, this ) ) 1076 { 1077 } 1078 1079 //------------------------------------------------------------------------- ~HangulHanjaConversion()1080 HangulHanjaConversion::~HangulHanjaConversion( ) 1081 { 1082 } 1083 1084 //------------------------------------------------------------------------- SetUseSavedConversionDirectionState(sal_Bool bVal)1085 void HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_Bool bVal ) 1086 { 1087 m_bUseSavedValues = bVal; 1088 } 1089 1090 //------------------------------------------------------------------------- IsUseSavedConversionDirectionState()1091 sal_Bool HangulHanjaConversion::IsUseSavedConversionDirectionState() 1092 { 1093 return m_bUseSavedValues; 1094 } 1095 1096 //------------------------------------------------------------------------- GetSourceLanguage() const1097 LanguageType HangulHanjaConversion::GetSourceLanguage( ) const 1098 { 1099 return m_pImpl->GetSourceLang(); 1100 } 1101 1102 //------------------------------------------------------------------------- GetTargetLanguage() const1103 LanguageType HangulHanjaConversion::GetTargetLanguage( ) const 1104 { 1105 return m_pImpl->GetTargetLang(); 1106 } 1107 1108 //------------------------------------------------------------------------- GetTargetFont() const1109 const Font * HangulHanjaConversion::GetTargetFont( ) const 1110 { 1111 return m_pImpl->GetTargetFont(); 1112 } 1113 1114 //------------------------------------------------------------------------- GetConversionOptions() const1115 sal_Int32 HangulHanjaConversion::GetConversionOptions( ) const 1116 { 1117 return m_pImpl->GetConvOptions(); 1118 } 1119 1120 //------------------------------------------------------------------------- IsInteractive() const1121 sal_Bool HangulHanjaConversion::IsInteractive( ) const 1122 { 1123 return m_pImpl->IsInteractive(); 1124 } 1125 1126 //------------------------------------------------------------------------- HandleNewUnit(const sal_Int32,const sal_Int32)1127 void HangulHanjaConversion::HandleNewUnit( const sal_Int32, const sal_Int32 ) 1128 { 1129 // nothing to do, only derived classes need this. 1130 } 1131 1132 //------------------------------------------------------------------------- GetNextPortion(::rtl::OUString &,LanguageType &,sal_Bool)1133 void HangulHanjaConversion::GetNextPortion( ::rtl::OUString&, LanguageType&, sal_Bool ) 1134 { 1135 DBG_ERROR( "HangulHanjaConversion::GetNextPortion: to be overridden!" ); 1136 } 1137 1138 //------------------------------------------------------------------------- ReplaceUnit(const sal_Int32,const sal_Int32,const::rtl::OUString &,const::rtl::OUString &,const::com::sun::star::uno::Sequence<sal_Int32> &,ReplacementAction,LanguageType *)1139 void HangulHanjaConversion::ReplaceUnit( 1140 const sal_Int32, const sal_Int32, 1141 const ::rtl::OUString&, 1142 const ::rtl::OUString&, 1143 const ::com::sun::star::uno::Sequence< sal_Int32 > &, 1144 ReplacementAction, 1145 LanguageType * ) 1146 { 1147 DBG_ERROR( "HangulHanjaConversion::ReplaceUnit: to be overridden!" ); 1148 } 1149 1150 //------------------------------------------------------------------------- HasRubySupport() const1151 sal_Bool HangulHanjaConversion::HasRubySupport() const 1152 { 1153 DBG_ERROR( "HangulHanjaConversion::HasRubySupport: to be overridden!" ); 1154 return sal_False; 1155 } 1156 1157 //------------------------------------------------------------------------- ConvertDocument()1158 void HangulHanjaConversion::ConvertDocument() 1159 { 1160 if ( m_pImpl->IsValid() ) 1161 m_pImpl->DoDocumentConversion( ); 1162 } 1163 1164 //............................................................................. 1165 } // namespace svx 1166 //............................................................................. 1167 1168