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