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

Generated by: LCOV version 1.10