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