1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef SVX_HANGUL_HANJA_CONVERSION_HXX
28 #define SVX_HANGUL_HANJA_CONVERSION_HXX
29 
30 #include <vcl/window.hxx>
31 #include <memory>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <com/sun/star/lang/Locale.hpp>
34 #include <com/sun/star/uno/Sequence.hxx>
35 #include "editeng/editengdllapi.h"
36 
37 //.............................................................................
38 namespace editeng
39 {
40 //.............................................................................
41 
42 	class HangulHanjaConversion_Impl;
43 
44 	//=========================================================================
45 	//= HangulHanjaConversion
46 	//=========================================================================
47 	/** encapsulates Hangul-Hanja conversion functionality
48 
49 		<p>terminology:
50 			<ul><li>A <b>text <em>portion</em></b> is some (potentially large) piece of text
51 				which is to be analyzed for convertible sub-strings.</li>
52 				<li>A <b>text <em>unit</em></b> is a sub string in a text portion, which is
53 				to be converted as a whole.</li>
54 			</ul>
55 			For instance, you could have two independent selections within your document, which are then
56 			two text portions. A text unit would be single Hangul/Hanja words within a portion, or even
57 			single Hangul syllabills when "replace by character" is enabled.
58 		</p>
59 	*/
60 	class EDITENG_DLLPUBLIC HangulHanjaConversion
61 	{
62 		friend class HangulHanjaConversion_Impl;
63 
64 	public:
65 		enum ReplacementAction
66 		{
67 			eExchange,				// simply exchange one text with another
68 			eReplacementBracketed,	// keep the original, and put the replacement in brackets after it
69 			eOriginalBracketed,		// replace the original text, but put it in brackeds after the replacement
70 			eReplacementAbove,		// keep the original, and put the replacement text as ruby text above it
71 			eOriginalAbove,			// replace the original text, but put it as ruby text above it
72 			eReplacementBelow,		// keep the original, and put the replacement text as ruby text below it
73 			eOriginalBelow			// replace the original text, but put it as ruby text below it
74 		};
75 
76         enum ConversionType             // does not specify direction...
77         {
78             eConvHangulHanja,           // Korean Hangul/Hanja conversion
79             eConvSimplifiedTraditional  // Chinese simplified / Chinese traditional conversion
80         };
81 
82         // Note: conversion direction for eConvSimplifiedTraditional is
83         // specified by source language.
84         // This one is for Hangul/Hanja where source and target language
85         // are the same.
86         enum ConversionDirection
87 		{
88 			eHangulToHanja,
89 			eHanjaToHangul
90 		};
91 
92 		enum ConversionFormat
93 		{
94             eSimpleConversion,          // used for simplified / traditional Chinese as well
95 			eHangulBracketed,
96 			eHanjaBracketed,
97 			eRubyHanjaAbove,
98 			eRubyHanjaBelow,
99 			eRubyHangulAbove,
100 			eRubyHangulBelow
101 		};
102 
103 	private:
104 		::std::auto_ptr< HangulHanjaConversion_Impl >	m_pImpl;
105 
106 		// used to set initial values of m_pImpl object from saved ones
107 		static sal_Bool				m_bUseSavedValues;	// defines if the followng two values should be used for initialization
108 		static sal_Bool				m_bTryBothDirectionsSave;
109         static ConversionDirection	m_ePrimaryConversionDirectionSave;
110 
111 		// Forbidden and not implemented.
112 		HangulHanjaConversion (const HangulHanjaConversion &);
113 		HangulHanjaConversion & operator= (const HangulHanjaConversion &);
114 
115     public:
116         HangulHanjaConversion(
117             Window* _pUIParent,
118             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
119             const ::com::sun::star::lang::Locale& _rSourceLocale,
120             const ::com::sun::star::lang::Locale& _rTargetLocale,
121             const Font* _pTargetFont,
122             sal_Int32 nOptions,
123             sal_Bool _bIsInteractive
124         );
125 
126         virtual ~HangulHanjaConversion( );
127 
128         // converts the whole document
129         void    ConvertDocument();
130 
131         LanguageType    GetSourceLanguage() const;
132         LanguageType    GetTargetLanguage() const;
133         const Font *    GetTargetFont() const;
134         sal_Int32       GetConversionOptions() const;
135         sal_Bool        IsInteractive() const;
136 
137         // chinese text conversion
138         static inline sal_Bool IsSimplified( LanguageType nLang );
139         static inline sal_Bool IsTraditional( LanguageType nLang );
140         static inline sal_Bool IsChinese( LanguageType nLang );
141         static inline sal_Bool IsSimilarChinese( LanguageType nLang1, LanguageType nLang2 );
142 
143 		// used to specify that the conversion direction states from the
144 		// last incarnation should be used as
145 		// initial conversion direction for the next incarnation.
146 		// (A hack used to transport a state information from
147 		// one incarnation to the next. Used in Writers text conversion...)
148 		static void		SetUseSavedConversionDirectionState( sal_Bool bVal );
149 		static sal_Bool IsUseSavedConversionDirectionState();
150 
151 	protected:
152 		/** retrieves the next text portion which is to be analyzed
153 
154 			<p>pseudo-abstract, needs to be overridden</p>
155 
156 			@param _rNextPortion
157 				upon return, this must contain the next text portion
158             @param _rLangOfPortion
159                 upon return, this must contain the language for the found text portion.
160                 (necessary for Chinese translation since there are 5 language variants
161                 too look for even if the 'source' language usually is only 'simplified'
162                 or 'traditional'.)
163 		*/
164         virtual void    GetNextPortion(
165                 ::rtl::OUString& /* [out] */ _rNextPortion,
166                 LanguageType& /* [out] */ _rLangOfPortion,
167                 sal_Bool /* [in] */ _bAllowImplicitChangesForNotConvertibleText );
168 
169 		/** announces a new "current unit"
170 
171 			<p>This will be called whenever it is necessary to interactively ask the user for
172 			a conversion. In such a case, a range within the current portion (see <member>GetNextPortion</member>)
173 			is presented to the user for chosing a substitution. Additionally, this method is called,
174 			so that derived classes can e.g. highlight this text range in a document view.</p>
175 
176 			<p>Note that the indexes are relative to the most recent replace action. See
177 			<member>ReplaceUnit</member> for details.</p>
178 
179 			@param _nUnitStart
180 				the start index of the unit
181 
182 			@param _nUnitEnd
183 				the start index (exclusively!) of the unit.
184 
185             @param _bAllowImplicitChangesForNotConvertibleText
186                 allows implicit changes other than the text itself for the
187                 text parts not being convertible.
188                 Used for chinese translation to attribute all not convertible
189                 text (e.g. western text, empty paragraphs, spaces, ...) to
190                 the target language and target font of the conversion.
191                 This is to ensure that after the conversion any new text entered
192                 anywhere in the document will have the target language (of course
193                 CJK Language only) and target font (CJK font only) set.
194 
195 			@see GetNextPortion
196 		*/
197 		virtual void	HandleNewUnit( const sal_Int32 _nUnitStart, const sal_Int32 _nUnitEnd );
198 
199 		/** replaces a text unit within a text portion with a new text
200 
201 			<p>pseudo-abstract, needs to be overridden</p>
202 
203 			<p>Note an important thing about the indicies: They are always relative to the <em>previous
204 			call</em> of ReplaceUnit. This means whe you get a call to ReplaceUnit, and replace some text
205 			in your document, than you have to remember the document position immediately <em>behind</em>
206 			the changed text. In a next call to ReplaceUnit, an index of <em>0</em> will denote exactly
207 			this position behind the previous replacement<br/>
208 			The reaons for this is that this class here does not know anything about your document structure,
209 			so after a replacement took place, it's impossible to address anything in the range from the
210 			beginning of the portion up to the replaced text.<br/>
211 			In the very first call to ReplaceUnit, an index of <em>0</em> denotes the very first position of
212 			the current portion.</p>
213 
214             <p>If the language of the text to be replaced is different from
215             the target language (as given by 'GetTargetLanguage') for example
216             when converting simplified Chinese from/to traditional Chinese
217             the language attribute of the new text has to be changed as well,
218 			**and** the font is to be set to the default (document) font for
219 			that language.</p>
220 
221 			@param _nUnitStart
222 				the start index of the range to replace
223 
224 			@param _nUnitEnd
225 				the end index (exclusively!) of the range to replace. E.g., an index
226 				pair (4,5) indicates a range of length 1.
227 
228             @param _rOrigText
229                 the original text to be replaced (as returned by GetNextPortion).
230                 Since in Chinese conversion the original text is needed as well
231                 in order to only do the minimal necassry text changes and to keep
232                 as much attributes as possible this is supplied here as well.
233 
234 			@param _rReplaceWith
235 				The replacement text
236 
237             @param _rOffsets
238                 An sequence matching the indices (characters) of _rReplaceWith
239                 to the indices of the characters in the original text they are
240                 replacing.
241                 This is necessary since some portions of the text may get
242                 converted in portions of different length than the original.
243                 The sequence will be empty if all conversions in the text are
244                 of equal length. That is if always the character at index i in
245                 _rOffsets is replacing the character at index i in the original
246                 text for all valid index values of i.
247 
248             @param _eAction
249 				replacement action to take
250 
251             @param pNewUnitLanguage
252                 if the replacement unit is required to have a new language that
253                 is specified here. If the language is to be left unchanged this
254                 is the 0 pointer.
255 		*/
256 		virtual void	ReplaceUnit(
257 							const sal_Int32 _nUnitStart, const sal_Int32 _nUnitEnd,
258                             const ::rtl::OUString& _rOrigText,
259                             const ::rtl::OUString& _rReplaceWith,
260                             const ::com::sun::star::uno::Sequence< sal_Int32 > &_rOffsets,
261                             ReplacementAction _eAction,
262                             LanguageType *pNewUnitLanguage
263 						);
264 
265         /** specifies if rubies are supported by the document implementing
266             this class.
267 
268             @return
269                 <TRUE/> if rubies are supported.
270         */
271         virtual sal_Bool    HasRubySupport() const;
272 	};
273 
274     sal_Bool HangulHanjaConversion::IsSimplified( LanguageType nLang )
275     {
276         return  nLang == LANGUAGE_CHINESE_SIMPLIFIED ||
277                 nLang == LANGUAGE_CHINESE_SINGAPORE;
278     }
279 
280     sal_Bool HangulHanjaConversion::IsTraditional( LanguageType nLang )
281     {
282         return  nLang == LANGUAGE_CHINESE_TRADITIONAL ||
283                 nLang == LANGUAGE_CHINESE_HONGKONG ||
284                 nLang == LANGUAGE_CHINESE_MACAU;
285     }
286 
287     sal_Bool HangulHanjaConversion::IsChinese( LanguageType nLang )
288     {
289         return IsTraditional( nLang ) || IsSimplified( nLang );
290     }
291 
292     sal_Bool HangulHanjaConversion::IsSimilarChinese( LanguageType nLang1, LanguageType nLang2 )
293     {
294         return (IsTraditional(nLang1) && IsTraditional(nLang2)) ||
295                (IsSimplified(nLang1)  && IsSimplified(nLang2));
296     }
297 
298 //.............................................................................
299 }	// namespace svx
300 //.............................................................................
301 
302 #endif // SVX_HANGUL_HANJA_CONVERSION_HXX
303