LCOV - code coverage report
Current view: top level - editeng/source/misc - hangulhanja.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 144 350 41.1 %
Date: 2015-06-13 12:38:46 Functions: 25 52 48.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11