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 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23 
24 #include <cstring>
25 #include <sys/stat.h>
26 #include <glib/gi18n.h>
27 #include <algorithm>
28 #include <cstdlib>
29 
30 #ifdef _WIN32
31 #  include <gdk/gdkwin32.h>
32 #endif
33 
34 #include "stardict.h"
35 #include "conf.h"
36 #include "desktop.h"
37 #include "ifo_file.h"
38 #include "lib/utils.h"
39 #include "lib/file-utils.h"
40 #include "dictmanage.h"
41 
42 #include "dictmanagedlg.h"
43 
44 enum DictListColumns {
45 	DICTLIST_TYPE_COLUMN, // 0 G_TYPE_INT
46 	DICTLIST_NAME_COLUMN, // 1
47 	DICTLIST_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
48 	DICTLIST_AUTHOR_COLUMN, // 3
49 	DICTLIST_EMAIL_COLUMN, // 4
50 	DICTLIST_WEB_SITE_COLUMN, // 5
51 	DICTLIST_DESCRIPTION_COLUMN, // 6
52 	DICTLIST_DATE_COLUMN, // 7
53 	DICTLIST_ID_COLUMN, // 8
54 	DICTLIST_ID_TYPE_STR_COLUMN, // 9
55 	DICTLIST_COLUMN_NUMBER
56 };
57 
58 enum TreeDictColumns {
59 	TREEDICT_ENABLED_COLUMN, // 0
60 	TREEDICT_NAME_COLUMN, // 1
61 	TREEDICT_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
62 	TREEDICT_AUTHOR_COLUMN, // 3
63 	TREEDICT_EMAIL_COLUMN, // 4
64 	TREEDICT_WEB_SITE_COLUMN, // 5
65 	TREEDICT_DESCRIPTION_COLUMN, // 6
66 	TREEDICT_DATE_COLUMN, // 7
67 	TREEDICT_ID_COLUMN, // 8
68 	TREEDICT_COLUMN_NUMBER
69 };
70 
71 enum NetworkDictColumns {
72 	NETWORKDICT_ID_COLUMN, // 0
73 	NETWORKDICT_NAME_COLUMN, // 1
74 	NETWORKDICT_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
75 	NETWORKDICT_COLUMN_NUMBER
76 };
77 
78 enum NetworkAddDlgDictColumns {
79 	NETWORK_ADD_DLG_NAME_COLUMN, // 0
80 	NETWORK_ADD_DLG_VISIBLE_COLUMN, // 1
81 	NETWORK_ADD_DLG_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
82 	NETWORK_ADD_DLG_ID_COLUMN, // 3
83 	NETWORK_ADD_DLG_NEED_LEVEL_COLUMN, // 4 G_TYPE_INT
84 	NETWORK_ADD_DLG_COLUMN_NUMBER
85 };
86 
87 enum DictManageColumns {
88 	DICT_MANAGE_ENABLE_COLUMN, // 0
89 	/* markup for row level 0, 1
90 	 * dictionary name for row level 2 */
91 	DICT_MANAGE_MARKUP_COLUMN, // 1
92 	DICT_MANAGE_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
93 	/* plain text name for row level 0, 1
94 	 * author for row level 2 */
95 	DICT_MANAGE_AUTHOR_COLUMN, // 3
96 	DICT_MANAGE_EMAIL_COLUMN, // 4
97 	DICT_MANAGE_WEB_SITE_COLUMN, // 5
98 	DICT_MANAGE_DESCRIPTION_COLUMN, // 6
99 	DICT_MANAGE_DATE_COLUMN, // 7
100 	DICT_MANAGE_ID_COLUMN, // 8
101 	/* if true, show details information: checkbox, word count
102 	 * if false, show only markup */
103 	DICT_MANAGE_SHOW_DETAILS_COLUMN, // 9
104 	DICT_MANAGE_ROW_LEVEL_COLUMN, // 10 G_TYPE_INT
105 	DICT_MANAGE_EDITABLE_COLUMN, // 11
106 	DICT_MANAGE_TYPE_COLUMN, // 12 G_TYPE_INT
107 	DICT_MANAGE_COLUMN_NUMBER // 13
108 };
109 
110 enum AddDictDlgColumns {
111 	ADD_DICT_TYPE_COLUMN, // 0 G_TYPE_INT
112 	ADD_DICT_NAME_COLUMN, // 1
113 	ADD_DICT_WORD_COUNT_COLUMN, // 2 G_TYPE_LONG
114 	ADD_DICT_AUTHOR_COLUMN, // 3
115 	ADD_DICT_EMAIL_COLUMN, // 4
116 	ADD_DICT_WEB_SITE_COLUMN, // 5
117 	ADD_DICT_DESCRIPTION_COLUMN, // 6
118 	ADD_DICT_DATE_COLUMN, // 7
119 	ADD_DICT_ID_COLUMN, // 8
120 	ADD_DICT_TYPE_STR_COLUMN, // 9
121 	ADD_DICT_COLUMN_NUMBER // 10
122 };
123 
NetworkAddDlg(DictManageDlg * dlg)124 NetworkAddDlg::NetworkAddDlg(DictManageDlg *dlg)
125 {
126 	dictdlg = dlg;
127 }
128 
on_network_adddlg_add_button_clicked(GtkWidget * widget,NetworkAddDlg * oNetworkAddDlg)129 void NetworkAddDlg::on_network_adddlg_add_button_clicked(GtkWidget *widget, NetworkAddDlg *oNetworkAddDlg)
130 {
131 	GtkTreeModel *model;
132 	GtkTreeIter iter;
133 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (oNetworkAddDlg->treeview));
134 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
135 		gboolean visible;
136 		gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_VISIBLE_COLUMN, &visible, -1);
137 		if (visible) {
138 			gchar *uid;
139 			gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_ID_COLUMN, &uid, -1);
140 			bool added = false;
141 			int row_count = 0;
142 			GtkTreeIter iter2;
143 			if (gtk_tree_model_get_iter_first(oNetworkAddDlg->dictdlg->network_tree_model, &iter2)) {
144 				gchar *uid2;
145 				do {
146 					row_count++;
147 					gtk_tree_model_get (
148 						oNetworkAddDlg->dictdlg->network_tree_model, &iter2,
149 						NETWORKDICT_ID_COLUMN, &uid2,
150 						-1
151 					);
152 					if (strcmp(uid, uid2)==0) {
153 						added = true;
154 						g_free(uid2);
155 						break;
156 					}
157 					g_free(uid2);
158 				} while (gtk_tree_model_iter_next(oNetworkAddDlg->dictdlg->network_tree_model, &iter2));
159 			}
160 			if (!added) {
161 				gchar *msg;
162 				if (row_count < oNetworkAddDlg->dictdlg->max_dict_count) {
163 					gint need_level;
164 					gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_NEED_LEVEL_COLUMN, &need_level, -1);
165 					if (need_level > oNetworkAddDlg->dictdlg->user_level) {
166 						msg = g_strdup_printf(_("Only level %d user can choose this dictionary!"), need_level);
167 					} else {
168 						msg = NULL;
169 						gchar *bookname;
170 						glong wordcount;
171 						gtk_tree_model_get (
172 							model, &iter,
173 							NETWORK_ADD_DLG_NAME_COLUMN, &bookname,
174 							NETWORK_ADD_DLG_WORD_COUNT_COLUMN, &wordcount,
175 							-1
176 						);
177 						gtk_list_store_append(GTK_LIST_STORE(oNetworkAddDlg->dictdlg->network_tree_model), &iter2);
178 						gtk_list_store_set(
179 							GTK_LIST_STORE(oNetworkAddDlg->dictdlg->network_tree_model),
180 							&iter2,
181 							NETWORKDICT_ID_COLUMN, uid,
182 							NETWORKDICT_NAME_COLUMN, bookname,
183 							NETWORKDICT_WORD_COUNT_COLUMN, wordcount,
184 							-1
185 						);
186 						g_free(bookname);
187 						oNetworkAddDlg->dictdlg->network_dictmask_changed = true;
188 					}
189 				} else {
190 					msg = g_strdup_printf(_("You can only choose %d dictionaries."), oNetworkAddDlg->dictdlg->max_dict_count);
191 				}
192 				if (msg) {
193 					GtkWidget *message_dlg =
194 						gtk_message_dialog_new(
195 								GTK_WINDOW(oNetworkAddDlg->window),
196 								(GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
197 								GTK_MESSAGE_INFO,  GTK_BUTTONS_OK,
198 								"%s", msg);
199 					g_free(msg);
200 					gtk_dialog_set_default_response(GTK_DIALOG(message_dlg), GTK_RESPONSE_OK);
201 					gtk_window_set_resizable(GTK_WINDOW(message_dlg), FALSE);
202 					gtk_dialog_run(GTK_DIALOG(message_dlg));
203 					gtk_widget_destroy(message_dlg);
204 				}
205 			}
206 			g_free(uid);
207 		}
208 	}
209 }
210 
on_network_adddlg_info_button_clicked(GtkWidget * widget,NetworkAddDlg * oNetworkAddDlg)211 void NetworkAddDlg::on_network_adddlg_info_button_clicked(GtkWidget *widget, NetworkAddDlg *oNetworkAddDlg)
212 {
213 	GtkTreeModel *model;
214 	GtkTreeIter iter;
215 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (oNetworkAddDlg->treeview));
216 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
217 		gboolean visible;
218 		gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_VISIBLE_COLUMN, &visible, -1);
219 		if (visible) {
220 			gchar *uid;
221 			gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_ID_COLUMN, &uid, -1);
222 			STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_DICT_INFO, uid);
223 			if (!gpAppFrame->oStarDictClient.try_cache(c))
224 				gpAppFrame->oStarDictClient.send_commands(1, c);
225 			g_free(uid);
226 		}
227 	}
228 }
229 
on_button_press(GtkWidget * widget,GdkEventButton * event,NetworkAddDlg * oNetworkAddDlg)230 gboolean NetworkAddDlg::on_button_press(GtkWidget * widget, GdkEventButton * event, NetworkAddDlg *oNetworkAddDlg)
231 {
232 	if (event->type==GDK_2BUTTON_PRESS) {
233 		GtkTreeModel *model;
234 		GtkTreeIter iter;
235 		GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
236 		if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
237 			gboolean visible;
238 			gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_VISIBLE_COLUMN, &visible, -1);
239 			if (visible) {
240 				gchar *uid;
241 				gtk_tree_model_get (model, &iter, NETWORK_ADD_DLG_ID_COLUMN, &uid, -1);
242 				STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_DICT_INFO, uid);
243 				if (!gpAppFrame->oStarDictClient.try_cache(c))
244 					gpAppFrame->oStarDictClient.send_commands(1, c);
245 				g_free(uid);
246 			} else {
247 				GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
248 				if (gtk_tree_view_row_expanded(GTK_TREE_VIEW (widget), path))
249 					gtk_tree_view_collapse_row(GTK_TREE_VIEW (widget), path);
250 				else
251 					gtk_tree_view_expand_row(GTK_TREE_VIEW (widget), path, FALSE);
252 				gtk_tree_path_free(path);
253 			}
254 		}
255 		return true;
256 	} else {
257 		return false;
258 	}
259 }
260 
on_row_expanded(GtkTreeView * treeview,GtkTreeIter * arg1,GtkTreePath * arg2,NetworkAddDlg * oNetworkAddDlg)261 void NetworkAddDlg::on_row_expanded(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, NetworkAddDlg *oNetworkAddDlg)
262 {
263 	GtkTreeIter iter;
264 	if (gtk_tree_model_iter_children(GTK_TREE_MODEL(oNetworkAddDlg->model), &iter, arg1) == FALSE)
265 		return;
266 	gchar *word;
267 	gtk_tree_model_get (GTK_TREE_MODEL(oNetworkAddDlg->model), &iter,
268 		NETWORK_ADD_DLG_NAME_COLUMN, &word,
269 		-1
270 	);
271 	if (word[0] == '\0') {
272 		gchar *path;
273 		gtk_tree_model_get (GTK_TREE_MODEL(oNetworkAddDlg->model), arg1,
274 			NETWORK_ADD_DLG_ID_COLUMN, &path,
275 			-1
276 		);
277 		STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_DIR_INFO, path);
278 		if (!gpAppFrame->oStarDictClient.try_cache(c))
279 			gpAppFrame->oStarDictClient.send_commands(1, c);
280 		g_free(path);
281 	}
282 	g_free(word);
283 }
284 
Show(GtkWindow * parent_win)285 void NetworkAddDlg::Show(GtkWindow *parent_win)
286 {
287 	window = gtk_dialog_new();
288 	gtk_window_set_transient_for(GTK_WINDOW(window), parent_win);
289 	gtk_dialog_add_button (GTK_DIALOG (window), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
290 	gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_CLOSE);
291 #if GTK_MAJOR_VERSION >= 3
292 	GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
293 #else
294 	GtkWidget *hbox = gtk_hbox_new(false, 6);
295 #endif
296 	GtkWidget *sw;
297 	sw = gtk_scrolled_window_new (NULL, NULL);
298 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
299 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
300 	gtk_widget_set_size_request (sw, 350, 230);
301 	model = gtk_tree_store_new(NETWORK_ADD_DLG_COLUMN_NUMBER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_LONG, G_TYPE_STRING, G_TYPE_INT);
302 	treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(model));
303 	g_object_unref (G_OBJECT (model));
304 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
305 	GtkTreeSelection *selection;
306 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
307 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
308 	GtkCellRenderer *renderer;
309 	GtkTreeViewColumn *column;
310 	renderer = gtk_cell_renderer_text_new ();
311 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
312 	column = gtk_tree_view_column_new_with_attributes (_("Dictionary Name"), renderer, "text", NETWORK_ADD_DLG_NAME_COLUMN, NULL);
313 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
314 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
315 	renderer = gtk_cell_renderer_text_new ();
316 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
317 	column = gtk_tree_view_column_new_with_attributes (_("Word count"), renderer,
318 		"text", NETWORK_ADD_DLG_WORD_COUNT_COLUMN,
319 		"visible", NETWORK_ADD_DLG_VISIBLE_COLUMN,
320 		NULL);
321 	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
322 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
323 	g_signal_connect (G_OBJECT (treeview), "button_press_event", G_CALLBACK (on_button_press), this);
324 	g_signal_connect (G_OBJECT (treeview), "row-expanded", G_CALLBACK (on_row_expanded), this);
325 	gtk_container_add (GTK_CONTAINER (sw), treeview);
326 	gtk_box_pack_start (GTK_BOX (hbox), sw, true, true, 0);
327 	GtkWidget *vbox;
328 #if GTK_MAJOR_VERSION >= 3
329 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
330 #else
331 	vbox = gtk_vbox_new(false, 6);
332 #endif
333 	GtkWidget *button;
334 	button = gtk_button_new_from_stock(GTK_STOCK_ADD);
335 	gtk_widget_set_can_focus (button, FALSE);
336 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_network_adddlg_add_button_clicked), this);
337 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
338 #ifdef CONFIG_MAEMO
339 	button = gtk_button_new_from_stock(GTK_STOCK_DIALOG_INFO);
340 #else
341 	button = gtk_button_new_from_stock(GTK_STOCK_INFO);
342 #endif
343 	gtk_widget_set_can_focus (button, FALSE);
344 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_network_adddlg_info_button_clicked), this);
345 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
346 	gtk_box_pack_start (GTK_BOX (hbox), vbox, false, false, 0);
347 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG (window))), hbox, true, true, 0);
348 	gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG (window)));
349 	gtk_window_set_title(GTK_WINDOW (window), _("Browse Dictionaries"));
350 	STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_DIR_INFO, "/");
351 	if (!gpAppFrame->oStarDictClient.try_cache(c))
352 		gpAppFrame->oStarDictClient.send_commands(1, c);
353 	gtk_dialog_run(GTK_DIALOG(window));
354 	gtk_widget_destroy(window);
355 }
356 
357 struct dirinfo_ParseUserData {
358 	GtkTreeStore *model;
359 	GtkTreeIter *iter;
360 	std::string parent;
361 	unsigned int userlevel;
362 	bool in_dir;
363 	std::string dir_name;
364 	std::string dir_dirname;
365 	std::string dir_dictcount;
366 	bool in_dict;
367 	std::string dict_islink;
368 	std::string dict_level;
369 	std::string dict_uid;
370 	std::string dict_bookname;
371 	std::string dict_wordcount;
372 };
373 
dirinfo_parse_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)374 static void dirinfo_parse_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
375 {
376 	if (strcmp(element_name, "dir")==0) {
377 		dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)user_data;
378 		Data->in_dir = true;
379 		Data->dir_name.clear();
380 		Data->dir_dirname.clear();
381 		Data->dir_dictcount.clear();
382 	} else if (strcmp(element_name, "dict")==0) {
383 		dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)user_data;
384 		Data->in_dict = true;
385 		Data->dict_islink.clear();
386 		Data->dict_level.clear();
387 		Data->dict_uid.clear();
388 		Data->dict_bookname.clear();
389 		Data->dict_wordcount.clear();
390 	}
391 }
392 
dirinfo_parse_end_element(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)393 static void dirinfo_parse_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
394 {
395 	if (strcmp(element_name, "dir")==0) {
396 		dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)user_data;
397 		Data->in_dir = false;
398 		GtkTreeIter iter;
399 		gtk_tree_store_append(Data->model, &iter, Data->iter);
400 		gtk_tree_store_set(
401 			Data->model, &iter,
402 			NETWORK_ADD_DLG_NAME_COLUMN, (Data->dir_dirname + " (" + Data->dir_dictcount + ')').c_str(),
403 			NETWORK_ADD_DLG_VISIBLE_COLUMN, FALSE,
404 			NETWORK_ADD_DLG_ID_COLUMN, (Data->parent + Data->dir_name + '/').c_str(),
405 			-1
406 		);
407 		GtkTreeIter iter1;
408 		gtk_tree_store_append(Data->model, &iter1, &iter);
409 		gtk_tree_store_set(
410 			Data->model, &iter1,
411 			NETWORK_ADD_DLG_NAME_COLUMN, "",
412 			NETWORK_ADD_DLG_VISIBLE_COLUMN, TRUE,
413 			-1
414 		);
415 	} else if (strcmp(element_name, "dict")==0) {
416 		dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)user_data;
417 		Data->in_dict = false;
418 		GtkTreeIter iter;
419 		gtk_tree_store_append(Data->model, &iter, Data->iter);
420 		gint need_level;
421 		if (Data->dict_level.empty())
422 			need_level = 0;
423 		else
424 			need_level = atoi(Data->dict_level.c_str());
425 		gtk_tree_store_set(
426 			Data->model, &iter,
427 			NETWORK_ADD_DLG_NAME_COLUMN, Data->dict_bookname.c_str(),
428 			NETWORK_ADD_DLG_VISIBLE_COLUMN, TRUE,
429 			NETWORK_ADD_DLG_WORD_COUNT_COLUMN, (glong)atol(Data->dict_wordcount.c_str()),
430 			NETWORK_ADD_DLG_ID_COLUMN, Data->dict_uid.c_str(),
431 			NETWORK_ADD_DLG_NEED_LEVEL_COLUMN, need_level,
432 			-1
433 		);
434 	}
435 }
436 
do_find_iter(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)437 static gboolean do_find_iter(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
438 {
439 	dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)data;
440 	gboolean visible;
441 	gtk_tree_model_get (model, iter, NETWORK_ADD_DLG_VISIBLE_COLUMN, &visible, -1);
442 	if (visible == FALSE) {
443 		gchar *dirpath;
444 		gtk_tree_model_get (model, iter, NETWORK_ADD_DLG_ID_COLUMN, &dirpath, -1);
445 		if (dirpath && Data->parent == dirpath) {
446 			Data->iter = (GtkTreeIter *)g_malloc(sizeof(GtkTreeIter));
447 			*(Data->iter) = *iter;
448 			g_free(dirpath);
449 			return TRUE;
450 		}
451 		g_free(dirpath);
452 	}
453 	return FALSE;
454 }
455 
dirinfo_parse_text(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)456 static void dirinfo_parse_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
457 {
458 	const gchar *element = g_markup_parse_context_get_element(context);
459 	if (!element)
460 		return;
461 	dirinfo_ParseUserData *Data = (dirinfo_ParseUserData *)user_data;
462 	if (strcmp(element, "parent")==0) {
463 		Data->parent.assign(text, text_len);
464 		if (Data->parent == "/") {
465 			Data->iter = NULL;
466 		} else {
467 			gtk_tree_model_foreach(GTK_TREE_MODEL(Data->model), do_find_iter, Data);
468 		}
469 	} else if (strcmp(element, "userlevel")==0) {
470 		std::string userlevel(text, text_len);
471 		Data->userlevel = atoi(userlevel.c_str());
472 	} else if (strcmp(element, "name")==0) {
473 		if (Data->in_dir)
474 			Data->dir_name.assign(text, text_len);
475 	} else if (strcmp(element, "dirname")==0) {
476 		if (Data->in_dir)
477 			Data->dir_dirname.assign(text, text_len);
478 	} else if (strcmp(element, "dictcount")==0) {
479 		if (Data->in_dir)
480 			Data->dir_dictcount.assign(text, text_len);
481 	} else if (strcmp(element, "islink")==0) {
482 		if (Data->in_dict)
483 			Data->dict_islink.assign(text, text_len);
484 	} else if (strcmp(element, "level")==0) {
485 		if (Data->in_dict)
486 			Data->dict_level.assign(text, text_len);
487 	} else if (strcmp(element, "uid")==0) {
488 		if (Data->in_dict)
489 			Data->dict_uid.assign(text, text_len);
490 	} else if (strcmp(element, "bookname")==0) {
491 		if (Data->in_dict)
492 			Data->dict_bookname.assign(text, text_len);
493 	} else if (strcmp(element, "wordcount")==0) {
494 		if (Data->in_dict)
495 			Data->dict_wordcount.assign(text, text_len);
496 	}
497 }
498 
network_getdirinfo(const char * xml)499 void NetworkAddDlg::network_getdirinfo(const char *xml)
500 {
501 	dirinfo_ParseUserData Data;
502 	Data.model = this->model;
503 	Data.iter = NULL;
504 	Data.userlevel = 0;
505 	Data.in_dir = false;
506 	Data.in_dict = false;
507 	GMarkupParser parser;
508 	parser.start_element = dirinfo_parse_start_element;
509 	parser.end_element = dirinfo_parse_end_element;
510 	parser.text = dirinfo_parse_text;
511 	parser.passthrough = NULL;
512 	parser.error = NULL;
513 	GMarkupParseContext* context = g_markup_parse_context_new(&parser, (GMarkupParseFlags)0, &Data, NULL);
514 	g_markup_parse_context_parse(context, xml, -1, NULL);
515 	g_markup_parse_context_end_parse(context, NULL);
516 	g_markup_parse_context_free(context);
517 	if (Data.iter) {
518 		GtkTreeIter iter;
519 		if (gtk_tree_model_iter_children(GTK_TREE_MODEL(Data.model), &iter, Data.iter))
520 			gtk_tree_store_remove(Data.model, &iter);
521 		g_free(Data.iter);
522 	}
523 	this->dictdlg->user_level = Data.userlevel;
524 }
525 
DictManageDlg(GtkWindow * pw,GdkPixbuf * di,GdkPixbuf * tdi)526 DictManageDlg::DictManageDlg(GtkWindow *pw, GdkPixbuf *di,  GdkPixbuf *tdi) :
527 	parent_win(pw), dicts_icon(di), tree_dicts_icon(tdi), network_add_dlg(NULL), window(NULL)
528 {
529 }
530 
response_handler(GtkDialog * dialog,gint res_id,DictManageDlg * oDictManageDlg)531 void DictManageDlg::response_handler (GtkDialog *dialog, gint res_id, DictManageDlg *oDictManageDlg)
532 {
533 	if (res_id==GTK_RESPONSE_HELP)
534 		show_help("stardict-dictmanage");
535 }
536 
on_dict_list_button_toggled(GtkToggleButton * button,DictManageDlg * oDictManageDlg)537 void DictManageDlg::on_dict_list_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg)
538 {
539 	if (gtk_toggle_button_get_active(button)) {
540 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 0);
541 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->button_notebook), 0);
542 		gtk_widget_show(oDictManageDlg->download_hbox);
543 		gtk_widget_hide(oDictManageDlg->info_label);
544 		gtk_widget_hide(oDictManageDlg->upgrade_eventbox);
545 	}
546 }
547 
on_manage_button_toggled(GtkToggleButton * button,DictManageDlg * oDictManageDlg)548 void DictManageDlg::on_manage_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg)
549 {
550 	if (gtk_toggle_button_get_active(button)) {
551 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 1);
552 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->button_notebook), 1);
553 		gtk_widget_show(oDictManageDlg->download_hbox);
554 		gtk_widget_hide(oDictManageDlg->info_label);
555 		gtk_widget_hide(oDictManageDlg->upgrade_eventbox);
556 	}
557 }
558 
on_tree_dict_button_toggled(GtkToggleButton * button,DictManageDlg * oDictManageDlg)559 void DictManageDlg::on_tree_dict_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg)
560 {
561 	if (gtk_toggle_button_get_active(button)) {
562 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 2);
563 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->button_notebook), 0);
564 		gtk_label_set_text(GTK_LABEL(oDictManageDlg->info_label), _("These settings will take effect the next time you run StarDict."));
565 		gtk_widget_show(oDictManageDlg->info_label);
566 		gtk_widget_hide(oDictManageDlg->download_hbox);
567 		gtk_widget_hide(oDictManageDlg->upgrade_eventbox);
568 	}
569 }
570 
on_network_button_toggled(GtkToggleButton * button,DictManageDlg * oDictManageDlg)571 void DictManageDlg::on_network_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg)
572 {
573 	if (gtk_toggle_button_get_active(button)) {
574 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 3);
575 		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->button_notebook), 2);
576 		if (oDictManageDlg->max_dict_count == -1) {
577 			gtk_label_set_text(GTK_LABEL(oDictManageDlg->info_label), _("Loading..."));
578 			STARDICT::Cmd *c1 = new STARDICT::Cmd(STARDICT::CMD_GET_DICT_MASK);
579 			STARDICT::Cmd *c2 = new STARDICT::Cmd(STARDICT::CMD_MAX_DICT_COUNT);
580 			gpAppFrame->oStarDictClient.try_cache_or_send_commands(2, c1, c2);
581 		} else {
582 			gchar *str = g_strdup_printf(_("You can only choose %d dictionaries."), oDictManageDlg->max_dict_count);
583 			gtk_label_set_text(GTK_LABEL(oDictManageDlg->info_label), str);
584 			g_free(str);
585 		}
586 		gtk_widget_show(oDictManageDlg->info_label);
587 		gtk_widget_hide(oDictManageDlg->download_hbox);
588 		STARDICT::Cmd *c3 = new STARDICT::Cmd(STARDICT::CMD_GET_ADINFO);
589 		gpAppFrame->oStarDictClient.try_cache_or_send_commands(1, c3);
590 		gtk_widget_show(oDictManageDlg->upgrade_eventbox);
591 	}
592 }
593 
create_dict_item_model(GtkTreeStore * model,GtkTreeIter * group_iter,std::list<DictManageItem> & dictitem,bool is_query)594 static void create_dict_item_model(GtkTreeStore *model, GtkTreeIter *group_iter, std::list<DictManageItem> &dictitem, bool is_query)
595 {
596 	GtkTreeIter type_iter;
597 	gtk_tree_store_append(model, &type_iter, group_iter);
598 	if (is_query) {
599 		gtk_tree_store_set(
600 			model, &type_iter,
601 			DICT_MANAGE_MARKUP_COLUMN, _("<span foreground=\"red\">Query Dict</span>"),
602 			DICT_MANAGE_AUTHOR_COLUMN, "querydict",
603 			DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
604 			DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)1,
605 			DICT_MANAGE_EDITABLE_COLUMN, FALSE,
606 			-1
607 		);
608 	} else {
609 		gtk_tree_store_set(
610 			model, &type_iter,
611 			DICT_MANAGE_MARKUP_COLUMN, _("<span foreground=\"red\">Scan Dict</span>"),
612 			DICT_MANAGE_AUTHOR_COLUMN, "scandict",
613 			DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
614 			DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)1,
615 			DICT_MANAGE_EDITABLE_COLUMN, FALSE,
616 			-1
617 		);
618 	}
619 	GtkTreeIter dict_iter;
620 	for (std::list<DictManageItem>::iterator i = dictitem.begin(); i != dictitem.end(); ++i) {
621 		if (i->type == LOCAL_DICT) {
622 			DictInfo dictinfo;
623 			if (dictinfo.load_from_ifo_file(i->file_or_id.c_str(),
624 				DictInfoType_NormDict)) {
625 				gchar *markup = g_markup_escape_text(dictinfo.get_bookname().c_str(), dictinfo.get_bookname().length());
626 				gtk_tree_store_append(model, &dict_iter, &type_iter);
627 				gtk_tree_store_set(
628 					model, &dict_iter,
629 					DICT_MANAGE_ENABLE_COLUMN, i->enable,
630 					DICT_MANAGE_MARKUP_COLUMN, markup,
631 					DICT_MANAGE_WORD_COUNT_COLUMN, (glong)dictinfo.get_wordcount(),
632 					DICT_MANAGE_AUTHOR_COLUMN, dictinfo.get_author().c_str(),
633 					DICT_MANAGE_EMAIL_COLUMN, dictinfo.get_email().c_str(),
634 					DICT_MANAGE_WEB_SITE_COLUMN, dictinfo.get_website().c_str(),
635 					DICT_MANAGE_DESCRIPTION_COLUMN, dictinfo.get_description().c_str(),
636 					DICT_MANAGE_DATE_COLUMN, dictinfo.get_date().c_str(),
637 					DICT_MANAGE_ID_COLUMN, i->file_or_id.c_str(),
638 					DICT_MANAGE_SHOW_DETAILS_COLUMN, true,
639 					DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)2,
640 					DICT_MANAGE_EDITABLE_COLUMN, FALSE,
641 					DICT_MANAGE_TYPE_COLUMN, (gint)LOCAL_DICT,
642 					-1
643 				);
644 				g_free(markup);
645 			}
646 		} else if (i->type == VIRTUAL_DICT) {
647 			size_t iPlugin;
648 			if (gpAppFrame->oStarDictPlugins->VirtualDictPlugins.find_dict_by_id(i->file_or_id, iPlugin)) {
649 				const char *dictname = gpAppFrame->oStarDictPlugins->VirtualDictPlugins.dict_name(iPlugin);
650 				gtk_tree_store_append(model, &dict_iter, &type_iter);
651 				gtk_tree_store_set(
652 					model, &dict_iter,
653 					DICT_MANAGE_ENABLE_COLUMN, i->enable,
654 					DICT_MANAGE_MARKUP_COLUMN, dictname,
655 					DICT_MANAGE_WORD_COUNT_COLUMN, (glong)0,
656 					DICT_MANAGE_AUTHOR_COLUMN, "",
657 					DICT_MANAGE_EMAIL_COLUMN, "",
658 					DICT_MANAGE_WEB_SITE_COLUMN, "",
659 					DICT_MANAGE_DESCRIPTION_COLUMN, _("Virtual Dictionary"),
660 					DICT_MANAGE_DATE_COLUMN, "",
661 					DICT_MANAGE_ID_COLUMN, i->file_or_id.c_str(),
662 					DICT_MANAGE_SHOW_DETAILS_COLUMN, true,
663 					DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)2,
664 					DICT_MANAGE_EDITABLE_COLUMN, FALSE,
665 					DICT_MANAGE_TYPE_COLUMN, (gint)VIRTUAL_DICT,
666 					-1
667 				);
668 			}
669 		} else if(i->type == NET_DICT) {
670 			size_t iPlugin;
671 			if (gpAppFrame->oStarDictPlugins->NetDictPlugins.find_dict_by_id(i->file_or_id, iPlugin)) {
672 				const char *dictname = gpAppFrame->oStarDictPlugins->NetDictPlugins.dict_name(iPlugin);
673 				gtk_tree_store_append(model, &dict_iter, &type_iter);
674 				gtk_tree_store_set(
675 					model, &dict_iter,
676 					DICT_MANAGE_ENABLE_COLUMN, i->enable,
677 					DICT_MANAGE_MARKUP_COLUMN, dictname,
678 					DICT_MANAGE_WORD_COUNT_COLUMN, (glong)0,
679 					DICT_MANAGE_AUTHOR_COLUMN, "",
680 					DICT_MANAGE_EMAIL_COLUMN, "",
681 					DICT_MANAGE_WEB_SITE_COLUMN, "",
682 					DICT_MANAGE_DESCRIPTION_COLUMN, _("Network Dictionary"),
683 					DICT_MANAGE_DATE_COLUMN, "",
684 					DICT_MANAGE_ID_COLUMN, i->file_or_id.c_str(),
685 					DICT_MANAGE_SHOW_DETAILS_COLUMN, true,
686 					DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)2,
687 					DICT_MANAGE_EDITABLE_COLUMN, FALSE,
688 					DICT_MANAGE_TYPE_COLUMN, (gint)NET_DICT,
689 					-1
690 				);
691 			}
692 		} else {
693 			g_assert_not_reached();
694 		}
695 	}
696 }
697 
create_dictmanage_tree_model()698 GtkTreeModel* DictManageDlg::create_dictmanage_tree_model()
699 {
700 	GtkTreeStore *model = gtk_tree_store_new(DICT_MANAGE_COLUMN_NUMBER, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_LONG, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT);
701 	GtkTreeIter group_iter;
702 	gchar *markup;
703 	for (std::list<DictManageGroup>::iterator i = gpAppFrame->dictinfo.groups.begin(); i != gpAppFrame->dictinfo.groups.end(); ++i) {
704 		markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", i->name.c_str());
705 		gtk_tree_store_append(model, &group_iter, NULL);
706 		gtk_tree_store_set(
707 			model, &group_iter,
708 			DICT_MANAGE_MARKUP_COLUMN, markup,
709 			DICT_MANAGE_AUTHOR_COLUMN, i->name.c_str(),
710 			DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
711 			DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)0,
712 			DICT_MANAGE_EDITABLE_COLUMN, TRUE,
713 			-1
714 		);
715 		g_free(markup);
716 		create_dict_item_model(model, &group_iter, i->querydict, true);
717 		create_dict_item_model(model, &group_iter, i->scandict, false);
718 	}
719 	return GTK_TREE_MODEL(model);
720 }
721 
722 class GetInfo {
723 public:
724 	/* istreedict_:
725 	 * 		DictInfoType_TreeDict if true
726 	 * 		DictInfoType_NormDict if false
727 	 * */
GetInfo(GtkListStore * model_,bool istreedict_)728 	GetInfo(GtkListStore *model_, bool istreedict_):
729 		model(model_), istreedict(istreedict_) {}
operator ()(const std::string & url,bool disable)730 	void operator()(const std::string& url, bool disable) {
731 		DictInfo dictinfo;
732 		if (dictinfo.load_from_ifo_file(url.c_str(),
733 			istreedict ? DictInfoType_TreeDict : DictInfoType_NormDict)) {
734 			GtkTreeIter iter;
735 			gtk_list_store_append(model, &iter);
736 			if(istreedict) {
737 				gtk_list_store_set(
738 					model, &iter,
739 					TREEDICT_ENABLED_COLUMN, (!disable),
740 					TREEDICT_NAME_COLUMN, dictinfo.get_bookname().c_str(),
741 					TREEDICT_WORD_COUNT_COLUMN, (glong)dictinfo.get_wordcount(),
742 					TREEDICT_AUTHOR_COLUMN, dictinfo.get_author().c_str(),
743 					TREEDICT_EMAIL_COLUMN, dictinfo.get_email().c_str(),
744 					TREEDICT_WEB_SITE_COLUMN, dictinfo.get_website().c_str(),
745 					TREEDICT_DESCRIPTION_COLUMN, dictinfo.get_description().c_str(),
746 					TREEDICT_DATE_COLUMN, dictinfo.get_date().c_str(),
747 					TREEDICT_ID_COLUMN, url.c_str(),
748 					-1
749 				);
750 			} else {
751 				gtk_list_store_set(
752 					model, &iter,
753 					DICTLIST_TYPE_COLUMN, (gint)LOCAL_DICT,
754 					DICTLIST_NAME_COLUMN, dictinfo.get_bookname().c_str(),
755 					DICTLIST_WORD_COUNT_COLUMN, (glong)dictinfo.get_wordcount(),
756 					DICTLIST_AUTHOR_COLUMN, dictinfo.get_author().c_str(),
757 					DICTLIST_EMAIL_COLUMN, dictinfo.get_email().c_str(),
758 					DICTLIST_WEB_SITE_COLUMN, dictinfo.get_website().c_str(),
759 					DICTLIST_DESCRIPTION_COLUMN, dictinfo.get_description().c_str(),
760 					DICTLIST_DATE_COLUMN, dictinfo.get_date().c_str(),
761 					DICTLIST_ID_COLUMN, url.c_str(),
762 					DICTLIST_ID_TYPE_STR_COLUMN, _("Local"),
763 					-1
764 				);
765 			}
766 		}
767 	}
768 private:
769 	GtkListStore *model;
770 	bool istreedict;
771 };
772 
create_tree_model(TDictTree dicttree)773 GtkTreeModel* DictManageDlg::create_tree_model(TDictTree dicttree)
774 {
775 	GtkListStore *model = NULL;
776 	if (dicttree == DictTree_TreeDict) {
777 		model = gtk_list_store_new(TREEDICT_COLUMN_NUMBER,
778 			G_TYPE_BOOLEAN, // 0 - TREEDICT_ENABLED_COLUMN
779 			G_TYPE_STRING, // 1 - TREEDICT_NAME_COLUMN
780 			G_TYPE_LONG, // 2 - TREEDICT_WORD_COUNT_COLUMN
781 			G_TYPE_STRING, // 3 - TREEDICT_AUTHOR_COLUMN
782 			G_TYPE_STRING, // 4 - TREEDICT_EMAIL_COLUMN
783 			G_TYPE_STRING, // 5 - TREEDICT_WEB_SITE_COLUMN
784 			G_TYPE_STRING, // 6 - TREEDICT_DESCRIPTION_COLUMN
785 			G_TYPE_STRING, // 7 - TREEDICT_DATE_COLUMN
786 			G_TYPE_STRING // 8 - TREEDICT_ID_COLUMN
787 		);
788 		const std::list<std::string>& treedict_order_list
789 			= conf->get_strlist("/apps/stardict/manage_dictionaries/treedict_order_list");
790 		const std::list<std::string>& treedict_disable_list
791 			= conf->get_strlist("/apps/stardict/manage_dictionaries/treedict_disable_list");
792 		const std::list<std::string>& treedict_dirs_list
793 			= conf->get_strlist("/apps/stardict/manage_dictionaries/treedict_dirs_list");
794 #ifdef _WIN32
795 		std::list<std::string> treedict_order_list_abs;
796 		std::list<std::string> treedict_disable_list_abs;
797 		std::list<std::string> treedict_dirs_list_abs;
798 		abs_path_to_data_dir(treedict_order_list, treedict_order_list_abs);
799 		abs_path_to_data_dir(treedict_disable_list, treedict_disable_list_abs);
800 		abs_path_to_data_dir(treedict_dirs_list, treedict_dirs_list_abs);
801 		for_each_file(treedict_dirs_list_abs, ".ifo",
802 				treedict_order_list_abs,
803 				treedict_disable_list_abs,
804 				GetInfo(model, true));
805 #else
806 		for_each_file(treedict_dirs_list, ".ifo",
807 				treedict_order_list,
808 				treedict_disable_list,
809 				GetInfo(model, true));
810 #endif
811 	} else if (dicttree == DictTree_DictList) {
812 		model = gtk_list_store_new(DICTLIST_COLUMN_NUMBER,
813 			G_TYPE_INT, // 0 - DICTLIST_TYPE_COLUMN
814 			G_TYPE_STRING, // 1 - DICTLIST_NAME_COLUMN
815 			G_TYPE_LONG,  // 2 - DICTLIST_WORD_COUNT_COLUMN
816 			G_TYPE_STRING, // 3 - DICTLIST_AUTHOR_COLUMN
817 			G_TYPE_STRING, // 4 - DICTLIST_EMAIL_COLUMN
818 			G_TYPE_STRING, // 5 - DICTLIST_WEB_SITE_COLUMN
819 			G_TYPE_STRING, // 6 - DICTLIST_DESCRIPTION_COLUMN
820 			G_TYPE_STRING, // 7 - DICTLIST_DATE_COLUMN
821 			G_TYPE_STRING, // 8 - DICTLIST_ID_COLUMN
822 			G_TYPE_STRING // 9 - DICTLIST_ID_TYPE_STR_COLUMN
823 		);
824 		std::list<std::string> dict_disable_list;
825 #ifdef _WIN32
826 		std::list<std::string> dict_order_list;
827 		std::list<std::string> dict_dirs_list;
828 		{
829 			const std::list<std::string>& dict_order_list_rel
830 				= conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
831 			const std::list<std::string>& dict_dirs_list_rel
832 				= conf->get_strlist("/apps/stardict/manage_dictionaries/dict_dirs_list");
833 			abs_path_to_data_dir(dict_order_list_rel, dict_order_list);
834 			abs_path_to_data_dir(dict_dirs_list_rel, dict_dirs_list);
835 		}
836 #else
837 		const std::list<std::string>& dict_order_list
838 			= conf->get_strlist("/apps/stardict/manage_dictionaries/dict_order_list");
839 		const std::list<std::string>& dict_dirs_list
840 			= conf->get_strlist("/apps/stardict/manage_dictionaries/dict_dirs_list");
841 #endif
842 		for_each_file_restricted(
843 			dict_dirs_list, ".ifo",
844 			dict_order_list,
845 			dict_disable_list, GetInfo(model, false));
846 		size_t n = gpAppFrame->oStarDictPlugins->VirtualDictPlugins.ndicts();
847 		const char *dictname, *dictid;
848 		GtkTreeIter iter;
849 		for (size_t i = 0; i < n; i++) {
850 			dictname = gpAppFrame->oStarDictPlugins->VirtualDictPlugins.dict_name(i);
851 			dictid = gpAppFrame->oStarDictPlugins->VirtualDictPlugins.dict_id(i);
852 			gtk_list_store_append(model, &iter);
853 			gtk_list_store_set(
854 				model, &iter,
855 				DICTLIST_TYPE_COLUMN, (gint)VIRTUAL_DICT,
856 				DICTLIST_NAME_COLUMN, dictname,
857 				DICTLIST_WORD_COUNT_COLUMN, (glong)0,
858 				DICTLIST_AUTHOR_COLUMN, "",
859 				DICTLIST_EMAIL_COLUMN, "",
860 				DICTLIST_WEB_SITE_COLUMN, "",
861 				DICTLIST_DESCRIPTION_COLUMN, _("Virtual Dictionary"),
862 				DICTLIST_DATE_COLUMN, "",
863 				DICTLIST_ID_COLUMN, dictid,
864 				DICTLIST_ID_TYPE_STR_COLUMN, _("Virtual"),
865 				-1
866 			);
867 		}
868 		n = gpAppFrame->oStarDictPlugins->NetDictPlugins.ndicts();
869 		for (size_t i = 0; i < n; i++) {
870 			dictname = gpAppFrame->oStarDictPlugins->NetDictPlugins.dict_name(i);
871 			dictid = gpAppFrame->oStarDictPlugins->NetDictPlugins.dict_id(i);
872 			gtk_list_store_append(model, &iter);
873 			gtk_list_store_set(
874 				model, &iter,
875 				DICTLIST_TYPE_COLUMN, (gint)NET_DICT,
876 				DICTLIST_NAME_COLUMN, dictname,
877 				DICTLIST_WORD_COUNT_COLUMN, (glong)0,
878 				DICTLIST_AUTHOR_COLUMN, "",
879 				DICTLIST_EMAIL_COLUMN, "",
880 				DICTLIST_WEB_SITE_COLUMN, "",
881 				DICTLIST_DESCRIPTION_COLUMN, _("Network Dictionary"),
882 				DICTLIST_DATE_COLUMN, "",
883 				DICTLIST_ID_COLUMN, dictid,
884 				DICTLIST_ID_TYPE_STR_COLUMN, _("Network"),
885 				-1
886 			);
887 		}
888 	} else if(dicttree == DictTree_NetworkDict) {
889 		model = gtk_list_store_new(NETWORKDICT_COLUMN_NUMBER,
890 			G_TYPE_STRING,
891 			G_TYPE_STRING,
892 			G_TYPE_LONG
893 		);
894 	}
895 	return GTK_TREE_MODEL(model);
896 }
897 
on_dictmanage_enable_toggled(GtkCellRendererToggle * cell,gchar * path_str,DictManageDlg * oDictManageDlg)898 void DictManageDlg::on_dictmanage_enable_toggled (GtkCellRendererToggle *cell, gchar *path_str, DictManageDlg *oDictManageDlg)
899 {
900 	GtkTreeModel *model = oDictManageDlg->dictmanage_tree_model;
901 	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
902 	GtkTreeIter iter;
903 	gtk_tree_model_get_iter (model, &iter, path);
904 	gboolean enable;
905 	gtk_tree_model_get (model, &iter, DICT_MANAGE_ENABLE_COLUMN, &enable, -1);
906 	enable = !enable;
907 	gtk_tree_store_set (GTK_TREE_STORE (model), &iter, DICT_MANAGE_ENABLE_COLUMN, enable, -1);
908 	gtk_tree_path_free (path);
909 	oDictManageDlg->dictmanage_config_changed = true;
910 }
911 
on_treedict_enable_toggled(GtkCellRendererToggle * cell,gchar * path_str,DictManageDlg * oDictManageDlg)912 void DictManageDlg::on_treedict_enable_toggled (GtkCellRendererToggle *cell, gchar *path_str, DictManageDlg *oDictManageDlg)
913 {
914 	GtkTreeModel *model = oDictManageDlg->treedict_tree_model;
915 	GtkTreeIter  iter;
916 	GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
917 	gboolean enable;
918 
919 	gtk_tree_model_get_iter (model, &iter, path);
920 	gtk_tree_model_get (model, &iter, TREEDICT_ENABLED_COLUMN, &enable, -1);
921 
922 	enable = !enable;
923 
924 	gtk_list_store_set (GTK_LIST_STORE (model), &iter, TREEDICT_ENABLED_COLUMN, enable, -1);
925 
926 	gtk_tree_path_free (path);
927 
928 	gboolean have_iter;
929 	gchar *filename;
930 	std::list<std::string> disable_list;
931 
932 	have_iter = gtk_tree_model_get_iter_first(model, &iter);
933 	while (have_iter) {
934 		gtk_tree_model_get (model, &iter, TREEDICT_ENABLED_COLUMN, &enable, -1);
935 		if (!enable) {
936 			gtk_tree_model_get (model, &iter, TREEDICT_ID_COLUMN, &filename, -1);
937 			disable_list.push_back(filename);
938 			g_free(filename);
939 		}
940 		have_iter = gtk_tree_model_iter_next(model, &iter);
941 	}
942 #ifdef _WIN32
943 	{
944 		std::list<std::string> disable_list_rel;
945 		rel_path_to_data_dir(disable_list, disable_list_rel);
946 		std::swap(disable_list, disable_list_rel);
947 	}
948 #endif
949 	conf->set_strlist("/apps/stardict/manage_dictionaries/treedict_disable_list", disable_list);
950 }
951 
drag_data_get_cb(GtkWidget * widget,GdkDragContext * ctx,GtkSelectionData * data,guint info,guint time,DictManageDlg * oDictManageDlg)952 void DictManageDlg::drag_data_get_cb(GtkWidget *widget, GdkDragContext *ctx, GtkSelectionData *data, guint info, guint time, DictManageDlg *oDictManageDlg)
953 {
954 	if (gtk_selection_data_get_target(data) == gdk_atom_intern("STARDICT_DICTMANAGE", FALSE)) {
955 		GtkTreeRowReference *ref;
956 		GtkTreePath *source_row;
957 
958 		ref = (GtkTreeRowReference *)g_object_get_data(G_OBJECT(ctx), "gtk-tree-view-source-row");
959 		source_row = gtk_tree_row_reference_get_path(ref);
960 
961 		if (source_row == NULL)
962 			return;
963 
964 		GtkTreeIter iter;
965 		if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button)))
966 			gtk_tree_model_get_iter(oDictManageDlg->dict_list_tree_model, &iter, source_row);
967 		else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->manage_button)))
968 			gtk_tree_model_get_iter(oDictManageDlg->dictmanage_tree_model, &iter, source_row);
969 		else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->tree_dict_button)))
970 			gtk_tree_model_get_iter(oDictManageDlg->treedict_tree_model, &iter, source_row);
971 		else
972 			gtk_tree_model_get_iter(oDictManageDlg->network_tree_model, &iter, source_row);
973 
974 		gtk_selection_data_set(data, gdk_atom_intern("STARDICT_DICTMANAGE", FALSE), 8, (const guchar *)&iter, sizeof(iter));
975 
976 		gtk_tree_path_free(source_row);
977 	}
978 }
979 
dictmanage_drag_data_received_cb(GtkWidget * widget,GdkDragContext * ctx,guint x,guint y,GtkSelectionData * sd,guint info,guint t,DictManageDlg * oDictManageDlg)980 void DictManageDlg::dictmanage_drag_data_received_cb(GtkWidget *widget, GdkDragContext *ctx, guint x, guint y, GtkSelectionData *sd, guint info, guint t, DictManageDlg *oDictManageDlg)
981 {
982 	if (gtk_selection_data_get_target(sd) == gdk_atom_intern("STARDICT_DICTMANAGE", FALSE) && gtk_selection_data_get_data(sd)) {
983 		GtkTreePath *path = NULL;
984 		GtkTreeViewDropPosition position;
985 
986 		GtkTreeIter drag_iter;
987 		memcpy(&drag_iter, gtk_selection_data_get_data(sd), sizeof(drag_iter));
988 
989 		if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
990 
991 			GtkTreeIter drop_iter;
992 
993 			GtkTreeModel *model = oDictManageDlg->dictmanage_tree_model;
994 			gtk_tree_model_get_iter(model, &drop_iter, path);
995 
996 			gint drop_type;
997 			gtk_tree_model_get (model, &drop_iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &drop_type, -1);
998 			gint drag_type;
999 			gtk_tree_model_get (model, &drag_iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &drag_type, -1);
1000 			if (drop_type != drag_type || drop_type == 1) {
1001 				gtk_drag_finish (ctx, FALSE, FALSE, t);
1002 				return;
1003 			}
1004 			if (drop_type == 2) {
1005 				GtkTreeIter drag_parent;
1006 				gtk_tree_model_iter_parent(model, &drag_parent, &drag_iter);
1007 				GtkTreePath* drag_parent_path = gtk_tree_model_get_path(model, &drag_parent);
1008 				GtkTreeIter drop_parent;
1009 				gtk_tree_model_iter_parent(model, &drop_parent, &drop_iter);
1010 				GtkTreePath* drop_parent_path = gtk_tree_model_get_path(model, &drop_parent);
1011 				if (gtk_tree_path_compare(drag_parent_path, drop_parent_path)!=0) {
1012 					gtk_tree_path_free(drag_parent_path);
1013 					gtk_tree_path_free(drop_parent_path);
1014 					gtk_drag_finish (ctx, FALSE, FALSE, t);
1015 					return;
1016 				}
1017 				gtk_tree_path_free(drag_parent_path);
1018 				gtk_tree_path_free(drop_parent_path);
1019 			}
1020 
1021 			switch (position) {
1022 				case GTK_TREE_VIEW_DROP_AFTER:
1023 				case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
1024 					gtk_tree_store_move_after(GTK_TREE_STORE(model), &drag_iter, &drop_iter);
1025 					break;
1026 
1027 				case GTK_TREE_VIEW_DROP_BEFORE:
1028 				case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
1029 					gtk_tree_store_move_before(GTK_TREE_STORE(model), &drag_iter, &drop_iter);
1030 					break;
1031 				default:
1032 					gtk_drag_finish (ctx, FALSE, FALSE, t);
1033 					return;
1034 			}
1035 			oDictManageDlg->dictmanage_config_changed = true;
1036 			gtk_drag_finish (ctx, TRUE, FALSE, t);
1037 		}
1038 	}
1039 }
1040 
drag_data_received_cb(GtkWidget * widget,GdkDragContext * ctx,guint x,guint y,GtkSelectionData * sd,guint info,guint t,DictManageDlg * oDictManageDlg)1041 void DictManageDlg::drag_data_received_cb(GtkWidget *widget, GdkDragContext *ctx, guint x, guint y, GtkSelectionData *sd, guint info, guint t, DictManageDlg *oDictManageDlg)
1042 {
1043 	if (gtk_selection_data_get_target(sd) == gdk_atom_intern("STARDICT_DICTMANAGE", FALSE) && gtk_selection_data_get_data(sd)) {
1044 		GtkTreePath *path = NULL;
1045 		GtkTreeViewDropPosition position;
1046 
1047 		GtkTreeIter drag_iter;
1048 		memcpy(&drag_iter, gtk_selection_data_get_data(sd), sizeof(drag_iter));
1049 
1050 		if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, &path, &position)) {
1051 
1052 			GtkTreeIter iter;
1053 
1054 			GtkTreeModel *model;
1055 			if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button)))
1056 				model = oDictManageDlg->dict_list_tree_model;
1057 			else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->tree_dict_button)))
1058 				model = oDictManageDlg->treedict_tree_model;
1059 			else
1060 				model = oDictManageDlg->network_tree_model;
1061 
1062 			gtk_tree_model_get_iter(model, &iter, path);
1063 
1064 			switch (position) {
1065 				case GTK_TREE_VIEW_DROP_AFTER:
1066 				case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
1067 					gtk_list_store_move_after(GTK_LIST_STORE(model), &drag_iter, &iter);
1068 					break;
1069 
1070 				case GTK_TREE_VIEW_DROP_BEFORE:
1071 				case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
1072 					gtk_list_store_move_before(GTK_LIST_STORE(model), &drag_iter, &iter);
1073 					break;
1074 				default:
1075 					gtk_drag_finish (ctx, FALSE, FALSE, t);
1076 					return;
1077 			}
1078 			if (model == oDictManageDlg->dict_list_tree_model)
1079 				oDictManageDlg->dictmanage_list_changed = true;
1080 			else if (model == oDictManageDlg->network_tree_model)
1081 				oDictManageDlg->network_dictmask_changed = true;
1082 			else
1083 				oDictManageDlg->write_treedict_order_list();
1084 			gtk_drag_finish (ctx, TRUE, FALSE, t);
1085 		}
1086 	}
1087 }
1088 
on_network_treeview_button_press(GtkWidget * widget,GdkEventButton * event,DictManageDlg * oDictManageDlg)1089 gboolean DictManageDlg::on_network_treeview_button_press(GtkWidget * widget, GdkEventButton * event, DictManageDlg *oDictManageDlg)
1090 {
1091 	if (event->type==GDK_2BUTTON_PRESS) {
1092 		GtkTreeModel *model;
1093 		GtkTreeIter iter;
1094 		GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
1095 		if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
1096 			gchar *uid;
1097 			gtk_tree_model_get (model, &iter, NETWORKDICT_ID_COLUMN, &uid, -1);
1098 			STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_DICT_INFO, uid);
1099 			if (!gpAppFrame->oStarDictClient.try_cache(c))
1100 				gpAppFrame->oStarDictClient.send_commands(1, c);
1101 			g_free(uid);
1102 		}
1103 		return true;
1104 	} else {
1105 		return false;
1106 	}
1107 }
1108 
show_dict_info()1109 void DictManageDlg::show_dict_info()
1110 {
1111 	GtkWidget *treeview;
1112 	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) == 0) {
1113 		treeview = dict_list_treeview;
1114 	} else if (gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)) == 1) {
1115 		treeview = dictmanage_treeview;
1116 	} else {
1117 		treeview = treedict_treeview;
1118 	}
1119 	GtkTreeModel *model;
1120 	GtkTreeIter iter;
1121 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1122 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
1123 		if (treeview == dictmanage_treeview) {
1124 			gint type;
1125 			gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
1126 			if (type == 0) {
1127 				GtkWidget *dialog = gtk_message_dialog_new(
1128 					GTK_WINDOW(window),
1129 					GTK_DIALOG_MODAL,
1130 					GTK_MESSAGE_INFO,
1131 					GTK_BUTTONS_OK,
1132 					_("You can have multiple groups of dictionaries, such as \"Study English\", \"Learn German\", and switch them instantly.")
1133 				);
1134 				gtk_dialog_run (GTK_DIALOG (dialog));
1135 				gtk_widget_destroy (dialog);
1136 				return;
1137 			} else if (type == 1) {
1138 				GtkWidget *dialog = gtk_message_dialog_new(
1139 					GTK_WINDOW(window),
1140 					GTK_DIALOG_MODAL,
1141 					GTK_MESSAGE_INFO,
1142 					GTK_BUTTONS_OK,
1143 					_("The Query Dict will show in the main window, the Scan Dict will show in the floating window.")
1144 				);
1145 				gtk_dialog_run (GTK_DIALOG (dialog));
1146 				gtk_widget_destroy (dialog);
1147 				return;
1148 			}
1149 		}
1150 		gchar *dictname, *author, *email, *website, *description, *date, *filename;
1151 		glong wordcount;
1152 		if(treeview == dict_list_treeview) {
1153 			gtk_tree_model_get (
1154 				model, &iter,
1155 				DICTLIST_NAME_COLUMN, &dictname,
1156 				DICTLIST_WORD_COUNT_COLUMN, &wordcount,
1157 				DICTLIST_AUTHOR_COLUMN, &author,
1158 				DICTLIST_EMAIL_COLUMN, &email,
1159 				DICTLIST_WEB_SITE_COLUMN, &website,
1160 				DICTLIST_DESCRIPTION_COLUMN, &description,
1161 				DICTLIST_DATE_COLUMN, &date,
1162 				DICTLIST_ID_COLUMN, &filename,
1163 				-1
1164 			);
1165 		} else if (treeview == treedict_treeview) {
1166 			gtk_tree_model_get (
1167 				model, &iter,
1168 				TREEDICT_NAME_COLUMN, &dictname,
1169 				TREEDICT_WORD_COUNT_COLUMN, &wordcount,
1170 				TREEDICT_AUTHOR_COLUMN, &author,
1171 				TREEDICT_EMAIL_COLUMN, &email,
1172 				TREEDICT_WEB_SITE_COLUMN, &website,
1173 				TREEDICT_DESCRIPTION_COLUMN, &description,
1174 				TREEDICT_DATE_COLUMN, &date,
1175 				TREEDICT_ID_COLUMN, &filename,
1176 				-1
1177 			);
1178 		} else if (treeview == dictmanage_treeview) {
1179 			gtk_tree_model_get (
1180 				model, &iter,
1181 				DICT_MANAGE_MARKUP_COLUMN, &dictname,
1182 				DICT_MANAGE_WORD_COUNT_COLUMN, &wordcount,
1183 				DICT_MANAGE_AUTHOR_COLUMN, &author,
1184 				DICT_MANAGE_EMAIL_COLUMN, &email,
1185 				DICT_MANAGE_WEB_SITE_COLUMN, &website,
1186 				DICT_MANAGE_DESCRIPTION_COLUMN, &description,
1187 				DICT_MANAGE_DATE_COLUMN, &date,
1188 				DICT_MANAGE_ID_COLUMN, &filename,
1189 				-1
1190 			);
1191 		}
1192 		GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Dictionary Information"),
1193 			GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT,
1194 			GTK_STOCK_CLOSE, GTK_RESPONSE_NONE, NULL);
1195 		gtk_window_set_default_size (GTK_WINDOW(dialog), 400, 400);
1196 		GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1197 		gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5);
1198 		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1199 			GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1200 		gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),scrolled_window,TRUE,TRUE,0);
1201 		GtkWidget *label = gtk_label_new(NULL);
1202 		gchar *markup;
1203 		markup = g_markup_printf_escaped (
1204 			"<b>%s:</b> %s\n<b>%s:</b> %ld\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s",
1205 			_("Dictionary Name"), dictname,
1206 			_("Word count"), wordcount,
1207 			_("Author"), author,
1208 			_("Email"), email,
1209 			_("Website"), website,
1210 			_("Description"), description,
1211 			_("Date"), date,
1212 			_("File name"), filename);
1213 		g_free(dictname);
1214 		g_free(author);
1215 		g_free(email);
1216 		g_free(website);
1217 		g_free(description);
1218 		g_free(date);
1219 		g_free(filename);
1220 		gtk_label_set_markup(GTK_LABEL(label), markup);
1221 		g_free (markup);
1222 		gtk_label_set_selectable(GTK_LABEL(label), TRUE);
1223 		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1224 		gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
1225 		gtk_misc_set_alignment(GTK_MISC(label), 0., 0.);
1226 		gtk_misc_set_padding(GTK_MISC(label), 5, 5);
1227 		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), label);
1228 		g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
1229 		gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
1230 		gtk_widget_show_all(dialog);
1231 	}
1232 }
1233 
on_dictlist_treeview_button_press(GtkWidget * widget,GdkEventButton * event,DictManageDlg * oDictManageDlg)1234 gboolean DictManageDlg::on_dictlist_treeview_button_press(GtkWidget * widget, GdkEventButton * event, DictManageDlg *oDictManageDlg)
1235 {
1236 	if (event->type==GDK_2BUTTON_PRESS && event->button == 1) {
1237 		oDictManageDlg->show_dict_info();
1238 		return true;
1239 	} else {
1240 		return false;
1241 	}
1242 }
1243 
on_dicttree_and_manage_treeview_button_press(GtkWidget * widget,GdkEventButton * event,DictManageDlg * oDictManageDlg)1244 gboolean DictManageDlg::on_dicttree_and_manage_treeview_button_press(GtkWidget * widget, GdkEventButton * event, DictManageDlg *oDictManageDlg)
1245 {
1246 	if (event->type==GDK_2BUTTON_PRESS && event->button == 1) {
1247 		oDictManageDlg->show_dict_info();
1248 		return true;
1249 	}else if (event->button == 3) {
1250 		gtk_menu_popup(GTK_MENU(oDictManageDlg->popup_menu), NULL, NULL, NULL, NULL, event->button, event->time);
1251 		return false; //So it can be selected.
1252 	} else {
1253 		return false;
1254 	}
1255 }
1256 
create_dict_tree(TDictTree dicttree)1257 GtkWidget *DictManageDlg::create_dict_tree(TDictTree dicttree)
1258 {
1259 	GtkWidget *sw;
1260 	sw = gtk_scrolled_window_new (NULL, NULL);
1261 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
1262 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1263 				      GTK_POLICY_AUTOMATIC,
1264 				      GTK_POLICY_AUTOMATIC);
1265 
1266 	gtk_widget_set_size_request (sw, 350, 230);
1267 
1268 	GtkTreeModel *now_tree_model = create_tree_model (dicttree);
1269 	if (dicttree == DictTree_DictList)
1270 		dict_list_tree_model = now_tree_model;
1271 	else if (dicttree == DictTree_TreeDict)
1272 		treedict_tree_model = now_tree_model;
1273 	else if(dicttree == DictTree_NetworkDict)
1274 		network_tree_model = now_tree_model;
1275 
1276 	GtkWidget *now_treeview = gtk_tree_view_new_with_model (now_tree_model);
1277 	if (dicttree == DictTree_DictList) {
1278 		g_signal_connect(G_OBJECT(now_treeview), "button_press_event",
1279 			G_CALLBACK(on_dictlist_treeview_button_press), this);
1280 	} else if (dicttree == DictTree_TreeDict) {
1281 		g_signal_connect(G_OBJECT(now_treeview), "button_press_event",
1282 			G_CALLBACK(on_dicttree_and_manage_treeview_button_press), this);
1283 	} else if (dicttree == DictTree_NetworkDict) {
1284 		g_signal_connect(G_OBJECT(now_treeview), "button_press_event",
1285 			G_CALLBACK(on_network_treeview_button_press), this);
1286 	}
1287 	if (dicttree == DictTree_DictList)
1288 		dict_list_treeview = now_treeview;
1289 	else if (dicttree == DictTree_TreeDict)
1290 		treedict_treeview = now_treeview;
1291 	else if (dicttree == DictTree_NetworkDict)
1292 		network_treeview = now_treeview;
1293 	g_object_unref (G_OBJECT (now_tree_model));
1294 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (now_treeview), TRUE);
1295 
1296 	GtkTreeSelection *selection;
1297 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
1298 
1299 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
1300 
1301 	GtkCellRenderer *renderer;
1302 	GtkTreeViewColumn *column;
1303 
1304 	if (dicttree==DictTree_TreeDict) {
1305 		renderer = gtk_cell_renderer_toggle_new ();
1306 		g_signal_connect (renderer, "toggled", G_CALLBACK (on_treedict_enable_toggled), this);
1307 		column = gtk_tree_view_column_new_with_attributes (_("Enable"), renderer, "active", TREEDICT_ENABLED_COLUMN, NULL);
1308 		gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
1309 		gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1310 	}
1311 
1312 	renderer = gtk_cell_renderer_text_new ();
1313 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
1314 	glong store_column;
1315 	if (dicttree == DictTree_DictList)
1316 		store_column = DICTLIST_NAME_COLUMN;
1317 	else if (dicttree == DictTree_TreeDict)
1318 		store_column = TREEDICT_NAME_COLUMN;
1319 	else if (dicttree == DictTree_NetworkDict)
1320 		store_column = NETWORKDICT_NAME_COLUMN;
1321 	column = gtk_tree_view_column_new_with_attributes (_("Dictionary Name"), renderer, "text", store_column, NULL);
1322 	gtk_tree_view_column_set_resizable(column, TRUE);
1323 	gtk_tree_view_column_set_expand(column, TRUE);
1324 	gtk_tree_view_column_set_sort_column_id(column, store_column);
1325 	if(dicttree == DictTree_DictList)
1326 		g_signal_connect(column, "clicked", G_CALLBACK(on_dict_list_dict_name_column_clicked), this);
1327 	else if(dicttree == DictTree_TreeDict)
1328 		g_signal_connect(column, "clicked", G_CALLBACK(on_treedict_dict_name_column_clicked), this);
1329 	else if(dicttree == DictTree_NetworkDict)
1330 		g_signal_connect(column, "clicked", G_CALLBACK(on_network_dict_name_column_clicked), this);
1331 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
1332 
1333 	renderer = gtk_cell_renderer_text_new ();
1334 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
1335 	if (dicttree == DictTree_DictList)
1336 		store_column = DICTLIST_WORD_COUNT_COLUMN;
1337 	else if (dicttree == DictTree_TreeDict)
1338 		store_column = TREEDICT_WORD_COUNT_COLUMN;
1339 	else if (dicttree == DictTree_NetworkDict)
1340 		store_column = NETWORKDICT_WORD_COUNT_COLUMN;
1341 	column = gtk_tree_view_column_new_with_attributes (_("Word count"), renderer, "text", store_column, NULL);
1342 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
1343 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1344 
1345 	if(dicttree == DictTree_DictList)
1346 	{
1347 		renderer = gtk_cell_renderer_text_new ();
1348 		g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
1349 		column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer, "text", DICTLIST_ID_TYPE_STR_COLUMN, NULL);
1350 		gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
1351 		gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1352 	}
1353 
1354 	GtkTargetEntry gte[] = {{(gchar *)"STARDICT_DICTMANAGE", GTK_TARGET_SAME_APP, 0}};
1355 	gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(now_treeview), GDK_BUTTON1_MASK, gte, 1, GDK_ACTION_COPY);
1356 	gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(now_treeview), gte, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
1357 
1358 	g_signal_connect(G_OBJECT(now_treeview), "drag-data-received", G_CALLBACK(drag_data_received_cb), this);
1359 	g_signal_connect(G_OBJECT(now_treeview), "drag-data-get", G_CALLBACK(drag_data_get_cb), this);
1360 
1361 	gtk_container_add (GTK_CONTAINER (sw), now_treeview);
1362 	return sw;
1363 }
1364 
on_group_name_cell_edited(GtkCellRendererText * cell,const gchar * path_string,const gchar * new_text,DictManageDlg * oDictManageDlg)1365 void DictManageDlg::on_group_name_cell_edited(GtkCellRendererText *cell, const gchar *path_string, const gchar *new_text, DictManageDlg *oDictManageDlg)
1366 {
1367 	if (*new_text) {
1368 		GtkTreeModel *model = oDictManageDlg->dictmanage_tree_model;
1369 		GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
1370 		GtkTreeIter iter;
1371 		gtk_tree_model_get_iter (model, &iter, path);
1372 		gchar *markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", new_text);
1373 		gtk_tree_store_set(GTK_TREE_STORE(model), &iter,
1374 			DICT_MANAGE_MARKUP_COLUMN, markup,
1375 			DICT_MANAGE_AUTHOR_COLUMN, new_text,
1376 		-1);
1377 		g_free(markup);
1378 		gtk_tree_path_free (path);
1379 		oDictManageDlg->dictmanage_config_changed = true;
1380 	}
1381 }
1382 
create_dictmanage_tree()1383 GtkWidget *DictManageDlg::create_dictmanage_tree()
1384 {
1385 	GtkWidget *sw;
1386 	sw = gtk_scrolled_window_new (NULL, NULL);
1387 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
1388 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1389 				      GTK_POLICY_AUTOMATIC,
1390 				      GTK_POLICY_AUTOMATIC);
1391 
1392 	gtk_widget_set_size_request (sw, 350, 230);
1393 
1394 	dictmanage_tree_model = create_dictmanage_tree_model ();
1395 
1396 	dictmanage_treeview = gtk_tree_view_new_with_model (dictmanage_tree_model);
1397 	g_signal_connect(G_OBJECT(dictmanage_treeview), "button_press_event",
1398 		G_CALLBACK(on_dicttree_and_manage_treeview_button_press), this);
1399 	g_object_unref (G_OBJECT (dictmanage_tree_model));
1400 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dictmanage_treeview), TRUE);
1401 
1402 	GtkTreeSelection *selection;
1403 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dictmanage_treeview));
1404 
1405 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
1406 
1407 	GtkCellRenderer *renderer;
1408 	GtkTreeViewColumn *column;
1409 
1410 	renderer = gtk_cell_renderer_toggle_new ();
1411 	g_signal_connect (renderer, "toggled", G_CALLBACK (on_dictmanage_enable_toggled), this);
1412 	column = gtk_tree_view_column_new_with_attributes (
1413 		_("Enable"), renderer,
1414 		"active", DICT_MANAGE_ENABLE_COLUMN,
1415 		"visible", DICT_MANAGE_SHOW_DETAILS_COLUMN,
1416 		NULL
1417 	);
1418 	gtk_tree_view_append_column (GTK_TREE_VIEW(dictmanage_treeview), column);
1419 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1420 
1421 	renderer = gtk_cell_renderer_text_new ();
1422 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
1423 	column = gtk_tree_view_column_new_with_attributes (
1424 		_("Dictionary Name"), renderer,
1425 		"markup", DICT_MANAGE_MARKUP_COLUMN,
1426 		"editable", DICT_MANAGE_EDITABLE_COLUMN,
1427 		NULL
1428 	);
1429 	gtk_tree_view_column_set_resizable(column, TRUE);
1430 	gtk_tree_view_column_set_expand(column, TRUE);
1431 	g_signal_connect (renderer, "edited", G_CALLBACK (on_group_name_cell_edited), this);
1432 	gtk_tree_view_append_column (GTK_TREE_VIEW(dictmanage_treeview), column);
1433 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1434 
1435 	renderer = gtk_cell_renderer_text_new ();
1436 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
1437 	column = gtk_tree_view_column_new_with_attributes (
1438 		_("Word count"), renderer,
1439 		"text", DICT_MANAGE_WORD_COUNT_COLUMN,
1440 		"visible", DICT_MANAGE_SHOW_DETAILS_COLUMN,
1441 		NULL
1442 	);
1443 	gtk_tree_view_append_column (GTK_TREE_VIEW(dictmanage_treeview), column);
1444 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
1445 
1446 	GtkTargetEntry gte[] = {{(gchar *)"STARDICT_DICTMANAGE", GTK_TARGET_SAME_APP, 0}};
1447 	gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(dictmanage_treeview), GDK_BUTTON1_MASK, gte, 1, GDK_ACTION_COPY);
1448 	gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(dictmanage_treeview), gte, 1, (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE));
1449 
1450 	g_signal_connect(G_OBJECT(dictmanage_treeview), "drag-data-received", G_CALLBACK(dictmanage_drag_data_received_cb), this);
1451 	g_signal_connect(G_OBJECT(dictmanage_treeview), "drag-data-get", G_CALLBACK(drag_data_get_cb), this);
1452 
1453 	gtk_tree_view_expand_all(GTK_TREE_VIEW (dictmanage_treeview));
1454 	gtk_container_add (GTK_CONTAINER (sw), dictmanage_treeview);
1455 	return sw;
1456 }
1457 
write_treedict_order_list()1458 void DictManageDlg::write_treedict_order_list()
1459 {
1460 	GtkTreeIter iter;
1461 	gboolean have_iter;
1462 	gchar *filename;
1463 	std::list<std::string> order_list;
1464 
1465 	have_iter = gtk_tree_model_get_iter_first(treedict_tree_model, &iter);
1466 	while (have_iter) {
1467 		gtk_tree_model_get (treedict_tree_model, &iter, TREEDICT_ID_COLUMN, &filename, -1);
1468 		order_list.push_back(filename);
1469 		g_free(filename);
1470 		have_iter = gtk_tree_model_iter_next(treedict_tree_model, &iter);
1471 	}
1472 
1473 #ifdef _WIN32
1474 	{
1475 		std::list<std::string> order_list_rel;
1476 		rel_path_to_data_dir(order_list, order_list_rel);
1477 		std::swap(order_list, order_list_rel);
1478 	}
1479 #endif
1480 	conf->set_strlist("/apps/stardict/manage_dictionaries/treedict_order_list", order_list);
1481 }
1482 
ChangeNetworkDictMask()1483 void DictManageDlg::ChangeNetworkDictMask()
1484 {
1485 	GtkTreeIter iter;
1486 	std::string dictmask;
1487 	if (gtk_tree_model_get_iter_first(network_tree_model, &iter)) {
1488 		gchar *uid;
1489 		gtk_tree_model_get (network_tree_model, &iter, NETWORKDICT_ID_COLUMN, &uid, -1);
1490 		dictmask = uid;
1491 		g_free(uid);
1492 		while (gtk_tree_model_iter_next(network_tree_model, &iter)) {
1493 			gtk_tree_model_get (network_tree_model, &iter, NETWORKDICT_ID_COLUMN, &uid, -1);
1494 			dictmask += ' ';
1495 			dictmask += uid;
1496 			g_free(uid);
1497 		}
1498 	}
1499 	STARDICT::Cmd *c = new STARDICT::Cmd(STARDICT::CMD_SET_DICT_MASK, dictmask.c_str());
1500 	gpAppFrame->oStarDictClient.send_commands(1, c);
1501 }
1502 
process_dictmanage_type_iter(GtkTreeModel * model,GtkTreeIter * parent_iter,std::string & configxml)1503 static void process_dictmanage_type_iter(GtkTreeModel *model, GtkTreeIter *parent_iter, std::string &configxml)
1504 {
1505 	GtkTreeIter iter;
1506 	gboolean have_next = gtk_tree_model_iter_children(model, &iter, parent_iter);
1507 	while (have_next) {
1508 		gboolean enable;
1509 		DictManageItemType dicttype;
1510 		gint intdicttype;
1511 		gchar *file;
1512 		gtk_tree_model_get (
1513 			model, &iter,
1514 			DICT_MANAGE_ENABLE_COLUMN, &enable,
1515 			DICT_MANAGE_ID_COLUMN, &file,
1516 			DICT_MANAGE_TYPE_COLUMN, &intdicttype,
1517 			-1
1518 		);
1519 		dicttype = (DictManageItemType)intdicttype;
1520 		if (dicttype == LOCAL_DICT) {
1521 			configxml += "<localdict enable=\"";
1522 			if (enable)
1523 				configxml += "true";
1524 			else
1525 				configxml += "false";
1526 #ifdef _WIN32
1527 			gchar *estr = g_markup_escape_text(rel_path_to_data_dir(file).c_str(), -1);
1528 #else
1529 			gchar *estr = g_markup_escape_text(file, -1);
1530 #endif
1531 			g_free(file);
1532 			configxml += "\" file=\"";
1533 			configxml += estr;
1534 			configxml += "\"/>";
1535 			g_free(estr);
1536 		} else if (dicttype == VIRTUAL_DICT) {
1537 			configxml += "<virtualdict enable=\"";
1538 			if (enable)
1539 				configxml += "true";
1540 			else
1541 				configxml += "false";
1542 #ifdef _WIN32
1543 			gchar *estr = g_markup_escape_text(rel_path_to_data_dir(file).c_str(), -1);
1544 #else
1545 			gchar *estr = g_markup_escape_text(file, -1);
1546 #endif
1547 			g_free(file);
1548 			configxml += "\" id=\"";
1549 			configxml += estr;
1550 			configxml += "\"/>";
1551 			g_free(estr);
1552 		} else if (dicttype == NET_DICT) {
1553 			configxml += "<netdict enable=\"";
1554 			if (enable)
1555 				configxml += "true";
1556 			else
1557 				configxml += "false";
1558 #ifdef _WIN32
1559 			gchar *estr = g_markup_escape_text(rel_path_to_data_dir(file).c_str(), -1);
1560 #else
1561 			gchar *estr = g_markup_escape_text(file, -1);
1562 #endif
1563 			g_free(file);
1564 			configxml += "\" id=\"";
1565 			configxml += estr;
1566 			configxml += "\"/>";
1567 			g_free(estr);
1568 		} else {
1569 			g_assert_not_reached();
1570 		}
1571 		have_next = gtk_tree_model_iter_next(model, &iter);
1572 	}
1573 }
1574 
process_dictmanage_group_iter(GtkTreeModel * model,GtkTreeIter * parent_iter,std::string & configxml)1575 static void process_dictmanage_group_iter(GtkTreeModel *model, GtkTreeIter *parent_iter, std::string &configxml)
1576 {
1577 	GtkTreeIter iter;
1578 	gboolean have_next = gtk_tree_model_iter_children(model, &iter, parent_iter);
1579 	while (have_next) {
1580 		gchar *type_name;
1581 		gtk_tree_model_get (model, &iter, DICT_MANAGE_AUTHOR_COLUMN, &type_name, -1);
1582 		configxml += "<";
1583 		configxml += type_name;
1584 		configxml += ">";
1585 		process_dictmanage_type_iter(model, &iter, configxml);
1586 		configxml += "</";
1587 		configxml += type_name;
1588 		configxml += ">";
1589 		g_free(type_name);
1590 		have_next = gtk_tree_model_iter_next(model, &iter);
1591 	}
1592 }
1593 
SaveDictManageConfig()1594 void DictManageDlg::SaveDictManageConfig()
1595 {
1596 	std::string configxml;
1597 	GtkTreeIter iter;
1598 	gboolean have_next = gtk_tree_model_get_iter_first(dictmanage_tree_model, &iter);
1599 	while (have_next) {
1600 		gchar *groupname;
1601 		gtk_tree_model_get (dictmanage_tree_model, &iter, DICT_MANAGE_AUTHOR_COLUMN, &groupname, -1);
1602 		gchar *estr = g_markup_escape_text(groupname, -1);
1603 		g_free(groupname);
1604 		configxml += "<dictgroup name=\"";
1605 		configxml += estr;
1606 		configxml += "\">";
1607 		g_free(estr);
1608 		process_dictmanage_group_iter(dictmanage_tree_model, &iter, configxml);
1609 		configxml += "</dictgroup>";
1610 		have_next = gtk_tree_model_iter_next(dictmanage_tree_model, &iter);
1611 	}
1612 	conf->set_string("/apps/stardict/manage_dictionaries/dict_config_xml", configxml);
1613 	LoadDictInfo();
1614 }
1615 
SaveDictManageList()1616 void DictManageDlg::SaveDictManageList()
1617 {
1618 	GtkTreeIter iter;
1619 	gboolean have_iter;
1620 	gchar *filename;
1621 	DictManageItemType dicttype;
1622 	std::list<std::string> order_list;
1623 
1624 	have_iter = gtk_tree_model_get_iter_first(dict_list_tree_model, &iter);
1625 	while (have_iter) {
1626 		gint intdicttype;
1627 		gtk_tree_model_get (dict_list_tree_model, &iter, DICTLIST_TYPE_COLUMN, &intdicttype, -1);
1628 		dicttype = (DictManageItemType)intdicttype;
1629 		if (dicttype == LOCAL_DICT) {
1630 			gtk_tree_model_get (dict_list_tree_model, &iter, DICTLIST_ID_COLUMN, &filename, -1);
1631 			order_list.push_back(filename);
1632 			g_free(filename);
1633 		}
1634 		have_iter = gtk_tree_model_iter_next(dict_list_tree_model, &iter);
1635 	}
1636 #ifdef _WIN32
1637 	{
1638 		std::list<std::string> order_list_rel;
1639 		rel_path_to_data_dir(order_list, order_list_rel);
1640 		std::swap(order_list, order_list_rel);
1641 	}
1642 #endif
1643 	conf->set_strlist("/apps/stardict/manage_dictionaries/dict_order_list", order_list);
1644 }
1645 
on_move_top_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)1646 void DictManageDlg::on_move_top_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
1647 {
1648 	gboolean istreedict = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button));
1649 	GtkWidget *now_treeview;
1650 	if (istreedict)
1651 		now_treeview = oDictManageDlg->treedict_treeview;
1652 	else
1653 		now_treeview = oDictManageDlg->dict_list_treeview;
1654 
1655 	GtkTreeSelection *selection;
1656 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
1657 	GtkTreeModel *model;
1658 	GtkTreeIter iter;
1659 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1660 		GtkTreePath* first_path = gtk_tree_path_new_first();
1661 		GtkTreePath* now_path = gtk_tree_model_get_path(model, &iter);
1662 		if (gtk_tree_path_compare(first_path, now_path)!=0) {
1663 			gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, NULL);
1664 
1665 			gtk_tree_selection_select_path(selection, first_path);
1666 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), first_path, NULL, false, 0, 0);
1667 			if (istreedict)
1668 				oDictManageDlg->write_treedict_order_list();
1669 			else
1670 				oDictManageDlg->dictmanage_list_changed = true;
1671 		}
1672 		gtk_tree_path_free(first_path);
1673 		gtk_tree_path_free(now_path);
1674 	}
1675 }
1676 
on_move_bottom_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)1677 void DictManageDlg::on_move_bottom_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
1678 {
1679 	gboolean istreedict = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button));
1680 	GtkWidget *now_treeview;
1681 	if (istreedict)
1682 		now_treeview = oDictManageDlg->treedict_treeview;
1683 	else
1684 		now_treeview = oDictManageDlg->dict_list_treeview;
1685 
1686 	GtkTreeSelection *selection;
1687 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
1688 	GtkTreeModel *model;
1689 	GtkTreeIter iter;
1690 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1691 		GtkTreeIter tmp,last;
1692 		tmp = last = iter;
1693 		while (gtk_tree_model_iter_next(model, &tmp))
1694 			last = tmp;
1695 		GtkTreePath* now_path = gtk_tree_model_get_path(model, &iter);
1696 		GtkTreePath* last_path = gtk_tree_model_get_path(model, &last);
1697 		if (gtk_tree_path_compare(last_path, now_path)!=0) {
1698 			gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &last);
1699 
1700 			gtk_tree_selection_select_path(selection, last_path);
1701 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), last_path, NULL, false, 0, 0);
1702 			if (istreedict)
1703 				oDictManageDlg->write_treedict_order_list();
1704 			else
1705 				oDictManageDlg->dictmanage_list_changed = true;
1706 		}
1707 		gtk_tree_path_free(last_path);
1708 		gtk_tree_path_free(now_path);
1709 	}
1710 }
1711 
on_move_up_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)1712 void DictManageDlg::on_move_up_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
1713 {
1714 	TDictTree dicttree;
1715 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button)))
1716 		dicttree = DictTree_DictList;
1717 	else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->tree_dict_button)))
1718 		dicttree = DictTree_TreeDict;
1719 	else
1720 		dicttree = DictTree_NetworkDict;
1721 	GtkWidget *now_treeview;
1722 	if (dicttree == DictTree_TreeDict)
1723 		now_treeview = oDictManageDlg->treedict_treeview;
1724 	else if (dicttree == DictTree_DictList)
1725 		now_treeview = oDictManageDlg->dict_list_treeview;
1726 	else
1727 		now_treeview = oDictManageDlg->network_treeview;
1728 
1729 	GtkTreeSelection *selection;
1730 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
1731 	GtkTreeModel *model;
1732 	GtkTreeIter iter;
1733 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1734 		GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
1735 		if (gtk_tree_path_prev(path)) {
1736 			GtkTreeIter prev;
1737 			gtk_tree_model_get_iter(model, &prev, path);
1738 			gtk_list_store_swap(GTK_LIST_STORE(model), &iter, &prev);
1739 			gtk_tree_selection_select_path(selection, path);
1740 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), path, NULL, false, 0, 0);
1741 			if (dicttree == DictTree_NetworkDict)
1742 				oDictManageDlg->network_dictmask_changed = true;
1743 			else if (dicttree == DictTree_DictList)
1744 				oDictManageDlg->dictmanage_list_changed = true;
1745 			else
1746 				oDictManageDlg->write_treedict_order_list();
1747 		}
1748 		gtk_tree_path_free(path);
1749 	}
1750 }
1751 
on_move_down_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)1752 void DictManageDlg::on_move_down_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
1753 {
1754 	TDictTree dicttree;
1755 	if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->dict_list_button)))
1756 		dicttree = DictTree_DictList;
1757 	else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oDictManageDlg->tree_dict_button)))
1758 		dicttree = DictTree_TreeDict;
1759 	else
1760 		dicttree = DictTree_NetworkDict;
1761 	GtkWidget *now_treeview;
1762 	if (dicttree == DictTree_TreeDict)
1763 		now_treeview = oDictManageDlg->treedict_treeview;
1764 	else if (dicttree == DictTree_DictList)
1765 		now_treeview = oDictManageDlg->dict_list_treeview;
1766 	else
1767 		now_treeview = oDictManageDlg->network_treeview;
1768 
1769 	GtkTreeSelection *selection;
1770 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
1771 	GtkTreeModel *model;
1772 	GtkTreeIter iter;
1773 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
1774 		GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
1775 		gtk_tree_path_next(path);
1776 		GtkTreeIter next;
1777 		if (gtk_tree_model_get_iter(model, &next, path)) {
1778 			gtk_list_store_swap(GTK_LIST_STORE(model), &iter, &next);
1779 			gtk_tree_selection_select_path(selection, path);
1780 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), path, NULL, false, 0, 0);
1781 			if (dicttree == DictTree_NetworkDict)
1782 				oDictManageDlg->network_dictmask_changed = true;
1783 			else if (dicttree == DictTree_DictList)
1784 				oDictManageDlg->dictmanage_list_changed = true;
1785 			else
1786 				oDictManageDlg->write_treedict_order_list();
1787 		}
1788 		gtk_tree_path_free(path);
1789 	}
1790 }
1791 
show_delete_group_dialog(GtkTreeIter * iter)1792 void DictManageDlg::show_delete_group_dialog(GtkTreeIter *iter)
1793 {
1794 	GtkWidget *dialog = gtk_message_dialog_new(
1795 			GTK_WINDOW(window),
1796 			GTK_DIALOG_MODAL,
1797 			GTK_MESSAGE_QUESTION,
1798 			GTK_BUTTONS_YES_NO,
1799 			_("Are you sure you want to delete this group of dictionaries?")
1800 	);
1801 	gint response = gtk_dialog_run (GTK_DIALOG (dialog));
1802 	if (response == GTK_RESPONSE_YES) {
1803 		gtk_tree_store_remove(GTK_TREE_STORE(dictmanage_tree_model), iter);
1804 		dictmanage_config_changed = true;
1805 	}
1806 	gtk_widget_destroy (dialog);
1807 }
1808 
show_delete_subgroup_dialog(GtkTreeIter * first)1809 void DictManageDlg::show_delete_subgroup_dialog(GtkTreeIter *first)
1810 {
1811 	GtkWidget *dialog = gtk_message_dialog_new(
1812 			GTK_WINDOW(window),
1813 			GTK_DIALOG_MODAL,
1814 			GTK_MESSAGE_QUESTION,
1815 			GTK_BUTTONS_YES_NO,
1816 			_("Are you sure you want to delete this sub-group of dictionaries?")
1817 	);
1818 	gint response = gtk_dialog_run (GTK_DIALOG (dialog));
1819 	if (response == GTK_RESPONSE_YES) {
1820 		while (true) {
1821 			if (!gtk_tree_store_remove(GTK_TREE_STORE(dictmanage_tree_model), first))
1822 				break;
1823 		}
1824 		dictmanage_config_changed = true;
1825 	}
1826 	gtk_widget_destroy (dialog);
1827 }
1828 
on_add_group_entry_activated(GtkEntry * entry,GtkDialog * dialog)1829 static void on_add_group_entry_activated(GtkEntry *entry, GtkDialog *dialog)
1830 {
1831 	gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT);
1832 }
1833 
show_add_group_dialog(GtkTreeIter * sibling)1834 void DictManageDlg::show_add_group_dialog(GtkTreeIter *sibling)
1835 {
1836 	GtkWidget *dialog = gtk_dialog_new_with_buttons(_("New dict group"), GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
1837 #if GTK_MAJOR_VERSION >= 3
1838 	GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
1839 #else
1840 	GtkWidget *hbox = gtk_hbox_new(false, 5);
1841 #endif
1842 	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),hbox,false,false,0);
1843 	GtkWidget *label = gtk_label_new(_("Group name:"));
1844 	gtk_box_pack_start(GTK_BOX(hbox),label,false,false,0);
1845 	GtkWidget *entry = gtk_entry_new();
1846 	g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(on_add_group_entry_activated), dialog);
1847 	gtk_box_pack_start(GTK_BOX(hbox),entry,false,false,0);
1848 	gtk_widget_show_all(hbox);
1849 	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1850 		const char *name = gtk_entry_get_text(GTK_ENTRY(entry));
1851 		if (name[0] != '\0') {
1852 			GtkTreeIter group_iter;
1853 			GtkTreeStore *model = GTK_TREE_STORE(dictmanage_tree_model);
1854 			gtk_tree_store_insert_after(model, &group_iter, NULL, sibling);
1855 			gchar *markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", name);
1856 			gtk_tree_store_set(
1857 				model, &group_iter,
1858 				DICT_MANAGE_MARKUP_COLUMN, markup,
1859 				DICT_MANAGE_AUTHOR_COLUMN, name,
1860 				DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
1861 				DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)0,
1862 				DICT_MANAGE_EDITABLE_COLUMN, TRUE,
1863 				-1
1864 			);
1865 			g_free(markup);
1866 			GtkTreeIter type_iter;
1867 			gtk_tree_store_append(model, &type_iter, &group_iter);
1868 			gtk_tree_store_set(
1869 				model, &type_iter,
1870 				DICT_MANAGE_MARKUP_COLUMN, _("<span foreground=\"red\">Query Dict</span>"),
1871 				DICT_MANAGE_AUTHOR_COLUMN, "querydict",
1872 				DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
1873 				DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)1,
1874 				DICT_MANAGE_EDITABLE_COLUMN, FALSE,
1875 				-1
1876 			);
1877 			gtk_tree_store_append(model, &type_iter, &group_iter);
1878 			gtk_tree_store_set(
1879 				model, &type_iter,
1880 				DICT_MANAGE_MARKUP_COLUMN, _("<span foreground=\"red\">Scan Dict</span>"),
1881 				DICT_MANAGE_AUTHOR_COLUMN, "scandict",
1882 				DICT_MANAGE_SHOW_DETAILS_COLUMN, false,
1883 				DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)1,
1884 				DICT_MANAGE_EDITABLE_COLUMN, FALSE,
1885 				-1
1886 			);
1887 			dictmanage_config_changed = true;
1888 		}
1889 	}
1890 	gtk_widget_destroy(dialog);
1891 }
1892 
on_add_dict_dialog_treeview_button_press(GtkWidget * widget,GdkEventButton * event,GtkDialog * dialog)1893 static gboolean on_add_dict_dialog_treeview_button_press(GtkWidget * widget, GdkEventButton * event, GtkDialog *dialog)
1894 {
1895 	if (event->type==GDK_2BUTTON_PRESS && event->button == 1) {
1896 		gtk_dialog_response(dialog, GTK_RESPONSE_ACCEPT);
1897 		return true;
1898 	}
1899 	return false;
1900 }
1901 
show_add_dict_dialog(GtkTreeIter * parent_iter)1902 void DictManageDlg::show_add_dict_dialog(GtkTreeIter *parent_iter)
1903 {
1904 	GtkWidget *dialog = gtk_dialog_new_with_buttons(
1905 		_("Add dictionary"),
1906 		GTK_WINDOW(window),
1907 		GTK_DIALOG_MODAL,
1908 		GTK_STOCK_OK,
1909 		GTK_RESPONSE_ACCEPT,
1910 		GTK_STOCK_CANCEL,
1911 		GTK_RESPONSE_REJECT,
1912 		NULL
1913 	);
1914 #if GTK_MAJOR_VERSION >= 3
1915 	GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
1916 #else
1917 	GtkWidget *vbox = gtk_vbox_new(false, 5);
1918 #endif
1919 	gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),vbox,TRUE,TRUE,0);
1920 	GtkWidget *sw;
1921 	sw = gtk_scrolled_window_new (NULL, NULL);
1922 	gtk_box_pack_start(GTK_BOX(vbox),sw,TRUE,TRUE,0);
1923 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
1924 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1925 	gtk_widget_set_size_request (sw, 350, 230);
1926 	GtkListStore *now_tree_model = gtk_list_store_new(
1927 		ADD_DICT_COLUMN_NUMBER,
1928 		G_TYPE_INT,
1929 		G_TYPE_STRING,
1930 		G_TYPE_LONG,
1931 		G_TYPE_STRING,
1932 		G_TYPE_STRING,
1933 		G_TYPE_STRING,
1934 		G_TYPE_STRING,
1935 		G_TYPE_STRING,
1936 		G_TYPE_STRING,
1937 		G_TYPE_STRING
1938 	);
1939 	std::list<std::string> added_dictlist;
1940 	GtkTreeIter iter;
1941 	gboolean have_next = gtk_tree_model_iter_children(dictmanage_tree_model, &iter, parent_iter);
1942 	while (have_next) {
1943 		gchar *file;
1944 		gtk_tree_model_get (dictmanage_tree_model, &iter, DICT_MANAGE_ID_COLUMN, &file, -1);
1945 		added_dictlist.push_back(file);
1946 		g_free(file);
1947 		have_next = gtk_tree_model_iter_next(dictmanage_tree_model, &iter);
1948 	}
1949 	have_next = gtk_tree_model_get_iter_first(dict_list_tree_model, &iter);
1950 	while (have_next) {
1951 		gchar *file;
1952 		gtk_tree_model_get (dict_list_tree_model, &iter, DICTLIST_ID_COLUMN, &file, -1);
1953 		bool added = false;
1954 		for (std::list<std::string>::iterator i = added_dictlist.begin(); i != added_dictlist.end(); ++i) {
1955 			if (*i == file) {
1956 				added = true;
1957 				break;
1958 			}
1959 		}
1960 		if (!added) {
1961 			DictManageItemType dicttype;
1962 			gint intdicttype;
1963 			gchar *bookname, *author, *email, *website, *description, *date, *type_str;
1964 			glong wordcount;
1965 			gtk_tree_model_get (
1966 				dict_list_tree_model, &iter,
1967 				DICTLIST_TYPE_COLUMN, &intdicttype,
1968 				DICTLIST_NAME_COLUMN, &bookname,
1969 				DICTLIST_WORD_COUNT_COLUMN, &wordcount,
1970 				DICTLIST_AUTHOR_COLUMN, &author,
1971 				DICTLIST_EMAIL_COLUMN, &email,
1972 				DICTLIST_WEB_SITE_COLUMN, &website,
1973 				DICTLIST_DESCRIPTION_COLUMN, &description,
1974 				DICTLIST_DATE_COLUMN, &date,
1975 				DICTLIST_ID_TYPE_STR_COLUMN, &type_str,
1976 				-1
1977 			);
1978 			dicttype = (DictManageItemType)intdicttype;
1979 			GtkTreeIter new_iter;
1980 			gtk_list_store_append(now_tree_model, &new_iter);
1981 			gtk_list_store_set(
1982 				now_tree_model, &new_iter,
1983 				ADD_DICT_TYPE_COLUMN, (gint)dicttype,
1984 				ADD_DICT_NAME_COLUMN, bookname,
1985 				ADD_DICT_WORD_COUNT_COLUMN, wordcount,
1986 				ADD_DICT_AUTHOR_COLUMN, author,
1987 				ADD_DICT_EMAIL_COLUMN, email,
1988 				ADD_DICT_WEB_SITE_COLUMN, website,
1989 				ADD_DICT_DESCRIPTION_COLUMN, description,
1990 				ADD_DICT_DATE_COLUMN, date,
1991 				ADD_DICT_ID_COLUMN, file,
1992 				ADD_DICT_TYPE_STR_COLUMN, type_str,
1993 				-1
1994 			);
1995 			g_free(bookname);
1996 			g_free(author);
1997 			g_free(email);
1998 			g_free(website);
1999 			g_free(description);
2000 			g_free(date);
2001 			g_free(type_str);
2002 		}
2003 		g_free(file);
2004 		have_next = gtk_tree_model_iter_next(dict_list_tree_model, &iter);
2005 	}
2006 	GtkWidget *now_treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(now_tree_model));
2007 	g_object_unref (G_OBJECT (now_tree_model));
2008 	g_signal_connect (G_OBJECT (now_treeview), "button_press_event", G_CALLBACK (on_add_dict_dialog_treeview_button_press), dialog);
2009 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (now_treeview), TRUE);
2010 	GtkTreeSelection *selection;
2011 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2012 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
2013 	GtkCellRenderer *renderer;
2014 	GtkTreeViewColumn *column;
2015 
2016 	renderer = gtk_cell_renderer_text_new ();
2017 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
2018 	column = gtk_tree_view_column_new_with_attributes (_("Dictionary Name"), renderer, "text", ADD_DICT_NAME_COLUMN, NULL);
2019 	gtk_tree_view_column_set_resizable(column, TRUE);
2020 	gtk_tree_view_column_set_expand(column, TRUE);
2021 	gtk_tree_view_column_set_sort_column_id(column, ADD_DICT_NAME_COLUMN);
2022 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
2023 
2024 	renderer = gtk_cell_renderer_text_new ();
2025 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
2026 	column = gtk_tree_view_column_new_with_attributes (_("Word count"), renderer, "text", ADD_DICT_WORD_COUNT_COLUMN, NULL);
2027 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
2028 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
2029 
2030 	renderer = gtk_cell_renderer_text_new ();
2031 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
2032 	column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer, "text", ADD_DICT_TYPE_STR_COLUMN, NULL);
2033 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
2034 	gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), FALSE);
2035 
2036 	renderer = gtk_cell_renderer_text_new ();
2037 	g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
2038 	column = gtk_tree_view_column_new_with_attributes (_("Path"), renderer, "text", ADD_DICT_ID_COLUMN, NULL);
2039 	gtk_tree_view_column_set_resizable(column, TRUE);
2040 	gtk_tree_view_column_set_expand(column, TRUE);
2041 	gtk_tree_view_column_set_sort_column_id(column, ADD_DICT_ID_COLUMN);
2042 	gtk_tree_view_column_set_reorderable(column, TRUE);
2043 	gtk_tree_view_append_column (GTK_TREE_VIEW(now_treeview), column);
2044 
2045 	gtk_container_add (GTK_CONTAINER (sw), now_treeview);
2046 	gtk_widget_show_all(vbox);
2047 	gint response = gtk_dialog_run(GTK_DIALOG(dialog));
2048 	if (response == GTK_RESPONSE_ACCEPT) {
2049 		GList *selectlist = gtk_tree_selection_get_selected_rows(selection, NULL);
2050 		if (selectlist) {
2051 			GList *list = selectlist;
2052 			GtkTreeIter select_iter;
2053 			while (list) {
2054 				gtk_tree_model_get_iter(GTK_TREE_MODEL(now_tree_model), &select_iter, (GtkTreePath *)(list->data));
2055 				DictManageItemType dicttype;
2056 				gint intdicttype;
2057 				gchar *bookname, *author, *email, *website, *description, *date, *file;
2058 				glong wordcount;
2059 				gtk_tree_model_get (
2060 					GTK_TREE_MODEL(now_tree_model), &select_iter,
2061 					ADD_DICT_TYPE_COLUMN, &intdicttype,
2062 					ADD_DICT_NAME_COLUMN, &bookname,
2063 					ADD_DICT_WORD_COUNT_COLUMN, &wordcount,
2064 					ADD_DICT_AUTHOR_COLUMN, &author,
2065 					ADD_DICT_EMAIL_COLUMN, &email,
2066 					ADD_DICT_WEB_SITE_COLUMN, &website,
2067 					ADD_DICT_DESCRIPTION_COLUMN, &description,
2068 					ADD_DICT_DATE_COLUMN, &date,
2069 					ADD_DICT_ID_COLUMN, &file,
2070 					-1
2071 				);
2072 				dicttype = (DictManageItemType)intdicttype;
2073 				GtkTreeIter new_iter;
2074 				gtk_tree_store_insert_before(GTK_TREE_STORE(dictmanage_tree_model), &new_iter, parent_iter, NULL);
2075 				gtk_tree_store_set(
2076 					GTK_TREE_STORE(dictmanage_tree_model), &new_iter,
2077 					DICT_MANAGE_ENABLE_COLUMN, TRUE,
2078 					DICT_MANAGE_MARKUP_COLUMN, bookname,
2079 					DICT_MANAGE_WORD_COUNT_COLUMN, wordcount,
2080 					DICT_MANAGE_AUTHOR_COLUMN, author,
2081 					DICT_MANAGE_EMAIL_COLUMN, email,
2082 					DICT_MANAGE_WEB_SITE_COLUMN, website,
2083 					DICT_MANAGE_DESCRIPTION_COLUMN, description,
2084 					DICT_MANAGE_DATE_COLUMN, date,
2085 					DICT_MANAGE_ID_COLUMN, file,
2086 					DICT_MANAGE_SHOW_DETAILS_COLUMN, true,
2087 					DICT_MANAGE_ROW_LEVEL_COLUMN, (gint)2,
2088 					DICT_MANAGE_EDITABLE_COLUMN, FALSE,
2089 					DICT_MANAGE_TYPE_COLUMN, (gint)dicttype,
2090 					-1
2091 				);
2092 				g_free(bookname);
2093 				g_free(author);
2094 				g_free(email);
2095 				g_free(website);
2096 				g_free(description);
2097 				g_free(date);
2098 				g_free(file);
2099 				list = list->next;
2100 			}
2101 			g_list_foreach (selectlist, (GFunc)gtk_tree_path_free, NULL);
2102 			g_list_free (selectlist);
2103 			dictmanage_config_changed = true;
2104 		}
2105 	}
2106 	gtk_widget_destroy(dialog);
2107 }
2108 
on_dictmanage_add_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2109 void DictManageDlg::on_dictmanage_add_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2110 {
2111 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (oDictManageDlg->dictmanage_treeview));
2112 	GtkTreeModel *model;
2113 	GtkTreeIter iter;
2114 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
2115 		gint type;
2116 		gtk_tree_model_get (
2117 			oDictManageDlg->dictmanage_tree_model, &iter,
2118 			DICT_MANAGE_ROW_LEVEL_COLUMN, &type,
2119 			-1
2120 		);
2121 		if (type == 0) {
2122 			oDictManageDlg->show_add_group_dialog(&iter);
2123 		} else if (type == 1) {
2124 			oDictManageDlg->show_add_dict_dialog(&iter);
2125 		} else {
2126 			GtkTreeIter parent_iter;
2127 			if (gtk_tree_model_iter_parent(oDictManageDlg->dictmanage_tree_model, &parent_iter, &iter))
2128 				oDictManageDlg->show_add_dict_dialog(&parent_iter);
2129 		}
2130 	}
2131 }
2132 
on_dictmanage_delete_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2133 void DictManageDlg::on_dictmanage_delete_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2134 {
2135 	GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (oDictManageDlg->dictmanage_treeview));
2136 	GtkTreeModel *model;
2137 	GtkTreeIter iter;
2138 	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
2139 		gint type;
2140 		gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2141 		if (type == 0) {
2142 			if (gtk_tree_model_iter_n_children(model, NULL) > 1)
2143 				oDictManageDlg->show_delete_group_dialog(&iter);
2144 		} else if (type == 1) {
2145 			GtkTreeIter first;
2146 			if (gtk_tree_model_iter_children(model, &first, &iter)) {
2147 				oDictManageDlg->show_delete_subgroup_dialog(&first);
2148 			}
2149 		} else if (type == 2) {
2150 			gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
2151 			oDictManageDlg->dictmanage_config_changed = true;
2152 		}
2153 	}
2154 }
2155 
on_dictmanage_info_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2156 void DictManageDlg::on_dictmanage_info_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2157 {
2158 	oDictManageDlg->show_dict_info();
2159 }
2160 
on_dictmanage_move_top_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2161 void DictManageDlg::on_dictmanage_move_top_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2162 {
2163 	GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2164 	GtkTreeSelection *selection;
2165 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2166 	GtkTreeModel *model;
2167 	GtkTreeIter iter;
2168 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2169 		gint type;
2170 		gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2171 		if (type == 1)
2172 			return;
2173 		GtkTreePath* now_path = gtk_tree_model_get_path(model, &iter);
2174 		GtkTreePath* first_path;
2175 		if (type == 0) {
2176 			first_path = gtk_tree_path_new_first();
2177 		} else {
2178 			GtkTreeIter parent;
2179 			gtk_tree_model_iter_parent(model, &parent, &iter);
2180 			GtkTreeIter first;
2181 			gtk_tree_model_iter_children(model, &first, &parent);
2182 			first_path = gtk_tree_model_get_path(model, &first);
2183 		}
2184 		if (gtk_tree_path_compare(first_path, now_path)!=0) {
2185 			gtk_tree_store_move_after(GTK_TREE_STORE(model), &iter, NULL);
2186 			gtk_tree_selection_select_path(selection, first_path);
2187 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), first_path, NULL, false, 0, 0);
2188 			oDictManageDlg->dictmanage_config_changed = true;
2189 		}
2190 		gtk_tree_path_free(first_path);
2191 		gtk_tree_path_free(now_path);
2192 	}
2193 }
2194 
on_dictmanage_move_bottom_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2195 void DictManageDlg::on_dictmanage_move_bottom_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2196 {
2197 	GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2198 	GtkTreeSelection *selection;
2199 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2200 	GtkTreeModel *model;
2201 	GtkTreeIter iter;
2202 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2203 		gint type;
2204 		gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2205 		if (type == 1)
2206 			return;
2207 		GtkTreePath* now_path = gtk_tree_model_get_path(model, &iter);
2208 		GtkTreePath* last_path;
2209 		GtkTreeIter last;
2210 		if (type == 0) {
2211 			gint n = gtk_tree_model_iter_n_children(model, NULL);
2212 			gtk_tree_model_iter_nth_child(model, &last, NULL, n-1);
2213 		} else {
2214 			GtkTreeIter parent;
2215 			gtk_tree_model_iter_parent(model, &parent, &iter);
2216 			gint n = gtk_tree_model_iter_n_children(model, &parent);
2217 			gtk_tree_model_iter_nth_child(model, &last, &parent, n-1);
2218 		}
2219 		last_path = gtk_tree_model_get_path(model, &last);
2220 		if (gtk_tree_path_compare(last_path, now_path)!=0) {
2221 			gtk_tree_store_move_after(GTK_TREE_STORE(model), &iter, &last);
2222 			gtk_tree_selection_select_path(selection, last_path);
2223 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), last_path, NULL, false, 0, 0);
2224 			oDictManageDlg->dictmanage_config_changed = true;
2225 		}
2226 		gtk_tree_path_free(last_path);
2227 		gtk_tree_path_free(now_path);
2228 	}
2229 }
2230 
on_dictmanage_move_up_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2231 void DictManageDlg::on_dictmanage_move_up_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2232 {
2233 	GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2234 	GtkTreeSelection *selection;
2235 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2236 	GtkTreeModel *model;
2237 	GtkTreeIter iter;
2238 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2239 		gint type;
2240 		gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2241 		if (type == 1)
2242 			return;
2243 		GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
2244 		if (gtk_tree_path_prev(path)) {
2245 			GtkTreeIter prev;
2246 			gtk_tree_model_get_iter(model, &prev, path);
2247 			gtk_tree_store_swap(GTK_TREE_STORE(model), &iter, &prev);
2248 			gtk_tree_selection_select_path(selection, path);
2249 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), path, NULL, false, 0, 0);
2250 			oDictManageDlg->dictmanage_config_changed = true;
2251 		}
2252 		gtk_tree_path_free(path);
2253 	}
2254 }
2255 
on_dictmanage_move_down_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2256 void DictManageDlg::on_dictmanage_move_down_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2257 {
2258 	GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2259 	GtkTreeSelection *selection;
2260 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2261 	GtkTreeModel *model;
2262 	GtkTreeIter iter;
2263 	if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2264 		gint type;
2265 		gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2266 		if (type == 1)
2267 			return;
2268 		GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
2269 		gtk_tree_path_next(path);
2270 		GtkTreeIter next;
2271 		if (gtk_tree_model_get_iter(model, &next, path)) {
2272 			gtk_tree_store_swap(GTK_TREE_STORE(model), &iter, &next);
2273 			gtk_tree_selection_select_path(selection, path);
2274 			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (now_treeview), path, NULL, false, 0, 0);
2275 			oDictManageDlg->dictmanage_config_changed = true;
2276 		}
2277 		gtk_tree_path_free(path);
2278 	}
2279 }
2280 
on_network_add_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2281 void DictManageDlg::on_network_add_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2282 {
2283 	if (oDictManageDlg->network_add_dlg)
2284 		return;
2285 	oDictManageDlg->network_add_dlg = new NetworkAddDlg(oDictManageDlg);
2286 	oDictManageDlg->network_add_dlg->Show(GTK_WINDOW(oDictManageDlg->window));
2287 	delete oDictManageDlg->network_add_dlg;
2288 	oDictManageDlg->network_add_dlg = NULL;
2289 }
2290 
on_network_remove_button_clicked(GtkWidget * widget,DictManageDlg * oDictManageDlg)2291 void DictManageDlg::on_network_remove_button_clicked(GtkWidget *widget, DictManageDlg *oDictManageDlg)
2292 {
2293 	GtkTreeSelection *selection;
2294 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (oDictManageDlg->network_treeview));
2295 	GtkTreeIter iter;
2296 	if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
2297 		gtk_list_store_remove(GTK_LIST_STORE(oDictManageDlg->network_tree_model), &iter);
2298 		oDictManageDlg->network_dictmask_changed = true;
2299 	}
2300 }
2301 
on_popup_menu_show_info_activate(GtkMenuItem * menuitem,DictManageDlg * oDictManageDlg)2302 void DictManageDlg::on_popup_menu_show_info_activate(GtkMenuItem *menuitem, DictManageDlg *oDictManageDlg)
2303 {
2304 	oDictManageDlg->show_dict_info();
2305 }
2306 
on_popup_menu_select_all_activate(GtkMenuItem * menuitem,DictManageDlg * oDictManageDlg)2307 void DictManageDlg::on_popup_menu_select_all_activate(GtkMenuItem *menuitem, DictManageDlg *oDictManageDlg)
2308 {
2309 	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook)) == 1) {
2310 		GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2311 		GtkTreeSelection *selection;
2312 		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2313 		GtkTreeModel *model;
2314 		GtkTreeIter iter;
2315 		if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2316 			gint type;
2317 			gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2318 			if (type == 0)
2319 				return;
2320 			GtkTreeIter first;
2321 			if (type == 1) {
2322 				if (!gtk_tree_model_iter_children(model, &first, &iter))
2323 					return;
2324 			} else {
2325 				GtkTreeIter parent;
2326 				gtk_tree_model_iter_parent(model, &parent, &iter);
2327 				gtk_tree_model_iter_children(model, &first, &parent);
2328 			}
2329 			gboolean have_iter = true;
2330 			while (have_iter) {
2331 				gtk_tree_store_set (GTK_TREE_STORE (model), &first, DICT_MANAGE_ENABLE_COLUMN, TRUE, -1);
2332 				have_iter = gtk_tree_model_iter_next(model, &first);
2333 			}
2334 			oDictManageDlg->dictmanage_config_changed = true;
2335 		}
2336 	} else if (gtk_notebook_get_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook)) == 2) {
2337 		GtkTreeModel *model = oDictManageDlg->treedict_tree_model;
2338 		gboolean have_iter;
2339 		GtkTreeIter iter;
2340 		have_iter = gtk_tree_model_get_iter_first(model, &iter);
2341 		while (have_iter) {
2342 			gtk_list_store_set (GTK_LIST_STORE (model), &iter, TREEDICT_ENABLED_COLUMN, TRUE, -1);
2343 			have_iter = gtk_tree_model_iter_next(model, &iter);
2344 		}
2345 		std::list<std::string> disable_list;
2346 		conf->set_strlist("/apps/stardict/manage_dictionaries/treedict_disable_list", disable_list);
2347 	}
2348 }
2349 
on_popup_menu_unselect_all_activate(GtkMenuItem * menuitem,DictManageDlg * oDictManageDlg)2350 void DictManageDlg::on_popup_menu_unselect_all_activate(GtkMenuItem *menuitem, DictManageDlg *oDictManageDlg)
2351 {
2352 	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook)) == 1) {
2353 		GtkWidget *now_treeview = oDictManageDlg->dictmanage_treeview;
2354 		GtkTreeSelection *selection;
2355 		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (now_treeview));
2356 		GtkTreeModel *model;
2357 		GtkTreeIter iter;
2358 		if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
2359 			gint type;
2360 			gtk_tree_model_get (model, &iter, DICT_MANAGE_ROW_LEVEL_COLUMN, &type, -1);
2361 			if (type == 0)
2362 				return;
2363 			GtkTreeIter first;
2364 			if (type == 1) {
2365 				if (!gtk_tree_model_iter_children(model, &first, &iter))
2366 					return;
2367 			} else {
2368 				GtkTreeIter parent;
2369 				gtk_tree_model_iter_parent(model, &parent, &iter);
2370 				gtk_tree_model_iter_children(model, &first, &parent);
2371 			}
2372 			gboolean have_iter = true;
2373 			while (have_iter) {
2374 				gtk_tree_store_set (GTK_TREE_STORE (model), &first, DICT_MANAGE_ENABLE_COLUMN, FALSE, -1);
2375 				have_iter = gtk_tree_model_iter_next(model, &first);
2376 			}
2377 			oDictManageDlg->dictmanage_config_changed = true;
2378 		}
2379 	} else if (gtk_notebook_get_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook)) == 2) {
2380 		GtkTreeModel *model = oDictManageDlg->treedict_tree_model;
2381 		gboolean have_iter;
2382 		GtkTreeIter iter;
2383 		have_iter = gtk_tree_model_get_iter_first(model, &iter);
2384 		gchar *filename;
2385 		std::list<std::string> disable_list;
2386 		while (have_iter) {
2387 			gtk_list_store_set (GTK_LIST_STORE (model), &iter, TREEDICT_ENABLED_COLUMN, FALSE, -1);
2388 			gtk_tree_model_get (model, &iter, TREEDICT_ID_COLUMN, &filename, -1);
2389 			disable_list.push_back(filename);
2390 			g_free(filename);
2391 			have_iter = gtk_tree_model_iter_next(model, &iter);
2392 		}
2393 #ifdef _WIN32
2394 		{
2395 			std::list<std::string> disable_list_rel;
2396 			rel_path_to_data_dir(disable_list, disable_list_rel);
2397 			std::swap(disable_list, disable_list_rel);
2398 		}
2399 #endif
2400 		conf->set_strlist("/apps/stardict/manage_dictionaries/treedict_disable_list", disable_list);
2401 	}
2402 }
2403 
create_buttons()2404 GtkWidget *DictManageDlg::create_buttons()
2405 {
2406 	GtkWidget *vbox;
2407 #ifdef CONFIG_GPE
2408 #if GTK_MAJOR_VERSION >= 3
2409 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
2410 #else
2411 	vbox = gtk_vbox_new(false,2);
2412 #endif
2413 #else
2414 #if GTK_MAJOR_VERSION >= 3
2415 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
2416 #else
2417 	vbox = gtk_vbox_new(false,6);
2418 #endif
2419 #endif
2420 	GtkWidget *button;
2421 	button = gtk_button_new_from_stock(GTK_STOCK_GOTO_TOP);
2422 	gtk_widget_set_can_focus (button, FALSE);
2423 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_top_button_clicked), this);
2424 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2425 	button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
2426 	gtk_widget_set_can_focus (button, FALSE);
2427 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_up_button_clicked), this);
2428 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2429 	button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
2430 	gtk_widget_set_can_focus (button, FALSE);
2431 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_down_button_clicked), this);
2432 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2433 	button = gtk_button_new_from_stock(GTK_STOCK_GOTO_BOTTOM);
2434 	gtk_widget_set_can_focus (button, FALSE);
2435 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_bottom_button_clicked), this);
2436 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2437 	return vbox;
2438 }
2439 
create_dictmanage_buttons()2440 GtkWidget *DictManageDlg::create_dictmanage_buttons()
2441 {
2442 	GtkWidget *hbox;
2443 	GtkWidget *vbox;
2444 	GtkWidget *button;
2445 	GtkWidget *image;
2446 #if GTK_MAJOR_VERSION >= 3
2447 	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
2448 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
2449 #else
2450 	hbox = gtk_hbox_new(false, 6);
2451 	vbox = gtk_vbox_new(false,6);
2452 #endif
2453 	gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2454 	button = gtk_button_new();
2455 	image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
2456 	gtk_button_set_image(GTK_BUTTON(button), image);
2457 	gtk_widget_set_tooltip_text(button,_("Add"));
2458 	gtk_widget_set_can_focus (button, FALSE);
2459 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_add_button_clicked), this);
2460 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2461 	button = gtk_button_new();
2462 	image = gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON);
2463 	gtk_button_set_image(GTK_BUTTON(button), image);
2464 	gtk_widget_set_tooltip_text(button,_("Delete"));
2465 	gtk_widget_set_can_focus (button, FALSE);
2466 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_delete_button_clicked), this);
2467 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2468 	button = gtk_button_new();
2469 	image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
2470 	gtk_button_set_image(GTK_BUTTON(button), image);
2471 	gtk_widget_set_tooltip_text(button,_("Information"));
2472 	gtk_widget_set_can_focus (button, FALSE);
2473 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_info_button_clicked), this);
2474 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2475 #if GTK_MAJOR_VERSION >= 3
2476 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
2477 #else
2478 	vbox = gtk_vbox_new(false,6);
2479 #endif
2480 	gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
2481 	button = gtk_button_new();
2482 	image = gtk_image_new_from_stock(GTK_STOCK_GOTO_TOP, GTK_ICON_SIZE_BUTTON);
2483 	gtk_button_set_image(GTK_BUTTON(button), image);
2484 	gtk_widget_set_tooltip_text(button,_("Move to top"));
2485 	gtk_widget_set_can_focus (button, FALSE);
2486 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_move_top_button_clicked), this);
2487 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2488 	button = gtk_button_new();
2489 	image = gtk_image_new_from_stock(GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
2490 	gtk_button_set_image(GTK_BUTTON(button), image);
2491 	gtk_widget_set_tooltip_text(button,_("Move up"));
2492 	gtk_widget_set_can_focus (button, FALSE);
2493 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_move_up_button_clicked), this);
2494 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2495 	button = gtk_button_new();
2496 	image = gtk_image_new_from_stock(GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON);
2497 	gtk_button_set_image(GTK_BUTTON(button), image);
2498 	gtk_widget_set_tooltip_text(button,_("Move down"));
2499 	gtk_widget_set_can_focus (button, FALSE);
2500 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_move_down_button_clicked), this);
2501 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2502 	button = gtk_button_new();
2503 	image = gtk_image_new_from_stock(GTK_STOCK_GOTO_BOTTOM, GTK_ICON_SIZE_BUTTON);
2504 	gtk_button_set_image(GTK_BUTTON(button), image);
2505 	gtk_widget_set_tooltip_text(button,_("Move to bottom"));
2506 	gtk_widget_set_can_focus (button, FALSE);
2507 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_dictmanage_move_bottom_button_clicked), this);
2508 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2509 	return hbox;
2510 }
2511 
create_network_buttons()2512 GtkWidget *DictManageDlg::create_network_buttons()
2513 {
2514 	GtkWidget *vbox;
2515 #ifdef CONFIG_GPE
2516 #if GTK_MAJOR_VERSION >= 3
2517 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
2518 #else
2519 	vbox = gtk_vbox_new(false,2);
2520 #endif
2521 #else
2522 #if GTK_MAJOR_VERSION >= 3
2523 	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
2524 #else
2525 	vbox = gtk_vbox_new(false,6);
2526 #endif
2527 #endif
2528 	GtkWidget *button;
2529 	button = gtk_button_new_from_stock(GTK_STOCK_ADD);
2530 	gtk_widget_set_can_focus (button, FALSE);
2531 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_network_add_button_clicked), this);
2532 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2533 	button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
2534 	gtk_widget_set_can_focus (button, FALSE);
2535 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_network_remove_button_clicked), this);
2536 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2537 	button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
2538 	gtk_widget_set_can_focus (button, FALSE);
2539 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_up_button_clicked), this);
2540 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2541 	button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
2542 	gtk_widget_set_can_focus (button, FALSE);
2543 	g_signal_connect(G_OBJECT(button),"clicked", G_CALLBACK(on_move_down_button_clicked), this);
2544 	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
2545 	return vbox;
2546 }
2547 
on_download_eventbox_clicked(GtkWidget * widget,GdkEventButton * event,DictManageDlg * oDictManageDlg)2548 void DictManageDlg::on_download_eventbox_clicked(GtkWidget *widget, GdkEventButton *event, DictManageDlg *oDictManageDlg)
2549 {
2550 	show_url("http://www.stardict.org");
2551 }
2552 
on_upgrade_eventbox_clicked(GtkWidget * widget,GdkEventButton * event,DictManageDlg * oDictManageDlg)2553 void DictManageDlg::on_upgrade_eventbox_clicked(GtkWidget *widget, GdkEventButton *event, DictManageDlg *oDictManageDlg)
2554 {
2555 	if (oDictManageDlg->upgrade_url.empty()) {
2556 		show_url("http://www.stardict.org/finance.php");
2557 	} else {
2558 		show_url(oDictManageDlg->upgrade_url.c_str());
2559 	}
2560 }
2561 
on_dict_list_dict_name_column_clicked(GtkTreeViewColumn * treeviewcolumn,DictManageDlg * oDictManageDlg)2562 void DictManageDlg::on_dict_list_dict_name_column_clicked(GtkTreeViewColumn *treeviewcolumn, DictManageDlg *oDictManageDlg)
2563 {
2564 	oDictManageDlg->dictmanage_list_changed = true;
2565 }
2566 
on_treedict_dict_name_column_clicked(GtkTreeViewColumn * treeviewcolumn,DictManageDlg * oDictManageDlg)2567 void DictManageDlg::on_treedict_dict_name_column_clicked(GtkTreeViewColumn *treeviewcolumn, DictManageDlg *oDictManageDlg)
2568 {
2569 	oDictManageDlg->write_treedict_order_list();
2570 }
2571 
on_network_dict_name_column_clicked(GtkTreeViewColumn * treeviewcolumn,DictManageDlg * oDictManageDlg)2572 void DictManageDlg::on_network_dict_name_column_clicked(GtkTreeViewColumn *treeviewcolumn, DictManageDlg *oDictManageDlg)
2573 {
2574 	oDictManageDlg->network_dictmask_changed = true;
2575 }
2576 
Show(bool & dictmanage_config_changed_)2577 bool DictManageDlg::Show(bool &dictmanage_config_changed_)
2578 {
2579 	if (!window) {
2580 		window = gtk_dialog_new();
2581 		gtk_window_set_transient_for(GTK_WINDOW(window), parent_win);
2582 
2583 		gtk_dialog_add_button(GTK_DIALOG(window),
2584 			GTK_STOCK_HELP,
2585 			GTK_RESPONSE_HELP);
2586 
2587 		gtk_dialog_add_button (GTK_DIALOG (window),
2588 			GTK_STOCK_CLOSE,
2589 			GTK_RESPONSE_CLOSE);
2590 		gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_CLOSE);
2591 		g_signal_connect(G_OBJECT(window), "response",
2592 			G_CALLBACK(response_handler), this);
2593 
2594 		GtkWidget *vbox;
2595 #ifdef CONFIG_GPE
2596 #if GTK_MAJOR_VERSION >= 3
2597 		vbox = gtk_vbox_new (FALSE, 2);
2598 #else
2599 		vbox = gtk_vbox_new(false,2);
2600 #endif
2601 		gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
2602 #else
2603 #if GTK_MAJOR_VERSION >= 3
2604 		vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
2605 #else
2606 		vbox = gtk_vbox_new(false,6);
2607 #endif
2608 		gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
2609 #endif
2610 
2611 #if GTK_MAJOR_VERSION >= 3
2612 		GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3);
2613 #else
2614 		GtkWidget *hbox = gtk_hbox_new(false, 3);
2615 #endif
2616 		gtk_box_pack_start(GTK_BOX(vbox),hbox, false, false, 0);
2617 
2618 		dict_list_button = gtk_radio_button_new(NULL);
2619 		gtk_widget_set_can_focus (dict_list_button, FALSE);
2620 		gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(dict_list_button), false);
2621 		gtk_box_pack_start (GTK_BOX (hbox), dict_list_button, false, false, 0);
2622 #if GTK_MAJOR_VERSION >= 3
2623 		GtkWidget *hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
2624 #else
2625 		GtkWidget *hbox1 = gtk_hbox_new(false, 2);
2626 #endif
2627 		gtk_container_add (GTK_CONTAINER (dict_list_button), hbox1);
2628 		GtkWidget *image = gtk_image_new_from_pixbuf(dicts_icon);
2629 		gtk_box_pack_start (GTK_BOX (hbox1), image, FALSE, FALSE, 0);
2630 		GtkWidget *label = gtk_label_new_with_mnemonic(_("D_ict List"));
2631 		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2632 		gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
2633 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), dict_list_button);
2634 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dict_list_button), true);
2635 		g_signal_connect(G_OBJECT(dict_list_button),"toggled", G_CALLBACK(on_dict_list_button_toggled), this);
2636 
2637 		manage_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(dict_list_button));
2638 		gtk_widget_set_can_focus (manage_button, FALSE);
2639 		gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(manage_button), false);
2640 		gtk_box_pack_start (GTK_BOX (hbox), manage_button, false, false, 0);
2641 #if GTK_MAJOR_VERSION >= 3
2642 		hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
2643 #else
2644 		hbox1 = gtk_hbox_new(false, 2);
2645 #endif
2646 		gtk_container_add (GTK_CONTAINER (manage_button), hbox1);
2647 		image = gtk_image_new_from_stock(GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_SMALL_TOOLBAR);
2648 		gtk_box_pack_start (GTK_BOX (hbox1), image, FALSE, FALSE, 0);
2649 		label = gtk_label_new_with_mnemonic(_("Manage _Dict"));
2650 		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2651 		gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
2652 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), manage_button);
2653 		g_signal_connect(G_OBJECT(manage_button),"toggled", G_CALLBACK(on_manage_button_toggled), this);
2654 
2655 		tree_dict_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(manage_button));
2656 		gtk_widget_set_can_focus (tree_dict_button, FALSE);
2657 		gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(tree_dict_button), false);
2658 		gtk_box_pack_start (GTK_BOX (hbox), tree_dict_button, false, false, 0);
2659 #if GTK_MAJOR_VERSION >= 3
2660 		hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
2661 #else
2662 		hbox1 = gtk_hbox_new(false, 2);
2663 #endif
2664 		gtk_container_add (GTK_CONTAINER (tree_dict_button), hbox1);
2665 		image = gtk_image_new_from_pixbuf(tree_dicts_icon);
2666 		gtk_box_pack_start (GTK_BOX (hbox1), image, FALSE, FALSE, 0);
2667 		label = gtk_label_new_with_mnemonic(_("T_ree dictionaries"));
2668 		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2669 		gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
2670 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), tree_dict_button);
2671 		g_signal_connect(G_OBJECT(tree_dict_button),"toggled", G_CALLBACK(on_tree_dict_button_toggled), this);
2672 
2673 		GtkWidget *network_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(tree_dict_button));
2674 		gtk_widget_set_can_focus (network_button, FALSE);
2675 		gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(network_button), false);
2676 		gtk_box_pack_start (GTK_BOX (hbox), network_button, false, false, 0);
2677 #if GTK_MAJOR_VERSION >= 3
2678 		hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
2679 #else
2680 		hbox1 = gtk_hbox_new(false, 2);
2681 #endif
2682 		gtk_container_add (GTK_CONTAINER (network_button), hbox1);
2683 		image = gtk_image_new_from_stock(GTK_STOCK_NETWORK, GTK_ICON_SIZE_SMALL_TOOLBAR);
2684 		gtk_box_pack_start (GTK_BOX (hbox1), image, FALSE, FALSE, 0);
2685 		label = gtk_label_new_with_mnemonic(_("_Network dictionaries"));
2686 		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
2687 		gtk_box_pack_start (GTK_BOX (hbox1), label, FALSE, FALSE, 0);
2688 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), network_button);
2689 		g_signal_connect(G_OBJECT(network_button),"toggled", G_CALLBACK(on_network_button_toggled), this);
2690 #ifdef CONFIG_GPE
2691 #if GTK_MAJOR_VERSION >= 3
2692 		hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
2693 #else
2694 		hbox = gtk_hbox_new (FALSE, 2);
2695 #endif
2696 #else
2697 #if GTK_MAJOR_VERSION >= 3
2698 		hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 18);
2699 #else
2700 		hbox = gtk_hbox_new (FALSE, 18);
2701 #endif
2702 #endif
2703 		gtk_box_pack_start (GTK_BOX (vbox), hbox, true, true, 0);
2704 
2705 		notebook = gtk_notebook_new();
2706 		gtk_box_pack_start(GTK_BOX(hbox),notebook, true, true, 0);
2707 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), false);
2708 		gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), false);
2709 
2710 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_dict_tree(DictTree_DictList), NULL);
2711 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_dictmanage_tree(), NULL);
2712 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_dict_tree(DictTree_TreeDict), NULL);
2713 		gtk_notebook_append_page(GTK_NOTEBOOK(notebook), create_dict_tree(DictTree_NetworkDict), NULL);
2714 
2715 		popup_menu = gtk_menu_new();
2716 		GtkWidget *menuitem;
2717 		menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Show information"));
2718 		image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_MENU);
2719 		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
2720 		gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
2721 		g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_popup_menu_show_info_activate), this);
2722 		gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), menuitem);
2723 		menuitem = gtk_separator_menu_item_new();
2724 		gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), menuitem);
2725 		menuitem = gtk_image_menu_item_new_with_mnemonic(_("Select _All"));
2726 		image = gtk_image_new_from_stock(GTK_STOCK_SELECT_ALL, GTK_ICON_SIZE_MENU);
2727 		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
2728 		gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
2729 		g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_popup_menu_select_all_activate), this);
2730 		gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), menuitem);
2731 		menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Unselect all"));
2732 		image = gtk_image_new_from_stock(GTK_STOCK_CANCEL, GTK_ICON_SIZE_MENU);
2733 		gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
2734 		gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
2735 		g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(on_popup_menu_unselect_all_activate), this);
2736 		gtk_menu_shell_append(GTK_MENU_SHELL(popup_menu), menuitem);
2737 		gtk_widget_show_all(popup_menu);
2738 
2739 		button_notebook = gtk_notebook_new();
2740 		gtk_box_pack_start (GTK_BOX (hbox), button_notebook, false, false, 0);
2741 		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(button_notebook), false);
2742 		gtk_notebook_set_show_border(GTK_NOTEBOOK(button_notebook), false);
2743 		gtk_notebook_append_page(GTK_NOTEBOOK(button_notebook), create_buttons(), NULL);
2744 		gtk_notebook_append_page(GTK_NOTEBOOK(button_notebook), create_dictmanage_buttons(), NULL);
2745 		gtk_notebook_append_page(GTK_NOTEBOOK(button_notebook), create_network_buttons(), NULL);
2746 
2747 #if GTK_MAJOR_VERSION >= 3
2748 		hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
2749 #else
2750 		hbox = gtk_hbox_new (FALSE, 6);
2751 #endif
2752 		gtk_box_pack_start (GTK_BOX (vbox), hbox, false, false, 0);
2753 #if GTK_MAJOR_VERSION >= 3
2754 		download_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2755 #else
2756 		download_hbox = gtk_hbox_new(FALSE, 0);
2757 #endif
2758 		gtk_box_pack_start (GTK_BOX (hbox), download_hbox, FALSE, FALSE, 0);
2759 		label = gtk_label_new(_("Visit "));
2760 		gtk_box_pack_start (GTK_BOX (download_hbox), label, FALSE, FALSE, 0);
2761 		label = gtk_label_new(NULL);
2762 		gtk_label_set_markup(GTK_LABEL(label), "<span foreground=\"blue\" underline=\"single\">http://www.stardict.org</span>");
2763 		GtkWidget *download_eventbox = gtk_event_box_new();
2764 		g_signal_connect(G_OBJECT(download_eventbox),"button-release-event", G_CALLBACK(on_download_eventbox_clicked), this);
2765 		gtk_container_add(GTK_CONTAINER(download_eventbox), label);
2766 		gtk_box_pack_start (GTK_BOX (download_hbox), download_eventbox, FALSE, FALSE, 0);
2767 		label = gtk_label_new(_(" to download dictionaries!"));
2768 		gtk_box_pack_start (GTK_BOX (download_hbox), label, FALSE, FALSE, 0);
2769 
2770 		info_label = gtk_label_new (NULL);
2771 		gtk_label_set_justify (GTK_LABEL (info_label), GTK_JUSTIFY_LEFT);
2772 		g_object_set (G_OBJECT (info_label), "xalign", 0.0, NULL);
2773 		gtk_box_pack_start (GTK_BOX (hbox), info_label, FALSE, FALSE, 0);
2774 
2775 		upgrade_label = gtk_label_new(NULL);
2776 		gchar *markup = g_markup_printf_escaped("<span foreground=\"blue\" underline=\"single\">%s</span>", _("Upgrade Now!"));
2777 		gtk_label_set_markup(GTK_LABEL(upgrade_label), markup);
2778 		g_free(markup);
2779 		upgrade_eventbox = gtk_event_box_new();
2780 		g_signal_connect(G_OBJECT(upgrade_eventbox),"button-release-event", G_CALLBACK(on_upgrade_eventbox_clicked), this);
2781 		gtk_container_add(GTK_CONTAINER(upgrade_eventbox), upgrade_label);
2782 		gtk_box_pack_start (GTK_BOX (hbox), upgrade_eventbox, FALSE, FALSE, 0);
2783 
2784 		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area(GTK_DIALOG (window))), vbox, true, true, 0);
2785 		gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG (window)));
2786 
2787 		GdkCursor* cursor = gdk_cursor_new(GDK_HAND2);
2788 		gtk_widget_realize(download_eventbox);
2789 		gdk_window_set_cursor(gtk_widget_get_window(download_eventbox), cursor);
2790 		gtk_widget_realize(upgrade_eventbox);
2791 		gdk_window_set_cursor(gtk_widget_get_window(upgrade_eventbox), cursor);
2792 #if GTK_MAJOR_VERSION >= 3
2793 		g_object_unref(cursor);
2794 #else
2795 		gdk_cursor_unref(cursor);
2796 #endif
2797 
2798 		gtk_widget_hide(info_label);
2799 		gtk_widget_hide(upgrade_eventbox);
2800 
2801 		gtk_window_set_title(GTK_WINDOW (window), _("Manage Dictionaries"));
2802 	}
2803 	max_dict_count = -1;
2804 	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(this->notebook)) == 3) {
2805 		STARDICT::Cmd *c1 = new STARDICT::Cmd(STARDICT::CMD_GET_DICT_MASK);
2806 		STARDICT::Cmd *c2 = new STARDICT::Cmd(STARDICT::CMD_MAX_DICT_COUNT);
2807 		STARDICT::Cmd *c3 = new STARDICT::Cmd(STARDICT::CMD_GET_ADINFO);
2808 		gpAppFrame->oStarDictClient.try_cache_or_send_commands(3, c1, c2, c3);
2809 	}
2810 	network_dictmask_changed = false;
2811 	dictmanage_list_changed = false;
2812 	dictmanage_config_changed = false;
2813 	gint result;
2814 	while ((result = gtk_dialog_run(GTK_DIALOG(window)))==GTK_RESPONSE_HELP)
2815 		;
2816 	if (network_dictmask_changed) {
2817 		ChangeNetworkDictMask();
2818 	}
2819 	if (dictmanage_list_changed) {
2820 		SaveDictManageList();
2821 	}
2822 	if (dictmanage_config_changed) {
2823 		SaveDictManageConfig();
2824 	}
2825 	dictmanage_config_changed_ = dictmanage_config_changed;
2826 	if (result == GTK_RESPONSE_NONE) {
2827 		// Caused by gtk_widget_destroy(), quitting.
2828 		return true;
2829 	} else {
2830 		gtk_widget_hide(GTK_WIDGET(window));
2831 		return false;
2832 	}
2833 }
2834 
Close()2835 void DictManageDlg::Close()
2836 {
2837 	if (window) {
2838 		gtk_widget_destroy (window);
2839 		gtk_widget_destroy(popup_menu);
2840 		window = NULL;
2841 	}
2842 }
2843 
2844 struct dictmask_ParseUserData {
2845 	GtkListStore *model;
2846 	std::string uid;
2847 	std::string bookname;
2848 	std::string wordcount;
2849 };
2850 
dictmask_parse_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)2851 static void dictmask_parse_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
2852 {
2853 	if (strcmp(element_name, "dict")==0) {
2854 		dictmask_ParseUserData *Data = (dictmask_ParseUserData *)user_data;
2855 		Data->uid.clear();
2856 		Data->bookname.clear();
2857 		Data->wordcount.clear();
2858 	}
2859 }
2860 
dictmask_parse_end_element(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)2861 static void dictmask_parse_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
2862 {
2863 	if (strcmp(element_name, "dict")==0) {
2864 		dictmask_ParseUserData *Data = (dictmask_ParseUserData *)user_data;
2865 		GtkTreeIter iter;
2866 		gtk_list_store_append(Data->model, &iter);
2867 		gtk_list_store_set(
2868 			Data->model, &iter,
2869 			NETWORKDICT_ID_COLUMN, Data->uid.c_str(),
2870 			NETWORKDICT_NAME_COLUMN, Data->bookname.c_str(),
2871 			NETWORKDICT_WORD_COUNT_COLUMN, (glong)atol(Data->wordcount.c_str()),
2872 			-1
2873 		);
2874 	}
2875 }
2876 
dictmask_parse_text(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)2877 static void dictmask_parse_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
2878 {
2879 	const gchar *element = g_markup_parse_context_get_element(context);
2880 	if (!element)
2881 		return;
2882 	dictmask_ParseUserData *Data = (dictmask_ParseUserData *)user_data;
2883 	if (strcmp(element, "uid")==0) {
2884 		Data->uid.assign(text, text_len);
2885 	} else if (strcmp(element, "bookname")==0) {
2886 		Data->bookname.assign(text, text_len);
2887 	} else if (strcmp(element, "wordcount")==0) {
2888 		Data->wordcount.assign(text, text_len);
2889 	}
2890 }
2891 
network_getdictmask(const char * xml)2892 void DictManageDlg::network_getdictmask(const char *xml)
2893 {
2894 	if (!window)
2895 		return;
2896 	gtk_list_store_clear(GTK_LIST_STORE(network_tree_model));
2897 	dictmask_ParseUserData Data;
2898 	Data.model = GTK_LIST_STORE(network_tree_model);
2899 	GMarkupParser parser;
2900 	parser.start_element = dictmask_parse_start_element;
2901 	parser.end_element = dictmask_parse_end_element;
2902 	parser.text = dictmask_parse_text;
2903 	parser.passthrough = NULL;
2904 	parser.error = NULL;
2905 	GMarkupParseContext* context = g_markup_parse_context_new(&parser, (GMarkupParseFlags)0, &Data, NULL);
2906 	g_markup_parse_context_parse(context, xml, -1, NULL);
2907 	g_markup_parse_context_end_parse(context, NULL);
2908 	g_markup_parse_context_free(context);
2909 }
2910 
2911 struct adinfo_ParseUserData {
2912 	std::string title;
2913 	std::string url;
2914 };
2915 
adinfo_parse_text(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)2916 static void adinfo_parse_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
2917 {
2918 	const gchar *element = g_markup_parse_context_get_element(context);
2919 	if (!element)
2920 		return;
2921 	adinfo_ParseUserData *Data = (adinfo_ParseUserData *)user_data;
2922 	if (strcmp(element, "title")==0) {
2923 		Data->title.assign(text, text_len);
2924 	} else if (strcmp(element, "url")==0) {
2925 		Data->url.assign(text, text_len);
2926 	}
2927 }
2928 
network_getadinfo(const char * xml)2929 void DictManageDlg::network_getadinfo(const char *xml)
2930 {
2931 	if (!window)
2932 		return;
2933 	adinfo_ParseUserData Data;
2934 	GMarkupParser parser;
2935 	parser.start_element = NULL;
2936 	parser.end_element = NULL;
2937 	parser.text = adinfo_parse_text;
2938 	parser.passthrough = NULL;
2939 	parser.error = NULL;
2940 	GMarkupParseContext* context = g_markup_parse_context_new(&parser, (GMarkupParseFlags)0, &Data, NULL);
2941 	g_markup_parse_context_parse(context, xml, -1, NULL);
2942 	g_markup_parse_context_end_parse(context, NULL);
2943 	g_markup_parse_context_free(context);
2944 
2945 	gchar *markup = g_markup_printf_escaped("<span foreground=\"blue\" underline=\"single\">%s</span>", Data.title.c_str());
2946 	gtk_label_set_markup(GTK_LABEL(upgrade_label), markup);
2947 	g_free(markup);
2948 	upgrade_url = Data.url;
2949 }
2950 
network_dirinfo(const char * xml)2951 void DictManageDlg::network_dirinfo(const char *xml)
2952 {
2953 	if (network_add_dlg)
2954 		network_add_dlg->network_getdirinfo(xml);
2955 }
2956 
2957 struct dictinfo_ParseUserData {
2958 	GtkWindow *parent;
2959 	std::string dictinfo_bookname;
2960 	std::string dictinfo_wordcount;
2961 	std::string dictinfo_synwordcount;
2962 	std::string dictinfo_author;
2963 	std::string dictinfo_email;
2964 	std::string dictinfo_website;
2965 	std::string dictinfo_description;
2966 	std::string dictinfo_date;
2967 	std::string dictinfo_download;
2968 };
2969 
dictinfo_parse_start_element(GMarkupParseContext * context,const gchar * element_name,const gchar ** attribute_names,const gchar ** attribute_values,gpointer user_data,GError ** error)2970 static void dictinfo_parse_start_element(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
2971 {
2972 	if (strcmp(element_name, "dictinfo")==0) {
2973 		dictinfo_ParseUserData *Data = (dictinfo_ParseUserData *)user_data;
2974 		Data->dictinfo_bookname.clear();
2975 		Data->dictinfo_wordcount.clear();
2976 		Data->dictinfo_synwordcount.clear();
2977 		Data->dictinfo_author.clear();
2978 		Data->dictinfo_email.clear();
2979 		Data->dictinfo_website.clear();
2980 		Data->dictinfo_description.clear();
2981 		Data->dictinfo_date.clear();
2982 		Data->dictinfo_download.clear();
2983 	}
2984 }
2985 
on_download_clicked(GtkWidget * widget,gpointer data)2986 static void on_download_clicked(GtkWidget *widget, gpointer data)
2987 {
2988 	show_url((const gchar*)g_object_get_data(G_OBJECT(widget), "stardict_download"));
2989 }
2990 
dictinfo_parse_end_element(GMarkupParseContext * context,const gchar * element_name,gpointer user_data,GError ** error)2991 static void dictinfo_parse_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
2992 {
2993 	if (strcmp(element_name, "dictinfo")==0) {
2994 		dictinfo_ParseUserData *Data = (dictinfo_ParseUserData *)user_data;
2995 		GtkWidget *dialog = gtk_dialog_new_with_buttons (
2996 			_("Dictionary Information"),
2997 			Data->parent,
2998 			GTK_DIALOG_DESTROY_WITH_PARENT,
2999 			GTK_STOCK_CLOSE,
3000 			GTK_RESPONSE_NONE,
3001 			NULL
3002 		);
3003 		GtkWidget *label = gtk_label_new(NULL);
3004 		char *markup;
3005 		markup = g_markup_printf_escaped (
3006 			"<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s\n<b>%s:</b> %s",
3007 			_("Dictionary Name"), Data->dictinfo_bookname.c_str(),
3008 			_("Word count"), Data->dictinfo_wordcount.c_str(),
3009 			_("Synonym word count"), Data->dictinfo_synwordcount.c_str(),
3010 			_("Author"), Data->dictinfo_author.c_str(),
3011 			_("Email"), Data->dictinfo_email.c_str(),
3012 			_("Website"), Data->dictinfo_website.c_str(),
3013 			_("Description"), Data->dictinfo_description.c_str(),
3014 			_("Date"), Data->dictinfo_date.c_str()
3015 		);
3016 		gtk_label_set_markup(GTK_LABEL(label), markup);
3017 		g_free (markup);
3018 		gtk_label_set_selectable(GTK_LABEL(label), TRUE);
3019 		gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
3020 		gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),label,false,false,6);
3021 		if (!Data->dictinfo_download.empty()) {
3022 #if GTK_MAJOR_VERSION >= 3
3023 			GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
3024 #else
3025 			GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
3026 #endif
3027 			gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),hbox,false,false,6);
3028 			GtkWidget *button = gtk_button_new_with_label(_("Download Now!"));
3029 			g_object_set_data_full(G_OBJECT(button), "stardict_download", g_strdup(Data->dictinfo_download.c_str()), g_free);
3030 			g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_download_clicked), NULL);
3031 			gtk_box_pack_start(GTK_BOX(hbox),button,false,false,6);
3032 		}
3033 
3034 		g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog);
3035 		gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
3036 		gtk_widget_show_all(dialog);
3037 	}
3038 }
3039 
dictinfo_parse_text(GMarkupParseContext * context,const gchar * text,gsize text_len,gpointer user_data,GError ** error)3040 static void dictinfo_parse_text(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
3041 {
3042 	const gchar *element = g_markup_parse_context_get_element(context);
3043 	if (!element)
3044 		return;
3045 	dictinfo_ParseUserData *Data = (dictinfo_ParseUserData *)user_data;
3046 	if (strcmp(element, "bookname")==0) {
3047 		Data->dictinfo_bookname.assign(text, text_len);
3048 	} else if (strcmp(element, "wordcount")==0) {
3049 		Data->dictinfo_wordcount.assign(text, text_len);
3050 	} else if (strcmp(element, "synwordcount")==0) {
3051 		Data->dictinfo_synwordcount.assign(text, text_len);
3052 	} else if (strcmp(element, "author")==0) {
3053 		Data->dictinfo_author.assign(text, text_len);
3054 	} else if (strcmp(element, "email")==0) {
3055 		Data->dictinfo_email.assign(text, text_len);
3056 	} else if (strcmp(element, "website")==0) {
3057 		Data->dictinfo_website.assign(text, text_len);
3058 	} else if (strcmp(element, "description")==0) {
3059 		Data->dictinfo_description.assign(text, text_len);
3060 	} else if (strcmp(element, "date")==0) {
3061 		Data->dictinfo_date.assign(text, text_len);
3062 	} else if (strcmp(element, "download")==0) {
3063 		Data->dictinfo_download.assign(text, text_len);
3064 	}
3065 }
3066 
network_dictinfo(const char * xml)3067 void DictManageDlg::network_dictinfo(const char *xml)
3068 {
3069 	dictinfo_ParseUserData Data;
3070 	if (network_add_dlg)
3071 		Data.parent = GTK_WINDOW(network_add_dlg->window);
3072 	else
3073 		Data.parent = GTK_WINDOW(this->window);
3074 	GMarkupParser parser;
3075 	parser.start_element = dictinfo_parse_start_element;
3076 	parser.end_element = dictinfo_parse_end_element;
3077 	parser.text = dictinfo_parse_text;
3078 	parser.passthrough = NULL;
3079 	parser.error = NULL;
3080 	GMarkupParseContext* context = g_markup_parse_context_new(&parser, (GMarkupParseFlags)0, &Data, NULL);
3081 	g_markup_parse_context_parse(context, xml, -1, NULL);
3082 	g_markup_parse_context_end_parse(context, NULL);
3083 	g_markup_parse_context_free(context);
3084 }
3085 
network_maxdictcount(int count)3086 void DictManageDlg::network_maxdictcount(int count)
3087 {
3088 	max_dict_count = count;
3089 	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(this->notebook)) == 3) {
3090 		gchar *str = g_strdup_printf(_("You can only choose %d dictionaries."), count);
3091 		gtk_label_set_text(GTK_LABEL(this->info_label), str);
3092 		g_free(str);
3093 	}
3094 }
3095