1 /*
2  * Copyright 2011 kubtek <kubtek@mail.com>
3  *
4  * This file is part of StarDict.
5  *
6  * StarDict is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * StarDict is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with StarDict.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef __SD_CONF_H__
21 #define __SD_CONF_H__
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <glib.h>
28 #include <map>
29 #include <memory>
30 #include <string>
31 #include <cstring>
32 
33 #ifdef _WIN32
34 #  include <windows.h>
35 #endif
36 
37 #include "config_file.h"
38 #include "lib/iappdirs.h"
39 
40 const int MIN_MAX_FLOATWIN_WIDTH=80; // if user 's MAX_FLOATWIN_WIDTH setting is less then this,it will be set to DEFAULT_MAX_FLOATWIN_WIDTH.
41 const int MIN_MAX_FLOATWIN_HEIGHT=60;
42 #ifdef CONFIG_GPE
43 const int DEFAULT_MAX_FLOATWIN_WIDTH=160;
44 const int DEFAULT_MAX_FLOATWIN_HEIGHT=120;
45 #else
46 const int DEFAULT_MAX_FLOATWIN_WIDTH=320; // This is the label's width in fact.
47 const int DEFAULT_MAX_FLOATWIN_HEIGHT=240;
48 #endif
49 
50 #ifdef _WIN32
51 extern HINSTANCE stardictexe_hInstance;
52 
53 std::string get_application_dir(void);
54 int abs_path_to_app_dir(const std::string& path, std::string& abs_path);
55 #endif
56 
57 template <typename T>
58 struct Type2Type {
59 	typedef T OriginType;
60 };
61 
62 enum TNotifAreaMiddleClickAction {
63 	namclaQueryFloatWindow,
64 	namclaQueryMainWindow,
65 	namclaDoNothing,
66 };
67 
68 /*
69  * AppConf class encapsulate
70  * all preference of StarDict.
71 */
72 
73 class AppConf {
74 public:
75 	AppConf();
76 	~AppConf();
77 	void Load();
78 
79 	typedef std::map<std::string, baseconfval *> cache_t;
80 
get_bool(const char * name)81 	bool get_bool(const char *name) const {
82 		return get(name, Type2Type<bool>());
83 	}
get_bool_at(const char * name)84 	bool get_bool_at(const char *name) const {
85 		return get_at(name, Type2Type<bool>());
86 	}
87 
get_int(const char * name)88 	int get_int(const char *name) const {
89 		return get(name, Type2Type<int>());
90 	}
91 
get_int_at(const char * name)92 	int get_int_at(const char *name) const {
93 		return get_at(name, Type2Type<int>());
94 	}
95 
get_double(const char * name)96 	double get_double(const char *name) const {
97 		return get(name, Type2Type<double>());
98 	}
99 
get_double_at(const char * name)100 	double get_double_at(const char *name) const {
101 		return get_at(name, Type2Type<double>());
102 	}
103 
get_string(const char * name)104 	const std::string& get_string(const char *name) const {
105 		return get(name, Type2Type<std::string>());
106 	}
107 
get_string_at(const char * name)108 	const std::string& get_string_at(const char *name) const {
109 		return get_at(name, Type2Type<std::string>());
110 	}
111 
get_strlist(const char * name)112 	const std::list<std::string>& get_strlist(const char *name) const {
113 		return get(name, Type2Type< std::list<std::string> >());
114 	}
115 
get_strlist_at(const char * name)116 	const std::list<std::string>& get_strlist_at(const char *name) const {
117 		return get_at(name, Type2Type< std::list<std::string> >());
118 	}
119 
set_bool(const char * name,const bool & v)120 	void set_bool(const char *name, const bool& v) {
121 		set_value(name, v);
122 	}
123 
set_bool_at(const char * name,const bool & v)124 	void set_bool_at(const char *name, const bool& v) {
125 		set_value(name, v, false);
126 	}
127 
set_int(const char * name,const int & v)128 	void set_int(const char *name, const int& v) {
129 		set_value(name, v);
130 	}
131 
set_int_at(const char * name,const int & v)132 	void set_int_at(const char *name, const int& v) {
133 		set_value(name, v, false);
134 	}
135 
set_double(const char * name,const double & v)136 	void set_double(const char *name, const double& v) {
137 		set_value(name, v);
138 	}
139 
set_double_at(const char * name,const double & v)140 	void set_double_at(const char *name, const double& v) {
141 		set_value(name, v, false);
142 	}
143 
set_string(const char * name,const std::string & v)144 	void set_string(const char *name, const std::string& v) {
145 		set_value(name, v);
146 	}
147 
set_string_at(const char * name,const std::string & v)148 	void set_string_at(const char *name, const std::string& v) {
149 		set_value(name, v, false);
150 	}
151 
set_strlist(const char * name,const std::list<std::string> & v)152 	void set_strlist(const char *name, const std::list<std::string>& v) {
153 		set_value(name, v);
154 	}
155 
set_strlist_at(const char * name,const std::list<std::string> & v)156 	void set_strlist_at(const char *name, const std::list<std::string>& v) {
157 		set_value(name, v, false);
158 	}
159 
160 	template <typename T>
add_entry(const char * name,const T & def_val)161 	void add_entry(const char *name, const T& def_val) {
162 		confval<T> *v = new confval<T>(def_val);
163 		g_assert(v->type_ != baseconfval::UNKNOWN_TYPE);
164 		cache[name] = v;
165 	}
166 	void notify_add(const char * name, const sigc::slot<void, const baseconfval*>&);
167 private:
168 	std::auto_ptr<config_file> cf;
169 	cache_t cache;
170 
171 	template <typename T>
172 	void set_value(const char *name, const T& val, bool abs = true) {
173 		cache_t::iterator p;
174 		p = abs ? cache.find(name) :
175 			cache.find(std::string("/apps/stardict/preferences/") +
176 				   name);
177 		if (p == cache.end() ||
178 		    static_cast<confval<T> *>(p->second)->val_ == val)
179 			return;
180 
181 		confval<T> *cfgval = static_cast<confval<T> *> (p->second);
182 		cfgval->val_ = val;
183 
184 		size_t len = strlen(name);
185 		const char *key = strrchr(name, '/');
186 		if (!key)
187 			key = name + len;
188 		std::string sect(name, 0, key - name);
189 		if (!*key)
190 			key = "";
191 		else
192 			++key;
193 		if (!abs)
194 			sect = "/apps/stardict/preferences/" + sect;
195 
196 		cfgval->save(*cf, sect.c_str(), key);
197 	}
198 
199 	static std::string get_default_history_filename();
200 	static std::string get_default_export_filename();
201 	static std::list<std::string> get_default_search_website_list();
202 #ifdef _WIN32
203 	static bool get_win32_use_custom_font();
204 	static std::string get_win32_custom_font();
205 #endif
206 #ifdef CONFIG_DARWIN
207 	static bool get_darwin_use_custom_font();
208 	static std::string get_darwin_custom_font();
209 #endif
210 
211 	template <typename T>
get(const char * name,Type2Type<T>)212 	const T& get(const char *name, Type2Type<T>) const {
213 		static T empty;
214 		cache_t::const_iterator p = cache.find(name);
215 		if (p != cache.end())
216 			return static_cast<confval<T> *>(p->second)->val_;
217 		return empty;
218 	}
219 
220 	template <typename T>
get_at(const char * name,Type2Type<T>)221 	const T& get_at(const char *name, Type2Type<T>) const {
222 		return get((std::string("/apps/stardict/preferences/") +
223 			    name).c_str(), Type2Type<T>());
224 	}
225 };
226 
227 /* Collection of StarDict directories.
228  * Most of the dirs can be overridden with stardict-dirs.cfg file.
229  *
230  * Implementation note
231  *
232  * An object of this class is created very early in application initialization
233  * process. Be careful implementing this class, restrict used library objects
234  * to minimum. If it's found out that inifile class can not be used, we may
235  * retreat to environment variables. For example, STARDICT_DATA_DIR for
236  * data_dir.
237  * */
238 class AppDirs: public IAppDirs
239 {
240 public:
241 	explicit AppDirs(const std::string& dirs_config_file);
get_user_config_dir(void)242 	std::string get_user_config_dir(void) const { return user_config_dir; }
get_user_cache_dir(void)243 	std::string get_user_cache_dir(void) const { return user_cache_dir; }
get_data_dir(void)244 	std::string get_data_dir(void) const { return data_dir; }
get_log_dir(void)245 	std::string get_log_dir(void) const { return log_dir; }
246 #ifdef _WIN32
get_dll_dir(void)247 	std::string get_dll_dir(void) const { return dll_dir; }
248 #endif
get_plugin_dir(void)249 	std::string get_plugin_dir(void) const { return plugin_dir; }
250 #ifndef CONFIG_GNOME
get_help_dir(void)251 	std::string get_help_dir(void) const { return help_dir; }
252 #endif
get_locale_dir(void)253 	std::string get_locale_dir(void) const { return locale_dir; }
254 #ifndef _WIN32
255 	std::string get_system_icon_dir(void) const;
256 #endif
257 #ifdef CONFIG_GNOME
get_system_data_dir(void)258 	std::string get_system_data_dir(void) const { return SYSTEM_DATA_DIR; }
259 #endif
260 
261 private:
262 	std::string get_dirs_config_file(const std::string& dirs_config_file) const;
263 	std::string get_default_user_config_dir(void) const;
264 	std::string get_default_user_cache_dir(void) const;
265 	std::string get_default_data_dir(void) const;
266 	std::string get_default_log_dir(void) const;
267 	std::string get_default_plugin_dir(void) const;
268 	std::string get_default_help_dir(void) const;
269 	std::string get_default_locale_dir(void) const;
270 
271 private:
272 	std::string user_config_dir;
273 	std::string user_cache_dir;
274 	/* contains subdirs: dic, treedict, sounds, skins, pixmaps, locale */
275 	std::string data_dir;
276 	std::string log_dir;
277 #ifdef _WIN32
278 	/* dir with TextOutSpy.dll and TextOutHook.dll */
279 	std::string dll_dir;
280 #endif
281 	/* StarDict plugins dir */
282 	std::string plugin_dir;
283 #ifndef CONFIG_GNOME
284 	/* help dir, contains subdirs: C, mk, nl,... with localized manuals. */
285 	std::string help_dir;
286 #endif
287 	/* dir containing getgext translated messages */
288 	std::string locale_dir;
289 };
290 
291 
292 extern std::auto_ptr<AppConf> conf;//global exemplar of AppConf class
293 extern std::auto_ptr<AppDirs> conf_dirs;
294 
295 #endif
296