merge the formfield patch from ooo-build
[ooovba.git] / svx / source / dialog / hangulhanja.cxx
blobcb7ef22f73afc7196bbcd6225dd1a9093c2af513
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: hangulhanja.cxx,v $
10 * $Revision: 1.20.102.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/hangulhanja.hxx>
34 #include <vcl/msgbox.hxx> //add CHINA001
35 #include <vcl/button.hxx>
36 // header for class SvtLinguConfig
37 #include <svtools/lingucfg.hxx>
38 #include <svtools/linguprops.hxx>
40 #include <set>
41 #include <map>
42 #include <com/sun/star/uno/Sequence.hxx>
43 #include <com/sun/star/i18n/XBreakIterator.hpp>
44 #include <com/sun/star/i18n/ScriptType.hpp>
45 #include <com/sun/star/i18n/UnicodeScript.hpp>
46 #include <com/sun/star/i18n/XTextConversion.hpp>
47 #include <com/sun/star/i18n/XExtendedTextConversion.hpp>
48 #include <com/sun/star/i18n/TextConversionType.hpp>
49 #include <com/sun/star/i18n/TextConversionOption.hpp>
50 #include <com/sun/star/i18n/WordType.hpp>
51 #include <vcl/stdtext.hxx>
52 #include <unotools/charclass.hxx>
54 #include <svx/svxdlg.hxx> //CHINA001
55 #include <svx/dialogs.hrc> //CHINA001
56 #include <unolingu.hxx>
58 #define HHC HangulHanjaConversion
60 //.............................................................................
61 namespace svx
63 //.............................................................................
65 using namespace ::com::sun::star::uno;
66 using namespace ::com::sun::star::i18n;
67 using namespace ::com::sun::star::i18n::TextConversionOption;
68 using namespace ::com::sun::star::i18n::TextConversionType;
69 using namespace ::com::sun::star::lang;
71 using HangulHanjaConversion::ReplacementAction;
72 using HangulHanjaConversion::eExchange;
73 using HangulHanjaConversion::eReplacementBracketed;
74 using HangulHanjaConversion::eOriginalBracketed;
75 using HangulHanjaConversion::eReplacementAbove;
76 using HangulHanjaConversion::eOriginalAbove;
77 using HangulHanjaConversion::eReplacementBelow;
78 using HangulHanjaConversion::eOriginalBelow;
80 using HangulHanjaConversion::eHangulToHanja;
81 using HangulHanjaConversion::eHanjaToHangul;
83 using HangulHanjaConversion::eSimpleConversion;
84 using HangulHanjaConversion::eHangulBracketed;
85 using HangulHanjaConversion::eHanjaBracketed;
86 using HangulHanjaConversion::eRubyHanjaAbove;
87 using HangulHanjaConversion::eRubyHanjaBelow;
88 using HangulHanjaConversion::eRubyHangulAbove;
89 using HangulHanjaConversion::eRubyHangulBelow;
91 using ::com::sun::star::i18n::TextConversionType::TO_HANJA;
92 using ::com::sun::star::i18n::TextConversionType::TO_HANGUL;
93 using ::com::sun::star::i18n::TextConversionOption::CHARACTER_BY_CHARACTER;
94 using ::com::sun::star::i18n::TextConversionOption::NONE;
96 //=========================================================================
97 //= HangulHanjaConversion_Impl
98 //=========================================================================
99 //using HangulHanjaConversion::ConversionFormat;
101 class HangulHanjaConversion_Impl
103 private:
104 typedef ::std::set< ::rtl::OUString, ::std::less< ::rtl::OUString > > StringBag;
105 typedef ::std::map< ::rtl::OUString, ::rtl::OUString, ::std::less< ::rtl::OUString > > StringMap;
107 private:
108 StringBag m_sIgnoreList;
109 StringMap m_aChangeList;
110 static StringMap m_aRecentlyUsedList;
112 // general
113 AbstractHangulHanjaConversionDialog* //CHINA001 HangulHanjaConversionDialog*
114 m_pConversionDialog; // the dialog to display for user interaction
115 Window* m_pUIParent; // the parent window for any UI we raise
116 Reference< XMultiServiceFactory >
117 m_xORB; // the service factory to use
118 Reference< XTextConversion >
119 m_xConverter; // the text conversion service
120 Locale m_aSourceLocale; // the locale we're working with
122 // additions for Chinese simplified / traditional conversion
123 HHC::ConversionType m_eConvType; // conversion type (Hangul/Hanja, simplified/traditional Chinese,...)
124 LanguageType m_nSourceLang; // just a 'copy' of m_aSourceLocale in order in order to
125 // save the applications from always converting to this
126 // type in their implementations
127 LanguageType m_nTargetLang; // target language of new replacement text
128 const Font* m_pTargetFont; // target font of new replacement text
129 sal_Int32 m_nConvOptions; // text conversion options (as used by 'getConversions')
130 sal_Bool m_bIsInteractive; // specifies if the conversion requires user interaction
131 // (and likeley a specialised dialog) or if it is to run
132 // automatically without any user interaction.
133 // True for Hangul / Hanja conversion
134 // False for Chinese simlified / traditional conversion
136 HangulHanjaConversion* m_pAntiImpl; // our "anti-impl" instance
138 // options
139 sal_Bool m_bByCharacter; // are we in "by character" mode currently?
140 HHC::ConversionFormat m_eConversionFormat; // the current format for the conversion
141 HHC::ConversionDirection m_ePrimaryConversionDirection; // the primary conversion direction
142 HHC::ConversionDirection m_eCurrentConversionDirection; // the primary conversion direction
144 //options from Hangul/Hanja Options dialog (also saved to configuration)
145 bool m_bIgnorePostPositionalWord;
146 bool m_bShowRecentlyUsedFirst;
147 bool m_bAutoReplaceUnique;
149 // state
150 ::rtl::OUString m_sCurrentPortion; // the text which we are currently working on
151 LanguageType m_nCurrentPortionLang; // language of m_sCurrentPortion found
152 sal_Int32 m_nCurrentStartIndex; // the start index within m_sCurrentPortion of the current convertible portion
153 sal_Int32 m_nCurrentEndIndex; // the end index (excluding) within m_sCurrentPortion of the current convertible portion
154 sal_Int32 m_nReplacementBaseIndex;// index which ReplaceUnit-calls need to be relative to
155 sal_Int32 m_nCurrentConversionOption;
156 sal_Int16 m_nCurrentConversionType;
157 Sequence< ::rtl::OUString >
158 m_aCurrentSuggestions; // the suggestions for the current unit
159 // (means for the text [m_nCurrentStartIndex, m_nCurrentEndIndex) in m_sCurrentPortion)
160 sal_Bool m_bTryBothDirections; // specifies if other conversion directions should be tried when looking for convertible characters
163 public:
164 HangulHanjaConversion_Impl(
165 Window* _pUIParent,
166 const Reference< XMultiServiceFactory >& _rxORB,
167 const Locale& _rSourceLocale,
168 const Locale& _rTargetLocale,
169 const Font* _pTargetFont,
170 sal_Int32 _nConvOptions,
171 sal_Bool _bIsInteractive,
172 HangulHanjaConversion* _pAntiImpl );
174 public:
176 static void SetUseSavedConversionDirectionState( sal_Bool bVal );
178 void DoDocumentConversion( );
180 inline sal_Bool IsByCharacter( ) const { return m_bByCharacter; }
182 inline sal_Bool IsValid() const { return m_xConverter.is(); }
184 inline LanguageType GetSourceLang() const { return m_nSourceLang; }
185 inline LanguageType GetTargetLang() const { return m_nTargetLang; }
186 inline const Font * GetTargetFont() const { return m_pTargetFont; }
187 inline sal_Int32 GetConvOptions() const { return m_nConvOptions; }
188 inline sal_Bool IsInteractive() const { return m_bIsInteractive; }
190 protected:
191 void createDialog();
193 /** continue with the conversion, return <TRUE/> if and only if the complete conversion is done
194 @param _bRepeatCurrentUnit
195 if <TRUE/>, an implNextConvertible will be called initially to advance to the next convertible.
196 if <FALSE/>, the method will initially work with the current convertible unit
198 sal_Bool ContinueConversion( bool _bRepeatCurrentUnit );
200 private:
201 DECL_LINK( OnOptionsChanged, void* );
202 DECL_LINK( OnIgnore, void* );
203 DECL_LINK( OnIgnoreAll, void* );
204 DECL_LINK( OnChange, void* );
205 DECL_LINK( OnChangeAll, void* );
206 DECL_LINK( OnByCharClicked, CheckBox* );
207 DECL_LINK( OnConversionTypeChanged, void* );
208 DECL_LINK( OnFind, void* );
210 /** proceed, after the current convertible has been handled
212 <p><b>Attention:</b>
213 When returning from this method, the dialog may have been deleted!</p>
215 @param _bRepeatCurrentUnit
216 will be passed to the <member>ContinueConversion</member> call
218 void implProceed( bool _bRepeatCurrentUnit );
220 // change the current convertible, and do _not_ proceed
221 void implChange( const ::rtl::OUString& _rChangeInto );
223 /** find the next convertible piece of text, with possibly advancing to the next portion
225 @see HangulHanjaConversion::GetNextPortion
227 sal_Bool implNextConvertible( bool _bRepeatUnit );
229 /** find the next convertible unit within the current portion
230 @param _bRepeatUnit
231 if <TRUE/>, the search will start at the beginning of the current unit,
232 if <FALSE/>, it will start at the end of the current unit
234 bool implNextConvertibleUnit( const sal_Int32 _nStartAt );
236 /** retrieves the next portion, with setting the index members properly
237 @return
238 <TRUE/> if and only if there is a next portion
240 bool implRetrieveNextPortion( );
242 /** determine the ConversionDirection for m_sCurrentPortion
243 @return
244 <FALSE/> if and only if something went wrong
246 bool implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection );
248 /** member m_aCurrentSuggestions and m_nCurrentEndIndex are updated according to the other settings and current dictionaries
250 if _bAllowSearchNextConvertibleText is true _nStartAt is used as starting point to search the next
251 convertible text portion. This may result in changing of the member m_nCurrentStartIndex additionally.
253 @return
254 <TRUE/> if Suggestions were found
256 bool implUpdateSuggestions( const bool _bAllowSearchNextConvertibleText=false, const sal_Int32 _nStartAt=-1 );
258 /** reads the options from Hangul/Hanja Options dialog that are saved to configuration
260 void implReadOptionsFromConfiguration();
262 /** get the string currently considered to be replaced or ignored
264 ::rtl::OUString GetCurrentUnit() const;
266 /** read options from configuration, update suggestion list and dialog content
268 void implUpdateData();
270 /** get the conversion direction dependent from m_eConvType and m_eCurrentConversionDirection
271 in case of switching the direction is allowed this can be triggered with parameter bSwitchDirection
273 sal_Int16 implGetConversionType( bool bSwitchDirection=false ) const;
276 //=========================================================================
277 //= HangulHanjaConversion_Impl
278 //=========================================================================
279 //-------------------------------------------------------------------------
280 // static member initialization
281 HangulHanjaConversion_Impl::StringMap HangulHanjaConversion_Impl::m_aRecentlyUsedList = HangulHanjaConversion_Impl::StringMap();
283 //-------------------------------------------------------------------------
284 HangulHanjaConversion_Impl::HangulHanjaConversion_Impl( Window* _pUIParent,
285 const Reference< XMultiServiceFactory >& _rxORB,
286 const Locale& _rSourceLocale,
287 const Locale& _rTargetLocale,
288 const Font* _pTargetFont,
289 sal_Int32 _nOptions,
290 sal_Bool _bIsInteractive,
291 HangulHanjaConversion* _pAntiImpl )
292 : m_pConversionDialog( NULL )
293 , m_pUIParent( _pUIParent )
294 , m_xORB( _rxORB )
295 , m_aSourceLocale( _rSourceLocale )
296 , m_nSourceLang( SvxLocaleToLanguage( _rSourceLocale ) )
297 , m_nTargetLang( SvxLocaleToLanguage( _rTargetLocale ) )
298 , m_pTargetFont( _pTargetFont )
299 , m_bIsInteractive( _bIsInteractive )
300 , m_pAntiImpl( _pAntiImpl )
301 , m_nCurrentPortionLang( LANGUAGE_NONE )
302 , m_nCurrentStartIndex( 0 )
303 , m_nCurrentEndIndex( 0 )
304 , m_nReplacementBaseIndex( 0 )
305 , m_nCurrentConversionOption( TextConversionOption::NONE )
306 , m_nCurrentConversionType( -1 ) // not yet known
307 , m_bTryBothDirections( sal_True )
309 implReadOptionsFromConfiguration();
311 DBG_ASSERT( m_xORB.is(), "HangulHanjaConversion_Impl::HangulHanjaConversion_Impl: no ORB!" );
313 // determine conversion type
314 if (m_nSourceLang == LANGUAGE_KOREAN && m_nTargetLang == LANGUAGE_KOREAN)
315 m_eConvType = HHC::eConvHangulHanja;
316 else if ( (m_nSourceLang == LANGUAGE_CHINESE_TRADITIONAL && m_nTargetLang == LANGUAGE_CHINESE_SIMPLIFIED) ||
317 (m_nSourceLang == LANGUAGE_CHINESE_SIMPLIFIED && m_nTargetLang == LANGUAGE_CHINESE_TRADITIONAL) )
318 m_eConvType = HHC::eConvSimplifiedTraditional;
319 else
321 DBG_ERROR( "failed to determine conversion type from languages" );
324 // set remaining conversion parameters to their default values
325 m_nConvOptions = _nOptions;
326 m_bByCharacter = 0 != (_nOptions & CHARACTER_BY_CHARACTER);
327 m_eConversionFormat = HHC::eSimpleConversion;
328 m_ePrimaryConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja
329 m_eCurrentConversionDirection = HHC::eHangulToHanja; // used for eConvHangulHanja
331 if ( m_xORB.is() )
333 ::rtl::OUString sTextConversionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.TextConversion" ) );
334 m_xConverter = m_xConverter.query( m_xORB->createInstance( sTextConversionService ) );
335 if ( !m_xConverter.is() )
336 ShowServiceNotAvailableError( m_pUIParent, sTextConversionService, sal_True );
341 //-------------------------------------------------------------------------
342 void HangulHanjaConversion_Impl::createDialog()
344 DBG_ASSERT( m_bIsInteractive, "createDialog when the conversion should not be interactive?" );
345 if ( m_bIsInteractive && !m_pConversionDialog )
347 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
348 if(pFact)
350 m_pConversionDialog = pFact->CreateHangulHanjaConversionDialog(m_pUIParent, m_ePrimaryConversionDirection, RID_SVX_MDLG_HANGULHANJA);
351 DBG_ASSERT(m_pConversionDialog, "Dialogdiet fail!");//CHINA001
353 m_pConversionDialog->EnableRubySupport( m_pAntiImpl->HasRubySupport() );
355 m_pConversionDialog->SetByCharacter( m_bByCharacter );
356 m_pConversionDialog->SetConversionFormat( m_eConversionFormat );
357 m_pConversionDialog->SetConversionDirectionState( m_bTryBothDirections, m_ePrimaryConversionDirection );
359 // the handlers
360 m_pConversionDialog->SetOptionsChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnOptionsChanged ) );
361 m_pConversionDialog->SetIgnoreHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnore ) );
362 m_pConversionDialog->SetIgnoreAllHdl( LINK( this, HangulHanjaConversion_Impl, OnIgnoreAll ) );
363 m_pConversionDialog->SetChangeHdl( LINK( this, HangulHanjaConversion_Impl, OnChange ) );
364 m_pConversionDialog->SetChangeAllHdl( LINK( this, HangulHanjaConversion_Impl, OnChangeAll ) );
365 m_pConversionDialog->SetClickByCharacterHdl( LINK( this, HangulHanjaConversion_Impl, OnByCharClicked ) );
366 m_pConversionDialog->SetConversionFormatChangedHdl( LINK( this, HangulHanjaConversion_Impl, OnConversionTypeChanged ) );
367 m_pConversionDialog->SetFindHdl( LINK( this, HangulHanjaConversion_Impl, OnFind ) );
372 //-------------------------------------------------------------------------
373 sal_Int16 HangulHanjaConversion_Impl::implGetConversionType( bool bSwitchDirection ) const
375 sal_Int16 nConversionType = -1;
376 if (m_eConvType == HHC::eConvHangulHanja)
377 nConversionType = HHC::eHangulToHanja == ( m_eCurrentConversionDirection && !bSwitchDirection ) ? TO_HANJA : TO_HANGUL;
378 else if (m_eConvType == HHC::eConvSimplifiedTraditional)
379 nConversionType = LANGUAGE_CHINESE_SIMPLIFIED == m_nTargetLang ? TO_SCHINESE : TO_TCHINESE;
380 DBG_ASSERT( nConversionType != -1, "unexpected conversion type" );
381 return nConversionType;
384 //-------------------------------------------------------------------------
385 bool HangulHanjaConversion_Impl::implUpdateSuggestions( bool _bAllowSearchNextConvertibleText, const sal_Int32 _nStartAt )
387 // parameters for the converter
388 sal_Int32 nStartSearch = m_nCurrentStartIndex;
389 if( _bAllowSearchNextConvertibleText )
390 nStartSearch = _nStartAt;
392 sal_Int32 nLength = m_sCurrentPortion.getLength() - nStartSearch;
393 m_nCurrentConversionType = implGetConversionType();
394 m_nCurrentConversionOption = IsByCharacter() ? CHARACTER_BY_CHARACTER : NONE;
395 if( m_bIgnorePostPositionalWord )
396 m_nCurrentConversionOption = m_nCurrentConversionOption | IGNORE_POST_POSITIONAL_WORD;
398 // no need to check both directions for chinese conversion (saves time)
399 if (m_eConvType == HHC::eConvSimplifiedTraditional)
400 m_bTryBothDirections = sal_False;
402 sal_Bool bFoundAny = sal_True;
405 TextConversionResult aResult = m_xConverter->getConversions(
406 m_sCurrentPortion,
407 nStartSearch,
408 nLength,
409 m_aSourceLocale,
410 m_nCurrentConversionType,
411 m_nCurrentConversionOption
413 sal_Bool bFoundPrimary = aResult.Boundary.startPos < aResult.Boundary.endPos;
414 bFoundAny = bFoundPrimary;
416 if ( m_bTryBothDirections )
417 { // see if we find another convertible when assuming the other direction
418 TextConversionResult aSecondResult = m_xConverter->getConversions(
419 m_sCurrentPortion,
420 nStartSearch,
421 nLength,
422 m_aSourceLocale,
423 implGetConversionType( true ), // switched!
424 m_nCurrentConversionOption
426 if ( aSecondResult.Boundary.startPos < aSecondResult.Boundary.endPos )
427 { // we indeed found such a convertible
429 // in case the first attempt (with the original conversion direction)
430 // didn't find anything
431 if ( !bFoundPrimary
432 // or if the second location is _before_ the first one
433 || ( aSecondResult.Boundary.startPos < aResult.Boundary.startPos )
436 // then use the second finding
437 aResult = aSecondResult;
439 // our current conversion direction changed now
440 m_eCurrentConversionDirection = ( HHC::eHangulToHanja == m_eCurrentConversionDirection )
441 ? HHC::eHanjaToHangul : HHC::eHangulToHanja;
442 bFoundAny = sal_True;
447 if( _bAllowSearchNextConvertibleText )
449 //this might change the current position
450 m_aCurrentSuggestions = aResult.Candidates;
451 m_nCurrentStartIndex = aResult.Boundary.startPos;
452 m_nCurrentEndIndex = aResult.Boundary.endPos;
454 else
456 //the change of starting position is not allowed
457 if( m_nCurrentStartIndex == aResult.Boundary.startPos
458 && aResult.Boundary.endPos != aResult.Boundary.startPos )
460 m_aCurrentSuggestions = aResult.Candidates;
461 m_nCurrentEndIndex = aResult.Boundary.endPos;
463 else
465 m_aCurrentSuggestions.realloc( 0 );
466 if( m_sCurrentPortion.getLength() >= m_nCurrentStartIndex+1 )
467 m_nCurrentEndIndex = m_nCurrentStartIndex+1;
471 //put recently used string to front:
472 if( m_bShowRecentlyUsedFirst && m_aCurrentSuggestions.getLength()>1 )
474 ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
475 StringMap::const_iterator aRecentlyUsed = m_aRecentlyUsedList.find( sCurrentUnit );
476 bool bUsedBefore = aRecentlyUsed != m_aRecentlyUsedList.end();
477 if( bUsedBefore && m_aCurrentSuggestions[0] != aRecentlyUsed->second )
479 sal_Int32 nCount = m_aCurrentSuggestions.getLength();
480 Sequence< ::rtl::OUString > aTmp(nCount);
481 aTmp[0]=aRecentlyUsed->second;
482 sal_Int32 nDiff = 1;
483 for( sal_Int32 n=1; n<nCount; n++)//we had 0 already
485 if( nDiff && m_aCurrentSuggestions[n-nDiff]==aRecentlyUsed->second )
486 nDiff=0;
487 aTmp[n]=m_aCurrentSuggestions[n-nDiff];
489 m_aCurrentSuggestions = aTmp;
493 catch( const Exception& )
495 DBG_ERROR( "HangulHanjaConversion_Impl::implNextConvertibleUnit: caught an exception!" );
497 //!!! at least we want to move on in the text in order
498 //!!! to avoid an endless loop...
499 return false;
501 return bFoundAny;
504 //-------------------------------------------------------------------------
505 bool HangulHanjaConversion_Impl::implNextConvertibleUnit( const sal_Int32 _nStartAt )
507 m_aCurrentSuggestions.realloc( 0 );
509 // ask the TextConversion service for the next convertible piece of text
511 // get current values from dialog
512 if( m_eConvType == HHC::eConvHangulHanja && m_pConversionDialog )
514 m_bTryBothDirections = m_pConversionDialog->GetUseBothDirections();
515 HHC::ConversionDirection eDialogDirection = HHC::eHangulToHanja;
516 eDialogDirection = m_pConversionDialog->GetDirection( eDialogDirection );
518 if( !m_bTryBothDirections && eDialogDirection != m_eCurrentConversionDirection )
520 m_eCurrentConversionDirection = eDialogDirection;
523 // save curently used value for possible later use
524 m_pAntiImpl->m_bTryBothDirectionsSave = m_bTryBothDirections;
525 m_pAntiImpl->m_ePrimaryConversionDirectionSave = m_eCurrentConversionDirection;
528 bool bFoundAny = implUpdateSuggestions( true, _nStartAt );
530 return bFoundAny &&
531 (m_nCurrentStartIndex < m_sCurrentPortion.getLength());
534 //-------------------------------------------------------------------------
535 bool HangulHanjaConversion_Impl::implRetrieveNextPortion( )
537 sal_Bool bAllowImplicitChanges = m_eConvType == HHC::eConvSimplifiedTraditional;
539 m_sCurrentPortion = ::rtl::OUString();
540 m_nCurrentPortionLang = LANGUAGE_NONE;
541 m_pAntiImpl->GetNextPortion( m_sCurrentPortion, m_nCurrentPortionLang, bAllowImplicitChanges );
542 m_nReplacementBaseIndex = 0;
543 m_nCurrentStartIndex = m_nCurrentEndIndex = 0;
545 bool bRet = 0 != m_sCurrentPortion.getLength();
547 if (m_eConvType == HHC::eConvHangulHanja && m_bTryBothDirections)
548 implGetConversionDirectionForCurrentPortion( m_eCurrentConversionDirection );
550 return bRet;
553 //-------------------------------------------------------------------------
554 sal_Bool HangulHanjaConversion_Impl::implNextConvertible( bool _bRepeatUnit )
556 if ( _bRepeatUnit || ( m_nCurrentEndIndex < m_sCurrentPortion.getLength() ) )
558 if ( implNextConvertibleUnit(
559 _bRepeatUnit
560 ? ( IsByCharacter() ? m_nCurrentStartIndex : m_nCurrentStartIndex )
561 : m_nCurrentEndIndex
563 return sal_True;
566 // no convertible text in the current portion anymore
567 // -> advance to the next portion
570 // next portion
571 if ( implRetrieveNextPortion( ) )
572 { // there is a next portion
573 // -> find the next convertible unit in the current portion
574 if ( implNextConvertibleUnit( 0 ) )
575 return sal_True;
578 while ( m_sCurrentPortion.getLength() );
580 // no more portions
581 return sal_False;
584 //-------------------------------------------------------------------------
585 ::rtl::OUString HangulHanjaConversion_Impl::GetCurrentUnit() const
587 DBG_ASSERT( m_nCurrentStartIndex < m_sCurrentPortion.getLength(),
588 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" );
589 DBG_ASSERT( m_nCurrentEndIndex <= m_sCurrentPortion.getLength(),
590 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid index into current portion!" );
591 DBG_ASSERT( m_nCurrentStartIndex <= m_nCurrentEndIndex,
592 "HangulHanjaConversion_Impl::GetCurrentUnit: invalid interval!" );
594 ::rtl::OUString sCurrentUnit = m_sCurrentPortion.copy( m_nCurrentStartIndex, m_nCurrentEndIndex - m_nCurrentStartIndex );
595 return sCurrentUnit;
598 //-------------------------------------------------------------------------
599 sal_Bool HangulHanjaConversion_Impl::ContinueConversion( bool _bRepeatCurrentUnit )
601 sal_Bool bNeedUserInteraction = sal_False; // when we leave here, do we need user interaction?
602 sal_Bool bDocumentDone = sal_False; // did we already check the whole document?
604 while ( !bDocumentDone && !bNeedUserInteraction && implNextConvertible( _bRepeatCurrentUnit ) )
606 ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
608 // do we need to ignore it?
609 sal_Bool bAlwaysIgnoreThis = m_sIgnoreList.end() != m_sIgnoreList.find( sCurrentUnit );
611 // do we need to change it?
612 StringMap::const_iterator aChangeListPos = m_aChangeList.find( sCurrentUnit );
613 sal_Bool bAlwaysChangeThis = m_aChangeList.end() != aChangeListPos;
615 // do we automatically change this?
616 sal_Bool bAutoChange = m_bAutoReplaceUnique && m_aCurrentSuggestions.getLength() == 1;
618 if (!m_bIsInteractive)
620 // silent conversion (e.g. for simplified/traditional Chinese)...
621 if(m_aCurrentSuggestions.getLength()>0)
622 implChange( m_aCurrentSuggestions.getConstArray()[0] );
624 else if (bAutoChange)
626 implChange( m_aCurrentSuggestions.getConstArray()[0] );
628 else if ( bAlwaysChangeThis )
630 implChange( aChangeListPos->second );
632 else if ( !bAlwaysIgnoreThis )
634 // here we need to ask the user for what to do with the text
635 // for this, allow derivees to highlight the current text unit in a possible document view
636 m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex );
638 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
639 if( m_pConversionDialog )
640 m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions );
642 // do not look for the next convertible: We have to wait for the user to interactivly
643 // decide what happens with the current convertible
644 bNeedUserInteraction = sal_True;
649 if ( bDocumentDone )
650 return sal_True; // we explicitly know that the complete document is done
651 else if ( bNeedUserInteraction )
652 return sal_False; // the doc is not done, we found a convertible, but need the user to decide
653 else
654 return sal_True; // we did not find a next convertible, so the document is implicitly done
657 return bDocumentDone || !bNeedUserInteraction;
660 //-------------------------------------------------------------------------
661 bool HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion( HHC::ConversionDirection& rDirection )
663 // - For eConvHangulHanja the direction is determined by
664 // the first encountered Korean character.
665 // - For eConvSimplifiedTraditional the conversion direction
666 // is already specified by the source language.
668 bool bSuccess = true;
670 if (m_eConvType == HHC::eConvHangulHanja)
672 bSuccess = false;
675 // get the break iterator service
676 ::rtl::OUString sBreakIteratorService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) );
677 Reference< XInterface > xBI( m_xORB->createInstance( ::rtl::OUString( sBreakIteratorService ) ) );
678 Reference< XBreakIterator > xBreakIter( xBI, UNO_QUERY );
679 if ( !xBreakIter.is() )
681 ShowServiceNotAvailableError( m_pUIParent, sBreakIteratorService, sal_True );
683 else
685 sal_Int32 nNextAsianScript = xBreakIter->beginOfScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN );
686 if ( -1 == nNextAsianScript )
687 nNextAsianScript = xBreakIter->nextScript( m_sCurrentPortion, m_nCurrentStartIndex, com::sun::star::i18n::ScriptType::ASIAN );
688 if ( ( nNextAsianScript >= m_nCurrentStartIndex ) && ( nNextAsianScript < m_sCurrentPortion.getLength() ) )
689 { // found asian text
691 // determine if it's Hangul
692 CharClass aCharClassificaton( m_xORB, m_aSourceLocale );
693 sal_Int16 nScript = aCharClassificaton.getScript( m_sCurrentPortion, sal::static_int_cast< USHORT >(nNextAsianScript) );
694 if ( ( UnicodeScript_kHangulJamo == nScript )
695 || ( UnicodeScript_kHangulCompatibilityJamo == nScript )
696 || ( UnicodeScript_kHangulSyllable == nScript )
699 rDirection = HHC::eHangulToHanja;
701 else
703 rDirection = HHC::eHanjaToHangul;
706 bSuccess = true;
710 catch( const Exception& )
712 DBG_ERROR( "HangulHanjaConversion_Impl::implGetConversionDirectionForCurrentPortion: caught an exception!" );
716 return bSuccess;
719 //-------------------------------------------------------------------------
720 void HangulHanjaConversion_Impl::DoDocumentConversion( )
722 // clear the change-all list - it's to be re-initialized for every single document
724 StringMap aEmpty;
725 m_aChangeList.swap( aEmpty );
728 // first of all, we need to guess the direction of our conversion - it is determined by the first
729 // hangul or hanja character in the first text
730 if ( !implRetrieveNextPortion() )
732 DBG_WARNING( "HangulHanjaConversion_Impl::DoDocumentConversion: why did you call me if you do have nothing to convert?" );
733 // nothing to do
734 return;
736 if( m_eConvType == HHC::eConvHangulHanja )
738 //init conversion direction from saved value
739 HHC::ConversionDirection eDirection = HHC::eHangulToHanja;
740 if(!implGetConversionDirectionForCurrentPortion( eDirection ))
741 // something went wrong, has already been asserted
742 return;
744 if (m_pAntiImpl->IsUseSavedConversionDirectionState())
746 m_ePrimaryConversionDirection = m_pAntiImpl->m_ePrimaryConversionDirectionSave;
747 m_bTryBothDirections = m_pAntiImpl->m_bTryBothDirectionsSave;
748 if( m_bTryBothDirections )
749 m_eCurrentConversionDirection = eDirection;
750 else
751 m_eCurrentConversionDirection = m_ePrimaryConversionDirection;
753 else
755 m_ePrimaryConversionDirection = eDirection;
756 m_eCurrentConversionDirection = eDirection;
760 if (m_bIsInteractive && m_eConvType == HHC::eConvHangulHanja)
762 //always open dialog if at least having a hangul or hanja text portion
763 createDialog();
764 if(m_pAntiImpl->IsUseSavedConversionDirectionState())
765 ContinueConversion( sal_False );
766 else
767 implUpdateData();
768 m_pConversionDialog->Execute();
769 DELETEZ( m_pConversionDialog );
771 else
773 #ifdef DBG_UTIL
774 sal_Bool bCompletelyDone =
775 #endif
776 ContinueConversion( sal_False );
777 DBG_ASSERT( bCompletelyDone, "HangulHanjaConversion_Impl::DoDocumentConversion: ContinueConversion should have returned true here!" );
781 //-------------------------------------------------------------------------
782 void HangulHanjaConversion_Impl::implProceed( bool _bRepeatCurrentUnit )
784 if ( ContinueConversion( _bRepeatCurrentUnit ) )
785 { // we're done with the whole document
786 DBG_ASSERT( !m_bIsInteractive || m_pConversionDialog, "HangulHanjaConversion_Impl::implProceed: we should not reach this here without dialog!" );
787 if ( m_pConversionDialog )
788 m_pConversionDialog->EndDialog( RET_OK );
792 //-------------------------------------------------------------------------
793 void HangulHanjaConversion_Impl::implChange( const ::rtl::OUString& _rChangeInto )
795 if( !_rChangeInto.getLength() )
796 return;
798 // translate the conversion format into a replacement action
799 // this translation depends on whether we have a Hangul original, or a Hanja original
801 HHC::ReplacementAction eAction( HHC::eExchange );
803 if (m_eConvType == HHC::eConvHangulHanja)
805 // is the original we're about to change in Hangul?
806 sal_Bool bOriginalIsHangul = HHC::eHangulToHanja == m_eCurrentConversionDirection;
808 switch ( m_eConversionFormat )
810 case HHC::eSimpleConversion: eAction = HHC::eExchange; break;
811 case HHC::eHangulBracketed: eAction = bOriginalIsHangul ? HHC::eOriginalBracketed : HHC::eReplacementBracketed; break;
812 case HHC::eHanjaBracketed: eAction = bOriginalIsHangul ? HHC::eReplacementBracketed : HHC::eOriginalBracketed; break;
813 case HHC::eRubyHanjaAbove: eAction = bOriginalIsHangul ? HHC::eReplacementAbove : HHC::eOriginalAbove; break;
814 case HHC::eRubyHanjaBelow: eAction = bOriginalIsHangul ? HHC::eReplacementBelow : HHC::eOriginalBelow; break;
815 case HHC::eRubyHangulAbove: eAction = bOriginalIsHangul ? HHC::eOriginalAbove : HHC::eReplacementAbove; break;
816 case HHC::eRubyHangulBelow: eAction = bOriginalIsHangul ? HHC::eOriginalBelow : HHC::eReplacementBelow; break;
817 default:
818 DBG_ERROR( "HangulHanjaConversion_Impl::implChange: invalid/unexpected conversion format!" );
822 // the proper indicies (the wrapper implementation needs indicies relative to the
823 // previous replacement)
824 DBG_ASSERT( ( m_nReplacementBaseIndex <= m_nCurrentStartIndex ) && ( m_nReplacementBaseIndex <= m_nCurrentEndIndex ),
825 "HangulHanjaConversion_Impl::implChange: invalid replacement base!" );
827 sal_Int32 nStartIndex = m_nCurrentStartIndex - m_nReplacementBaseIndex;
828 sal_Int32 nEndIndex = m_nCurrentEndIndex - m_nReplacementBaseIndex;
830 //remind this decision
831 m_aRecentlyUsedList[ GetCurrentUnit() ] = _rChangeInto;
833 LanguageType *pNewUnitLang = 0;
834 LanguageType nNewUnitLang = LANGUAGE_NONE;
835 if (m_eConvType == HHC::eConvSimplifiedTraditional)
837 // check if language needs to be changed
838 if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_TRADITIONAL &&
839 !m_pAntiImpl->IsTraditional( m_nCurrentPortionLang ))
840 nNewUnitLang = LANGUAGE_CHINESE_TRADITIONAL;
841 else if ( m_pAntiImpl->GetTargetLanguage() == LANGUAGE_CHINESE_SIMPLIFIED &&
842 !m_pAntiImpl->IsSimplified( m_nCurrentPortionLang ))
843 nNewUnitLang = LANGUAGE_CHINESE_SIMPLIFIED;
844 if (nNewUnitLang != LANGUAGE_NONE)
845 pNewUnitLang = &nNewUnitLang;
848 // according to FT we should not (yet) bother about Hangul/Hanja conversion here
850 // aOffsets is needed in ReplaceUnit below in order to to find out
851 // exactly which characters are really changed in order to keep as much
852 // from attributation for the text as possible.
853 Sequence< sal_Int32 > aOffsets;
854 Reference< XExtendedTextConversion > xExtConverter( m_xConverter, UNO_QUERY );
855 if (m_eConvType == HHC::eConvSimplifiedTraditional && xExtConverter.is())
859 ::rtl::OUString aConvText = xExtConverter->getConversionWithOffset(
860 m_sCurrentPortion,
861 m_nCurrentStartIndex,
862 m_nCurrentEndIndex - m_nCurrentStartIndex,
863 m_aSourceLocale,
864 m_nCurrentConversionType,
865 m_nCurrentConversionOption,
866 aOffsets
869 catch( const Exception& )
871 DBG_ERROR( "HangulHanjaConversion_Impl::implChange: caught unexpected exception!" );
872 aOffsets.realloc(0);
876 // do the replacement
877 m_pAntiImpl->ReplaceUnit( nStartIndex, nEndIndex, m_sCurrentPortion,
878 _rChangeInto, aOffsets, eAction, pNewUnitLang );
881 // adjust the replacement base
882 m_nReplacementBaseIndex = m_nCurrentEndIndex;
885 //-------------------------------------------------------------------------
886 void HangulHanjaConversion_Impl::implReadOptionsFromConfiguration()
888 SvtLinguConfig aLngCfg;
889 aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD ) >>= m_bIgnorePostPositionalWord;
890 aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST ) >>= m_bShowRecentlyUsedFirst;
891 aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES ) >>= m_bAutoReplaceUnique;
894 //-------------------------------------------------------------------------
895 void HangulHanjaConversion_Impl::implUpdateData()
897 implReadOptionsFromConfiguration();
898 implUpdateSuggestions();
900 if(m_pConversionDialog)
902 ::rtl::OUString sCurrentUnit( GetCurrentUnit() );
904 m_pConversionDialog->SetCurrentString( sCurrentUnit, m_aCurrentSuggestions );
905 m_pConversionDialog->FocusSuggestion();
908 m_pAntiImpl->HandleNewUnit( m_nCurrentStartIndex - m_nReplacementBaseIndex, m_nCurrentEndIndex - m_nReplacementBaseIndex );
911 //-------------------------------------------------------------------------
912 IMPL_LINK( HangulHanjaConversion_Impl, OnOptionsChanged, void*, EMPTYARG )
914 //options and dictionaries might have been changed
915 //-> update our internal settings and the dialog
916 implUpdateData();
918 return 0L;
921 //-------------------------------------------------------------------------
922 IMPL_LINK( HangulHanjaConversion_Impl, OnIgnore, void*, EMPTYARG )
924 // simply ignore, and proceed
925 implProceed( sal_False );
926 return 0L;
929 //-------------------------------------------------------------------------
930 IMPL_LINK( HangulHanjaConversion_Impl, OnIgnoreAll, void*, EMPTYARG )
932 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnIgnoreAll: no dialog! How this?" );
934 if ( m_pConversionDialog )
936 String sCurrentUnit = m_pConversionDialog->GetCurrentString();
937 DBG_ASSERT( m_sIgnoreList.end() == m_sIgnoreList.find( sCurrentUnit ),
938 "HangulHanjaConversion_Impl, OnIgnoreAll: shouldn't this have been ignored before" );
940 // put into the "ignore all" list
941 m_sIgnoreList.insert( sCurrentUnit );
943 // and proceed
944 implProceed( sal_False );
947 return 0L;
950 //-------------------------------------------------------------------------
951 IMPL_LINK( HangulHanjaConversion_Impl, OnChange, void*, EMPTYARG )
953 // change
954 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
955 if( m_pConversionDialog )
956 implChange( m_pConversionDialog->GetCurrentSuggestion( ) );
957 // and proceed
958 implProceed( sal_False );
960 return 0L;
963 //-------------------------------------------------------------------------
964 IMPL_LINK( HangulHanjaConversion_Impl, OnChangeAll, void*, EMPTYARG )
966 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnChangeAll: no dialog! How this?" );
967 if ( m_pConversionDialog )
969 ::rtl::OUString sCurrentUnit( m_pConversionDialog->GetCurrentString() );
970 ::rtl::OUString sChangeInto( m_pConversionDialog->GetCurrentSuggestion( ) );
972 if( sChangeInto.getLength() )
974 // change the current occurence
975 implChange( sChangeInto );
977 // put into the "change all" list
978 m_aChangeList.insert( StringMap::value_type( sCurrentUnit, sChangeInto ) );
981 // and proceed
982 implProceed( sal_False );
985 return 0L;
988 //-------------------------------------------------------------------------
989 IMPL_LINK( HangulHanjaConversion_Impl, OnByCharClicked, CheckBox*, _pBox )
991 m_bByCharacter = _pBox->IsChecked();
993 // continue conversion, without advancing to the next unit, but instead continuing with the current unit
994 implProceed( sal_True );
995 return 0L;
998 //-------------------------------------------------------------------------
999 IMPL_LINK( HangulHanjaConversion_Impl, OnConversionTypeChanged, void*, EMPTYARG )
1001 DBG_ASSERT( m_pConversionDialog, "we should always have a dialog here!" );
1002 if( m_pConversionDialog )
1003 m_eConversionFormat = m_pConversionDialog->GetConversionFormat( );
1004 return 0L;
1007 //-------------------------------------------------------------------------
1008 IMPL_LINK( HangulHanjaConversion_Impl, OnFind, void*, EMPTYARG )
1010 DBG_ASSERT( m_pConversionDialog, "HangulHanjaConversion_Impl::OnFind: where did this come from?" );
1011 if ( m_pConversionDialog )
1015 ::rtl::OUString sNewOriginal( m_pConversionDialog->GetCurrentSuggestion( ) );
1016 Sequence< ::rtl::OUString > aSuggestions;
1018 DBG_ASSERT( m_xConverter.is(), "HangulHanjaConversion_Impl::OnFind: no converter!" );
1019 TextConversionResult aToHanja = m_xConverter->getConversions(
1020 sNewOriginal,
1021 0, sNewOriginal.getLength(),
1022 m_aSourceLocale,
1023 TextConversionType::TO_HANJA,
1024 TextConversionOption::NONE
1026 TextConversionResult aToHangul = m_xConverter->getConversions(
1027 sNewOriginal,
1028 0, sNewOriginal.getLength(),
1029 m_aSourceLocale,
1030 TextConversionType::TO_HANGUL,
1031 TextConversionOption::NONE
1034 bool bHaveToHanja = ( aToHanja.Boundary.startPos < aToHanja.Boundary.endPos );
1035 bool bHaveToHangul = ( aToHangul.Boundary.startPos < aToHangul.Boundary.endPos );
1037 TextConversionResult* pResult = NULL;
1038 if ( bHaveToHanja && bHaveToHangul )
1039 { // it found convertibles in both directions -> use the first
1040 if ( aToHangul.Boundary.startPos < aToHanja.Boundary.startPos )
1041 pResult = &aToHangul;
1042 else
1043 pResult = &aToHanja;
1045 else if ( bHaveToHanja )
1046 { // only found toHanja
1047 pResult = &aToHanja;
1049 else
1050 { // only found toHangul
1051 pResult = &aToHangul;
1053 if ( pResult )
1054 aSuggestions = pResult->Candidates;
1056 m_pConversionDialog->SetCurrentString( sNewOriginal, aSuggestions, false );
1057 m_pConversionDialog->FocusSuggestion();
1059 catch( const Exception& )
1061 DBG_ERROR( "HangulHanjaConversion_Impl::OnFind: caught an exception!" );
1064 return 0L;
1067 //=========================================================================
1068 //= HangulHanjaConversion
1069 //=========================================================================
1070 //-------------------------------------------------------------------------
1072 // static member initialization
1073 sal_Bool HangulHanjaConversion::m_bUseSavedValues = sal_False;
1074 sal_Bool HangulHanjaConversion::m_bTryBothDirectionsSave = sal_False;
1075 HHC::ConversionDirection HangulHanjaConversion::m_ePrimaryConversionDirectionSave = HHC::eHangulToHanja;
1077 //-------------------------------------------------------------------------
1078 HangulHanjaConversion::HangulHanjaConversion( Window* _pUIParent,
1079 const Reference< XMultiServiceFactory >& _rxORB,
1080 const Locale& _rSourceLocale, const Locale& _rTargetLocale,
1081 const Font* _pTargetFont,
1082 sal_Int32 _nOptions, sal_Bool _bIsInteractive)
1083 :m_pImpl( new HangulHanjaConversion_Impl( _pUIParent, _rxORB, _rSourceLocale, _rTargetLocale, _pTargetFont, _nOptions, _bIsInteractive, this ) )
1087 //-------------------------------------------------------------------------
1088 HangulHanjaConversion::~HangulHanjaConversion( )
1092 //-------------------------------------------------------------------------
1093 void HangulHanjaConversion::SetUseSavedConversionDirectionState( sal_Bool bVal )
1095 m_bUseSavedValues = bVal;
1098 //-------------------------------------------------------------------------
1099 sal_Bool HangulHanjaConversion::IsUseSavedConversionDirectionState()
1101 return m_bUseSavedValues;
1104 //-------------------------------------------------------------------------
1105 LanguageType HangulHanjaConversion::GetSourceLanguage( ) const
1107 return m_pImpl->GetSourceLang();
1110 //-------------------------------------------------------------------------
1111 LanguageType HangulHanjaConversion::GetTargetLanguage( ) const
1113 return m_pImpl->GetTargetLang();
1116 //-------------------------------------------------------------------------
1117 const Font * HangulHanjaConversion::GetTargetFont( ) const
1119 return m_pImpl->GetTargetFont();
1122 //-------------------------------------------------------------------------
1123 sal_Int32 HangulHanjaConversion::GetConversionOptions( ) const
1125 return m_pImpl->GetConvOptions();
1128 //-------------------------------------------------------------------------
1129 sal_Bool HangulHanjaConversion::IsInteractive( ) const
1131 return m_pImpl->IsInteractive();
1134 //-------------------------------------------------------------------------
1135 void HangulHanjaConversion::HandleNewUnit( const sal_Int32, const sal_Int32 )
1137 // nothing to do, only derived classes need this.
1140 //-------------------------------------------------------------------------
1141 void HangulHanjaConversion::GetNextPortion( ::rtl::OUString&, LanguageType&, sal_Bool )
1143 DBG_ERROR( "HangulHanjaConversion::GetNextPortion: to be overridden!" );
1146 //-------------------------------------------------------------------------
1147 void HangulHanjaConversion::ReplaceUnit(
1148 const sal_Int32, const sal_Int32,
1149 const ::rtl::OUString&,
1150 const ::rtl::OUString&,
1151 const ::com::sun::star::uno::Sequence< sal_Int32 > &,
1152 ReplacementAction,
1153 LanguageType * )
1155 DBG_ERROR( "HangulHanjaConversion::ReplaceUnit: to be overridden!" );
1158 //-------------------------------------------------------------------------
1159 sal_Bool HangulHanjaConversion::HasRubySupport() const
1161 DBG_ERROR( "HangulHanjaConversion::HasRubySupport: to be overridden!" );
1162 return sal_False;
1165 //-------------------------------------------------------------------------
1166 void HangulHanjaConversion::ConvertDocument()
1168 if ( m_pImpl->IsValid() )
1169 m_pImpl->DoDocumentConversion( );
1172 //.............................................................................
1173 } // namespace svx
1174 //.............................................................................