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