Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules_wearable / localization / src / LanguageTagsProvider.cpp
1 /*
2  * Copyright (c) 2012 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  * @file    LanguageTagsProvider.cpp
18  * @author  Marcin Kaminski (marcin.ka@samsung.com)
19  * @version 1.0
20  */
21
22 #include "LanguageTagsProvider.h"
23
24 #include <algorithm>
25 #include <cassert>
26 #include <iostream>
27 #include <locale>
28 #include <cstddef>
29 #include <string>
30
31 #include <dpl/log/log.h>
32 #include <dpl/singleton_impl.h>
33 #include <vconf.h>
34
35 IMPLEMENT_SINGLETON(LanguageTagsProvider)
36
37 /* ========== public ========== */
38 const LanguageTags LanguageTagsProvider::getLanguageTags() const
39 {
40     return m_languageTagsList;
41 }
42
43 void LanguageTagsProvider::setLanguageTags(const LanguageTags& taglist)
44 {
45     m_languageTagsList = taglist;
46     /* If given list does not contain default value (empty string)
47      * than append it to the list.
48      * In case of empty list given as parameter only default value
49      * will exist on m_languageTagsList. */
50     DPL::String tofind = L"";
51     if (std::find(m_languageTagsList.begin(), m_languageTagsList.end(),
52                   tofind) == m_languageTagsList.end())
53     {
54         m_languageTagsList.push_back(L"");
55     }
56 }
57
58 void LanguageTagsProvider::setLanguageTagsFromLocales(const char* locales)
59 {
60     LogDebug("Setting new language tags for locales " << locales);
61     this->createTagsFromLocales(locales);
62 }
63
64 void LanguageTagsProvider::resetLanguageTags()
65 {
66     this->loadSystemTags();
67 }
68
69 void LanguageTagsProvider::addWidgetDefaultLocales(
70     const DPL::String& defaultLocale)
71 {
72     if (defaultLocale.size() > 0 &&
73         std::find(m_languageTagsList.begin(), m_languageTagsList.end(),
74                   defaultLocale) == m_languageTagsList.end())
75     {
76         if (m_languageTagsList.size() < 2) {
77             m_languageTagsList.push_front(defaultLocale);
78         } else {
79             LanguageTags::iterator placeToInsert = m_languageTagsList.end();
80             --placeToInsert;
81             if (*placeToInsert != L"") {
82                 ++placeToInsert;
83             }
84             m_languageTagsList.insert(placeToInsert, defaultLocale);
85         }
86     }
87 }
88
89 DPL::String LanguageTagsProvider::BCP47LanguageTagToLocale(
90     const DPL::String& inLanguageTag)
91 {
92     DPL::String languageTag(inLanguageTag);
93     /* Replace all */
94     std::replace(languageTag.begin(), languageTag.end(), '-', '_');
95     return languageTag;
96 }
97
98 DPL::String LanguageTagsProvider::LocaleToBCP47LanguageTag(
99     const DPL::String& inLocaleString)
100 {
101     /* Cut off codepage information from given string (if any exists)
102      * i.e. change en_US.UTF-8 into en_US */
103     DPL::String localeString = inLocaleString.substr(
104             0, inLocaleString.find_first_of(L"."));
105     /* Replace all '_' with '-' */
106     std::replace(localeString.begin(), localeString.end(), '_', '-');
107     return localeString;
108 }
109
110 /* ========== private ========== */
111 LanguageTagsProvider::LanguageTagsProvider()
112 {
113     LogDebug("Creating LanguageTagsProvider instance");
114     this->loadSystemTags();
115 }
116
117 LanguageTagsProvider::~LanguageTagsProvider()
118 {}
119
120 void LanguageTagsProvider::loadSystemTags()
121 {
122     char* language = vconf_get_str(VCONFKEY_LANGSET);
123     if (!language) {
124         LogError("Failed to get language from vconf");
125     } else {
126         LogDebug("Language fetched from vconf: " << language);
127     }
128     createTagsFromLocales(language);
129     free(language);
130 }
131
132 void LanguageTagsProvider::createTagsFromLocales(const char* language)
133 {
134     m_languageTagsList.clear();
135     if (!language) {
136         LogDebug("Setting default language tags");
137         /* If NULL language given than set default language tags
138          * and return. */
139         m_languageTagsList.push_back(L"");
140         return;
141     }
142
143     LogDebug("Setting tags for language: " << language);
144     DPL::String langdescr =
145         LocaleToBCP47LanguageTag(DPL::FromUTF8String(language));
146
147     if (langdescr.empty()) {
148         LogError("Empty language description while correct value needed");
149     } else {
150         /* Language tags list should not be cleared before this place to
151          * avoid losing current data when new data are invalid */
152         size_t position;
153         while (true) {
154             LogDebug("Processing language description: " << langdescr);
155             m_languageTagsList.push_back(langdescr);
156
157             // compatibility with lower language Tag by SDK
158             std::string langtag = DPL::ToUTF8String(langdescr);
159             std::transform(langtag.begin(), langtag.end(), langtag.begin(), ::tolower);
160             if (langtag != DPL::ToUTF8String(langdescr)) {
161                 m_languageTagsList.push_back(DPL::FromUTF8String(langtag));
162             }
163
164             position = langdescr.find_last_of(L"-");
165             if (position == DPL::String::npos) {
166                 break;
167             }
168             langdescr = langdescr.substr(0, position);
169         }
170     }
171     /* Add empty tag for non-localized content */
172     m_languageTagsList.push_back(L"");
173 }