1 /*
2  * Program: rubrica
3  * file: search_view.h
4 *
5 *  Copyright (C) 2000-2005 Nicola Fragale <nicolafragale@libero.it>
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 3 of the License
10 *
11 *  This program 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 this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 
21 #include <gtk/gtk.h>
22 #include <glade/glade.h>
23 #include <glib/gi18n-lib.h>
24 #include <time.h>
25 
26 #include "search_dialog.h"
27 #include "calendar.h"
28 #include "types.h"
29 #include "utils.h"
30 
31 #include "libral.h"
32 
33 
34 typedef struct {
35   gchar* str;
36 } ComboLabel;
37 
38 static ComboLabel combo_labels[] = {
39   {N_("is")       },
40   {N_("is before of")},
41   {N_("is after of") },
42   {N_("is between")  },
43   {NULL}
44 };
45 
46 typedef enum {
47   SEARCH_DATE = 0,
48   SEARCH_BEFORE,
49   SEARCH_AFTER,
50   SEARCH_BETWEEN,
51 } SearchOn;
52 
53 
54 
55 typedef struct {
56   GtkWidget* window;
57 
58   GtkWidget* search;         // entry for string to search for
59   GtkWidget* date_check;     // check button (checked if search on date)
60   GtkWidget* str_box;        // enabled if search is performed on string
61   GtkWidget* date_box;       // enabled if search is performed on date
62   GtkWidget* date2_box;      // enabled if search is between dates
63   GtkWidget* creation;       // radio button
64   GtkWidget* last_change;    // radio button
65   GtkWidget* combo;          // date search type
66   GtkWidget* combo_box;      // date search type
67   GtkWidget* date1;          // entry for (first) date
68   GtkWidget* date2;          // entry for second date
69   GtkWidget* calendar1_box;  // calendar button
70   GtkWidget* calendar2_box;  // calendar button
71 } RubricaSearchDialog;
72 
73 RubricaSearch* search;
74 
75 
76 static void on_date_check         (GtkWidget* check, gpointer data);
77 static void on_radio_cb           (GtkWidget* radio, gpointer data);
78 static void on_combo_changed      (GtkWidget* combo, gpointer data);
79 
80 static void on_get_first_date_cb  (GtkWidget* calendar, GDate* date,
81 				   gpointer data);
82 static void on_get_second_date_cb (GtkWidget* calendar, GDate* date,
83 				   gpointer data);
84 
85 
86 
87 static void
on_date_check(GtkWidget * button,gpointer data)88 on_date_check(GtkWidget* button, gpointer data)
89 {
90   RubricaSearchDialog* dialog = (RubricaSearchDialog*) data;
91   SearchType active;
92 
93   if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->date_check)))
94     {
95       gtk_widget_set_sensitive(dialog->date_box, TRUE);
96       gtk_widget_set_sensitive(dialog->str_box, FALSE);
97 
98       if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->creation)))
99 	search->type = SEARCH_ON_CREATION;
100       else
101 	search->type = SEARCH_ON_CHANGE;
102     }
103   else
104     {
105       gtk_widget_set_sensitive(dialog->date_box, FALSE);
106       gtk_widget_set_sensitive(dialog->str_box, TRUE);
107 
108       search->type = SEARCH_ON_STRING;
109     }
110 
111   active = gtk_combo_box_get_active(GTK_COMBO_BOX(dialog->combo));
112   if (active == SEARCH_BETWEEN)
113     gtk_widget_show_all(dialog->date2_box);
114   else
115     gtk_widget_hide_all(dialog->date2_box);
116 }
117 
118 
119 static void
on_radio_cb(GtkWidget * radio,gpointer data)120 on_radio_cb (GtkWidget* radio, gpointer data)
121 {
122   RubricaSearchDialog* dialog = (RubricaSearchDialog*) data;
123 
124   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->creation)))
125     search->type = SEARCH_ON_CREATION;
126   else
127     search->type = SEARCH_ON_CHANGE;
128 }
129 
130 
131 static void
on_combo_changed(GtkWidget * combo,gpointer data)132 on_combo_changed (GtkWidget *combo, gpointer data)
133 {
134   RubricaSearchDialog* dialog = (RubricaSearchDialog*) data;
135   SearchOn active;
136 
137   gtk_widget_hide_all(dialog->date2_box);
138   active = (SearchOn) gtk_combo_box_get_active(GTK_COMBO_BOX(combo));
139   switch (active)
140     {
141     case SEARCH_BEFORE:
142       search->second = 0;
143       if  (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->creation)))
144 	search->type = SEARCH_CREATION_BEFORE;
145       else
146 	search->type = SEARCH_CHANGE_BEFORE;
147       break;
148 
149     case SEARCH_AFTER:
150       search->second = 0;
151       if  (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->creation)))
152       	search->type = SEARCH_CREATION_AFTER;
153       else
154 	search->type = SEARCH_CHANGE_AFTER;
155 
156       break;
157 
158     case SEARCH_BETWEEN:
159       gtk_widget_show_all(dialog->date2_box);
160 
161       if (search->type == SEARCH_ON_CREATION)
162 	search->type = SEARCH_CREATION_BETWEEN;
163       else
164 	search->type = SEARCH_CHANGE_BETWEEN;
165       break;
166 
167     default:
168       break;
169     }
170 }
171 
172 
173 static void
on_get_first_date_cb(GtkWidget * calendar,GDate * date,gpointer data)174 on_get_first_date_cb(GtkWidget* calendar, GDate* date, gpointer data)
175 {
176   struct tm tm;
177 
178   g_date_to_struct_tm(date, &tm);
179   search->first = mktime(&tm);
180 }
181 
182 static void
on_get_second_date_cb(GtkWidget * calendar,GDate * date,gpointer data)183 on_get_second_date_cb(GtkWidget* calendar, GDate* date, gpointer data)
184 {
185   struct tm tm;
186 
187   g_date_to_struct_tm(date, &tm);
188   search->second = mktime(&tm);
189 }
190 
191 
192 /*   Public
193  */
194 void
rubrica_search_dialog(RubricaApp * app)195 rubrica_search_dialog(RubricaApp* app)
196 {
197   GladeXML* gui;
198   RubricaSearchDialog* dialog;
199   RAbook* book;
200   GList* result = NULL;
201   gchar* string = NULL;
202   gint response, i;
203 
204   gui = glade_xml_new (RUBRICA_GUI_DIR"/Search.glade", NULL, NULL);
205   if (!gui)
206     g_error("Can't load gui");
207 
208   search = g_new0(RubricaSearch, 1);
209   dialog = g_new0(RubricaSearchDialog, 1);
210 
211   dialog->window        = glade_xml_get_widget(gui, "RubricaSearch");
212   dialog->search        = glade_xml_get_widget(gui, "search");
213   dialog->date_check    = glade_xml_get_widget(gui, "date_check");
214   dialog->date_box      = glade_xml_get_widget(gui, "date_box");
215   dialog->str_box       = glade_xml_get_widget(gui, "str_box");
216   dialog->creation      = glade_xml_get_widget(gui, "creation");
217   dialog->last_change   = glade_xml_get_widget(gui, "change");
218   dialog->combo_box     = glade_xml_get_widget(gui, "combo_box");
219   dialog->date2_box     = glade_xml_get_widget(gui, "date2_box");
220   dialog->calendar1_box = glade_xml_get_widget(gui, "calendar1_box");
221   dialog->calendar2_box = glade_xml_get_widget(gui, "calendar2_box");
222 
223   dialog->combo = gtk_combo_box_new_text();
224   gtk_box_pack_start(GTK_BOX(dialog->combo_box), dialog->combo,
225 		     TRUE, TRUE, 6);
226   for (i = 0; combo_labels[i].str; i++)
227     gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo),
228 			      _(combo_labels[i].str));
229   gtk_widget_show(dialog->combo);
230 
231   dialog->date1 = rubrica_calendar_new();
232   gtk_box_pack_start(GTK_BOX(dialog->calendar1_box), dialog->date1,
233 		     TRUE, TRUE, 6);
234   gtk_widget_show(dialog->date1);
235 
236   dialog->date2 = rubrica_calendar_new();
237   gtk_box_pack_start(GTK_BOX(dialog->calendar2_box), dialog->date2,
238 		     TRUE, TRUE, 6);
239   gtk_widget_hide_all(dialog->date2_box);
240 
241   g_object_unref(gui);
242 
243   search->type   = SEARCH_ON_STRING;
244   search->first  = 0;
245   search->second = 0;
246 
247   gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->combo), SEARCH_DATE);
248   gtk_widget_set_sensitive(dialog->date_box, FALSE);
249 
250   g_signal_connect(G_OBJECT(dialog->date_check), "toggled",
251 		   G_CALLBACK(on_date_check), dialog);
252 
253   g_signal_connect(G_OBJECT(dialog->creation), "clicked",
254 		   G_CALLBACK(on_radio_cb), dialog);
255 
256   g_signal_connect(G_OBJECT(dialog->last_change), "clicked",
257 		   G_CALLBACK(on_radio_cb), dialog);
258 
259   g_signal_connect(G_OBJECT(dialog->combo), "changed",
260 		   G_CALLBACK(on_combo_changed), dialog);
261 
262   g_signal_connect(G_OBJECT(dialog->date1), "calendar-change",
263 		   G_CALLBACK(on_get_first_date_cb), dialog->date1);
264 
265   g_signal_connect(G_OBJECT(dialog->date2), "calendar-change",
266 		   G_CALLBACK(on_get_second_date_cb), dialog->date2);
267 
268   response = gtk_dialog_run (GTK_DIALOG(dialog->window));
269   switch(response)
270     {
271     case GTK_RESPONSE_ACCEPT:
272       book = rubrica_app_get_active_addressbook(app);
273 
274       switch(search->type)
275 	{
276 	case SEARCH_ON_STRING:
277 	  string = g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->search)));
278 
279 	  result = r_abook_search(book, string);
280 	  break;
281 
282 	case SEARCH_ON_CREATION:
283 	case SEARCH_CREATION_BEFORE:
284 	case SEARCH_CREATION_AFTER:
285 	case SEARCH_ON_CHANGE:
286 	case SEARCH_CHANGE_AFTER:
287 	case SEARCH_CHANGE_BEFORE:
288 	  result = r_abook_search_date(book, search->first, search->type);
289 
290 	  break;
291 
292 	case SEARCH_CREATION_BETWEEN:
293 	case SEARCH_CHANGE_BETWEEN:
294 	  result = r_abook_search_between(book, search->first, search->second,
295 					  search->type);
296 	  break;
297 
298 	default:
299 	  break;
300 	}
301 
302       rubrica_app_display_search_results(app, result);
303       break;
304 
305     case GTK_RESPONSE_CLOSE:
306       break;
307     }
308 
309   gtk_widget_destroy(dialog->window);
310   g_free(string);
311   g_free(dialog);
312   g_free(search);
313 }
314 
315