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: */
|