LCOV - code coverage report
Current view: top level - editeng/source/misc - hangulhanja.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 364 0.5 %
Date: 2012-08-25 Functions: 2 56 3.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 514 0.4 %

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

Generated by: LCOV version 1.10