Update package version to 1.10.13
[platform/core/uifw/ise-default.git] / src / languages.cpp
1 /*
2  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <sclcommon.h>
19 #include <stdio.h>
20 #include <algorithm>
21 #include <assert.h>
22 #include <vconf.h>
23 #include <vconf-keys.h>
24 #include "utils.h"
25 #include "config.h"
26 #include "languages.h"
27 using namespace scl;
28 using std::string;
29 using std::vector;
30
31 static vector<LANGUAGE_INFO> _language_vector;
32 static int _current_language = -1;
33 static string _default_resource_file;
34
35 // A class function that is used for algorithm std::find_if
36 class _language_info_finder {
37 public:
38     _language_info_finder(const string &language_name): m_name(language_name) {}
39     bool operator() (const LANGUAGE_INFO &info) {
40         return info.name == m_name;
41     }
42 private:
43     string m_name;
44 };
45
46 sclboolean
47 ISELanguageManager::set_all_languages_enabled(sclboolean enabled)
48 {
49     sclboolean ret = FALSE;
50
51     vector<LANGUAGE_INFO>::iterator iter;
52     for (iter = _language_vector.begin(); iter != _language_vector.end(); ++iter) {
53             iter->enabled = enabled;
54             iter->enabled_temporarily = FALSE;
55             ret = TRUE;
56     }
57
58     return ret;
59 }
60
61 /* Each language-specific source files should put their callback information in the following vectors */
62 sclboolean
63 ISELanguageManager::add_language(LANGUAGE_INFO &language)
64 {
65     int language_id = -1;
66
67     // check whether there is an language_info has the same name with "language" in the vector
68     vector<LANGUAGE_INFO>::iterator it;
69     it = std::find_if(_language_vector.begin(), _language_vector.end(), _language_info_finder(language.name));
70     if (it != _language_vector.end()) {
71         // if the assigned one has the priority "LANGUAGE_PRIORITY_SPECIALIZED" - which means high priority,
72         // then the assigned one will replace with the original one
73         if (language.priority == LANGUAGE_PRIORITY_SPECIALIZED) {
74             *it = language;
75             language_id = it - _language_vector.begin();
76         }
77     } else {
78         _language_vector.push_back(language);
79         language_id = _language_vector.size() -1;
80     }
81
82     if (_current_language == -1) {
83         /* If there is no default language set currently, assume this to be a default language */
84         _current_language = language_id;
85     } else if (language.priority == LANGUAGE_PRIORITY_SPECIALIZED) {
86         /* If this language has the SPECIALIZED priority, assume this to be a default language */
87         _current_language = language_id;
88     }
89     if (language.resource_file.length() > 0) {
90         if (_default_resource_file.empty()) {
91             /* If we don't have default resource file, set this resource file information as default */
92             _default_resource_file = language.resource_file;
93         } else if (language.priority == LANGUAGE_PRIORITY_SPECIALIZED) {
94             /* Or if this has SPECIALIZED priority, overwrite the existing default resource file information */
95             _default_resource_file = language.resource_file;
96         }
97     }
98
99     return TRUE;
100 }
101
102 int
103 _find_language_info(const string &language_name, const vector<LANGUAGE_INFO>& vec_language_info)
104 {
105     vector<LANGUAGE_INFO>::const_iterator it;
106
107     it = std::find_if(vec_language_info.begin(), vec_language_info.end(), _language_info_finder(language_name));
108     if (it != vec_language_info.end()) {
109         return it - vec_language_info.begin();
110     }
111     return -1;
112 }
113
114 // normal routine of select language
115 sclboolean
116 ISELanguageManager::do_select_language(int language_info_index)
117 {
118     sclboolean ret = FALSE;
119
120     if (language_info_index < 0 || language_info_index >= (int)_language_vector.size()) {
121         return FALSE;
122     }
123     LANGUAGE_INFO &language_info = _language_vector.at(language_info_index);
124     // if not enabled and not temporary, return false
125     if (!language_info.enabled && !language_info.enabled_temporarily) {
126         return FALSE;
127     }
128
129     // run the callback function
130     ILanguageCallback *callback = language_info.callback;
131     if (callback) {
132         ret = callback->on_language_selected(language_info.name.c_str(), language_info.selected_input_mode.c_str());
133     }
134     if (ret == FALSE) {
135         return ret;
136     }
137
138     _current_language = language_info_index;
139     if (!language_info.enabled_temporarily) {
140         /* Save the selected language */
141         CONFIG_VALUES *config_values = get_config_values();
142         if (config_values)
143             config_values->selected_language = language_info.name;
144         write_ise_config_values();
145     }
146
147     vconf_set_str(VCONFKEY_ISF_INPUT_LANGUAGE, language_info.locale_string.c_str());
148
149     return ret;
150 }
151
152 // normal routine of select language
153 sclboolean
154 ISELanguageManager::do_unselect_language(int language_info_index)
155 {
156     sclboolean ret = FALSE;
157     if (language_info_index < 0 || language_info_index >= (int)_language_vector.size()) {
158         return FALSE;
159     }
160
161     LANGUAGE_INFO &language_info = _language_vector.at(language_info_index);
162     if (language_info.callback) {
163         ret = language_info.callback->on_language_unselected(language_info.name.c_str(), language_info.selected_input_mode.c_str());
164     }
165
166     return ret;
167 }
168
169 // interface function, call do_select_language actually
170 sclboolean
171 ISELanguageManager::select_language(const sclchar *language, sclboolean temporarily)
172 {
173     sclboolean ret = FALSE;
174
175     if (language == NULL) return FALSE;
176     int pos = _find_language_info(language, _language_vector);
177
178     // the assigned language could not be found in the language info vector
179     if (pos < 0 || pos >= (int)_language_vector.size()) {
180         return FALSE;
181     }
182
183     LANGUAGE_INFO &info = _language_vector.at(pos);
184     info.enabled_temporarily = temporarily;
185
186     ret = do_select_language(pos);
187
188     if (ret == FALSE) {
189         ret = select_next_language();
190     }
191     return ret;
192 }
193
194 sclboolean
195 ISELanguageManager::select_current_language()
196 {
197     sclboolean ret = FALSE;
198     ret = do_select_language(_current_language);
199
200     return ret;
201 }
202
203 sclboolean
204 ISELanguageManager::select_next_language()
205 {
206     sclboolean ret = FALSE;
207
208     // do some work before change to next language
209     // eg: commit preedit string...
210     ret = do_unselect_language(_current_language);
211     if (ret == FALSE) {
212         return FALSE;
213     }
214
215     // get next position
216     int next_pos = -1;
217     if (_current_language == (int)_language_vector.size()-1) {
218         next_pos = 0;
219     } else {
220         next_pos = _current_language + 1;
221     }
222     assert(next_pos >= 0 && next_pos < (int)_language_vector.size());
223
224     // select next language
225     // the next one may be not enabled, so the loop below is to search afterwards
226     // continually until find an enabled one
227     // example: if current index is 5, the search order is:
228     // 5, 6, 7, 8, max, 0, 1, 2, 3, 4
229     sclboolean b_select_ok = FALSE;
230     for (int i = next_pos; i < (int)_language_vector.size(); ++i) {
231         b_select_ok = do_select_language(i);
232         if (b_select_ok == TRUE) {
233             break;
234         }
235     }
236
237     if (b_select_ok == FALSE) {
238         for (int i = 0; i < next_pos; ++i) {
239             b_select_ok = do_select_language(i);
240             if (b_select_ok == TRUE) {
241                 break;
242             }
243         }
244     }
245     ret = b_select_ok;
246
247     return ret;
248 }
249
250 sclboolean
251 ISELanguageManager::select_previous_language()
252 {
253     sclboolean ret = FALSE;
254
255     // do some work before change to previous language
256     // eg: commit predit string...
257     ret = do_unselect_language(_current_language);
258     if (ret == FALSE) {
259         return FALSE;
260     }
261
262     // get previous position
263     int pre_pos = -1;
264     assert(_current_language >= 0 && _current_language < (int)_language_vector.size());
265     if (_current_language == 0) {
266         pre_pos = _language_vector.size() -1;
267     } else {
268         pre_pos = _current_language -1;
269     }
270     assert(pre_pos >= 0 && pre_pos < (int)_language_vector.size());
271
272     // select previous language
273     // the previous one may be not enabled, so the loop below is to search forwards
274     // continually until find an enabled one
275     // example: if current index is 5, the search order is:
276     // 5, 4, 3, 2, 1, 0, max, max-1, ...4
277     sclboolean b_select_ok = FALSE;
278     for (int i = pre_pos; i >= 0; --i) {
279         b_select_ok = do_select_language(i);
280         if (b_select_ok == TRUE) {
281             break;
282         }
283     }
284     if (b_select_ok == FALSE) {
285         for (int i = _language_vector.size() -1; i > pre_pos; --i) {
286             b_select_ok = do_select_language(i);
287             if (b_select_ok == TRUE) {
288                 break;
289             }
290         }
291     }
292     ret = b_select_ok;
293
294     return ret;
295 }
296
297 sclboolean
298 ISELanguageManager::reset_language(const sclchar *name)
299 {
300     sclboolean ret = FALSE;
301
302     if (name == NULL) return FALSE;
303     int pos = _find_language_info(name, _language_vector);
304
305     // the assigned language could not be found in the language info vector
306     if (pos < 0 || pos >= (int)_language_vector.size()) {
307         return FALSE;
308     }
309
310     // if the language is not the one currently selected
311     if (pos != _current_language) {
312         return FALSE;
313     }
314
315     LANGUAGE_INFO &language_info = _language_vector.at(pos);
316     // if not enabled and not temporary, return false
317     if (!language_info.enabled && !language_info.enabled_temporarily) {
318         return FALSE;
319     }
320
321     // run the callback function
322     ILanguageCallback *callback = language_info.callback;
323     if (callback) {
324         ret = callback->reset_language(get_current_language());
325     }
326
327     return ret;
328 }
329
330 sclboolean ISELanguageManager::set_language_enabled(const sclchar *name, sclboolean enabled)
331 {
332     sclboolean ret = FALSE;
333
334     if (name) {
335         for (vector<LANGUAGE_INFO>::iterator iter = _language_vector.begin();
336             iter != _language_vector.end() && !ret;advance(iter, 1)) {
337                 if (iter->name.length() > 0) {
338                     if (iter->name.compare(name) == 0) {
339                         iter->enabled = enabled;
340                         ret = TRUE;
341                     }
342                 }
343         }
344     }
345
346     return ret;
347 }
348
349 sclboolean ISELanguageManager::set_language_enabled_temporarily(const sclchar *name, sclboolean enabled_temporarily)
350 {
351     sclboolean ret = FALSE;
352
353     if (name) {
354         for (vector<LANGUAGE_INFO>::iterator iter = _language_vector.begin();
355             iter != _language_vector.end() && !ret;advance(iter, 1)) {
356                 if (iter->name.length() > 0) {
357                     if (iter->name.compare(name) == 0) {
358                         iter->enabled_temporarily = enabled_temporarily;
359                         ret = TRUE;
360                     }
361                 }
362         }
363     }
364
365     return ret;
366 }
367
368 sclboolean
369 ISELanguageManager::enable_languages(const vector<string> &vec_language_id)
370 {
371     sclboolean ret = FALSE;
372
373     if (vec_language_id.size() != 0) {
374         ret = set_all_languages_enabled(FALSE);
375
376         if (ret == FALSE) return ret;
377
378         vector<string>::const_iterator citer;
379         for (citer = vec_language_id.begin(); citer != vec_language_id.end(); ++citer) {
380             ret = set_language_enabled(citer->c_str(), TRUE);
381             if (ret == FALSE) return FALSE;
382         }
383     }
384
385     return ret;
386 }
387
388 /* FIXME A temporary way for enable default language */
389 sclboolean ISELanguageManager::enable_default_language()
390 {
391     if (!_language_vector.empty()) {
392         LANGUAGE_INFO &default_language = _language_vector.at(0);
393         default_language.enabled = TRUE;
394         default_language.enabled_temporarily = FALSE;
395         return TRUE;
396     }
397
398     return FALSE;
399 }
400
401 sclboolean ISELanguageManager::set_enabled_languages(const vector<string> &vec_language_id)
402 {
403     sclboolean ret = FALSE;
404
405     if (vec_language_id.empty() || FALSE == enable_languages(vec_language_id)) {
406         ret = enable_default_language();
407     }
408
409     return ret;
410 }
411
412 const sclchar* ISELanguageManager::get_current_language()
413 {
414     if (_current_language >= 0 && _current_language < (int)_language_vector.size()) {
415         return _language_vector.at(_current_language).name.c_str();
416     }
417     return NULL;
418 }
419
420 const sclchar* ISELanguageManager::get_previous_language()
421 {
422     // get previous position
423     int pre_pos = -1;
424     assert(_current_language >= 0 && _current_language < (int)_language_vector.size());
425     if (_current_language == 0) {
426         pre_pos = _language_vector.size() -1;
427     } else {
428         pre_pos = _current_language -1;
429     }
430     assert(pre_pos >= 0 && pre_pos < (int)_language_vector.size());
431
432     // select previous language
433     // the previous one may be not enabled, so the loop below is to search forwards
434     // continually until find an enabled one
435     // example: if current index is 5, the search order is:
436     // 5, 4, 3, 2, 1, 0, max, max-1, ...4
437     sclboolean b_select_ok = FALSE;
438     for (int i = pre_pos; i >= 0; --i) {
439         if (_language_vector.at(i).enabled) {
440             b_select_ok = TRUE;
441             LANGUAGE_INFO &info = _language_vector.at(i);
442             return info.display_name.c_str();
443         }
444     }
445     if (b_select_ok == FALSE) {
446         for (int i = _language_vector.size() -1; i > pre_pos; --i) {
447             if (_language_vector.at(i).enabled) {
448                 LANGUAGE_INFO &info = _language_vector.at(i);
449                 return info.display_name.c_str();
450             }
451         }
452     }
453     return NULL;
454 }
455
456 const sclchar* ISELanguageManager::get_next_language()
457 {
458     // get next position
459     int next_pos = -1;
460     if (_current_language == (int)_language_vector.size()-1) {
461         next_pos = 0;
462     } else {
463         next_pos = _current_language + 1;
464     }
465     assert(next_pos >= 0 && next_pos < (int)_language_vector.size());
466
467     // select next language
468     // the next one may be not enabled, so the loop below is to search afterwards
469     // continually until find an enabled one
470     // example: if current index is 5, the search order is:
471     // 5, 6, 7, 8, max, 0, 1, 2, 3, 4
472     sclboolean b_select_ok = FALSE;
473     for (int i = next_pos; i < (int)_language_vector.size(); ++i) {
474         if (_language_vector.at(i).enabled) {
475             b_select_ok = TRUE;
476             LANGUAGE_INFO &info = _language_vector.at(i);
477             return info.display_name.c_str();
478         }
479     }
480
481     if (b_select_ok == FALSE) {
482         for (int i = 0; i < next_pos; ++i) {
483             if (_language_vector.at(i).enabled) {
484                 LANGUAGE_INFO &info = _language_vector.at(i);
485                 return info.display_name.c_str();
486             }
487         }
488     }
489     return NULL;
490 }
491
492 const sclchar* ISELanguageManager::get_resource_file_path()
493 {
494     return _default_resource_file.c_str();
495 }
496
497 bool ISELanguageManager::set_resource_file_path(const char *resource_file)
498 {
499     if (NULL == resource_file) {
500         return false;
501     }
502     _default_resource_file = resource_file;
503     return true;
504 }
505
506 scluint ISELanguageManager::get_languages_num()
507 {
508     return _language_vector.size();
509 }
510
511 scluint ISELanguageManager::get_enabled_languages_num()
512 {
513     scluint ret = 0;
514
515     for (vector<LANGUAGE_INFO>::iterator iter = _language_vector.begin();
516         iter != _language_vector.end();advance(iter, 1)) {
517             if (iter->enabled || iter->enabled_temporarily) {
518                 ret++;
519             }
520     }
521
522     return ret;
523 }
524
525 LANGUAGE_INFO* ISELanguageManager::get_language_info(const sclchar *language_name)
526 {
527     vector<LANGUAGE_INFO>::iterator it;
528
529     it = std::find_if(_language_vector.begin(), _language_vector.end(), _language_info_finder(language_name));
530
531     if (it != _language_vector.end()) {
532         return &(*it);
533     }
534     return NULL;
535 }
536
537 LANGUAGE_INFO* ISELanguageManager::get_language_info(int index)
538 {
539     LANGUAGE_INFO *ret = NULL;
540
541     if (index >= 0 && index < (int)_language_vector.size()) {
542         ret = &(_language_vector.at(index));
543     }
544
545     return ret;
546 }
547
548 LANGUAGE_INFO* ISELanguageManager::get_current_language_info()
549 {
550     return get_language_info(_current_language);
551 }