summaryrefslogtreecommitdiff
path: root/src/prefs_search_folder.c
diff options
context:
space:
mode:
authorSimeon Simeonov2018-02-26 11:23:00 +0100
committerSimeon Simeonov2018-02-26 11:23:00 +0100
commit0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc (patch)
treeaf916a30553c78ce9d4f2d8658656a175c5b6921 /src/prefs_search_folder.c
Initial commit for sylpheed 3.7.0
Diffstat (limited to 'src/prefs_search_folder.c')
-rw-r--r--src/prefs_search_folder.c453
1 files changed, 453 insertions, 0 deletions
diff --git a/src/prefs_search_folder.c b/src/prefs_search_folder.c
new file mode 100644
index 0000000..a8ad0cd
--- /dev/null
+++ b/src/prefs_search_folder.c
@@ -0,0 +1,453 @@
1/*
2 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2006 Hiroyuki Yamamoto
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21# include "config.h"
22#endif
23
24#include "defs.h"
25
26#include <glib.h>
27#include <glib/gi18n.h>
28#include <gdk/gdkkeysyms.h>
29#include <gtk/gtkwidget.h>
30#include <gtk/gtkwindow.h>
31#include <gtk/gtkstyle.h>
32#include <gtk/gtkvbox.h>
33#include <gtk/gtkoptionmenu.h>
34#include <gtk/gtkmenuitem.h>
35#include <gtk/gtklabel.h>
36#include <gtk/gtkentry.h>
37#include <gtk/gtkhbox.h>
38#include <gtk/gtkcheckbutton.h>
39#include <gtk/gtkhbbox.h>
40#include <gtk/gtkbutton.h>
41#include <gtk/gtkstock.h>
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45
46#include "prefs_search_folder.h"
47#include "prefs_ui.h"
48#include "mainwindow.h"
49#include "manage_window.h"
50#include "alertpanel.h"
51#include "foldersel.h"
52#include "folder.h"
53#include "filter.h"
54#include "prefs_filter.h"
55#include "prefs_filter_edit.h"
56#include "menu.h"
57#include "utils.h"
58#include "gtkutils.h"
59
60typedef struct _PrefsSearchFolderDialog PrefsSearchFolderDialog;
61
62struct _PrefsSearchFolderDialog
63{
64 PrefsDialog *dialog;
65 FolderItem *item;
66
67 GtkWidget *name_entry;
68
69 GtkWidget *bool_optmenu;
70
71 FilterCondEdit *cond_edit;
72
73 GtkWidget *folder_entry;
74 GtkWidget *folder_btn;
75
76 GtkWidget *subfolder_checkbtn;
77 GtkWidget *case_checkbtn;
78
79 gboolean finished;
80 gboolean updated;
81};
82
83static PrefsSearchFolderDialog *prefs_search_folder_create(FolderItem *item);
84static void prefs_search_folder_set_dialog(PrefsSearchFolderDialog *dialog);
85static void prefs_search_folder_destroy (PrefsSearchFolderDialog *dialog);
86
87static gint prefs_search_folder_delete_cb(GtkWidget *widget,
88 GdkEventAny *event,
89 PrefsSearchFolderDialog *dialog);
90static gint prefs_search_folder_key_press_cb
91 (GtkWidget *widget,
92 GdkEventKey *event,
93 PrefsSearchFolderDialog *dialog);
94
95static void prefs_search_folder_select_folder
96 (GtkWidget *widget,
97 PrefsSearchFolderDialog *dialog);
98
99static void prefs_search_folder_ok_cb (GtkWidget *widget,
100 PrefsSearchFolderDialog *dialog);
101static void prefs_search_folder_apply_cb (GtkWidget *widget,
102 PrefsSearchFolderDialog *dialog);
103static void prefs_search_folder_cancel_cb(GtkWidget *widget,
104 PrefsSearchFolderDialog *dialog);
105
106
107gboolean prefs_search_folder_open(FolderItem *item)
108{
109 PrefsSearchFolderDialog *dialog;
110 gboolean updated;
111
112 g_return_val_if_fail(item != NULL, FALSE);
113
114 dialog = prefs_search_folder_create(item);
115 manage_window_set_transient(GTK_WINDOW(dialog->dialog->window));
116 prefs_search_folder_set_dialog(dialog);
117 gtk_widget_show(dialog->dialog->window);
118
119 while (dialog->finished == FALSE)
120 gtk_main_iteration();
121
122 updated = dialog->updated;
123 prefs_search_folder_destroy(dialog);
124
125 return updated;
126}
127
128static PrefsSearchFolderDialog *prefs_search_folder_create(FolderItem *item)
129{
130 PrefsSearchFolderDialog *new_dialog;
131 PrefsDialog *dialog;
132 gchar *title;
133 GtkWidget *vbox;
134
135 GtkWidget *name_hbox;
136 GtkWidget *name_label;
137 GtkWidget *name_entry;
138 GtkStyle *style;
139
140 GtkWidget *bool_hbox;
141 GtkWidget *bool_optmenu;
142 GtkWidget *bool_menu;
143 GtkWidget *menuitem;
144
145 GtkWidget *scrolledwin;
146 FilterCondEdit *cond_edit;
147
148 GtkWidget *folder_hbox;
149 GtkWidget *folder_label;
150 GtkWidget *folder_entry;
151 GtkWidget *folder_btn;
152
153 GtkWidget *checkbtn_hbox;
154 GtkWidget *subfolder_checkbtn;
155 GtkWidget *case_checkbtn;
156
157 new_dialog = g_new0(PrefsSearchFolderDialog, 1);
158
159 dialog = g_new0(PrefsDialog, 1);
160 prefs_dialog_create(dialog);
161 gtk_widget_hide(dialog->apply_btn);
162
163 gtk_widget_set_size_request(dialog->window, 600, -1);
164 title = g_strdup_printf(_("%s - Edit search condition"), item->name);
165 gtk_window_set_title(GTK_WINDOW(dialog->window), title);
166 g_free(title);
167 gtk_notebook_set_show_border(GTK_NOTEBOOK(dialog->notebook), FALSE);
168 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(dialog->notebook), FALSE);
169 gtk_widget_realize(dialog->window);
170
171 g_signal_connect(G_OBJECT(dialog->window), "delete_event",
172 G_CALLBACK(prefs_search_folder_delete_cb), new_dialog);
173 g_signal_connect(G_OBJECT(dialog->window), "key_press_event",
174 G_CALLBACK(prefs_search_folder_key_press_cb),
175 new_dialog);
176
177 MANAGE_WINDOW_SIGNALS_CONNECT(dialog->window);
178
179 vbox = gtk_vbox_new(FALSE, 6);
180 gtk_widget_show(vbox);
181 gtk_container_add(GTK_CONTAINER(dialog->notebook), vbox);
182
183 name_hbox = gtk_hbox_new(FALSE, 8);
184 gtk_widget_show(name_hbox);
185 gtk_box_pack_start(GTK_BOX(vbox), name_hbox, FALSE, FALSE, 0);
186
187 name_label = gtk_label_new(_("Name:"));
188 gtk_widget_show(name_label);
189 gtk_box_pack_start(GTK_BOX(name_hbox), name_label, FALSE, FALSE, 0);
190
191 name_entry = gtk_entry_new();
192 gtk_widget_show(name_entry);
193 gtk_editable_set_editable(GTK_EDITABLE(name_entry), FALSE);
194 gtk_box_pack_start(GTK_BOX(name_hbox), name_entry, TRUE, TRUE, 0);
195
196 style = gtk_widget_get_style(dialog->window);
197 gtk_widget_modify_base(name_entry, GTK_STATE_NORMAL,
198 &style->bg[GTK_STATE_NORMAL]);
199
200 bool_hbox = gtk_hbox_new(FALSE, 12);
201 gtk_widget_show(bool_hbox);
202 gtk_box_pack_start(GTK_BOX(vbox), bool_hbox, FALSE, FALSE, 0);
203
204 bool_optmenu = gtk_option_menu_new();
205 gtk_widget_show(bool_optmenu);
206 gtk_box_pack_start(GTK_BOX(bool_hbox), bool_optmenu, FALSE, FALSE, 0);
207
208 bool_menu = gtk_menu_new();
209 MENUITEM_ADD(bool_menu, menuitem, _("Match any of the following"),
210 FLT_OR);
211 MENUITEM_ADD(bool_menu, menuitem, _("Match all of the following"),
212 FLT_AND);
213 gtk_option_menu_set_menu(GTK_OPTION_MENU(bool_optmenu), bool_menu);
214
215 scrolledwin = gtk_scrolled_window_new(NULL, NULL);
216 gtk_widget_show(scrolledwin);
217 gtk_widget_set_size_request(scrolledwin, -1, 150);
218 gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
219 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
220 GTK_POLICY_AUTOMATIC,
221 GTK_POLICY_AUTOMATIC);
222
223 cond_edit = prefs_filter_edit_cond_edit_create();
224 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwin),
225 cond_edit->cond_vbox);
226
227 folder_hbox = gtk_hbox_new(FALSE, 8);
228 gtk_widget_show(folder_hbox);
229 gtk_box_pack_start(GTK_BOX(vbox), folder_hbox, FALSE, FALSE, 0);
230
231 folder_label = gtk_label_new(_("Folder:"));
232 gtk_widget_show(folder_label);
233 gtk_box_pack_start(GTK_BOX(folder_hbox), folder_label, FALSE, FALSE, 0);
234
235 folder_entry = gtk_entry_new();
236 gtk_widget_show(folder_entry);
237 gtk_box_pack_start(GTK_BOX(folder_hbox), folder_entry, TRUE, TRUE, 0);
238
239 folder_btn = gtk_button_new_with_label("...");
240 gtk_widget_show(folder_btn);
241 gtk_box_pack_start(GTK_BOX(folder_hbox), folder_btn, FALSE, FALSE, 0);
242
243 checkbtn_hbox = gtk_hbox_new(FALSE, 12);
244 gtk_widget_show(checkbtn_hbox);
245 gtk_box_pack_start(GTK_BOX(vbox), checkbtn_hbox, FALSE, FALSE, 0);
246
247 subfolder_checkbtn =
248 gtk_check_button_new_with_label(_("Search subfolders"));
249 gtk_widget_show(subfolder_checkbtn);
250 gtk_box_pack_start(GTK_BOX(checkbtn_hbox), subfolder_checkbtn,
251 FALSE, FALSE, 0);
252
253 case_checkbtn = gtk_check_button_new_with_label(_("Case sensitive"));
254 gtk_widget_show(case_checkbtn);
255 gtk_box_pack_start(GTK_BOX(checkbtn_hbox), case_checkbtn,
256 FALSE, FALSE, 0);
257
258 g_signal_connect(G_OBJECT(folder_btn), "clicked",
259 G_CALLBACK(prefs_search_folder_select_folder),
260 new_dialog);
261 g_signal_connect(G_OBJECT(dialog->ok_btn), "clicked",
262 G_CALLBACK(prefs_search_folder_ok_cb), new_dialog);
263 g_signal_connect(G_OBJECT(dialog->apply_btn), "clicked",
264 G_CALLBACK(prefs_search_folder_apply_cb), new_dialog);
265 g_signal_connect(G_OBJECT(dialog->cancel_btn), "clicked",
266 G_CALLBACK(prefs_search_folder_cancel_cb), new_dialog);
267
268 gtk_widget_grab_focus(dialog->ok_btn);
269
270 new_dialog->dialog = dialog;
271 new_dialog->item = item;
272 new_dialog->name_entry = name_entry;
273 new_dialog->bool_optmenu = bool_optmenu;
274 new_dialog->cond_edit = cond_edit;
275
276 new_dialog->folder_entry = folder_entry;
277 new_dialog->folder_btn = folder_btn;
278 new_dialog->subfolder_checkbtn = subfolder_checkbtn;
279 new_dialog->case_checkbtn = case_checkbtn;
280
281 new_dialog->finished = FALSE;
282 new_dialog->updated = FALSE;
283
284 return new_dialog;
285}
286
287static void prefs_search_folder_set_dialog(PrefsSearchFolderDialog *dialog)
288{
289 GSList *flist;
290 FilterRule *rule;
291 GSList *cur;
292 gchar *path;
293 gchar *rule_file;
294 gint index;
295 gboolean case_sens = FALSE;
296
297 path = folder_item_get_path(dialog->item);
298 rule_file = g_strconcat(path, G_DIR_SEPARATOR_S, "filter.xml", NULL);
299 flist = filter_read_file(rule_file);
300 g_free(rule_file);
301 g_free(path);
302
303 if (!flist) {
304 g_warning("filter rule not found\n");
305 return;
306 }
307
308 gtk_entry_set_text(GTK_ENTRY(dialog->name_entry), dialog->item->name);
309
310 rule = (FilterRule *)flist->data;
311
312 index = menu_find_option_menu_index
313 (GTK_OPTION_MENU(dialog->bool_optmenu),
314 GINT_TO_POINTER(rule->bool_op), NULL);
315 if (index < 0)
316 index = 0;
317 gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->bool_optmenu),
318 index);
319
320 gtk_entry_set_text(GTK_ENTRY(dialog->folder_entry),
321 rule->target_folder);
322 gtk_toggle_button_set_active
323 (GTK_TOGGLE_BUTTON(dialog->subfolder_checkbtn),
324 rule->recursive);
325 for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
326 FilterCond *cond = (FilterCond *)cur->data;
327 if (FLT_IS_CASE_SENS(cond->match_flag)) {
328 case_sens = TRUE;
329 break;
330 }
331 }
332 gtk_toggle_button_set_active
333 (GTK_TOGGLE_BUTTON(dialog->case_checkbtn), case_sens);
334
335 prefs_filter_set_header_list(NULL);
336 prefs_filter_edit_set_header_list(dialog->cond_edit, rule);
337 prefs_filter_edit_add_rule_cond(dialog->cond_edit, rule);
338
339 filter_rule_list_free(flist);
340}
341
342static void prefs_search_folder_destroy(PrefsSearchFolderDialog *dialog)
343{
344 prefs_dialog_destroy(dialog->dialog);
345 g_free(dialog->dialog);
346 g_free(dialog);
347
348 main_window_popup(main_window_get());
349}
350
351static gint prefs_search_folder_delete_cb(GtkWidget *widget, GdkEventAny *event,
352 PrefsSearchFolderDialog *dialog)
353{
354 dialog->finished = TRUE;
355 return TRUE;
356}
357
358static gint prefs_search_folder_key_press_cb(GtkWidget *widget,
359 GdkEventKey *event,
360 PrefsSearchFolderDialog *dialog)
361{
362 if (event && event->keyval == GDK_Escape) {
363 prefs_search_folder_cancel_cb(widget, dialog);
364 return TRUE;
365 }
366 return FALSE;
367}
368
369static void prefs_search_folder_select_folder(GtkWidget *widget,
370 PrefsSearchFolderDialog *dialog)
371{
372 FolderItem *item;
373 gchar *id;
374
375 item = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL);
376 if (!item || item->stype == F_VIRTUAL)
377 return;
378
379 id = folder_item_get_identifier(item);
380 if (id) {
381 gtk_entry_set_text(GTK_ENTRY(dialog->folder_entry), id);
382 g_free(id);
383 }
384}
385
386static void prefs_search_folder_ok_cb(GtkWidget *widget,
387 PrefsSearchFolderDialog *dialog)
388{
389 prefs_search_folder_apply_cb(widget, dialog);
390 dialog->finished = TRUE;
391}
392
393static void prefs_search_folder_apply_cb(GtkWidget *widget,
394 PrefsSearchFolderDialog *dialog)
395{
396 const gchar *id;
397 FolderItem *item;
398 FilterBoolOp bool_op;
399 gboolean recursive;
400 gboolean case_sens;
401 GSList *cond_list;
402 FilterRule *rule;
403 GSList list;
404 gchar *file;
405 gchar *path;
406
407 id = gtk_entry_get_text(GTK_ENTRY(dialog->folder_entry));
408 item = folder_find_item_from_identifier(id);
409 if (!item)
410 return;
411
412 bool_op = menu_get_option_menu_active_index
413 (GTK_OPTION_MENU(dialog->bool_optmenu));
414 recursive = gtk_toggle_button_get_active
415 (GTK_TOGGLE_BUTTON(dialog->subfolder_checkbtn));
416 case_sens = gtk_toggle_button_get_active
417 (GTK_TOGGLE_BUTTON(dialog->case_checkbtn));
418
419 cond_list = prefs_filter_edit_cond_edit_to_list(dialog->cond_edit,
420 case_sens);
421 if (!cond_list)
422 return;
423
424 rule = filter_rule_new(dialog->item->name, bool_op, cond_list, NULL);
425 rule->target_folder = g_strdup(id);
426 rule->recursive = recursive;
427 list.data = rule;
428 list.next = NULL;
429
430 path = folder_item_get_path(dialog->item);
431 file = g_strconcat(path, G_DIR_SEPARATOR_S, FILTER_LIST, NULL);
432 filter_write_file(&list, file);
433 g_free(file);
434 file = g_strconcat(path, G_DIR_SEPARATOR_S, FILTER_LIST, ".bak", NULL);
435 if (is_file_exist(file))
436 g_unlink(file);
437 g_free(file);
438 file = g_strconcat(path, G_DIR_SEPARATOR_S, SEARCH_CACHE, NULL);
439 if (is_file_exist(file))
440 g_unlink(file);
441 g_free(file);
442 g_free(path);
443
444 filter_rule_free(rule);
445
446 dialog->updated = TRUE;
447}
448
449static void prefs_search_folder_cancel_cb(GtkWidget *widget,
450 PrefsSearchFolderDialog *dialog)
451{
452 dialog->finished = TRUE;
453}