1 /* vim:set et ts=4 sts=4:
2  *
3  * libpyzy - The Chinese PinYin and Bopomofo conversion library.
4  *
5  * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
20  * USA
21  */
22 /**
23  * \brief Converts Pinyin / Bopomofo characters to phrases.
24  *
25  * Takes PinYin / Bopomofo characters and convert it to phrases.
26  * This class provides following methods.
27  * - Context manipulation methods like insert(), removeCharBefore(), ...
28  * - Getters of input / preedit / candidates / cursor / ...
29  * - Getters / Setters of some conversion options.
30  *
31  * To use this class, you should call InputContext::init() at first and
32  * InputContext::finalize() at last.
33  */
34 #ifndef __PYZY_INPUT_CONTEXT_H_
35 #define __PYZY_INPUT_CONTEXT_H_
36 
37 #include <string>
38 #include <vector>
39 
40 namespace PyZy {
41 
42 class Variant;
43 
44 /**
45  * \brief An enum to represent a candidate type.
46  */
47 enum CandidateType {
48     /** Candidate from a system dictionary. */
49     NORMAL_PHRASE,
50     /** Candidate from a user input. */
51     USER_PHRASE,
52     /** Candidate from a special phrase. */
53     SPECIAL_PHRASE,
54 };
55 
56 /**
57  * \brief Contains a candidate data.
58  */
59 struct Candidate {
60     /** Text of a candidate */
61     std::string text;
62     /** Type of a candidate */
63     CandidateType type;
64 };
65 
66 /**
67  * \brief Pinyin / Bopomofo conversion class.
68  *
69  * This class is a factory class. You call a create() method and you get a
70  * pointer of the instance. You should delete it yourself.
71  * If some context are modified, you can get a nortification through Observer
72  * instance.
73  */
74 class InputContext {
75 public:
76     /**
77      * \brief Virtual destructor.
78      */
~InputContext(void)79     virtual ~InputContext (void) { }
80 
81     /**
82      * \brief Observer class of the InputContext.
83      *
84      * You override this class and pass it to InputContext::create, and you
85      * can get a nortification as a callback through this instance when some
86      * context are modified.
87      */
88     class Observer {
89     public:
~Observer()90         virtual ~Observer () { }
91 
92 
93         /**
94          * \brief Notifies a commit text.
95          * @param context InputContext instance which triggered this method.
96          * @param commit_text Commited text.
97          *
98          * This method is triggered by InputContext when conversion result
99          * is commited.
100          */
101         virtual void commitText (InputContext * context,
102                                  const std::string &commit_text) = 0;
103 
104         /**
105          * \brief Notifies input text is changed.
106          * @param context InputContext instance which triggered this method.
107          *
108          * This method is triggered by InputContext when input text is
109          * changed.
110          */
111         virtual void inputTextChanged (InputContext * context) = 0;
112 
113         /**
114          * \brief Notifies cursor is changed.
115          * @param context InputContext instance which triggered this method.
116          *
117          * This method is triggered by InputContext when cursor is changed.
118          */
119         virtual void cursorChanged (InputContext * context) = 0;
120 
121         /**
122          * \brief Notifies preedit text is changed.
123          * @param context InputContext instance which triggered this method.
124          *
125          * This method is triggered by InputContext when preedit text is
126          * changed.
127          */
128         virtual void preeditTextChanged (InputContext * context) = 0;
129 
130         /**
131          * \brief Notifies auxiliary text is changed.
132          * @param context InputContext instance which triggered this method.
133          *
134          * This method is triggered by InputContext when auxiliary text is
135          * changed.
136          */
137         virtual void auxiliaryTextChanged (InputContext * context) = 0;
138 
139         /**
140          * \brief Notifies candidates are changed.
141          * @param context InputContext instance which triggered this method.
142          *
143          * This method is triggered by InputContext when candidates are
144          * changed.
145          */
146         virtual void candidatesChanged (InputContext * context) = 0;
147     };
148 
149     /**
150      * \brief Input text type.
151      */
152     enum InputType {
153         /** Input text is full pinyin. */
154         FULL_PINYIN,
155         /** Input text is double pinyin. */
156         DOUBLE_PINYIN,
157         /** Input text is bopomofo. */
158         BOPOMOFO,
159     };
160 
161     /**
162      * \brief Commit type.
163      */
164     enum CommitType {
165         /** Commits a input text directly. */
166         TYPE_RAW,
167         /** Commits a phonetic symbols, mainly used for Bopomofo. */
168         TYPE_PHONETIC,
169         /** Commits a selected text, focused conversion text and rest text. */
170         TYPE_CONVERTED,
171     };
172 
173     /**
174      * \brief PropertyName
175      */
176     enum PropertyName {
177         /**
178          * Conversion option
179          * @see Const.h
180          *
181          * Default value is PINYIN_INCORRECT_PINYIN | PINYIN_CORRECT_ALL |
182          * PYZY_FUZZY_ALL
183          */
184         PROPERTY_CONVERSION_OPTION,
185         /**
186          * \brief Double pinyin schema
187          * @see Const.h
188          *
189          * Default value is DOUBLE_PINYIN_KEYBOARD_MSPY.
190          */
191         PROPERTY_DOUBLE_PINYIN_SCHEMA,
192         /**
193          * \brief Bopomofo schema
194          * @see Const.h
195          *
196          * Default value is BOPOMOFO_KEYBOARD_STANDARD.
197          */
198         PROPERTY_BOPOMOFO_SCHEMA,
199         /**
200          * \brief Uses special phrase.
201          * Default value is true.
202         */
203         PROPERTY_SPECIAL_PHRASE,
204         /**
205          * \brief Uses simplified chinese character.
206          * Default value is true.
207          */
208         PROPERTY_MODE_SIMP,
209     };
210 
211     /**
212      * \brief Appends a new character on cursor position.
213      * @param ch Input character. It should be ASCII characters.
214      * @return true if succeed.
215      *
216      * Appends a new character. This method fails if there are too many
217      * characters or invalid character is input.
218      */
219     virtual bool insert (char ch) = 0;
220 
221     /**
222      * \brief Fixes the conversion result.
223      * @param type Commit type.
224      * @see CommitType
225      *
226      * Fixes the conversion result according to CommitType and resets the
227      * context.
228      */
229     virtual void commit (CommitType type = TYPE_CONVERTED) = 0;
230 
231     /**
232      * \brief Resets the context.
233      */
234     virtual void reset (void) = 0;
235 
236     /**
237      * \brief Moves a cursor to right input character.
238      * @return true if cursor is moved.
239      */
240     virtual bool moveCursorRight (void) = 0;
241 
242     /**
243      * \brief Moves a cursor to left input character.
244      * @return true if cursor is moved.
245      */
246     virtual bool moveCursorLeft (void) = 0;
247 
248     /**
249      * \brief Moves a cursor to left chinese character.
250      * @return true if cursor is moved.
251      * @see moveCursorToEnd
252      *
253      * Currently text after a cursor is not converted and it is assumed as one
254      * chinese character. So this method is same as moveCursorToEnd.
255      */
256     virtual bool moveCursorRightByWord (void) = 0;
257 
258     /**
259      * \brief Moves a cursor to right chinese character.
260      * @return true if cursor is moved.
261      */
262     virtual bool moveCursorLeftByWord (void) = 0;
263 
264     /**
265      * \brief Moves a cursor to the beginning of the the input text.
266      * @return true if cursor is moved.
267      */
268     virtual bool moveCursorToBegin (void) = 0;
269 
270     /**
271      * \brief Removes a input character before a cursor.
272      * @return true if a character is removed.
273      */
274     virtual bool removeCharBefore (void) = 0;
275 
276     /**
277      * \brief Removes a input character after a cursor.
278      * @return true if a character is removed.
279      */
280     virtual bool removeCharAfter (void) = 0;
281 
282     /**
283      * \brief Removes a chinese character before a cursor.
284      * @return true if a character is removed.
285      */
286     virtual bool removeWordBefore (void) = 0;
287 
288     /**
289      * \brief Removes a chinese character after a cursor.
290      * @return true if a character is removed.
291      *
292      * Currently text after a cursor is not converted and it is assumed as one
293      * chinese character. So this method removes all text after a cursor.
294      */
295     virtual bool removeWordAfter (void) = 0;
296 
297     /**
298      * \brief Moves a cursor to the end of the the input text.
299      * @return true if cursor is moved.
300      */
301     virtual bool moveCursorToEnd (void) = 0;
302 
303     /**
304      * \brief Selects a candidate and converts a rest text.
305      * @param index Index of the candidate. (0-origin)
306      * @return true if it takes valid index.
307      * @see commit
308      *
309      * If there are no rest text after select, this method triggeres commit.
310      */
311     virtual bool selectCandidate (size_t index) = 0;
312 
313     /**
314      * \brief Focuses a candidate.
315      * @param index Index of the candidate. (0-origin)
316      * @return true if it takes valid index.
317      */
318     virtual bool focusCandidate (size_t index) = 0;
319 
320     /**
321      * \brief Focuses a previous candidate.
322      * @return true if focused index is changed.
323      */
324     virtual bool focusCandidatePrevious (void) = 0;
325 
326     /**
327      * \brief Focuses a next candidate.
328      * @return true if there are some candidates after the focused candidate;
329      *           false otherwise.
330      */
331     virtual bool focusCandidateNext (void) = 0;
332 
333     /**
334      * \brief Resets a user input history of the candidate.
335      * @param index Index of the candidate. (0-origin)
336      * @return true if it takes valid index.
337      */
338     virtual bool resetCandidate (size_t index) = 0;
339 
340     /**
341      * \brief Unselects a selected text.
342      * @return true if there are some selected text.
343      */
344     virtual bool unselectCandidates () = 0;
345 
346     /**
347      * \brief Checks the candidate is exist or not.
348      * @param index Index of the candidate. (0-origin)
349      * @return true if the candidate is exist.
350      * @see getPreparedCandidatesSize
351      *
352      * This method may update prepared
353      * candidates size.
354      */
355     virtual bool hasCandidate (size_t index) = 0;
356 
357     /**
358      * \brief Gets the candidate if exists.
359      * @param index Index of the candidate. (0-origin)
360      * @param output A candidate which is got.
361      * @return true if the candidate is exist.
362      * @see getPreparedCandidatesSize
363      *
364      * This method may update prepared
365      * candidates size.
366      */
367     virtual bool getCandidate (size_t index, Candidate & output) = 0;
368 
369     /**
370      * \brief Gets a already prepared candidates size.
371      * @return Prepared candidates size.
372      *
373      * To avoid a performance issue, this library prepares candidates on demand.
374      * This method returns a size of candidates which are already prepared.
375      */
376     virtual size_t getPreparedCandidatesSize () const = 0;
377 
378     /**
379      * \brief Initializes a InputContext class.
380      *
381      * This is a wrapper function of input (user_cache_dir, user_config_dir).
382      * Default values are set to user_cache_dir and user_config_dir.
383      * You should call this function at first.
384      */
385     static void init ();
386 
387     /**
388      * \brief Initializes a InputContext class.
389      * @param user_cache_dir Directory which stores a user cache data.
390      *        (input history, etc.)
391      * @param user_config_dir Directory which stores a user config data.
392      *        If you want to use original special phrase table, please create
393      *        "phrases.txt" under this directory.
394      *
395      * Specifies a directory to stores user data.
396      * You can set a same directory to user_cache_dir and user_config_dir.
397      * You should call this function at first.
398      */
399     static void init (const std::string & user_cache_dir,
400                       const std::string & user_config_dir);
401 
402     /**
403      * \brief Finalizes a InputContext class.
404      *
405      *  You should call it at last.
406      */
407     static void finalize ();
408 
409     /**
410      * \brief Creates a new InputContext instance.
411      * @param type The type of the input.
412      * @param observer Observer to get a notification from the InputContext
413      *        instance.
414      * @return instance of the InputContext.
415      *
416      * You should take responsibility for deleting the instance.
417      */
418     static InputContext * create (InputContext::InputType type,
419                                   InputContext::Observer * observer);
420 
421     /**
422      * \brief Returns a input text.
423      * @return input text.
424      */
425     virtual const std::string & inputText () const = 0;
426 
427     /**
428      * \brief Returns a selected text.
429      * @return selected text.
430      */
431     virtual const std::string & selectedText (void) const = 0;
432 
433     /**
434      * \brief Returns a conversion text.
435      * @return conversion text.
436      */
437     virtual const std::string & conversionText (void) const = 0;
438 
439     /**
440      * \brief Returns a rest text.
441      * @return rest text.
442      */
443     virtual const std::string & restText (void) const = 0;
444 
445     /**
446      * \brief Returns a auxiliary text.
447      * @return auxiliary text.
448      */
449     virtual const std::string & auxiliaryText (void) const = 0;
450 
451     /**
452      * \brief Returns a cursor position from the beginning of the input text.
453      * @return cursor position.
454      */
455     virtual unsigned int cursor () const = 0;
456 
457     /**
458      * \brief Returns a index of the focused candidate.
459      * @return index of the focused candidate. (0-origin)
460      */
461     virtual unsigned int focusedCandidate () const = 0;
462 
463     /**
464      * \brief Gets property of the context.
465      * @param name you want to get.
466      * @return value of the property.
467      */
468     virtual Variant getProperty (PropertyName name) const = 0;
469 
470     /**
471      * \brief Sets property of the context.
472      * @param name you want to get.
473      * @param variant value of the property.
474      * @return true if the value is set successfully.
475      */
476     virtual bool setProperty (PropertyName name, const Variant &variant)= 0;
477 };
478 
479 }; // namespace PyZy
480 
481 #endif  // __PYZY_INPUT_CONTEXT_H_
482