aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk_unindex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk_unindex.c')
-rw-r--r--src/fs/gnunet-fs-gtk_unindex.c584
1 files changed, 584 insertions, 0 deletions
diff --git a/src/fs/gnunet-fs-gtk_unindex.c b/src/fs/gnunet-fs-gtk_unindex.c
new file mode 100644
index 00000000..1c49747a
--- /dev/null
+++ b/src/fs/gnunet-fs-gtk_unindex.c
@@ -0,0 +1,584 @@
1/*
2 This file is part of GNUnet
3 (C) 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/fs/gnunet-fs-gtk_unindex.c
23 * @author Christian Grothoff
24 * @brief operations to display and unindex indexed files
25 */
26#include "gnunet-fs-gtk.h"
27#include "gnunet-fs-gtk_common.h"
28#include "gnunet-fs-gtk_event-handler.h"
29#include "gnunet-fs-gtk_unindex.h"
30
31
32/**
33 * Columns in the unindex model.
34 */
35enum UNINDEX_ModelColumns
36 {
37 /**
38 * A gchararray.
39 */
40 UNINDEX_MC_FILENAME = 0,
41
42 /**
43 * A guint64.
44 */
45 UNINDEX_MC_FILESIZE = 1,
46
47 /**
48 * A gchararray representing a color.
49 */
50 UNINDEX_MC_BACKGROUND_COLOR = 2,
51
52 /**
53 * A 'struct UnindexEntry' (gpointer)
54 */
55 UNINDEX_MC_UNINDEX_CONTEXT = 3,
56
57 /**
58 * A gfloat.
59 */
60 UNINDEX_MC_UNINDEX_PROGRESS = 4,
61
62 /**
63 * A boolean.
64 */
65 UNINDEX_MC_PROGRESS_VISIBLE = 5,
66
67 /**
68 * A gchararray.
69 */
70 UNINDEX_MC_ERROR = 6
71 };
72
73
74/**
75 * Overall context for the dialog.
76 */
77struct UnindexDialogContext
78{
79 GtkBuilder *builder;
80
81 /**
82 * The dialog object.
83 */
84 GtkWidget *dialog;
85
86 /**
87 * The unindex button.
88 */
89 GtkWidget *unindex_button;
90
91 /**
92 * Main treeview object.
93 */
94 GtkTreeView *treeview;
95
96 /**
97 * Selection of our treeview.
98 */
99 GtkTreeSelection *selection;
100
101 /**
102 * Unindex data model.
103 */
104 GtkTreeModel *model;
105
106 /**
107 * Context for initial listing of indexed files.
108 */
109 struct GNUNET_FS_GetIndexedContext *gic;
110};
111
112
113/**
114 * Information for a specific unindex operation.
115 */
116struct UnindexEntry
117{
118
119 /**
120 * Kept in a DLL.
121 */
122 struct UnindexEntry *next;
123
124 /**
125 * Next entry.
126 */
127 struct UnindexEntry *prev;
128
129 /**
130 * Name of the file being unindexed.
131 */
132 char *filename;
133
134 /**
135 * Error description, NULL if no error
136 */
137 char *emsg;
138
139 /**
140 * Handle with FS.
141 */
142 struct GNUNET_FS_UnindexContext *uc;
143
144 /**
145 * Row reference, NULL if the dialog is not open.
146 */
147 GtkTreeRowReference *rr;
148
149 /**
150 * Size of the file.
151 */
152 uint64_t filesize;
153
154 /**
155 * Percentage progress made so far.
156 */
157 gint progress;
158};
159
160
161/**
162 * There can only be one.
163 */
164static struct UnindexDialogContext *master_udc;
165
166/**
167 * Head of linked list.
168 */
169static struct UnindexEntry *ue_head;
170
171/**
172 * Tail of linked list.
173 */
174static struct UnindexEntry *ue_tail;
175
176
177/**
178 * User has clicked on the 'delete/unindex' button for the dialog.
179 * Unindex the selected file.
180 *
181 * @param dummy the button
182 * @param user_data the unindex context
183 */
184void
185GNUNET_FS_GTK_unindex_button_clicked_cb (GtkWidget * dummy,
186 gpointer user_data)
187{
188 struct UnindexDialogContext *udc = user_data;
189 GtkTreeIter iter;
190 char *filename;
191 struct UnindexEntry *ue;
192 GtkTreePath *path;
193 guint64 filesize;
194
195 /* find out if a file is selected */
196 if (! gtk_tree_selection_get_selected (udc->selection, NULL, &iter))
197 {
198 GNUNET_break (0);
199 return;
200 }
201 gtk_tree_model_get (udc->model, &iter,
202 UNINDEX_MC_FILENAME, &filename,
203 UNINDEX_MC_FILESIZE, &filesize,
204 UNINDEX_MC_UNINDEX_CONTEXT, &ue,
205 -1);
206 if (NULL != ue)
207 {
208 GNUNET_break (0);
209 g_free (filename);
210 return;
211 }
212 ue = GNUNET_malloc (sizeof (struct UnindexEntry));
213 ue->filesize = filesize;
214 GNUNET_CONTAINER_DLL_insert (ue_head, ue_tail, ue);
215 ue->filename = GNUNET_strdup (filename);
216 path = gtk_tree_model_get_path (udc->model, &iter);
217 ue->rr = gtk_tree_row_reference_new (udc->model, path);
218 gtk_tree_path_free (path);
219 ue->uc = GNUNET_FS_unindex_start (GNUNET_FS_GTK_get_fs_handle (),
220 filename, ue);
221 gtk_list_store_set (GTK_LIST_STORE (udc->model),
222 &iter,
223 UNINDEX_MC_BACKGROUND_COLOR, "yellow",
224 UNINDEX_MC_UNINDEX_CONTEXT, ue,
225 UNINDEX_MC_UNINDEX_PROGRESS, 0,
226 UNINDEX_MC_PROGRESS_VISIBLE, TRUE,
227 -1);
228 gtk_widget_set_sensitive (udc->unindex_button, FALSE);
229}
230
231
232/**
233 * User has clicked on the 'close' button for the dialog. Close it.
234 *
235 * @param dummy the button
236 * @param user_data the unindex context
237 */
238void
239GNUNET_FS_GTK_unindex_close_button_clicked_cb (GtkWidget * dummy,
240 gpointer user_data)
241{
242 struct UnindexDialogContext *udc = user_data;
243 GtkTreeIter iter;
244 struct UnindexEntry *ue;
245
246 if (NULL != udc->gic)
247 {
248 GNUNET_FS_get_indexed_files_cancel (udc->gic);
249 udc->gic = NULL;
250 }
251 if (gtk_tree_model_get_iter_first (udc->model, &iter))
252 do
253 {
254 gtk_tree_model_get (udc->model, &iter,
255 UNINDEX_MC_UNINDEX_CONTEXT, &ue,
256 -1);
257 if (NULL != ue)
258 {
259 gtk_tree_row_reference_free (ue->rr);
260 ue->rr = NULL;
261 }
262 }
263 while (TRUE == gtk_tree_model_iter_next (udc->model, &iter));
264 gtk_widget_destroy (udc->dialog);
265 g_object_unref (G_OBJECT (udc->builder));
266 GNUNET_free (udc);
267 master_udc = NULL;
268}
269
270
271/**
272 * The selection in the tree view changed; update the button sensitivity.
273 *
274 * @param ts the changed selection
275 * @param user_data our unindex context
276 */
277static void
278selection_changed_cb (GtkTreeSelection * ts,
279 gpointer user_data)
280{
281 struct UnindexDialogContext *udc = user_data;
282 GtkTreeIter iter;
283 struct UnindexEntry *ue;
284
285 /* find out if a file is selected */
286 if (gtk_tree_selection_get_selected (udc->selection, NULL, &iter))
287 {
288 gtk_tree_model_get (udc->model, &iter,
289 UNINDEX_MC_UNINDEX_CONTEXT, &ue,
290 -1);
291 if (NULL == ue)
292 {
293 /* selected file not already being unindexed, enable button! */
294 gtk_widget_set_sensitive (udc->unindex_button, TRUE);
295 return;
296 }
297 }
298 gtk_widget_set_sensitive (udc->unindex_button, FALSE);
299}
300
301
302/**
303 * Type of a function called by "GNUNET_FS_get_indexed_files".
304 *
305 * @param cls closure
306 * @param filename the name of the file, NULL for end of list
307 * @param file_id hash of the contents of the indexed file
308 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
309 */
310static int
311add_indexed_file (void *cls, const char *filename,
312 const GNUNET_HashCode * file_id)
313{
314 struct UnindexDialogContext *udc = cls;
315 GtkTreeIter iter;
316 uint64_t filesize;
317 struct UnindexEntry *ue;
318 GtkTreePath *path;
319
320 if (NULL == filename)
321 {
322 /* end of list */
323 udc->gic = NULL;
324 return GNUNET_OK;
325 }
326 if (GNUNET_OK !=
327 GNUNET_DISK_file_size (filename,
328 &filesize,
329 GNUNET_YES))
330 {
331 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
332 _("Could not access indexed file `%s'\n"),
333 filename);
334 return GNUNET_OK;
335 }
336 for (ue = ue_head; ue != NULL; ue = ue->next)
337 if (0 == strcmp (ue->filename, filename))
338 break;
339 if (NULL == ue)
340 {
341 gtk_list_store_insert_with_values (GTK_LIST_STORE (udc->model),
342 &iter, G_MAXINT,
343 UNINDEX_MC_FILENAME, filename,
344 UNINDEX_MC_FILESIZE, (guint64) filesize,
345 UNINDEX_MC_BACKGROUND_COLOR, "white",
346 UNINDEX_MC_PROGRESS_VISIBLE, FALSE,
347 -1);
348 }
349 else
350 {
351 if (NULL != ue->rr)
352 {
353 GNUNET_break (0);
354 return GNUNET_OK;
355 }
356 gtk_list_store_insert_with_values (GTK_LIST_STORE (udc->model),
357 &iter, G_MAXINT,
358 UNINDEX_MC_FILENAME, filename,
359 UNINDEX_MC_FILESIZE, (guint64) filesize,
360 UNINDEX_MC_BACKGROUND_COLOR, (NULL == ue->emsg) ? "yellow" : "red",
361 UNINDEX_MC_UNINDEX_CONTEXT, ue,
362 UNINDEX_MC_UNINDEX_PROGRESS, ue->progress,
363 UNINDEX_MC_PROGRESS_VISIBLE, TRUE,
364 UNINDEX_MC_ERROR, ue->emsg,
365 -1);
366 path = gtk_tree_model_get_path (udc->model, &iter);
367 ue->rr = gtk_tree_row_reference_new (udc->model, path);
368 }
369 return GNUNET_OK;
370}
371
372
373/**
374 * User selected "List indexed files..." in menu. Display dialog.
375 *
376 * @param dummy the menu entry
377 * @param user_data the main dialog builder, unused
378 */
379void
380GNUNET_GTK_main_menu_unindex_activate_cb (GtkWidget * dummy,
381 gpointer data)
382{
383 GtkWidget *toplevel;
384 struct UnindexDialogContext *udc;
385
386 if (NULL != master_udc)
387 {
388 /* window already exists, raise focus */
389 gtk_window_present (GTK_WINDOW (master_udc->dialog));
390 return;
391 }
392 udc = GNUNET_malloc (sizeof (struct UnindexDialogContext));
393 udc->builder =
394 GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_unindex.glade", udc);
395 if (NULL == udc->builder)
396 {
397 GNUNET_break (0);
398 GNUNET_free (udc);
399 return;
400 }
401 udc->dialog = GTK_WIDGET (gtk_builder_get_object
402 (udc->builder, "GNUNET_FS_GTK_unindex_dialog"));
403 udc->treeview = GTK_TREE_VIEW (gtk_builder_get_object
404 (udc->builder, "GNUNET_FS_GTK_unindex_treeview"));
405 udc->selection = gtk_tree_view_get_selection (udc->treeview);
406 udc->unindex_button = GTK_WIDGET (gtk_builder_get_object
407 (udc->builder, "GNUNET_FS_GTK_unindex_button"));
408 udc->model = GTK_TREE_MODEL (gtk_builder_get_object
409 (udc->builder, "GNUNET_FS_GTK_unindex_liststore"));
410 udc->gic = GNUNET_FS_get_indexed_files (GNUNET_FS_GTK_get_fs_handle (),
411 &add_indexed_file,
412 udc);
413 toplevel = gtk_widget_get_toplevel (dummy);
414 if (GTK_IS_WINDOW (toplevel))
415 gtk_window_set_transient_for (GTK_WINDOW (udc->dialog), GTK_WINDOW (toplevel));
416 /* connect signals; FIXME-GTK3: these could be connected with (modern) Glade */
417 g_signal_connect (G_OBJECT (udc->selection), "changed",
418 G_CALLBACK (selection_changed_cb), udc);
419 gtk_window_present (GTK_WINDOW (udc->dialog));
420 master_udc = udc;
421}
422
423
424/**
425 * An unindex operation resumed. Setup the
426 * internal context for Gtk.
427 *
428 * @param fs unindex context with the FS library
429 * @param filename name of file being unindexed
430 * @param filesize size of the file
431 * @param completed how many bytes were done so far
432 * @param emsg NULL if everything is fine, otherwise error message
433 */
434struct UnindexEntry *
435GNUNET_FS_GTK_unindex_handle_resume_ (struct GNUNET_FS_UnindexContext *uc,
436 const char *filename,
437 uint64_t filesize,
438 uint64_t completed,
439 const char *emsg)
440{
441 struct UnindexEntry *ue;
442
443 ue = GNUNET_malloc (sizeof (struct UnindexEntry));
444 ue->filename = GNUNET_strdup (filename);
445 if (NULL != emsg)
446 ue->emsg = GNUNET_strdup (emsg);
447 ue->filesize = filesize;
448 ue->uc = uc;
449 ue->progress = (gint) ((100LL * completed) / filesize);
450 GNUNET_CONTAINER_DLL_insert (ue_head,
451 ue_tail,
452 ue);
453 return ue;
454}
455
456
457/**
458 * FS notified us that our undex operation was stopped.
459 *
460 * @param ue operation that stopped
461 */
462void
463GNUNET_FS_GTK_unindex_handle_stop_ (struct UnindexEntry *ue)
464{
465 GtkTreePath *path;
466 GtkTreeIter iter;
467 GtkTreeModel *model;
468
469 if (NULL != ue->rr)
470 {
471 path = gtk_tree_row_reference_get_path (ue->rr);
472 model = gtk_tree_row_reference_get_model (ue->rr);
473 gtk_tree_row_reference_free (ue->rr);
474 ue->rr = NULL;
475 GNUNET_assert (TRUE == gtk_tree_model_get_iter (model,
476 &iter,
477 path));
478 gtk_tree_path_free (path);
479 gtk_list_store_set (GTK_LIST_STORE (model),
480 &iter,
481 UNINDEX_MC_UNINDEX_CONTEXT, NULL,
482 -1);
483 }
484 GNUNET_CONTAINER_DLL_remove (ue_head,
485 ue_tail,
486 ue);
487 GNUNET_free_non_null (ue->emsg);
488 GNUNET_free (ue->filename);
489 GNUNET_free (ue);
490}
491
492
493/**
494 * FS notified us that our undex operation had an error.
495 *
496 * @param ue operation that had an error
497 * @param emsg error message
498 */
499void
500GNUNET_FS_GTK_unindex_handle_error_ (struct UnindexEntry *ue,
501 const char *emsg)
502{
503 GtkTreePath *path;
504 GtkTreeIter iter;
505 GtkTreeModel *model;
506
507 ue->emsg = GNUNET_strdup (emsg);
508 if (NULL == ue->rr)
509 return;
510 path = gtk_tree_row_reference_get_path (ue->rr);
511 model = gtk_tree_row_reference_get_model (ue->rr);
512 GNUNET_assert (TRUE == gtk_tree_model_get_iter (model,
513 &iter,
514 path));
515 gtk_tree_path_free (path);
516 gtk_list_store_set (GTK_LIST_STORE (model),
517 &iter,
518 UNINDEX_MC_BACKGROUND_COLOR, "red",
519 UNINDEX_MC_ERROR, emsg,
520 -1);
521}
522
523
524/**
525 * FS notified us that our undex operation made progress
526 *
527 * @param ue operation that made progress
528 * @param completed number of bytes completed now
529 */
530void
531GNUNET_FS_GTK_unindex_handle_progress_ (struct UnindexEntry *ue,
532 uint64_t completed)
533{
534 GtkTreePath *path;
535 GtkTreeIter iter;
536 GtkTreeModel *model;
537
538 ue->progress = (gint) ((100LL * completed) / ue->filesize);
539 if (NULL == ue->rr)
540 return;
541 path = gtk_tree_row_reference_get_path (ue->rr);
542 model = gtk_tree_row_reference_get_model (ue->rr);
543 GNUNET_assert (TRUE == gtk_tree_model_get_iter (model,
544 &iter,
545 path));
546 gtk_tree_path_free (path);
547 gtk_list_store_set (GTK_LIST_STORE (model),
548 &iter,
549 UNINDEX_MC_UNINDEX_PROGRESS, ue->progress,
550 -1);
551}
552
553
554/**
555 * FS notified us that our undex operation completed
556 *
557 * @param ue operation that completed
558 */
559void
560GNUNET_FS_GTK_unindex_handle_completed_ (struct UnindexEntry *ue)
561{
562 GtkTreePath *path;
563 GtkTreeIter iter;
564 GtkTreeModel *model;
565
566 if (NULL != ue->rr)
567 {
568 path = gtk_tree_row_reference_get_path (ue->rr);
569 model = gtk_tree_row_reference_get_model (ue->rr);
570 GNUNET_assert (TRUE == gtk_tree_model_get_iter (model,
571 &iter,
572 path));
573 gtk_tree_path_free (path);
574 gtk_list_store_remove (GTK_LIST_STORE (model),
575 &iter);
576 gtk_tree_row_reference_free (ue->rr);
577 ue->rr = NULL;
578 }
579 GNUNET_FS_unindex_stop (ue->uc);
580}
581
582
583
584/* end of gnunet-fs-gtk_unindex.c */