aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2006-10-29 19:50:11 +0000
committerChristian Grothoff <christian@grothoff.org>2006-10-29 19:50:11 +0000
commitb30837e852c7ba43ce4372aabe539be2cd565ebc (patch)
tree41bf3b8af3546b581aa40622f9b25a13221da527
parentb6eb2c21ad31d585bfcdf7be8d48df6433fd876f (diff)
downloadgnunet-gtk-b30837e852c7ba43ce4372aabe539be2cd565ebc.tar.gz
gnunet-gtk-b30837e852c7ba43ce4372aabe539be2cd565ebc.zip
fixing compile errors
-rw-r--r--TODO1
-rw-r--r--src/include/gnunetgtk_common.h8
-rw-r--r--src/plugins/daemon/daemon.c2
-rw-r--r--src/plugins/fs/Makefile.am1
-rw-r--r--src/plugins/fs/download.c705
-rw-r--r--src/plugins/fs/download.h56
-rw-r--r--src/plugins/fs/fs.c176
-rw-r--r--src/plugins/fs/fs.h136
-rw-r--r--src/plugins/fs/meta.c8
-rw-r--r--src/plugins/fs/search.c981
-rw-r--r--src/plugins/fs/search.h59
11 files changed, 1146 insertions, 987 deletions
diff --git a/TODO b/TODO
index f8134666..718334f9 100644
--- a/TODO
+++ b/TODO
@@ -4,6 +4,7 @@
4 * update event managements for upload 4 * update event managements for upload
5 * complete UI options processing for search and download and upload; 5 * complete UI options processing for search and download and upload;
6 including recursive download! 6 including recursive download!
7 * fix thread context switching
7 * test, test, test! 8 * test, test, test!
8 * support abort of search/download/upload (without killing it) 9 * support abort of search/download/upload (without killing it)
9 * check memory leaks! 10 * check memory leaks!
diff --git a/src/include/gnunetgtk_common.h b/src/include/gnunetgtk_common.h
index 86c19913..e33011eb 100644
--- a/src/include/gnunetgtk_common.h
+++ b/src/include/gnunetgtk_common.h
@@ -27,6 +27,10 @@
27#ifndef GTKUI_HELPER_H 27#ifndef GTKUI_HELPER_H
28#define GTKUI_HELPER_H 28#define GTKUI_HELPER_H
29 29
30#include <gtk/gtk.h>
31#include <gtk/gtktext.h>
32#include <glade/glade.h>
33
30#define DEBUG_GTK 0 34#define DEBUG_GTK 0
31 35
32#if DEBUG_GTK 36#if DEBUG_GTK
@@ -39,10 +43,6 @@
39#define DEBUG_END() 43#define DEBUG_END()
40#endif 44#endif
41 45
42#ifndef DATADIR
43#include "datadir.h"
44#endif
45
46void initGNUnetGTKCommon(struct GE_Context * ectx, 46void initGNUnetGTKCommon(struct GE_Context * ectx,
47 struct GC_Configuration * cfg, 47 struct GC_Configuration * cfg,
48 void * callback); 48 void * callback);
diff --git a/src/plugins/daemon/daemon.c b/src/plugins/daemon/daemon.c
index 3b8bf244..4f7737dc 100644
--- a/src/plugins/daemon/daemon.c
+++ b/src/plugins/daemon/daemon.c
@@ -101,7 +101,7 @@ static void updateAppModelSafe(void * unused) {
101 "applicationList"); 101 "applicationList");
102 gtk_tree_view_set_model(GTK_TREE_VIEW(w), 102 gtk_tree_view_set_model(GTK_TREE_VIEW(w),
103 GTK_TREE_MODEL(model)); 103 GTK_TREE_MODEL(model));
104 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(searchList)), 104 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)),
105 GTK_SELECTION_NONE); 105 GTK_SELECTION_NONE);
106 connection_destroy(sock); 106 connection_destroy(sock);
107} 107}
diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am
index b70c3284..fae720d5 100644
--- a/src/plugins/fs/Makefile.am
+++ b/src/plugins/fs/Makefile.am
@@ -16,6 +16,7 @@ libgnunetgtkmodule_fs_la_SOURCES = \
16 meta.c meta.h \ 16 meta.c meta.h \
17 namespace.c namespace.h \ 17 namespace.c namespace.h \
18 search.c search.h \ 18 search.c search.h \
19 download.c download.h \
19 upload.c upload.h 20 upload.c upload.h
20libgnunetgtkmodule_fs_la_LIBADD = \ 21libgnunetgtkmodule_fs_la_LIBADD = \
21 $(top_builddir)/src/common/libgnunetgtk_common.la \ 22 $(top_builddir)/src/common/libgnunetgtk_common.la \
diff --git a/src/plugins/fs/download.c b/src/plugins/fs/download.c
new file mode 100644
index 00000000..f425a3f7
--- /dev/null
+++ b/src/plugins/fs/download.c
@@ -0,0 +1,705 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006 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/**
23 * @file src/plugins/fs/download.c
24 * @brief code for downloading with gnunet-gtk
25 * @author Christian Grothoff
26 */
27
28#include "fs.h"
29#include "search.h"
30#include "meta.h"
31#include "platform.h"
32
33/* ****************** FSUI download events ****************** */
34
35/**
36 * We are iterating over the contents of a
37 * directory. Add the list of entries to
38 * the search page at the position indicated
39 * by the download list.
40 */
41static int
42addFilesToDirectory(const ECRS_FileInfo * fi,
43 const HashCode512 * key,
44 int isRoot,
45 void * closure) {
46 DownloadList * list = closure;
47 GtkTreeIter iter;
48 GtkTreeIter child;
49 int i;
50 GtkTreePath * path;
51 GtkTreeModel * model;
52
53 if (isRoot == YES)
54 return OK;
55 if (! gtk_tree_row_reference_valid(list->searchViewRowReference))
56 return SYSERR;
57 model = GTK_TREE_MODEL(list->searchList->tree);
58 path = gtk_tree_row_reference_get_path(list->searchViewRowReference);
59 gtk_tree_model_get_iter(model,
60 &iter,
61 path);
62 gtk_tree_path_free(path);
63 /* check for existing entry -- this function
64 maybe called multiple times for the same
65 directory entry */
66 for (i=gtk_tree_model_iter_n_children(model,
67 &iter)-1;i>=0;i--) {
68 if (TRUE == gtk_tree_model_iter_nth_child(model,
69 &child,
70 &iter,
71 i)) {
72 struct ECRS_URI * uri;
73 uri = NULL;
74 gtk_tree_model_get(model,
75 &child,
76 SEARCH_URI, &uri,
77 -1);
78 if ( (uri != NULL) &&
79 (ECRS_equalsUri(uri,
80 fi->uri)) )
81 return OK;
82 }
83 }
84 gtk_tree_store_append(GTK_TREE_STORE(model),
85 &child,
86 &iter);
87 addEntryToSearchTree(list->searchList,
88 list,
89 fi,
90 &child);
91 return OK;
92}
93
94static void
95refreshDirectoryViewFromDisk(DownloadList * list) {
96 unsigned long long size;
97 char * data;
98 int fd;
99 struct ECRS_MetaData * meta;
100
101 if ( (list->is_directory != YES) ||
102 (list->searchList == NULL) ||
103 (list->searchViewRowReference == NULL) ||
104 (! gtk_tree_row_reference_valid(list->searchViewRowReference)) )
105 return;
106
107 if (OK != disk_file_size(ectx,
108 list->filename,
109 &size,
110 YES))
111 return;
112 fd = disk_file_open(ectx,
113 list->filename,
114 O_RDONLY);
115 if (fd == -1)
116 return;
117 data = MMAP(NULL,
118 size,
119 PROT_READ,
120 MAP_SHARED,
121 fd,
122 0);
123 if ( (data == MAP_FAILED) ||
124 (data == NULL) ) {
125 GE_LOG_STRERROR_FILE(ectx,
126 GE_ERROR | GE_ADMIN | GE_BULK,
127 "mmap",
128 list->filename);
129 CLOSE(fd);
130 return;
131 }
132 meta = NULL;
133 ECRS_listDirectory(ectx,
134 data,
135 size,
136 &meta,
137 &addFilesToDirectory,
138 list);
139 MUNMAP(data, size);
140 CLOSE(fd);
141 if (meta != NULL)
142 ECRS_freeMetaData(meta);
143}
144
145/**
146 * A download has been started. Add an entry
147 * to the search tree view (if applicable) and
148 * the download summary.
149 */
150DownloadList *
151fs_download_started(struct FSUI_DownloadList * fsui_dl,
152 DownloadList * dl_parent,
153 SearchList * sl_parent,
154 unsigned long long total,
155 unsigned int anonymityLevel,
156 const ECRS_FileInfo * fi,
157 const char * filename,
158 unsigned long long completed,
159 cron_t eta) {
160 DownloadList * list;
161 GtkTreeIter iter;
162 GtkTreePath * path;
163 unsigned long long size;
164 char * size_h;
165 const char * sname;
166 int progress;
167 char * uri_name;
168 gboolean valid;
169 struct ECRS_URI * u;
170
171 /* setup visualization */
172 list = MALLOC(sizeof(DownloadList));
173 memset(list,
174 0,
175 sizeof(DownloadList));
176 list->uri = ECRS_dupUri(fi->uri);
177 list->filename = STRDUP(filename);
178 /* FIXME: if we have dl_parent,
179 we may not want to just append! */
180 gtk_tree_store_append(download_summary,
181 &iter,
182 NULL);
183 size = ECRS_fileSize(fi->uri);
184 size_h = string_get_fancy_byte_size(size);
185 sname = &filename[strlen(filename)-1];
186 while ( (sname > filename) &&
187 (sname[-1] != '/') &&
188 (sname[-1] != '\\') )
189 sname--;
190 if (size != 0)
191 progress = completed * 100 / size;
192 else
193 progress = 100;
194 uri_name = ECRS_uriToString(fi->uri);
195 gtk_tree_store_set(download_summary,
196 &iter,
197 DOWNLOAD_FILENAME, filename,
198 DOWNLOAD_SHORTNAME, sname,
199 DOWNLOAD_SIZE, size,
200 DOWNLOAD_HSIZE, size_h,
201 DOWNLOAD_PROGRESS, progress,
202 DOWNLOAD_URISTRING, uri_name,
203 DOWNLOAD_INTERNAL, list,
204 -1);
205 FREE(uri_name);
206 FREE(size_h);
207 path = gtk_tree_model_get_path(GTK_TREE_MODEL(download_summary),
208 &iter);
209 list->summaryViewRowReference
210 = gtk_tree_row_reference_new(GTK_TREE_MODEL(download_summary),
211 path);
212 gtk_tree_path_free(path);
213 list->searchList = sl_parent;
214 if (sl_parent != NULL) {
215 if (dl_parent != NULL) {
216 /* have parent, must be download from
217 directory inside of search */
218 path = gtk_tree_row_reference_get_path(dl_parent->searchViewRowReference);
219 valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(sl_parent->tree),
220 &iter,
221 path);
222 } else {
223 /* must be top-level entry in search */
224 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(sl_parent->tree),
225 &iter);
226 }
227 if (valid == TRUE) {
228 valid = FALSE;
229 /* find matching entry */
230 do {
231 gtk_tree_model_get(GTK_TREE_MODEL(sl_parent->tree),
232 &iter,
233 SEARCH_URI, &u,
234 -1);
235 if (ECRS_equalsUri(u,
236 fi->uri)) {
237 valid = TRUE;
238 path = gtk_tree_model_get_path(GTK_TREE_MODEL(sl_parent->tree),
239 &iter);
240 list->searchViewRowReference
241 = gtk_tree_row_reference_new(GTK_TREE_MODEL(sl_parent->tree),
242 path);
243 gtk_tree_path_free(path);
244 /* TODO: extend search model with status;
245 start to indicate active download! */
246 break;
247 }
248 } while (TRUE == gtk_tree_model_iter_next(GTK_TREE_MODEL(sl_parent->tree),
249 &iter));
250 }
251 if (valid == FALSE) {
252 /* did not find matching entry in search list
253 -- bug! Continue without adding to to
254 search list! */
255 GE_BREAK(ectx, 0);
256 list->searchList = NULL;
257 }
258 }
259 list->fsui_list = fsui_dl;
260 list->total = total;
261 list->is_directory = ECRS_isDirectory(fi->meta);
262 list->next = download_head;
263 download_head = list;
264 if ( (list->is_directory == YES) &&
265 (completed != 0) )
266 refreshDirectoryViewFromDisk(list);
267 return list;
268}
269
270/**
271 * The download has progressed. Update the
272 * summary and the preview of the directory
273 * contents in the search page (if applicable).
274 */
275void fs_download_update(DownloadList * list,
276 unsigned long long completed,
277 const char * data,
278 unsigned int size) {
279 GtkTreeIter iter;
280 GtkTreePath * path;
281 unsigned int val;
282
283 path = gtk_tree_row_reference_get_path(list->summaryViewRowReference);
284 gtk_tree_model_get_iter(GTK_TREE_MODEL(download_summary),
285 &iter,
286 path);
287 gtk_tree_path_free(path);
288 if (list->total != 0)
289 val = completed * 100 / list->total;
290 else
291 val = 100;
292 gtk_tree_store_set(download_summary,
293 &iter,
294 DOWNLOAD_PROGRESS, val,
295 -1);
296 if ( (list->is_directory == YES) &&
297 (list->searchList != NULL) &&
298 (list->searchViewRowReference != NULL) ) {
299 struct ECRS_MetaData * meta;
300
301 meta = NULL;
302 ECRS_listDirectory(ectx,
303 data,
304 size,
305 &meta,
306 &addFilesToDirectory,
307 list);
308 if (meta != NULL)
309 ECRS_freeMetaData(meta);
310 }
311}
312
313/**
314 * A download has terminated successfully. Update summary and
315 * possibly refresh directory listing.
316 */
317void fs_download_completed(DownloadList * downloadContext) {
318 /* FIXME: update summary? / search list status entry (once added) */
319 downloadContext->has_terminated = YES;
320 refreshDirectoryViewFromDisk(downloadContext);
321}
322
323/**
324 * A download has been aborted. Update summary and
325 * possibly refresh directory listing.
326 */
327void fs_download_aborted(DownloadList * downloadContext) {
328 /* FIXME: update summary? / search list status entry (once added) */
329 downloadContext->has_terminated = YES;
330 refreshDirectoryViewFromDisk(downloadContext);
331}
332
333/**
334 * A download has been stopped. Remove from summary
335 * and free associated resources.
336 */
337void fs_download_stopped(DownloadList * list) {
338 GtkTreeIter iter;
339 GtkTreePath * path;
340 DownloadList * prev;
341
342 path = gtk_tree_row_reference_get_path(list->summaryViewRowReference);
343 gtk_tree_model_get_iter(GTK_TREE_MODEL(download_summary),
344 &iter,
345 path);
346 gtk_tree_path_free(path);
347 gtk_tree_row_reference_free(list->summaryViewRowReference);
348 list->summaryViewRowReference = NULL;
349 gtk_tree_store_remove(download_summary,
350 &iter);
351 if (list->searchViewRowReference != NULL) {
352 gtk_tree_row_reference_free(list->searchViewRowReference);
353 list->searchViewRowReference = NULL;
354 }
355 FREE(list->filename);
356 ECRS_freeUri(list->uri);
357
358 if (download_head == list)
359 download_head = list->next;
360 else {
361 prev = download_head;
362 while ( (prev != NULL) &&
363 (prev->next != list) )
364 prev = prev->next;
365 if (prev != NULL)
366 prev->next = list->next;
367 else
368 GE_BREAK(ectx, 0);
369 }
370 FREE(list);
371}
372
373
374/* **************** user download events ******************** */
375
376/**
377 * The user clicked the download button.
378 * Start the download of the selected entry.
379 */
380static void
381initiateDownload(GtkTreeModel * model,
382 GtkTreePath * path,
383 GtkTreeIter * iter,
384 gpointer unused) {
385 char * uri_name;
386 char * final_download_dir;
387 GtkTreeIter iiter;
388 const char * oname;
389 const char * cname;
390 char * dname;
391 GtkTreePath *dirTreePath;
392 char *dirPath;
393 unsigned int dirPathLen;
394 struct ECRS_URI * idc_uri;
395 struct ECRS_MetaData * idc_meta;
396 const char * idc_name;
397 const char * idc_mime;
398 char * idc_final_download_destination;
399 SearchList * searchContext;
400 DownloadList * parentContext;
401
402#ifdef WINDOWS
403 char *filehash = NULL;
404#endif
405
406 DEBUG_BEGIN();
407 idc_uri = NULL;
408 idc_meta = NULL;
409 idc_name = NULL;
410 idc_mime = NULL;
411 searchContext = NULL;
412 parentContext = NULL;
413 gtk_tree_model_get(model,
414 iter,
415 SEARCH_NAME, &idc_name,
416 SEARCH_URI, &idc_uri,
417 SEARCH_META, &idc_meta,
418 SEARCH_MIME, &idc_mime,
419 SEARCH_INTERNAL, &searchContext,
420 SEARCH_INTERNAL_PARENT, &parentContext,
421 -1);
422 if ( (idc_uri == NULL) ||
423 (! ECRS_isFileUri(idc_uri)) ) {
424 GE_BREAK(ectx, 0);
425 return;
426 }
427 uri_name = ECRS_uriToString(idc_uri);
428 if ( (uri_name == NULL) ||
429 (strlen(uri_name) <
430 strlen(ECRS_URI_PREFIX) +
431 strlen(ECRS_FILE_INFIX)) ) {
432 GE_BREAK(ectx, 0);
433 FREENONNULL(uri_name);
434 return;
435 }
436 if (idc_name == NULL) {
437#ifdef WINDOWS
438 filehash = STRDUP(uri_name);
439 filehash[16] = 0;
440 idc_name = filehash;
441#else
442 idc_name = uri_name;
443#endif
444 }
445 cname = idc_name;
446 oname = idc_name;
447 dname = MALLOC(strlen(idc_name)+1);
448 dname[0] = '\0';
449 while (*idc_name != '\0') {
450 if ( (*idc_name == DIR_SEPARATOR) &&
451 (idc_name[1] != '\0') ) {
452 memcpy(dname, oname, idc_name - oname);
453 dname[idc_name - oname] = '\0';
454 cname = &idc_name[1];
455 }
456 idc_name++;
457 }
458 if (*cname == '\0') /* name ended in '/' - likely directory */
459 cname = oname;
460 idc_name = cname;
461 GC_get_configuration_value_filename(cfg,
462 "FS",
463 "INCOMINGDIR",
464 "$HOME/gnunet-downloads/",
465 &final_download_dir);
466 if (strlen(dname) > 0) {
467 char * tmp;
468 tmp = MALLOC(strlen(final_download_dir) + strlen(dname) + 2);
469 strcpy(tmp, final_download_dir);
470 if (tmp[strlen(tmp)] != DIR_SEPARATOR)
471 strcat(tmp, DIR_SEPARATOR_STR);
472 if (dname[0] == DIR_SEPARATOR)
473 strcat(tmp, &dname[1]);
474 else
475 strcat(tmp, dname);
476 FREE(final_download_dir);
477 final_download_dir = tmp;
478 }
479 FREE(dname);
480 disk_directory_create(ectx, final_download_dir);
481
482
483 /* If file is inside a directory, get the full path */
484 dirTreePath = gtk_tree_path_copy(path);
485 dirPath = MALLOC(1);
486 dirPath[0] = '\0';
487 dirPathLen = 0;
488 while (gtk_tree_path_get_depth(dirTreePath) > 1) {
489 const char * dirname;
490 char * new;
491
492 if (! gtk_tree_path_up(dirTreePath))
493 break;
494
495 if (!gtk_tree_model_get_iter(model,
496 &iiter,
497 dirTreePath))
498 break;
499 gtk_tree_model_get(model,
500 &iiter,
501 SEARCH_NAME, &dirname,
502 -1);
503 dirPathLen = strlen(dirPath) + strlen(dirname) + strlen(DIR_SEPARATOR_STR) + 1;
504 new = MALLOC(dirPathLen + 1);
505 strcpy(new, dirname);
506 if (new[strlen(new)-1] != DIR_SEPARATOR)
507 strcat(new, DIR_SEPARATOR_STR);
508 strcat(new, dirPath);
509 FREE(dirPath);
510 dirPath = new;
511 }
512 gtk_tree_path_free(dirTreePath);
513
514
515 /* construct completed/directory/real-filename */
516 idc_final_download_destination = MALLOC(strlen(final_download_dir) + 2 +
517 strlen(idc_name) + strlen(GNUNET_DIRECTORY_EXT) +
518 strlen(dirPath));
519 strcpy(idc_final_download_destination, final_download_dir);
520 if (idc_final_download_destination[strlen(idc_final_download_destination)-1] != DIR_SEPARATOR)
521 strcat(idc_final_download_destination,
522 DIR_SEPARATOR_STR);
523 strcat(idc_final_download_destination, dirPath);
524 disk_directory_create(ectx,
525 idc_final_download_destination);
526 strcat(idc_final_download_destination, idc_name);
527 if ( (idc_final_download_destination[strlen(idc_final_download_destination) - 1] == '/') ||
528 (idc_final_download_destination[strlen(idc_final_download_destination) - 1] == '\\') )
529 idc_final_download_destination[strlen(idc_final_download_destination) - 1] = '\0';
530 /* append ".gnd" if needed (== directory and .gnd not present) */
531 if ( (idc_mime != NULL) &&
532 (0 == strcmp(idc_mime, GNUNET_DIRECTORY_MIME)) &&
533 ( (strlen(idc_final_download_destination) < strlen(GNUNET_DIRECTORY_EXT)) ||
534 (0 != strcmp(&idc_final_download_destination[strlen(idc_final_download_destination)
535 - strlen(GNUNET_DIRECTORY_EXT)],
536 GNUNET_DIRECTORY_EXT)) ) )
537 strcat(idc_final_download_destination, GNUNET_DIRECTORY_EXT);
538
539 addLogEntry(_("Downloading `%s'"), idc_name);
540 FSUI_startDownload(ctx,
541 0, /* FIXME: anonymity level */
542 NO, /* FIXME: isRecursive */
543 idc_uri,
544 idc_meta,
545 idc_final_download_destination,
546 searchContext->fsui_list,
547 (parentContext != NULL) ? parentContext->fsui_list : NULL);
548 FREE(uri_name);
549 FREE(dirPath);
550 FREENONNULL(final_download_dir);
551#ifdef WINDOWS
552 FREENONNULL(filehash);
553#endif
554}
555
556/**
557 * The download button in the search dialog was
558 * clicked. Download all selected entries.
559 */
560void on_downloadButton_clicked_fs(GtkWidget * treeview,
561 GtkWidget * downloadButton) {
562 GtkTreeSelection * selection;
563
564 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
565 gtk_tree_selection_selected_foreach
566 (selection,
567 &initiateDownload,
568 NULL);
569}
570
571
572/**
573 * User used the URI download entry. Start download
574 * that is NOT rooted within a search or directory.
575 *
576 * TODO:
577 * - support for recursive downloads
578 * - support for showing directories (if downloaded like this)
579 * - support for user-specified filename
580 */
581void on_statusDownloadURIEntry_editing_done_fs(GtkWidget * entry,
582 GtkWidget * downloadButton) {
583 struct ECRS_URI * idc_uri;
584 struct ECRS_MetaData * idc_meta;
585 char * idc_final_download_destination;
586 const char * uris;
587 char * urid;
588 char * final_download_dir;
589 const char * dname;
590
591 uris = gtk_entry_get_text(GTK_ENTRY(entry));
592 urid = STRDUP(uris);
593 gtk_entry_set_text(GTK_ENTRY(entry),
594 ECRS_URI_PREFIX);
595 idc_uri = ECRS_stringToUri(ectx, urid);
596 if (idc_uri == NULL) {
597 addLogEntry(_("Invalid URI `%s'"), urid);
598 FREE(urid);
599 return;
600 }
601 if (ECRS_isKeywordUri(idc_uri)) {
602 addLogEntry(_("Please use the search function for keyword (KSK) URIs!"));
603 FREE(urid);
604 ECRS_freeUri(idc_uri);
605 return;
606 } else if (ECRS_isLocationUri(idc_uri)) {
607 addLogEntry(_("Location URIs are not yet supported"));
608 FREE(urid);
609 ECRS_freeUri(idc_uri);
610 return;
611 }
612 GC_get_configuration_value_filename(cfg,
613 "FS",
614 "INCOMINGDIR",
615 "$HOME/gnunet-downloads/",
616 &final_download_dir);
617 disk_directory_create(ectx, final_download_dir);
618 dname = &uris[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)];
619 idc_final_download_destination = MALLOC(strlen(final_download_dir) + strlen(dname) + 2);
620 strcpy(idc_final_download_destination, final_download_dir);
621 FREE(final_download_dir);
622 if (idc_final_download_destination[strlen(idc_final_download_destination)] != DIR_SEPARATOR)
623 strcat(idc_final_download_destination, DIR_SEPARATOR_STR);
624 strcat(idc_final_download_destination, dname);
625
626 addLogEntry(_("Downloading `%s'"), uris);
627 idc_meta = ECRS_createMetaData();
628 FSUI_startDownload(ctx,
629 getSpinButtonValue(getMainXML(),
630 "fsstatusAnonymitySpin"),
631 NO, /* FIXME: isRecursive */
632 idc_uri,
633 idc_meta,
634 idc_final_download_destination,
635 NULL,
636 NULL);
637 ECRS_freeMetaData(idc_meta);
638 FREE(urid);
639}
640
641
642static void
643clearCompletedDownloadCallback(GtkTreeModel * model,
644 GtkTreePath * path,
645 GtkTreeIter * iter,
646 gpointer unused) {
647 DownloadList * dl;
648
649 GE_ASSERT(ectx,
650 model == GTK_TREE_MODEL(download_summary));
651 gtk_tree_model_get(model,
652 iter,
653 DOWNLOAD_INTERNAL, &dl,
654 -1);
655 if (dl->has_terminated)
656 FSUI_stopDownload(ctx,
657 dl->fsui_list);
658}
659
660void on_clearCompletedDownloadsButton_clicked_fs(void * unused,
661 GtkWidget * clearButton) {
662 GtkTreeSelection * selection;
663 GtkWidget * downloadList;
664
665 downloadList = glade_xml_get_widget(getMainXML(),
666 "activeDownloadsList");
667 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(downloadList));
668 gtk_tree_selection_selected_foreach
669 (selection,
670 &clearCompletedDownloadCallback,
671 NULL);
672}
673
674static void
675abortDownloadCallback(GtkTreeModel * model,
676 GtkTreePath * path,
677 GtkTreeIter * iter,
678 gpointer unused) {
679 DownloadList * dl;
680
681 GE_ASSERT(ectx,
682 model == GTK_TREE_MODEL(download_summary));
683 gtk_tree_model_get(model,
684 iter,
685 DOWNLOAD_INTERNAL, &dl,
686 -1);
687 FSUI_abortDownload(ctx,
688 dl->fsui_list);
689}
690
691void on_abortDownloadButton_clicked_fs(void * unused,
692 GtkWidget * clearButton) {
693 GtkTreeSelection * selection;
694 GtkWidget * downloadList;
695
696 downloadList = glade_xml_get_widget(getMainXML(),
697 "activeDownloadsList");
698 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(downloadList));
699 gtk_tree_selection_selected_foreach
700 (selection,
701 &abortDownloadCallback,
702 NULL);
703}
704
705/* end of download.c */
diff --git a/src/plugins/fs/download.h b/src/plugins/fs/download.h
new file mode 100644
index 00000000..e639b9e7
--- /dev/null
+++ b/src/plugins/fs/download.h
@@ -0,0 +1,56 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006 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/plugins/fs/download.h
23 * @brief code for searching with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_DOWNLOAD_H
28#define GTK_DOWNLOAD_H
29
30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h>
32#include "fs.h"
33
34DownloadList *
35fs_download_started(struct FSUI_DownloadList * fsui_dl,
36 DownloadList * dl_parent,
37 SearchList * sl_parent,
38 unsigned long long total,
39 unsigned int anonymityLevel,
40 const ECRS_FileInfo * fi,
41 const char * filename,
42 unsigned long long completed,
43 cron_t eta);
44
45void fs_download_update(DownloadList * downloadContext,
46 unsigned long long completed,
47 const char * data,
48 unsigned int size);
49
50void fs_download_completed(DownloadList * downloadContext);
51
52void fs_download_aborted(DownloadList * downloadContext);
53
54void fs_download_stopped(DownloadList * downloadContext);
55
56#endif
diff --git a/src/plugins/fs/fs.c b/src/plugins/fs/fs.c
index 654d8c82..edd2e045 100644
--- a/src/plugins/fs/fs.c
+++ b/src/plugins/fs/fs.c
@@ -25,19 +25,26 @@
25 */ 25 */
26 26
27#include "platform.h" 27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h" 28#include "fs.h"
29#include "download.h"
30#include "search.h" 30#include "search.h"
31#include "upload.h" 31#include "upload.h"
32#include "collection.h" 32#include "collection.h"
33#include "namespace.h" 33#include "namespace.h"
34#include <GNUnet/gnunet_fsui_lib.h>
35 34
36struct FSUI_Context * ctx; 35struct FSUI_Context * ctx;
37 36
38static struct GE_Context * ectx; 37struct GE_Context * ectx;
39 38
40static struct GC_Configuration * cfg; 39struct GC_Configuration * cfg;
40
41SearchList * search_head;
42
43DownloadList * download_head;
44
45GtkListStore * search_summary;
46
47GtkTreeStore * download_summary;
41 48
42typedef struct { 49typedef struct {
43 const FSUI_Event * event; 50 const FSUI_Event * event;
@@ -112,7 +119,7 @@ static void saveEventProcessor(void * arg) {
112 break; 119 break;
113 case FSUI_download_started: 120 case FSUI_download_started:
114 cls->ret = fs_download_started(event->data.DownloadStarted.dc.pos, 121 cls->ret = fs_download_started(event->data.DownloadStarted.dc.pos,
115 event->data.DownloadStarted.dc.pctx, 122 event->data.DownloadStarted.dc.pcctx,
116 event->data.DownloadStarted.dc.sctx, 123 event->data.DownloadStarted.dc.sctx,
117 event->data.DownloadStarted.total, 124 event->data.DownloadStarted.total,
118 event->data.DownloadStarted.anonymityLevel, 125 event->data.DownloadStarted.anonymityLevel,
@@ -123,7 +130,7 @@ static void saveEventProcessor(void * arg) {
123 break; 130 break;
124 case FSUI_download_resumed: 131 case FSUI_download_resumed:
125 cls->ret = fs_download_started(event->data.DownloadResumed.dc.pos, 132 cls->ret = fs_download_started(event->data.DownloadResumed.dc.pos,
126 event->data.DownloadStarted.dc.pctx, 133 event->data.DownloadStarted.dc.pcctx,
127 event->data.DownloadStarted.dc.sctx, 134 event->data.DownloadStarted.dc.sctx,
128 event->data.DownloadResumed.total, 135 event->data.DownloadResumed.total,
129 event->data.DownloadResumed.anonymityLevel, 136 event->data.DownloadResumed.anonymityLevel,
@@ -185,6 +192,159 @@ static void * eventProcessor(void * unused,
185 return cls.ret; 192 return cls.ret;
186} 193}
187 194
195
196
197/**
198 * Setup the summary views (in particular the models
199 * and the renderers).
200 */
201static void fs_summary_start() {
202 GtkComboBoxEntry * searchCB;
203 GtkTreeView * searchList;
204 GtkTreeView * downloadList;
205 GtkListStore * model;
206 GtkCellRenderer * renderer;
207 GtkTreeViewColumn * column;
208 int col;
209
210 searchCB
211 = GTK_COMBO_BOX_ENTRY(glade_xml_get_widget(getMainXML(),
212 "fssearchKeywordComboBoxEntry"));
213
214 model = gtk_list_store_new(NS_SEARCH_NUM,
215 G_TYPE_STRING, /* what we show */
216 G_TYPE_STRING, /* EncName of namespace */
217 G_TYPE_POINTER, /* ECRS MetaData */
218 G_TYPE_POINTER, /* FSUI search list */
219 G_TYPE_INT); /* Meta-data about namespace */
220 gtk_combo_box_set_model(GTK_COMBO_BOX(searchCB),
221 GTK_TREE_MODEL(model));
222 gtk_combo_box_entry_set_text_column(searchCB,
223 NS_SEARCH_DESCRIPTION);
224 searchList = GTK_TREE_VIEW(glade_xml_get_widget(getMainXML(),
225 "activeSearchesSummary"));
226 search_summary =
227 gtk_list_store_new(SEARCH_SUMMARY_NUM,
228 G_TYPE_STRING, /* name */
229 G_TYPE_INT, /* # results */
230 G_TYPE_POINTER); /* internal: search list */
231 gtk_tree_view_set_model(searchList,
232 GTK_TREE_MODEL(search_summary));
233 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(searchList),
234 GTK_SELECTION_MULTIPLE);
235
236 renderer = gtk_cell_renderer_text_new();
237 col = gtk_tree_view_insert_column_with_attributes(searchList,
238 -1,
239 _("Query"),
240 renderer,
241 "text", SEARCH_SUMMARY_NAME,
242 NULL);
243 column = gtk_tree_view_get_column(searchList,
244 col - 1);
245 gtk_tree_view_column_set_resizable(column, TRUE);
246 gtk_tree_view_column_set_clickable(column, TRUE);
247 gtk_tree_view_column_set_reorderable(column, TRUE);
248 gtk_tree_view_column_set_sort_column_id(column, SEARCH_SUMMARY_NAME);
249 gtk_tree_view_column_set_resizable(column, TRUE);
250 renderer = gtk_cell_renderer_text_new();
251 col = gtk_tree_view_insert_column_with_attributes(searchList,
252 -1,
253 _("Results"),
254 renderer,
255 "text", SEARCH_SUMMARY_RESULT_COUNT,
256 NULL);
257 column = gtk_tree_view_get_column(searchList,
258 col - 1);
259 gtk_tree_view_column_set_resizable(column, TRUE);
260 gtk_tree_view_column_set_clickable(column, TRUE);
261 gtk_tree_view_column_set_reorderable(column, TRUE);
262 gtk_tree_view_column_set_sort_column_id(column, SEARCH_SUMMARY_RESULT_COUNT);
263 gtk_tree_view_column_set_resizable(column, TRUE);
264
265
266 downloadList = GTK_TREE_VIEW(glade_xml_get_widget(getMainXML(),
267 "activeDownloadsList"));
268 download_summary =
269 gtk_tree_store_new(DOWNLOAD_NUM,
270 G_TYPE_STRING, /* name (full-path file name) */
271 G_TYPE_STRING, /* name (user-friendly name) */
272 G_TYPE_UINT64, /* size */
273 G_TYPE_STRING, /* human readable size */
274 G_TYPE_INT, /* progress */
275 G_TYPE_STRING, /* uri as string */
276 G_TYPE_POINTER); /* internal download list ptr */
277 gtk_tree_view_set_model(downloadList,
278 GTK_TREE_MODEL(download_summary));
279 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(downloadList),
280 GTK_SELECTION_MULTIPLE);
281 renderer = gtk_cell_renderer_progress_new();
282 col = gtk_tree_view_insert_column_with_attributes(downloadList,
283 -1,
284 _("Name"),
285 renderer,
286 "value", DOWNLOAD_PROGRESS,
287 "text", DOWNLOAD_SHORTNAME,
288 NULL);
289 column = gtk_tree_view_get_column(downloadList,
290 col - 1);
291 gtk_tree_view_column_set_resizable(column, TRUE);
292 gtk_tree_view_column_set_clickable(column, TRUE);
293 gtk_tree_view_column_set_reorderable(column, TRUE);
294 gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_PROGRESS);
295 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
296 gtk_tree_view_column_set_resizable(column, TRUE);
297 renderer = gtk_cell_renderer_text_new();
298 g_object_set (renderer, "xalign", 1.00, NULL);
299 col = gtk_tree_view_insert_column_with_attributes(downloadList,
300 -1,
301 _("Size"),
302 renderer,
303 "text", DOWNLOAD_HSIZE,
304 NULL);
305
306 column = gtk_tree_view_get_column(downloadList,
307 col - 1);
308 gtk_tree_view_column_set_resizable(column, TRUE);
309 gtk_tree_view_column_set_clickable(column, TRUE);
310 gtk_tree_view_column_set_reorderable(column, TRUE);
311 gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_SIZE);
312 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
313 gtk_tree_view_column_set_resizable(column, TRUE);
314 renderer = gtk_cell_renderer_text_new();
315 col = gtk_tree_view_insert_column_with_attributes(downloadList,
316 -1,
317 _("URI"),
318 renderer,
319 "text", DOWNLOAD_URISTRING,
320 NULL);
321 column = gtk_tree_view_get_column(downloadList,
322 col - 1);
323 gtk_tree_view_column_set_resizable(column, TRUE);
324 gtk_tree_view_column_set_reorderable(column, TRUE);
325 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
326 gtk_tree_view_column_set_resizable(column, TRUE);
327}
328
329/**
330 * Shutdown.
331 */
332static void fs_summary_stop() {
333 GtkComboBox * searchCB;
334 GtkListStore * model;
335
336 searchCB
337 = GTK_COMBO_BOX(glade_xml_get_widget(getMainXML(),
338 "fssearchKeywordComboBoxEntry"));
339 model = GTK_LIST_STORE(gtk_combo_box_get_model(searchCB));
340 /* FIXME: iterate over model entries
341 and free URIs and MetaData! */
342}
343
344
345
346
347
188void init_fs(struct GE_Context * e, 348void init_fs(struct GE_Context * e,
189 struct GC_Configuration * c) { 349 struct GC_Configuration * c) {
190 GtkWidget * tab; 350 GtkWidget * tab;
@@ -211,7 +371,7 @@ void init_fs(struct GE_Context * e,
211 &eventProcessor, 371 &eventProcessor,
212 NULL); 372 NULL);
213 fs_collection_start(ectx, cfg); 373 fs_collection_start(ectx, cfg);
214 fs_search_start(ectx, cfg); 374 fs_summary_start();
215 fs_upload_start(ectx, cfg); 375 fs_upload_start(ectx, cfg);
216 fs_namespace_start(ectx, cfg); 376 fs_namespace_start(ectx, cfg);
217} 377}
@@ -223,7 +383,7 @@ void done_fs() {
223 = glade_xml_get_widget(getMainXML(), 383 = glade_xml_get_widget(getMainXML(),
224 "fsnotebook"); 384 "fsnotebook");
225 gtk_widget_hide(tab); 385 gtk_widget_hide(tab);
226 fs_search_stop(); 386 fs_summary_stop();
227 fs_collection_stop(); 387 fs_collection_stop();
228 fs_namespace_stop(); 388 fs_namespace_stop();
229 fs_upload_stop(); 389 fs_upload_stop();
diff --git a/src/plugins/fs/fs.h b/src/plugins/fs/fs.h
index 690bf072..24a638a1 100644
--- a/src/plugins/fs/fs.h
+++ b/src/plugins/fs/fs.h
@@ -29,7 +29,7 @@
29 29
30#include <GNUnet/gnunet_ecrs_lib.h> 30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h> 31#include <GNUnet/gnunet_fsui_lib.h>
32 32#include "gnunetgtk_common.h"
33 33
34/** 34/**
35 * On search box, for namespace selection 35 * On search box, for namespace selection
@@ -58,6 +58,7 @@ enum {
58 SEARCH_URI, 58 SEARCH_URI,
59 SEARCH_META, 59 SEARCH_META,
60 SEARCH_INTERNAL, 60 SEARCH_INTERNAL,
61 SEARCH_INTERNAL_PARENT,
61 SEARCH_NUM, 62 SEARCH_NUM,
62}; 63};
63 64
@@ -129,6 +130,139 @@ enum {
129 KTYPE_NUM, 130 KTYPE_NUM,
130}; 131};
131 132
133
134/**
135 * @brief linked list of pages in the search notebook
136 */
137typedef struct SL {
138 struct SL * next;
139 /**
140 * Reference to the glade XML context that was
141 * used to create the search page.
142 */
143 GladeXML * searchXML;
144
145 /**
146 * Reference to the glade XML context that was
147 * used to create the search label.
148 */
149 GladeXML * labelXML;
150
151 /**
152 * Tree view widget that is used to display the
153 * search results.
154 */
155 GtkTreeView * treeview;
156
157 /**
158 * Model of the tree view.
159 */
160 GtkTreeStore * tree;
161
162 /**
163 * The label used in the notebook page.
164 */
165 GtkWidget * tab_label;
166
167 /**
168 * The notebook page that is associated with this
169 * search.
170 */
171 GtkWidget * searchpage;
172
173 /**
174 * Path to the entry in the summary list
175 * for this search.
176 */
177 GtkTreeRowReference * summaryViewRowReference;
178
179 /**
180 * URI for this search.
181 */
182 struct ECRS_URI * uri;
183
184 /**
185 * String describing the search.
186 */
187 char * searchString;
188
189 /**
190 * Number of results received so far.
191 */
192 unsigned int resultsReceived;
193
194 /**
195 * FSUI search handle.
196 */
197 struct FSUI_SearchList * fsui_list;
198} SearchList;
199
200
201typedef struct DL {
202 struct DL * next;
203
204 /**
205 * URI of the download.
206 */
207 struct ECRS_URI * uri;
208
209 /**
210 * Where is the download being saved to?
211 */
212 char * filename;
213
214 /**
215 * Path in the summary view for this download.
216 */
217 GtkTreeRowReference * summaryViewRowReference;
218
219 /**
220 * Search that this download belongs to.
221 * Maybe NULL.
222 */
223 struct SL * searchList;
224
225 /**
226 * Path in the search view that this
227 * download is represented by. Maybe NULL
228 * if search has been closed or if download
229 * was initiated from URI without search.
230 */
231 GtkTreeRowReference * searchViewRowReference;
232
233 /**
234 * FSUI reference for the download.
235 */
236 struct FSUI_DownloadList * fsui_list;
237
238 /**
239 * Total size of the download.
240 */
241 unsigned long long total;
242
243 /**
244 * Is this a GNUnet directory? (by mime-type)
245 */
246 int is_directory;
247
248 int has_terminated;
249
250} DownloadList;
251
132extern struct FSUI_Context * ctx; 252extern struct FSUI_Context * ctx;
133 253
254extern struct GE_Context * ectx;
255
256extern struct GC_Configuration * cfg;
257
258extern SearchList * search_head;
259
260extern DownloadList * download_head;
261
262extern GtkListStore * search_summary;
263
264extern GtkTreeStore * download_summary;
265
266
267
134#endif 268#endif
diff --git a/src/plugins/fs/meta.c b/src/plugins/fs/meta.c
index 4c53891e..12087f30 100644
--- a/src/plugins/fs/meta.c
+++ b/src/plugins/fs/meta.c
@@ -498,7 +498,7 @@ char * getMimeTypeFromMetaData(const struct ECRS_MetaData * meta) {
498char * getFileNameFromMetaData(const struct ECRS_MetaData * meta) { 498char * getFileNameFromMetaData(const struct ECRS_MetaData * meta) {
499 char * name; 499 char * name;
500 500
501 name = ECRS_getFirstFromMetaData(info->meta, 501 name = ECRS_getFirstFromMetaData(meta,
502 EXTRACTOR_FILENAME, 502 EXTRACTOR_FILENAME,
503 EXTRACTOR_TITLE, 503 EXTRACTOR_TITLE,
504 EXTRACTOR_ARTIST, 504 EXTRACTOR_ARTIST,
@@ -522,7 +522,7 @@ char * getFileNameFromMetaData(const struct ECRS_MetaData * meta) {
522char * getDescriptionFromMetaData(const struct ECRS_MetaData * meta) { 522char * getDescriptionFromMetaData(const struct ECRS_MetaData * meta) {
523 char * desc; 523 char * desc;
524 524
525 desc = ECRS_getFirstFromMetaData(info->meta, 525 desc = ECRS_getFirstFromMetaData(meta,
526 EXTRACTOR_DESCRIPTION, 526 EXTRACTOR_DESCRIPTION,
527 EXTRACTOR_GENRE, 527 EXTRACTOR_GENRE,
528 EXTRACTOR_ALBUM, 528 EXTRACTOR_ALBUM,
@@ -538,7 +538,7 @@ char * getDescriptionFromMetaData(const struct ECRS_MetaData * meta) {
538} 538}
539 539
540GdkPixbuf * getThumbnailFromMetaData(const struct ECRS_MetaData * meta) { 540GdkPixbuf * getThumbnailFromMetaData(const struct ECRS_MetaData * meta) {
541 GdkPixbuf * pxibuf; 541 GdkPixbuf * pixbuf;
542 GdkPixbufLoader * loader; 542 GdkPixbufLoader * loader;
543 size_t ts; 543 size_t ts;
544 unsigned char * thumb; 544 unsigned char * thumb;
@@ -576,7 +576,7 @@ extractMainWidgetFromWindow(GladeXML * xml,
576 ret = gtk_bin_get_child(GTK_BIN(window)); 576 ret = gtk_bin_get_child(GTK_BIN(window));
577 gtk_widget_ref(ret); 577 gtk_widget_ref(ret);
578 gtk_container_remove(window, ret); 578 gtk_container_remove(window, ret);
579 gtk_widget_destroy(window); 579 gtk_widget_destroy(GTK_WIDGET(window));
580 return ret; 580 return ret;
581} 581}
582 582
diff --git a/src/plugins/fs/search.c b/src/plugins/fs/search.c
index 63d7622c..f026d07e 100644
--- a/src/plugins/fs/search.c
+++ b/src/plugins/fs/search.c
@@ -22,12 +22,6 @@
22 * @file src/plugins/fs/search.c 22 * @file src/plugins/fs/search.c
23 * @brief code for searching with gnunet-gtk 23 * @brief code for searching with gnunet-gtk
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 *
26 *
27 * TODO:
28 * - figure out how to handle directories displayed on the
29 * search page (and how to communicate for downloads that
30 * they do or do not hang in the search page!)
31 */ 25 */
32 26
33#include "platform.h" 27#include "platform.h"
@@ -40,123 +34,6 @@
40#include <GNUnet/gnunet_util_crypto.h> 34#include <GNUnet/gnunet_util_crypto.h>
41#include <GNUnet/gnunet_namespace_lib.h> 35#include <GNUnet/gnunet_namespace_lib.h>
42 36
43
44/**
45 * @brief linked list of pages in the search notebook
46 */
47typedef struct SL {
48 struct SL * next;
49 /**
50 * Reference to the glade XML context that was
51 * used to create the search page.
52 */
53 GladeXML * searchXML;
54
55 /**
56 * Reference to the glade XML context that was
57 * used to create the search label.
58 */
59 GladeXML * labelXML;
60
61 /**
62 * Tree view widget that is used to display the
63 * search results.
64 */
65 GtkTreeView * treeview;
66
67 /**
68 * Model of the tree view.
69 */
70 GtkTreeStore * tree;
71
72 /**
73 * The label used in the notebook page.
74 */
75 GtkLabel * tab_label;
76
77 /**
78 * The notebook page that is associated with this
79 * search.
80 */
81 GtkWidget * searchpage;
82
83 /**
84 * Path to the entry in the summary list
85 * for this search.
86 */
87 GtkTreeRowReference * summaryViewRowReference;
88
89 /**
90 * URI for this search.
91 */
92 struct ECRS_URI * uri;
93
94 /**
95 * String describing the search.
96 */
97 char * searchString;
98
99 /**
100 * Number of results received so far.
101 */
102 unsigned int resultsReceived;
103
104 /**
105 * FSUI search handle.
106 */
107 struct FSUI_SearchList * fsui_list;
108} SearchList;
109
110typedef struct DL {
111 struct DL * next;
112
113 /**
114 * URI of the download.
115 */
116 struct ECRS_URI * uri;
117
118 /**
119 * Where is the download being saved to?
120 */
121 char * filename;
122
123 /**
124 * Path in the summary view for this download.
125 */
126 GtkTreeRowReference * summaryViewRowReference;
127
128 /**
129 * Search that this download belongs to.
130 * Maybe NULL.
131 */
132 struct SL * searchList;
133
134 /**
135 * Path in the search view that this
136 * download is represented by. Maybe NULL
137 * if search has been closed or if download
138 * was initiated from URI without search.
139 */
140 GtkTreeRowReference * searchViewRowReference;
141
142 /**
143 * FSUI reference for the download.
144 */
145 struct FSUI_DownloadList * fsui_list;
146} DownloadList;
147
148static SearchList * search_head;
149
150static DownloadList * download_head;
151
152static GtkListStore * search_summary;
153
154static GtkTreeStore * download_summary;
155
156static struct GE_Context * ectx;
157
158static struct GC_Configuration * cfg;
159
160/** 37/**
161 * The user has clicked the "SEARCH" button. 38 * The user has clicked the "SEARCH" button.
162 * Initiate a search. 39 * Initiate a search.
@@ -301,7 +178,7 @@ void on_closeSearchButton_clicked_fs(GtkWidget * searchPage,
301 list = search_head; 178 list = search_head;
302 while (list != NULL) { 179 while (list != NULL) {
303 if ( (list->searchpage == searchPage) || 180 if ( (list->searchpage == searchPage) ||
304 (list->tab_label == searchPage) ) 181 (list->tab_label == searchPage) )
305 break; 182 break;
306 list = list->next; 183 list = list->next;
307 } 184 }
@@ -332,7 +209,7 @@ static void stopSearch(GtkTreeModel * model,
332 GtkTreePath * path, 209 GtkTreePath * path,
333 GtkTreeIter * iter, 210 GtkTreeIter * iter,
334 gpointer unused) { 211 gpointer unused) {
335 struct SL * s; 212 SearchList * s;
336 213
337 s = NULL; 214 s = NULL;
338 gtk_tree_model_get(model, 215 gtk_tree_model_get(model,
@@ -362,7 +239,7 @@ static void abortSearch(GtkTreeModel * model,
362 GtkTreePath * path, 239 GtkTreePath * path,
363 GtkTreeIter * iter, 240 GtkTreeIter * iter,
364 gpointer unused) { 241 gpointer unused) {
365 struct SL * s; 242 SearchList * s;
366 243
367 s = NULL; 244 s = NULL;
368 gtk_tree_model_get(model, 245 gtk_tree_model_get(model,
@@ -392,11 +269,11 @@ void on_abortSearchSummaryButton_clicked_fs(GtkWidget * treeview,
392 * Update the number of results received for the given 269 * Update the number of results received for the given
393 * search in the summary and in the label of the tab. 270 * search in the summary and in the label of the tab.
394 */ 271 */
395static void updateSearchSummary(struct SL * searchContext) { 272static void updateSearchSummary(SearchList * searchContext) {
396 GtkTreePath * path; 273 GtkTreePath * path;
397 GtkTreeIter iter; 274 GtkTreeIter iter;
398 char * new_title; 275 char * new_title;
399 GtkWidget * label; 276 GtkLabel * label;
400 277
401 path = gtk_tree_row_reference_get_path(searchContext->summaryViewRowReference); 278 path = gtk_tree_row_reference_get_path(searchContext->summaryViewRowReference);
402 if (TRUE != gtk_tree_model_get_iter(GTK_TREE_MODEL(search_summary), 279 if (TRUE != gtk_tree_model_get_iter(GTK_TREE_MODEL(search_summary),
@@ -418,45 +295,35 @@ static void updateSearchSummary(struct SL * searchContext) {
418 g_strdup_printf("%s (%u)", 295 g_strdup_printf("%s (%u)",
419 searchContext->searchString, 296 searchContext->searchString,
420 searchContext->resultsReceived); 297 searchContext->resultsReceived);
421 label = glade_xml_get_widget(searchContext->labelXML, 298 label = GTK_LABEL(glade_xml_get_widget(searchContext->labelXML,
422 "searchTabLabel"); 299 "searchTabLabel"));
423 gtk_label_set(label, new_title); 300 gtk_label_set(label, new_title);
424 FREE(new_title); 301 FREE(new_title);
425} 302}
426 303
427/** 304/**
428 * Add the given result to the model (search result 305 * Add the given search result to the search
429 * list). 306 * tree at the specified position.
430 *
431 * @param info the information to add to the model
432 * @param uri the search URI
433 * @param searchContext identifies the search page
434 */ 307 */
435void fs_search_result_received(struct SL * searchContext, 308void addEntryToSearchTree(SearchList * searchContext,
436 const ECRS_FileInfo * info, 309 DownloadList * downloadParent,
437 const struct ECRS_URI * uri) { 310 const ECRS_FileInfo * info,
311 GtkTreeIter * iter) {
438 char * name; 312 char * name;
439 char * mime; 313 char * mime;
440 char * desc; 314 char * desc;
441 unsigned long long size; 315 unsigned long long size;
442 char * size_h; 316 char * size_h;
443 GtkTreeStore * model; 317 GdkPixbuf * pixbuf;
444 GtkTreeIter iter;
445 318
446 mime = getMimeTypeFromMetaData(info->meta); 319 mime = getMimeTypeFromMetaData(info->meta);
447 desc = getDescriptionFromMetaData(info->meta); 320 desc = getDescriptionFromMetaData(info->meta);
448 name = getFileNameFromMetaData(info->meta); 321 name = getFileNameFromMetaData(info->meta);
449 size = ECRS_isFileUri(info->uri) ? ECRS_fileSize(info->uri) : 0 322 size = ECRS_isFileUri(info->uri) ? ECRS_fileSize(info->uri) : 0;
450 pixbuf = getThumbnailFromMetaData(info->meta); 323 pixbuf = getThumbnailFromMetaData(info->meta);
451 size_h = string_get_fancy_byte_size(size); 324 size_h = string_get_fancy_byte_size(size);
452 model = GTK_TREE_STORE 325 gtk_tree_store_set(searchContext->tree,
453 (gtk_tree_view_get_model 326 iter,
454 (GTK_TREE_VIEW(searchContext->treeview)));
455 gtk_tree_store_append(model,
456 &iter,
457 NULL);
458 gtk_tree_store_set(model,
459 &iter,
460 SEARCH_NAME, name, 327 SEARCH_NAME, name,
461 SEARCH_SIZE, size, 328 SEARCH_SIZE, size,
462 SEARCH_HSIZE, size_h, 329 SEARCH_HSIZE, size_h,
@@ -466,12 +333,36 @@ void fs_search_result_received(struct SL * searchContext,
466 SEARCH_URI, ECRS_dupUri(info->uri), 333 SEARCH_URI, ECRS_dupUri(info->uri),
467 SEARCH_META, ECRS_dupMetaData(info->meta), 334 SEARCH_META, ECRS_dupMetaData(info->meta),
468 SEARCH_INTERNAL, searchContext, 335 SEARCH_INTERNAL, searchContext,
336 SEARCH_INTERNAL_PARENT, downloadParent,
469 -1); 337 -1);
470 FREE(size_h); 338 FREE(size_h);
471 FREE(name); 339 FREE(name);
472 FREE(desc); 340 FREE(desc);
473 FREE(mime); 341 FREE(mime);
474 /* UNREF pixbuf? */ 342}
343
344/**
345 * Add the given result to the model (search result
346 * list).
347 *
348 * @param info the information to add to the model
349 * @param uri the search URI
350 * @param searchContext identifies the search page
351 */
352void fs_search_result_received(SearchList * searchContext,
353 const ECRS_FileInfo * info,
354 const struct ECRS_URI * uri) {
355 GtkTreeStore * model;
356 GtkTreeIter iter;
357
358 model = GTK_TREE_STORE(gtk_tree_view_get_model(searchContext->treeview));
359 gtk_tree_store_append(model,
360 &iter,
361 NULL);
362 addEntryToSearchTree(searchContext,
363 NULL,
364 info,
365 &iter);
475 searchContext->resultsReceived++; 366 searchContext->resultsReceived++;
476 updateSearchSummary(searchContext); 367 updateSearchSummary(searchContext);
477} 368}
@@ -480,23 +371,23 @@ void fs_search_result_received(struct SL * searchContext,
480 * FSUI event: a search was started; create the 371 * FSUI event: a search was started; create the
481 * tab and add an entry to the summary. 372 * tab and add an entry to the summary.
482 */ 373 */
483struct SL * 374SearchList *
484fs_search_started(struct FSUI_SearchList * fsui_list, 375fs_search_started(struct FSUI_SearchList * fsui_list,
485 const struct ECRS_URI * uri, 376 const struct ECRS_URI * uri,
486 unsigned int anonymityLevel, 377 unsigned int anonymityLevel,
487 unsigned int resultCount, 378 unsigned int resultCount,
488 const ECRS_FileInfo * results) { 379 const ECRS_FileInfo * results) {
489 struct SL * list; 380 SearchList * list;
490 gint pages; 381 gint pages;
491 char * description; 382 char * description;
492 const char * dhead; 383 const char * dhead;
493 GtkContainer * window;
494 GtkTreeViewColumn * column; 384 GtkTreeViewColumn * column;
495 GtkCellRenderer * renderer; 385 GtkCellRenderer * renderer;
496 int col;
497 GtkNotebook * notebook; 386 GtkNotebook * notebook;
498 GtkTreePath * path; 387 GtkTreePath * path;
499 GtkTreeIter iter; 388 GtkTreeIter iter;
389 int col;
390 int i;
500 391
501 description = ECRS_uriToString(uri); 392 description = ECRS_uriToString(uri);
502 if (description == NULL) { 393 if (description == NULL) {
@@ -515,10 +406,10 @@ fs_search_started(struct FSUI_SearchList * fsui_list,
515 strlen(ECRS_SUBSPACE_INFIX))) 406 strlen(ECRS_SUBSPACE_INFIX)))
516 dhead = &dhead[strlen(ECRS_SUBSPACE_INFIX)]; 407 dhead = &dhead[strlen(ECRS_SUBSPACE_INFIX)];
517 list 408 list
518 = MALLOC(sizeof(struct SL)); 409 = MALLOC(sizeof(SearchList));
519 memset(list, 410 memset(list,
520 0, 411 0,
521 sizeof(struct SL)); 412 sizeof(SearchList));
522 list->searchString 413 list->searchString
523 = STRDUP(dhead); 414 = STRDUP(dhead);
524 FREE(description); 415 FREE(description);
@@ -551,7 +442,8 @@ fs_search_started(struct FSUI_SearchList * fsui_list,
551 GDK_TYPE_PIXBUF, /* preview */ 442 GDK_TYPE_PIXBUF, /* preview */
552 G_TYPE_POINTER, /* url */ 443 G_TYPE_POINTER, /* url */
553 G_TYPE_POINTER, /* meta */ 444 G_TYPE_POINTER, /* meta */
554 G_TYPE_POINTER); /* internal: download info/NULL */ 445 G_TYPE_POINTER, /* internal: search list */
446 G_TYPE_POINTER); /* internal: download parent list */
555 447
556 gtk_tree_view_set_model(list->treeview, 448 gtk_tree_view_set_model(list->treeview,
557 GTK_TREE_MODEL(list->tree)); 449 GTK_TREE_MODEL(list->tree));
@@ -721,13 +613,12 @@ static void freeIterSubtree(GtkTreeModel * tree,
721 */ 613 */
722void fs_search_stopped(SearchList * list) { 614void fs_search_stopped(SearchList * list) {
723 GtkNotebook * notebook; 615 GtkNotebook * notebook;
724 int index;
725 int i;
726 GtkTreeIter iter; 616 GtkTreeIter iter;
727 struct ECRS_URI * euri;
728 SearchList * prev; 617 SearchList * prev;
729 DownloadList * downloads; 618 DownloadList * downloads;
730 GtkTreePath * path; 619 GtkTreePath * path;
620 int index;
621 int i;
731 622
732 /* remove from linked list */ 623 /* remove from linked list */
733 if (search_head == list) { 624 if (search_head == list) {
@@ -742,10 +633,10 @@ void fs_search_stopped(SearchList * list) {
742 /* remove links from download views */ 633 /* remove links from download views */
743 downloads = download_head; 634 downloads = download_head;
744 while (downloads != NULL) { 635 while (downloads != NULL) {
745 if (download->searchList == list) { 636 if (downloads->searchList == list) {
746 gtk_tree_row_reference_free(download->searchViewRowReference); 637 gtk_tree_row_reference_free(downloads->searchViewRowReference);
747 download->searchViewRowReference = NULL; 638 downloads->searchViewRowReference = NULL;
748 download->searchList = NULL; 639 downloads->searchList = NULL;
749 } 640 }
750 downloads = downloads->next; 641 downloads = downloads->next;
751 } 642 }
@@ -764,9 +655,9 @@ void fs_search_stopped(SearchList * list) {
764 index); 655 index);
765 656
766 /* recursively free search model */ 657 /* recursively free search model */
767 if (gtk_tree_model_get_iter_first(list->model, 658 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list->tree),
768 &iter)) 659 &iter))
769 freeIterSubtree(list->model, 660 freeIterSubtree(GTK_TREE_MODEL(list->tree),
770 &iter); 661 &iter);
771 662
772 /* destroy entry in summary */ 663 /* destroy entry in summary */
@@ -788,760 +679,4 @@ void fs_search_stopped(SearchList * list) {
788} 679}
789 680
790 681
791
792
793
794
795
796
797#if 0
798static int addFilesToDirectory
799 (const ECRS_FileInfo * fi,
800 const HashCode512 * key,
801 int isRoot,
802 void * closure) {
803 struct ECRS_URI * uri = closure;
804 DownloadList * pos;
805 GtkTreeIter iter;
806 GtkTreeIter child;
807 int i;
808 GtkTreePath * path;
809
810 if (isRoot == YES)
811 return OK;
812 DEBUG_BEGIN();
813 pos = download_head;
814 while (pos != NULL) {
815 if (ECRS_equalsUri(uri,
816 pos->uri))
817 break;
818 pos = pos->next;
819 }
820 if (pos != NULL) {
821 if (! gtk_tree_row_reference_valid(pos->rr))
822 return SYSERR;
823 path = gtk_tree_row_reference_get_path(pos->rr);
824 gtk_tree_model_get_iter(GTK_TREE_MODEL(pos->model),
825 &iter,
826 path);
827 gtk_tree_path_free(path);
828 for (i=gtk_tree_model_iter_n_children(pos->model,
829 &iter)-1;i>=0;i--) {
830 if (TRUE == gtk_tree_model_iter_nth_child(pos->model,
831 &child,
832 &iter,
833 i)) {
834 struct ECRS_URI * uri;
835 uri = NULL;
836 gtk_tree_model_get(pos->model,
837 &child,
838 SEARCH_URI, &uri,
839 -1);
840 if ( (uri != NULL) &&
841 (ECRS_equalsUri(uri,
842 fi->uri)) )
843 return OK;
844 }
845 }
846 gtk_tree_store_append(GTK_TREE_STORE(pos->model),
847 &child,
848 &iter);
849 addEntryToSearchTree(GTK_TREE_STORE(pos->model),
850 &child,
851 fi->uri,
852 fi->meta);
853 }
854 DEBUG_END();
855 return OK;
856}
857#endif
858
859
860/**
861 * A download has been started. Add an entry
862 * to the search tree view (if applicable) and
863 * the download summary.
864 */
865struct DL *
866fs_download_started(struct FSUI_DownloadList * fsui_dl,
867 struct DL * dl_parent,
868 struct SL * sl_parent,
869 unsigned long long total,
870 unsigned int anonymityLevel,
871 const ECRS_FileInfo * fi,
872 const char * filename,
873 unsigned long long completed,
874 cron_t eta) {
875 DownloadList * list;
876 GtkTreeIter iiter;
877 unsigned long long size;
878 char * size_h;
879 const char * sname;
880 int progress;
881 char * uri_name;
882
883 /* setup visualization */
884 list = MALLOC(sizeof(DownloadList));
885 list->fsui_list = fsui_dl;
886 list->rr = NULL;
887 list->model = NULL;
888#if 0
889 if (YES == ECRS_isDirectory(fi->meta)) {
890 list->rr = gtk_tree_row_reference_new(model, path);
891 list->model = model;
892 }
893#endif
894 list->uri = ECRS_dupUri(fi->uri);
895 list->filename = STRDUP(filename);
896 size = ECRS_fileSize(fi->uri);
897 size_h = string_get_fancy_byte_size(size);
898 sname = &filename[strlen(filename)-1];
899 while ( (sname > filename) &&
900 (sname[-1] != '/') &&
901 (sname[-1] != '\\') )
902 sname--;
903 if (size != 0)
904 progress = completed * 100 / size;
905 else
906 progress = 100;
907 uri_name = ECRS_uriToString(fi->uri);
908 gtk_tree_store_append(download_summary,
909 &iiter,
910 NULL);
911 gtk_tree_store_set(download_summary,
912 &iiter,
913 DOWNLOAD_FILENAME, filename,
914 DOWNLOAD_SHORTNAME, sname,
915 DOWNLOAD_SIZE, size,
916 DOWNLOAD_HSIZE, size_h,
917 DOWNLOAD_PROGRESS, progress,
918 DOWNLOAD_URISTRING, uri_name,
919 DOWNLOAD_URI, ECRS_dupUri(fi->uri),
920 DOWNLOAD_TREEPATH, list->rr, /* internal: row reference! */
921 DOWNLOAD_POS, list,
922 -1);
923 FREE(uri_name);
924 FREE(size_h);
925 list->next = download_head;
926 download_head = list;
927 DEBUG_END();
928 return list;
929}
930
931
932
933
934static void initiateDownload(GtkTreeModel * model,
935 GtkTreePath * path,
936 GtkTreeIter * iter,
937 gpointer unused) {
938 char * uri_name;
939 char * final_download_dir;
940 GtkTreeIter iiter;
941 GtkWidget * spin;
942 const char * oname;
943 const char * cname;
944 char * dname;
945 GtkTreePath *dirTreePath;
946 char *dirPath;
947 unsigned int dirPathLen;
948 struct ECRS_URI * idc_uri;
949 struct ECRS_MetaData * idc_meta;
950 const char * idc_name;
951 const char * idc_mime;
952 char * idc_final_download_destination;
953 unsigned int idc_anon;
954 struct SL * searchContext;
955
956#ifdef WINDOWS
957 char *filehash = NULL;
958#endif
959
960 DEBUG_BEGIN();
961 idc_uri = NULL;
962 idc_meta = NULL;
963 idc_name = NULL;
964 idc_mime = NULL;
965 gtk_tree_model_get(model,
966 iter,
967 SEARCH_NAME, &idc_name,
968 SEARCH_URI, &idc_uri,
969 SEARCH_META, &idc_meta,
970 SEARCH_MIME, &idc_mime,
971 SEARCH_INTERNAL, &searchContext,
972 -1);
973 if (idc_uri == NULL) {
974 GE_BREAK(ectx, 0);
975 return;
976 }
977
978 spin = searchContext->anonymityButton;
979 if (spin == NULL) {
980 GE_BREAK(ectx, 0);
981 idc_anon = 1;
982 } else {
983 idc_anon = gtk_spin_button_get_value_as_int
984 (GTK_SPIN_BUTTON(spin));
985 }
986 if (! ECRS_isFileUri(idc_uri)) {
987 if (ECRS_isNamespaceUri(idc_uri)) {
988 /* start namespace search; would probably be better
989 to add this as a subtree, but for simplicity
990 we'll just add it as a new tab for now */
991 FSUI_startSearch(ctx,
992 idc_anon,
993 1000, /* FIXME: max results */
994 99 * cronYEARS, /* fixme: timeout */
995 idc_uri);
996 return;
997 } else {
998 GE_BREAK(ectx, 0); /* unsupported URI type (i.e. ksk or loc) */
999 return;
1000 }
1001 }
1002
1003 uri_name = ECRS_uriToString(idc_uri);
1004 if ( (uri_name == NULL) ||
1005 (strlen(uri_name) <
1006 strlen(ECRS_URI_PREFIX) +
1007 strlen(ECRS_FILE_INFIX)) ) {
1008 GE_BREAK(ectx, 0);
1009 FREENONNULL(uri_name);
1010 return;
1011 }
1012
1013 if (idc_name == NULL) {
1014#ifdef WINDOWS
1015 filehash = STRDUP(uri_name);
1016 filehash[16] = 0;
1017 idc_name = filehash;
1018#else
1019 idc_name = uri_name;
1020#endif
1021 }
1022
1023 cname = idc_name;
1024 oname = idc_name;
1025 dname = MALLOC(strlen(idc_name)+1);
1026 dname[0] = '\0';
1027 while (*idc_name != '\0') {
1028 if ( (*idc_name == DIR_SEPARATOR) &&
1029 (idc_name[1] != '\0') ) {
1030 memcpy(dname, oname, idc_name - oname);
1031 dname[idc_name - oname] = '\0';
1032 cname = &idc_name[1];
1033 }
1034 idc_name++;
1035 }
1036 if (*cname == '\0') /* name ended in '/' - likely directory */
1037 cname = oname;
1038 idc_name = cname;
1039 GC_get_configuration_value_filename(cfg,
1040 "FS",
1041 "INCOMINGDIR",
1042 "$HOME/gnunet-downloads/",
1043 &final_download_dir);
1044 if (strlen(dname) > 0) {
1045 char * tmp;
1046 tmp = MALLOC(strlen(final_download_dir) + strlen(dname) + 2);
1047 strcpy(tmp, final_download_dir);
1048 if (tmp[strlen(tmp)] != DIR_SEPARATOR)
1049 strcat(tmp, DIR_SEPARATOR_STR);
1050 if (dname[0] == DIR_SEPARATOR)
1051 strcat(tmp, &dname[1]);
1052 else
1053 strcat(tmp, dname);
1054 FREE(final_download_dir);
1055 final_download_dir = tmp;
1056 }
1057 FREE(dname);
1058 disk_directory_create(ectx, final_download_dir);
1059
1060
1061 /* If file is inside a directory, get the full path */
1062 dirTreePath = gtk_tree_path_copy(path);
1063 dirPath = MALLOC(1);
1064 dirPath[0] = '\0';
1065 dirPathLen = 0;
1066 while (gtk_tree_path_get_depth(dirTreePath) > 1) {
1067 const char * dirname;
1068 char * new;
1069
1070 if (! gtk_tree_path_up(dirTreePath))
1071 break;
1072
1073 if (!gtk_tree_model_get_iter(model,
1074 &iiter,
1075 dirTreePath))
1076 break;
1077 gtk_tree_model_get(model,
1078 &iiter,
1079 SEARCH_NAME, &dirname,
1080 -1);
1081 dirPathLen = strlen(dirPath) + strlen(dirname) + strlen(DIR_SEPARATOR_STR) + 1;
1082 new = MALLOC(dirPathLen + 1);
1083 strcpy(new, dirname);
1084 if (new[strlen(new)-1] != DIR_SEPARATOR)
1085 strcat(new, DIR_SEPARATOR_STR);
1086 strcat(new, dirPath);
1087 FREE(dirPath);
1088 dirPath = new;
1089 }
1090 gtk_tree_path_free(dirTreePath);
1091
1092
1093 /* construct completed/directory/real-filename */
1094 idc_final_download_destination = MALLOC(strlen(final_download_dir) + 2 +
1095 strlen(idc_name) + strlen(GNUNET_DIRECTORY_EXT) +
1096 strlen(dirPath));
1097 strcpy(idc_final_download_destination, final_download_dir);
1098 if (idc_final_download_destination[strlen(idc_final_download_destination)-1] != DIR_SEPARATOR)
1099 strcat(idc_final_download_destination,
1100 DIR_SEPARATOR_STR);
1101 strcat(idc_final_download_destination, dirPath);
1102 disk_directory_create(ectx,
1103 idc_final_download_destination);
1104 strcat(idc_final_download_destination, idc_name);
1105 if ( (idc_final_download_destination[strlen(idc_final_download_destination) - 1] == '/') ||
1106 (idc_final_download_destination[strlen(idc_final_download_destination) - 1] == '\\') )
1107 idc_final_download_destination[strlen(idc_final_download_destination) - 1] = '\0';
1108 /* append ".gnd" if needed (== directory and .gnd not present) */
1109 if ( (idc_mime != NULL) &&
1110 (0 == strcmp(idc_mime, GNUNET_DIRECTORY_MIME)) &&
1111 ( (strlen(idc_final_download_destination) < strlen(GNUNET_DIRECTORY_EXT)) ||
1112 (0 != strcmp(&idc_final_download_destination[strlen(idc_final_download_destination)
1113 - strlen(GNUNET_DIRECTORY_EXT)],
1114 GNUNET_DIRECTORY_EXT)) ) )
1115 strcat(idc_final_download_destination, GNUNET_DIRECTORY_EXT);
1116
1117 addLogEntry(_("Downloading `%s'"), idc_name);
1118 FSUI_startDownload(ctx,
1119 idc_anon,
1120 NO, /* FIXME: isRecursive */
1121 idc_uri,
1122 idc_meta,
1123 idc_final_download_destination,
1124 NULL,
1125 NULL);
1126 FREE(uri_name);
1127 FREE(dirPath);
1128 FREENONNULL(final_download_dir);
1129#ifdef WINDOWS
1130 FREENONNULL(filehash);
1131#endif
1132}
1133
1134void on_downloadButton_clicked_fs(GtkWidget * treeview,
1135 GtkWidget * downloadButton) {
1136 GtkTreeSelection * selection;
1137
1138 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1139 gtk_tree_selection_selected_foreach
1140 (selection,
1141 &initiateDownload,
1142 NULL);
1143}
1144
1145
1146void on_statusDownloadURIEntry_editing_done_fs(GtkWidget * entry,
1147 GtkWidget * downloadButton) {
1148 struct ECRS_URI * idc_uri;
1149 struct ECRS_MetaData * idc_meta;
1150 char * idc_final_download_destination;
1151 unsigned int idc_anon;
1152 const char * uris;
1153 char * urid;
1154 GtkWidget * spin;
1155 char * final_download_dir;
1156 const char * dname;
1157
1158 uris = gtk_entry_get_text(GTK_ENTRY(entry));
1159 urid = STRDUP(uris);
1160 gtk_entry_set_text(GTK_ENTRY(entry),
1161 ECRS_URI_PREFIX);
1162 idc_uri = ECRS_stringToUri(ectx, urid);
1163 if (idc_uri == NULL) {
1164 addLogEntry(_("Invalid URI `%s'"), urid);
1165 FREE(urid);
1166 return;
1167 }
1168 if (ECRS_isKeywordUri(idc_uri)) {
1169 addLogEntry(_("Please use the search function for keyword (KSK) URIs!"));
1170 FREE(urid);
1171 ECRS_freeUri(idc_uri);
1172 return;
1173 } else if (ECRS_isLocationUri(idc_uri)) {
1174 addLogEntry(_("Location URIs are not yet supported"));
1175 FREE(urid);
1176 ECRS_freeUri(idc_uri);
1177 return;
1178 }
1179 GC_get_configuration_value_filename(cfg,
1180 "FS",
1181 "INCOMINGDIR",
1182 "$HOME/gnunet-downloads/",
1183 &final_download_dir);
1184 disk_directory_create(ectx, final_download_dir);
1185 dname = &uris[strlen(ECRS_URI_PREFIX) + strlen(ECRS_FILE_INFIX)];
1186 idc_final_download_destination = MALLOC(strlen(final_download_dir) + strlen(dname) + 2);
1187 strcpy(idc_final_download_destination, final_download_dir);
1188 FREE(final_download_dir);
1189 if (idc_final_download_destination[strlen(idc_final_download_destination)] != DIR_SEPARATOR)
1190 strcat(idc_final_download_destination, DIR_SEPARATOR_STR);
1191 strcat(idc_final_download_destination, dname);
1192
1193 /* get anonymity level */
1194 spin = glade_xml_get_widget(getMainXML(),
1195 "fsstatusAnonymitySpin");
1196 if (spin == NULL) {
1197 GE_BREAK(ectx, 0);
1198 idc_anon = 1;
1199 } else {
1200 idc_anon = gtk_spin_button_get_value_as_int
1201 (GTK_SPIN_BUTTON(spin));
1202 }
1203 addLogEntry(_("Downloading `%s'"), uris);
1204 idc_meta = ECRS_createMetaData();
1205 FSUI_startDownload(ctx,
1206 idc_anon,
1207 NO, /* FIXME: isRecursive */
1208 idc_uri,
1209 idc_meta,
1210 idc_final_download_destination,
1211 NULL,
1212 NULL);
1213 ECRS_freeMetaData(idc_meta);
1214 FREE(urid);
1215}
1216
1217
1218void fs_download_update(struct DL * downloadContext,
1219 unsigned long long completed,
1220 const char * data,
1221 unsigned int size) {
1222 GtkTreeIter iter;
1223 unsigned int val;
1224 unsigned long long total;
1225 struct DL * p;
1226
1227 DEBUG_BEGIN();
1228 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(download_summary),
1229 &iter)) {
1230 do {
1231 gtk_tree_model_get(GTK_TREE_MODEL(download_summary),
1232 &iter,
1233 DOWNLOAD_SIZE, &total,
1234 DOWNLOAD_POS, &p,
1235 -1);
1236 if (p == downloadContext) {
1237 if (total != 0)
1238 val = completed * 100 / total;
1239 else
1240 val = 100;
1241 gtk_tree_store_set(download_summary,
1242 &iter,
1243 DOWNLOAD_PROGRESS, val,
1244 -1);
1245 break;
1246 }
1247 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(download_summary),
1248 &iter));
1249 }
1250#if 0
1251 meta = NULL;
1252 ECRS_listDirectory(ectx,
1253 data,
1254 size,
1255 &meta,
1256 &addFilesToDirectory,
1257 downloadContext->uri);
1258 if (meta != NULL)
1259 ECRS_freeMetaData(meta);
1260#endif
1261 DEBUG_END();
1262}
1263
1264void fs_download_completed(struct DL * downloadContext) {
1265 unsigned long long size;
1266 char * data;
1267 int fd;
1268 struct ECRS_MetaData * meta;
1269
1270 DEBUG_BEGIN();
1271 GE_LOG(ectx,
1272 GE_STATUS | GE_USER | GE_BULK,
1273 _("Download '%s' complete.\n"),
1274 downloadContext->filename);
1275 /* Not available for resumed downloads */
1276 if ( (downloadContext->rr != NULL) &&
1277 (gtk_tree_row_reference_valid(downloadContext->rr)) ) {
1278 /* update directory view (if applicable!) */
1279 if (OK == disk_file_size(ectx,
1280 downloadContext->filename,
1281 &size,
1282 YES)) {
1283 GE_LOG(ectx,
1284 GE_DEBUG,
1285 "Updating directory view of '%s'\n",
1286 downloadContext->filename);
1287
1288 meta = NULL;
1289 fd = disk_file_open(ectx,
1290 downloadContext->filename,
1291 O_RDONLY);
1292 if (fd != -1) {
1293 data = MMAP(NULL,
1294 size,
1295 PROT_READ,
1296 MAP_SHARED,
1297 fd,
1298 0);
1299 if (data == MAP_FAILED) {
1300 GE_LOG_STRERROR_FILE(ectx,
1301 GE_ERROR | GE_ADMIN | GE_BULK,
1302 "mmap",
1303 downloadContext->filename);
1304 } else {
1305#if 0
1306 if (data != NULL) {
1307 ECRS_listDirectory(ectx,
1308 data,
1309 size,
1310 &meta,
1311 &addFilesToDirectory,
1312 downloadContext->uri);
1313 MUNMAP(data, size);
1314 }
1315#endif
1316 }
1317 CLOSE(fd);
1318 }
1319 if (meta != NULL)
1320 ECRS_freeMetaData(meta);
1321 }
1322 }
1323 DEBUG_END();
1324}
1325
1326void fs_download_stopped(struct DL * downloadContext) {
1327 GtkTreeIter iter;
1328 struct DL * d;
1329
1330 DEBUG_BEGIN();
1331 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(download_summary),
1332 &iter)) {
1333 do {
1334 gtk_tree_model_get(GTK_TREE_MODEL(download_summary),
1335 &iter,
1336 DOWNLOAD_POS, &d,
1337 -1);
1338 if (d == downloadContext) {
1339 gtk_tree_store_remove(download_summary,
1340 &iter);
1341 break;
1342 }
1343 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(download_summary),
1344 &iter));
1345 }
1346 DEBUG_END();
1347 /* FIXME: free dl downloadContext! */
1348}
1349
1350void on_clearCompletedDownloadsButton_clicked_fs(void * unused,
1351 GtkWidget * clearButton) {
1352 /* FIXME */
1353}
1354
1355static void abortDownloadCallback(GtkTreeModel * model,
1356 GtkTreePath * path,
1357 GtkTreeIter * iter,
1358 gpointer unused) {
1359 struct DL * dl;
1360
1361 GE_ASSERT(ectx, model == GTK_TREE_MODEL(download_summary));
1362 gtk_tree_model_get(model,
1363 iter,
1364 DOWNLOAD_POS, &dl,
1365 -1);
1366 FSUI_abortDownload(ctx,
1367 dl->fsui_list);
1368}
1369
1370void on_abortDownloadButton_clicked_fs(void * unused,
1371 GtkWidget * clearButton) {
1372 GtkTreeSelection * selection;
1373 GtkWidget * downloadList;
1374
1375 DEBUG_BEGIN();
1376 downloadList = glade_xml_get_widget(getMainXML(),
1377 "activeDownloadsList");
1378 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(downloadList));
1379 gtk_tree_selection_selected_foreach
1380 (selection,
1381 &abortDownloadCallback,
1382 NULL);
1383 DEBUG_END();
1384}
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394/* *************** startup/shutdown ****************** */
1395
1396/**
1397 * Setup the summary views (in particular the models
1398 * and the renderers).
1399 */
1400void fs_search_start(struct GE_Context * e,
1401 struct GC_Configuration * c) {
1402 GtkComboBoxEntry * searchCB;
1403 GtkTreeView * searchList;
1404 GtkTreeView * downloadList;
1405 GtkListStore * model;
1406 GtkCellRenderer * renderer;
1407 GtkTreeViewColumn * column;
1408 int col;
1409
1410 ectx = e;
1411 cfg = c;
1412 searchCB
1413 = GTK_COMBO_BOX_ENTRY(glade_xml_get_widget(getMainXML(),
1414 "fssearchKeywordComboBoxEntry"));
1415
1416 model = gtk_list_store_new(NS_SEARCH_NUM,
1417 G_TYPE_STRING, /* what we show */
1418 G_TYPE_STRING, /* EncName of namespace */
1419 G_TYPE_POINTER, /* ECRS MetaData */
1420 G_TYPE_POINTER, /* FSUI search list */
1421 G_TYPE_INT); /* Meta-data about namespace */
1422 gtk_combo_box_set_model(GTK_COMBO_BOX(searchCB),
1423 GTK_TREE_MODEL(model));
1424 gtk_combo_box_entry_set_text_column(searchCB,
1425 NS_SEARCH_DESCRIPTION);
1426 searchList = GTK_TREE_VIEW(glade_xml_get_widget(getMainXML(),
1427 "activeSearchesSummary"));
1428 search_summary =
1429 gtk_list_store_new(SER_SUM_NUM,
1430 G_TYPE_STRING, /* name */
1431 G_TYPE_INT, /* # results */
1432 G_TYPE_POINTER); /* internal: search list */
1433 gtk_tree_view_set_model(searchList,
1434 GTK_TREE_MODEL(search_summary));
1435 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(searchList),
1436 GTK_SELECTION_MULTIPLE);
1437
1438 renderer = gtk_cell_renderer_text_new();
1439 col = gtk_tree_view_insert_column_with_attributes(searchList,
1440 -1,
1441 _("Query"),
1442 renderer,
1443 "text", SERARCH_SUMMARY_NAME,
1444 NULL);
1445 column = gtk_tree_view_get_column(searchList,
1446 col - 1);
1447 gtk_tree_view_column_set_resizable(column, TRUE);
1448 gtk_tree_view_column_set_clickable(column, TRUE);
1449 gtk_tree_view_column_set_reorderable(column, TRUE);
1450 gtk_tree_view_column_set_sort_column_id(column, SER_SUM_NAME);
1451 gtk_tree_view_column_set_resizable(column, TRUE);
1452 renderer = gtk_cell_renderer_text_new();
1453 col = gtk_tree_view_insert_column_with_attributes(searchList,
1454 -1,
1455 _("Results"),
1456 renderer,
1457 "text", SERARCH_SUMMARY_RESULT_COUNT,
1458 NULL);
1459 column = gtk_tree_view_get_column(searchList,
1460 col - 1);
1461 gtk_tree_view_column_set_resizable(column, TRUE);
1462 gtk_tree_view_column_set_clickable(column, TRUE);
1463 gtk_tree_view_column_set_reorderable(column, TRUE);
1464 gtk_tree_view_column_set_sort_column_id(column, SER_SUM_COUNT);
1465 gtk_tree_view_column_set_resizable(column, TRUE);
1466
1467
1468 downloadList = GTK_TREE_VIEW(glade_xml_get_widget(getMainXML(),
1469 "activeDownloadsList"));
1470 download_summary =
1471 gtk_tree_store_new(DOWNLOAD_NUM,
1472 G_TYPE_STRING, /* name (full-path file name) */
1473 G_TYPE_STRING, /* name (user-friendly name) */
1474 G_TYPE_UINT64, /* size */
1475 G_TYPE_STRING, /* human readable size */
1476 G_TYPE_INT, /* progress */
1477 G_TYPE_STRING, /* uri as string */
1478 G_TYPE_POINTER); /* internal download list ptr */
1479 gtk_tree_view_set_model(downloadList,
1480 GTK_TREE_MODEL(download_summary));
1481 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(downloadList),
1482 GTK_SELECTION_MULTIPLE);
1483 renderer = gtk_cell_renderer_progress_new();
1484 col = gtk_tree_view_insert_column_with_attributes(downloadList,
1485 -1,
1486 _("Name"),
1487 renderer,
1488 "value", DOWNLOAD_PROGRESS,
1489 "text", DOWNLOAD_SHORTNAME,
1490 NULL);
1491 column = gtk_tree_view_get_column(downloadList,
1492 col - 1);
1493 gtk_tree_view_column_set_resizable(column, TRUE);
1494 gtk_tree_view_column_set_clickable(column, TRUE);
1495 gtk_tree_view_column_set_reorderable(column, TRUE);
1496 gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_PROGRESS);
1497 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
1498 gtk_tree_view_column_set_resizable(column, TRUE);
1499 renderer = gtk_cell_renderer_text_new();
1500 g_object_set (renderer, "xalign", 1.00, NULL);
1501 col = gtk_tree_view_insert_column_with_attributes(downloadList,
1502 -1,
1503 _("Size"),
1504 renderer,
1505 "text", DOWNLOAD_HSIZE,
1506 NULL);
1507
1508 column = gtk_tree_view_get_column(downloadList,
1509 col - 1);
1510 gtk_tree_view_column_set_resizable(column, TRUE);
1511 gtk_tree_view_column_set_clickable(column, TRUE);
1512 gtk_tree_view_column_set_reorderable(column, TRUE);
1513 gtk_tree_view_column_set_sort_column_id(column, DOWNLOAD_SIZE);
1514 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
1515 gtk_tree_view_column_set_resizable(column, TRUE);
1516 renderer = gtk_cell_renderer_text_new();
1517 col = gtk_tree_view_insert_column_with_attributes(downloadList,
1518 -1,
1519 _("URI"),
1520 renderer,
1521 "text", DOWNLOAD_URISTRING,
1522 NULL);
1523 column = gtk_tree_view_get_column(downloadList,
1524 col - 1);
1525 gtk_tree_view_column_set_resizable(column, TRUE);
1526 gtk_tree_view_column_set_reorderable(column, TRUE);
1527 /*gtk_tree_view_column_set_sort_indicator(column, TRUE);*/
1528 gtk_tree_view_column_set_resizable(column, TRUE);
1529}
1530
1531/**
1532 * Shutdown.
1533 */
1534void fs_search_stop() {
1535 GtkComboBox * searchCB;
1536 GtkListStore * model;
1537
1538 searchCB
1539 = GTK_COMBO_BOX(glade_xml_get_widget(getMainXML(),
1540 "fssearchKeywordComboBoxEntry"));
1541 model = gtk_combo_box_get_model(searchCB);
1542 /* FIXME: iterate over model entries
1543 and free URIs and MetaData! */
1544}
1545
1546
1547/* end of search.c */ 682/* end of search.c */
diff --git a/src/plugins/fs/search.h b/src/plugins/fs/search.h
index c161fb35..5b72aafd 100644
--- a/src/plugins/fs/search.h
+++ b/src/plugins/fs/search.h
@@ -29,33 +29,17 @@
29 29
30#include <GNUnet/gnunet_ecrs_lib.h> 30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h> 31#include <GNUnet/gnunet_fsui_lib.h>
32#include "fs.h"
32 33
33struct SL;
34
35struct DL;
36
37struct DL *
38fs_download_started(struct FSUI_DownloadList * fsui_dl,
39 struct DL * dl_parent,
40 struct SL * sl_parent,
41 unsigned long long total,
42 unsigned int anonymityLevel,
43 const ECRS_FileInfo * fi,
44 const char * filename,
45 unsigned long long completed,
46 cron_t eta);
47
48void fs_download_update(struct DL * downloadContext,
49 unsigned long long completed,
50 const char * data,
51 unsigned int size);
52
53void fs_download_completed(struct DL * downloadContext);
54
55void fs_download_aborted(struct DL * downloadContext);
56
57void fs_download_stopped(struct DL * downloadContext);
58 34
35/**
36 * Add the given search result to the search
37 * tree at the specified position.
38 */
39void addEntryToSearchTree(SearchList * searchContext,
40 DownloadList * downloadParent,
41 const ECRS_FileInfo * info,
42 GtkTreeIter * iter);
59 43
60/** 44/**
61 * Add the given result to the model (search result 45 * Add the given result to the model (search result
@@ -65,7 +49,7 @@ void fs_download_stopped(struct DL * downloadContext);
65 * @param path the tree path that selects where to add 49 * @param path the tree path that selects where to add
66 * the information, NULL for top-level 50 * the information, NULL for top-level
67 */ 51 */
68void fs_search_result_received(struct SL * searchContext, 52void fs_search_result_received(SearchList * searchContext,
69 const ECRS_FileInfo * info, 53 const ECRS_FileInfo * info,
70 const struct ECRS_URI * uri); 54 const struct ECRS_URI * uri);
71 55
@@ -74,7 +58,7 @@ void fs_search_result_received(struct SL * searchContext,
74 * 58 *
75 * @return internal search context 59 * @return internal search context
76 */ 60 */
77struct SL * 61SearchList *
78fs_search_started(struct FSUI_SearchList * list, 62fs_search_started(struct FSUI_SearchList * list,
79 const struct ECRS_URI * uri, 63 const struct ECRS_URI * uri,
80 unsigned int anonymityLevel, 64 unsigned int anonymityLevel,
@@ -84,28 +68,11 @@ fs_search_started(struct FSUI_SearchList * list,
84/** 68/**
85 * A search process has been aborted. Update display. 69 * A search process has been aborted. Update display.
86 */ 70 */
87void fs_search_aborted(struct SL * searchContext); 71void fs_search_aborted(SearchList * searchContext);
88 72
89/** 73/**
90 * A search process has stopped. Clean up. 74 * A search process has stopped. Clean up.
91 */ 75 */
92void fs_search_stopped(struct SL * searchContext); 76void fs_search_stopped(SearchList * searchContext);
93
94
95/**
96 * Initialize the search module.
97 */
98void fs_search_start(struct GE_Context * e,
99 struct GC_Configuration * c);
100
101/**
102 * Shutdown the search module.
103 */
104void fs_search_stop(void);
105
106
107void on_closeSearchButton_clicked_fs(GtkWidget * searchPage,
108 GtkWidget * closeButton);
109
110 77
111#endif 78#endif