1 /*
2 * Copyright (c) Stephan Arts 2006-2012 <stephan@xfce.org>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20 #include "util.h"
21 #include "privacy_dialog.h"
22
23 #include <libxfce4ui/libxfce4ui.h>
24
25
26
27 enum
28 {
29 PROP_0,
30 PROP_FILTER,
31 PROP_LIMIT,
32 PROP_LOCAL_ONLY,
33 PROP_SELECT_MULTIPLE,
34 PROP_RECENT_MANAGER,
35 PROP_SORT_TYPE,
36 PROP_SHOW_TIPS,
37 PROP_SHOW_ICONS,
38 PROP_SHOW_NOT_FOUND,
39 PROP_SHOW_PRIVATE,
40 };
41
42
43
44 static void
45 rstto_recent_chooser_init (GtkRecentChooserIface *iface);
46
47 static void
48 rstto_privacy_dialog_finalize (GObject *object);
49 static void
50 rstto_privacy_dialog_set_property (GObject *object,
51 guint property_id,
52 const GValue *value,
53 GParamSpec *pspec);
54 static void
55 rstto_privacy_dialog_get_property (GObject *object,
56 guint property_id,
57 GValue *value,
58 GParamSpec *pspec);
59
60 static void
61 rstto_recent_chooser_add_filter (GtkRecentChooser *chooser,
62 GtkRecentFilter *filter);
63 static GList *
64 rstto_recent_chooser_get_items (GtkRecentChooser *chooser);
65 static void
66 cb_rstto_privacy_dialog_combobox_timeframe_changed (GtkComboBox *combobox,
67 gpointer user_data);
68 gboolean
69 cb_rstto_recent_filter_filter_timeframe (const GtkRecentFilterInfo *filter_info,
70 gpointer user_data);
71
72
73
74 struct _RsttoPrivacyDialogPrivate
75 {
76 RsttoSettings *settings;
77
78 GtkWidget *cleanup_frame;
79 GtkWidget *cleanup_vbox;
80 GtkWidget *cleanup_timeframe_combo;
81
82 GtkRecentManager *recent_manager;
83 GSList *filters;
84 GtkRecentFilter *timeframe_filter;
85 time_t time_now;
86 time_t time_offset;
87 };
88
89
90
G_DEFINE_TYPE_WITH_CODE(RsttoPrivacyDialog,rstto_privacy_dialog,GTK_TYPE_DIALOG,G_ADD_PRIVATE (RsttoPrivacyDialog)G_IMPLEMENT_INTERFACE (GTK_TYPE_RECENT_CHOOSER,rstto_recent_chooser_init))91 G_DEFINE_TYPE_WITH_CODE (RsttoPrivacyDialog, rstto_privacy_dialog, GTK_TYPE_DIALOG,
92 G_ADD_PRIVATE (RsttoPrivacyDialog)
93 G_IMPLEMENT_INTERFACE (GTK_TYPE_RECENT_CHOOSER, rstto_recent_chooser_init))
94
95
96
97 static void
98 rstto_privacy_dialog_init (RsttoPrivacyDialog *dialog)
99 {
100 GtkWidget *display_main_hbox;
101 GtkWidget *display_main_lbl;
102 GtkWidget *button;
103
104 dialog->priv = rstto_privacy_dialog_get_instance_private (dialog);
105
106 dialog->priv->settings = rstto_settings_new ();
107 dialog->priv->time_now = time (0);
108 dialog->priv->timeframe_filter = gtk_recent_filter_new ();
109
110 /* Add recent-filter function to filter in access-time */
111 gtk_recent_filter_add_custom (
112 dialog->priv->timeframe_filter,
113 GTK_RECENT_FILTER_URI,
114 cb_rstto_recent_filter_filter_timeframe,
115 dialog,
116 NULL);
117
118 display_main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
119 display_main_lbl = gtk_label_new (_("Time range to clear:"));
120
121 dialog->priv->cleanup_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
122 dialog->priv->cleanup_frame = xfce_gtk_frame_box_new_with_content (_("Cleanup"), dialog->priv->cleanup_vbox);
123 gtk_widget_set_margin_start (dialog->priv->cleanup_frame, 6);
124 dialog->priv->cleanup_timeframe_combo = gtk_combo_box_text_new ();
125 gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (dialog->priv->cleanup_timeframe_combo), 0, _("Last Hour"));
126 gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (dialog->priv->cleanup_timeframe_combo), 1, _("Last Two Hours"));
127 gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (dialog->priv->cleanup_timeframe_combo), 2, _("Last Four Hours"));
128 gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (dialog->priv->cleanup_timeframe_combo), 3, _("Today"));
129 gtk_combo_box_text_insert_text (GTK_COMBO_BOX_TEXT (dialog->priv->cleanup_timeframe_combo), 4, _("Everything"));
130 g_signal_connect (dialog->priv->cleanup_timeframe_combo, "changed",
131 G_CALLBACK (cb_rstto_privacy_dialog_combobox_timeframe_changed), dialog);
132 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->cleanup_timeframe_combo), 0);
133
134 gtk_box_pack_start (GTK_BOX (dialog->priv->cleanup_vbox),
135 display_main_hbox, FALSE, FALSE, 0);
136 gtk_box_pack_start (GTK_BOX (display_main_hbox),
137 display_main_lbl, FALSE, FALSE, 0);
138 gtk_box_pack_start (GTK_BOX (display_main_hbox),
139 dialog->priv->cleanup_timeframe_combo, FALSE, FALSE, 0);
140
141 gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
142 dialog->priv->cleanup_frame);
143
144 gtk_widget_show_all (dialog->priv->cleanup_frame);
145
146 /* Window should not be resizable */
147 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
148
149 button = xfce_gtk_button_new_mixed ("gtk-cancel", _("_Cancel"));
150 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CANCEL);
151 gtk_widget_show (button);
152 button = xfce_gtk_button_new_mixed ("gtk-apply", _("_Apply"));
153 gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
154 gtk_widget_show (button);
155 }
156
157 static void
rstto_privacy_dialog_class_init(RsttoPrivacyDialogClass * klass)158 rstto_privacy_dialog_class_init (RsttoPrivacyDialogClass *klass)
159 {
160 GObjectClass *object_class = G_OBJECT_CLASS (klass);
161 GParamSpec *pspec;
162
163 object_class->finalize = rstto_privacy_dialog_finalize;
164 object_class->set_property = rstto_privacy_dialog_set_property;
165 object_class->get_property = rstto_privacy_dialog_get_property;
166
167 pspec = g_param_spec_object ("filter",
168 "",
169 "",
170 GTK_TYPE_RECENT_FILTER,
171 G_PARAM_READWRITE);
172 g_object_class_install_property (object_class,
173 PROP_FILTER,
174 pspec);
175 pspec = g_param_spec_object ("recent-manager",
176 "",
177 "",
178 GTK_TYPE_RECENT_MANAGER,
179 G_PARAM_READWRITE);
180 g_object_class_install_property (object_class,
181 PROP_RECENT_MANAGER,
182 pspec);
183 pspec = g_param_spec_int ("limit",
184 "",
185 "",
186 -1,
187 100,
188 -1,
189 G_PARAM_READWRITE);
190 g_object_class_install_property (object_class,
191 PROP_LIMIT,
192 pspec);
193 pspec = g_param_spec_boolean ("local-only",
194 "",
195 "",
196 FALSE,
197 G_PARAM_READWRITE);
198 g_object_class_install_property (object_class,
199 PROP_LOCAL_ONLY,
200 pspec);
201
202 pspec = g_param_spec_boolean ("select-multiple",
203 "",
204 "",
205 FALSE,
206 G_PARAM_READWRITE);
207 g_object_class_install_property (object_class,
208 PROP_SELECT_MULTIPLE,
209 pspec);
210 pspec = g_param_spec_boolean ("show-tips",
211 "",
212 "",
213 FALSE,
214 G_PARAM_READWRITE);
215 g_object_class_install_property (object_class,
216 PROP_SHOW_TIPS,
217 pspec);
218 pspec = g_param_spec_boolean ("show-icons",
219 "",
220 "",
221 FALSE,
222 G_PARAM_READWRITE);
223 g_object_class_install_property (object_class,
224 PROP_SHOW_ICONS,
225 pspec);
226 pspec = g_param_spec_boolean ("show-not-found",
227 "",
228 "",
229 FALSE,
230 G_PARAM_READWRITE);
231 g_object_class_install_property (object_class,
232 PROP_SHOW_NOT_FOUND,
233 pspec);
234 pspec = g_param_spec_boolean ("show-private",
235 "",
236 "",
237 FALSE,
238 G_PARAM_READWRITE);
239 g_object_class_install_property (object_class,
240 PROP_SHOW_PRIVATE,
241 pspec);
242 pspec = g_param_spec_enum ("sort-type",
243 "",
244 "",
245 GTK_TYPE_RECENT_SORT_TYPE,
246 GTK_RECENT_SORT_NONE,
247 G_PARAM_READWRITE);
248 g_object_class_install_property (object_class,
249 PROP_SORT_TYPE,
250 pspec);
251 }
252
253 static void
rstto_recent_chooser_init(GtkRecentChooserIface * iface)254 rstto_recent_chooser_init (GtkRecentChooserIface *iface)
255 {
256 iface->add_filter = rstto_recent_chooser_add_filter;
257 iface->get_items = rstto_recent_chooser_get_items;
258 }
259
260 static void
rstto_privacy_dialog_finalize(GObject * object)261 rstto_privacy_dialog_finalize (GObject *object)
262 {
263 RsttoPrivacyDialog *dialog = RSTTO_PRIVACY_DIALOG (object);
264
265 if (dialog->priv->settings)
266 {
267 g_object_unref (dialog->priv->settings);
268 dialog->priv->settings = NULL;
269 }
270
271 if (dialog->priv->filters)
272 {
273 g_slist_free (dialog->priv->filters);
274 dialog->priv->filters = NULL;
275 }
276
277 G_OBJECT_CLASS (rstto_privacy_dialog_parent_class)->finalize (object);
278 }
279
280
281 static void
rstto_privacy_dialog_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)282 rstto_privacy_dialog_set_property (GObject *object,
283 guint property_id,
284 const GValue *value,
285 GParamSpec *pspec)
286 {
287 RsttoPrivacyDialog *dialog = RSTTO_PRIVACY_DIALOG (object);
288
289 switch (property_id)
290 {
291 case PROP_RECENT_MANAGER:
292 dialog->priv->recent_manager = g_value_get_object (value);
293 break;
294 }
295
296 }
297
298 static void
rstto_privacy_dialog_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)299 rstto_privacy_dialog_get_property (GObject *object,
300 guint property_id,
301 GValue *value,
302 GParamSpec *pspec)
303 {
304 }
305
306 /******************************************/
307 /* GtkRecentChooserIface static functions */
308 /* */
309 /******************************************/
310
311 static void
rstto_recent_chooser_add_filter(GtkRecentChooser * chooser,GtkRecentFilter * filter)312 rstto_recent_chooser_add_filter (
313 GtkRecentChooser *chooser,
314 GtkRecentFilter *filter)
315 {
316 RsttoPrivacyDialog *dialog = RSTTO_PRIVACY_DIALOG (chooser);
317
318 /* Add the filter to the list of available filters */
319 dialog->priv->filters =
320 g_slist_append (dialog->priv->filters, filter);
321 }
322
323 static GList *
rstto_recent_chooser_get_items(GtkRecentChooser * chooser)324 rstto_recent_chooser_get_items (
325 GtkRecentChooser *chooser)
326 {
327 RsttoPrivacyDialog *dialog = RSTTO_PRIVACY_DIALOG (chooser);
328 GList *all_items = gtk_recent_manager_get_items (dialog->priv->recent_manager);
329 GList *all_items_iter = all_items;
330 GList *items = g_list_copy (all_items);
331 GList *lp;
332 GSList *filters;
333 GtkRecentInfo *info;
334 GtkRecentFilterInfo filter_info;
335 gsize n_applications;
336
337 for (lp = items; lp != NULL; lp = lp->next)
338 gtk_recent_info_ref (lp->data);
339
340 while (NULL != all_items_iter)
341 {
342 info = all_items_iter->data;
343
344 filter_info.contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_APPLICATION;
345 filter_info.uri = gtk_recent_info_get_uri (info);
346 filter_info.applications = (const gchar **) gtk_recent_info_get_applications (info, &n_applications);
347
348 if (!gtk_recent_filter_filter (dialog->priv->timeframe_filter, &filter_info))
349 {
350 items = g_list_remove (items, info);
351 gtk_recent_info_unref (info);
352 }
353 else
354 {
355 filters = dialog->priv->filters;
356
357 while (NULL != filters)
358 {
359 if (!gtk_recent_filter_filter (filters->data, &filter_info))
360 {
361 items = g_list_remove (items, info);
362 gtk_recent_info_unref (info);
363 break;
364 }
365
366 filters = g_slist_next (filters);
367 }
368 }
369
370 g_strfreev ((gchar **) filter_info.applications);
371 all_items_iter = g_list_next (all_items_iter);
372 }
373
374 g_list_free_full (all_items, (GDestroyNotify) gtk_recent_info_unref);
375
376 return items;
377 }
378
379
380
381
382 /***************/
383 /* CALLBACKS */
384 /***************/
385 static void
cb_rstto_privacy_dialog_combobox_timeframe_changed(GtkComboBox * combobox,gpointer user_data)386 cb_rstto_privacy_dialog_combobox_timeframe_changed (GtkComboBox *combobox, gpointer user_data)
387 {
388 RsttoPrivacyDialog *dialog = user_data;
389 struct tm *time_info;
390
391 switch (gtk_combo_box_get_active (combobox))
392 {
393 case 0:
394 dialog->priv->time_offset = 3600;
395 break;
396 case 1:
397 dialog->priv->time_offset = 7200;
398 break;
399 case 2:
400 dialog->priv->time_offset = 14200;
401 break;
402 case 3:
403 /* Convert to localtime */
404 time_info = localtime (&(dialog->priv->time_now));
405
406 dialog->priv->time_offset = (time_info->tm_hour * 3600) +
407 (time_info->tm_min * 60) +
408 time_info->tm_sec;
409 break;
410 case 4:
411 dialog->priv->time_offset = dialog->priv->time_now;
412 break;
413 }
414 }
415
416 gboolean
cb_rstto_recent_filter_filter_timeframe(const GtkRecentFilterInfo * filter_info,gpointer user_data)417 cb_rstto_recent_filter_filter_timeframe (
418 const GtkRecentFilterInfo *filter_info,
419 gpointer user_data)
420 {
421 RsttoPrivacyDialog *dialog = user_data;
422 GtkRecentInfo *info = gtk_recent_manager_lookup_item (dialog->priv->recent_manager, filter_info->uri, NULL);
423 const time_t visited = gtk_recent_info_get_visited (info);
424
425 gtk_recent_info_unref (info);
426
427 return (dialog->priv->time_now - visited) < dialog->priv->time_offset;
428 }
429
430 /********************/
431 /* Public functions */
432 /********************/
433
434 GtkWidget *
rstto_privacy_dialog_new(GtkWindow * parent,GtkRecentManager * recent_manager)435 rstto_privacy_dialog_new (GtkWindow *parent, GtkRecentManager *recent_manager)
436 {
437 GtkWidget *dialog = g_object_new (RSTTO_TYPE_PRIVACY_DIALOG,
438 "title", _("Clear private data"),
439 "icon-name", "edit-clear",
440 "recent-manager", recent_manager,
441 NULL);
442
443 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
444
445 return dialog;
446 }
447