1 /** @file scim_filter_manager.cpp
2  *  @brief Implementation of class FilterManager.
3  */
4 
5 /*
6  * Smart Common Input Method
7  *
8  * Copyright (c) 2005 James Su <suzhe@tsinghua.org.cn>
9  *
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this program; if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24  * Boston, MA  02111-1307  USA
25  *
26  * $Id: scim_filter_manager.cpp,v 1.4 2005/12/16 11:12:27 suzhe Exp $
27  */
28 
29 #define Uses_SCIM_FILTER_MODULE
30 #define Uses_SCIM_FILTER_MANAGER
31 #define Uses_SCIM_CONFIG_PATH
32 #include "scim_private.h"
33 #include "scim.h"
34 
35 namespace scim {
36 
37 struct FilterModuleIndex
38 {
39     FilterModule *module;
40     unsigned int  index;
41 
FilterModuleIndexscim::FilterModuleIndex42     FilterModuleIndex () : module (0), index (0) { }
43 };
44 
45 static bool                     __filter_initialized = false;
46 static unsigned int             __number_of_modules = 0;
47 static FilterModule            *__filter_modules    = 0;
48 
49 static std::vector <std::pair <FilterModuleIndex, FilterInfo> > __filter_infos;
50 
51 static void
__initialize_modules(const ConfigPointer & config)52 __initialize_modules (const ConfigPointer &config)
53 {
54     if (__filter_initialized) return;
55 
56     __filter_initialized = true;
57 
58     std::vector <String> mod_list;
59 
60     __number_of_modules = scim_get_filter_module_list (mod_list);
61 
62     if (!__number_of_modules) return;
63 
64     __filter_modules = new FilterModule [__number_of_modules];
65 
66     unsigned int i, j;
67 
68     for (i = 0; i < __number_of_modules; ++i) {
69         if (__filter_modules [i].load (mod_list [i], config)) {
70             for (j = 0; j < __filter_modules [i].number_of_filters (); ++j) {
71                 FilterModuleIndex index;
72                 FilterInfo info;
73                 if (__filter_modules [i].get_filter_info (j, info)) {
74                     index.module = & __filter_modules [i];
75                     index.index = j;
76                     __filter_infos.push_back (std::make_pair (index, info));
77                 }
78             }
79         }
80     }
81 }
82 
83 class FilterManager::FilterManagerImpl
84 {
85 public:
86     ConfigPointer        m_config;
87 
FilterManagerImpl(const ConfigPointer & config)88     FilterManagerImpl (const ConfigPointer &config) : m_config (config) { }
89 };
90 
FilterManager(const ConfigPointer & config)91 FilterManager::FilterManager (const ConfigPointer &config)
92     : m_impl (new FilterManagerImpl (config))
93 {
94 }
95 
~FilterManager()96 FilterManager::~FilterManager ()
97 {
98     delete m_impl;
99 }
100 
101 unsigned int
number_of_filters() const102 FilterManager::number_of_filters () const
103 {
104     if (!__filter_initialized) __initialize_modules (m_impl->m_config);
105 
106     return __filter_infos.size ();
107 }
108 
109 bool
get_filter_info(unsigned int idx,FilterInfo & info) const110 FilterManager::get_filter_info (unsigned int idx, FilterInfo &info) const
111 {
112     if (!__filter_initialized) __initialize_modules (m_impl->m_config);
113 
114     if (idx < number_of_filters ()) {
115         info = __filter_infos [idx].second;
116         return true;
117     }
118     return false;
119 }
120 
121 bool
get_filter_info(const String & uuid,FilterInfo & info) const122 FilterManager::get_filter_info (const String &uuid, FilterInfo &info) const
123 {
124     if (!__filter_initialized) __initialize_modules (m_impl->m_config);
125 
126     for (size_t i = 0; i < __filter_infos.size (); ++i) {
127         if (__filter_infos [i].second.uuid == uuid) {
128             info = __filter_infos [i].second;
129             return true;
130         }
131     }
132 
133     return false;
134 }
135 
136 FilterFactoryPointer
create_filter(unsigned int idx) const137 FilterManager::create_filter (unsigned int idx) const
138 {
139     if (!__filter_initialized) __initialize_modules (m_impl->m_config);
140 
141     if (idx < __filter_infos.size () && __filter_infos [idx].first.module && __filter_infos [idx].first.module->valid ()) {
142         return __filter_infos [idx].first.module->create_filter (__filter_infos [idx].first.index);
143     }
144 
145     return FilterFactoryPointer (0);
146 }
147 
148 FilterFactoryPointer
create_filter(const String & uuid) const149 FilterManager::create_filter (const String &uuid) const
150 {
151     if (!__filter_initialized) __initialize_modules (m_impl->m_config);
152 
153     for (size_t i = 0; i < __filter_infos.size (); ++i) {
154         if (__filter_infos [i].second.uuid == uuid && __filter_infos [i].first.module && __filter_infos [i].first.module->valid ())
155             return __filter_infos [i].first.module->create_filter (__filter_infos [i].first.index);
156     }
157 
158     return FilterFactoryPointer (0);
159 }
160 
161 void
clear_all_filter_settings() const162 FilterManager::clear_all_filter_settings () const
163 {
164     if (!m_impl->m_config.null () && m_impl->m_config->valid ()) {
165         std::vector <String> tmp;
166         scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String ("")));
167 
168         for (size_t i = 0; i < tmp.size (); ++i)
169             m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + tmp [i]);
170 
171         m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST));
172     }
173 }
174 
175 size_t
get_filters_for_imengine(const String & uuid,std::vector<String> & filters) const176 FilterManager::get_filters_for_imengine (const String &uuid, std::vector <String> &filters) const
177 {
178     filters.clear ();
179 
180     if (!m_impl->m_config.null () && m_impl->m_config->valid ()) {
181         std::vector <String> tmp;
182         scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String ("")));
183 
184         if (std::find (tmp.begin (), tmp.end (), uuid) != tmp.end ()) {
185             FilterInfo info;
186 
187             scim_split_string_list (tmp, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid, String ("")));
188 
189             for (size_t i = 0; i < tmp.size (); ++i) {
190                 if (std::find (filters.begin (), filters.end (), tmp [i]) == filters.end () && get_filter_info (tmp [i], info))
191                     filters.push_back (tmp [i]);
192             }
193         }
194     }
195 
196     return filters.size ();
197 }
198 
199 void
set_filters_for_imengine(const String & uuid,const std::vector<String> & filters) const200 FilterManager::set_filters_for_imengine (const String &uuid, const std::vector <String> &filters) const
201 {
202     if (!m_impl->m_config.null () && m_impl->m_config->valid ()) {
203         std::vector <String> valid_filters;
204 
205         FilterInfo info;
206 
207         for (size_t i = 0; i < filters.size (); ++i) {
208             if (std::find (valid_filters.begin (), valid_filters.end (), filters [i]) == valid_filters.end () && get_filter_info (filters [i], info))
209                 valid_filters.push_back (filters [i]);
210         }
211 
212         std::vector <String> filtered_ims;
213         scim_split_string_list (filtered_ims, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String ("")));
214 
215         if (valid_filters.size ()) {
216             if (std::find (filtered_ims.begin (), filtered_ims.end (), uuid) == filtered_ims.end ())
217                 filtered_ims.push_back (uuid);
218             m_impl->m_config->write (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid, scim_combine_string_list (valid_filters));
219         } else {
220             std::vector <String>::iterator it = std::find (filtered_ims.begin (), filtered_ims.end (), uuid);
221             if (it != filtered_ims.end ())
222                 filtered_ims.erase (it);
223             m_impl->m_config->erase (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES) + String ("/") + uuid);
224         }
225 
226         m_impl->m_config->write (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), scim_combine_string_list (filtered_ims));
227     }
228 }
229 
230 size_t
get_filtered_imengines(std::vector<String> & imengines) const231 FilterManager::get_filtered_imengines (std::vector <String> &imengines) const
232 {
233     scim_split_string_list (imengines, m_impl->m_config->read (String (SCIM_CONFIG_FILTER_FILTERED_IMENGINES_LIST), String ("")));
234     return imengines.size ();
235 }
236 
237 IMEngineFactoryPointer
attach_filters_to_factory(const IMEngineFactoryPointer & factory) const238 FilterManager::attach_filters_to_factory (const IMEngineFactoryPointer &factory) const
239 {
240     IMEngineFactoryPointer root = factory;
241 
242     std::vector <String> filters;
243 
244     if (!factory.null () && get_filters_for_imengine (factory->get_uuid (), filters)) {
245         for (size_t i = 0; i < filters.size (); ++i) {
246             FilterFactoryPointer filter = create_filter (filters [i]);
247             if (!filter.null ()) {
248                 filter->attach_imengine_factory (root);
249                 root = filter;
250             }
251         }
252     }
253 
254     return root;
255 }
256 
257 } // namespace scim
258 
259 /*
260 vi:ts=4:nowrap:ai:expandtab
261 */
262 
263