diff options
author | Christian Grothoff <christian@grothoff.org> | 2006-10-29 19:50:11 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2006-10-29 19:50:11 +0000 |
commit | b30837e852c7ba43ce4372aabe539be2cd565ebc (patch) | |
tree | 41bf3b8af3546b581aa40622f9b25a13221da527 | |
parent | b6eb2c21ad31d585bfcdf7be8d48df6433fd876f (diff) | |
download | gnunet-gtk-b30837e852c7ba43ce4372aabe539be2cd565ebc.tar.gz gnunet-gtk-b30837e852c7ba43ce4372aabe539be2cd565ebc.zip |
fixing compile errors
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | src/include/gnunetgtk_common.h | 8 | ||||
-rw-r--r-- | src/plugins/daemon/daemon.c | 2 | ||||
-rw-r--r-- | src/plugins/fs/Makefile.am | 1 | ||||
-rw-r--r-- | src/plugins/fs/download.c | 705 | ||||
-rw-r--r-- | src/plugins/fs/download.h | 56 | ||||
-rw-r--r-- | src/plugins/fs/fs.c | 176 | ||||
-rw-r--r-- | src/plugins/fs/fs.h | 136 | ||||
-rw-r--r-- | src/plugins/fs/meta.c | 8 | ||||
-rw-r--r-- | src/plugins/fs/search.c | 981 | ||||
-rw-r--r-- | src/plugins/fs/search.h | 59 |
11 files changed, 1146 insertions, 987 deletions
@@ -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 | |||
46 | void initGNUnetGTKCommon(struct GE_Context * ectx, | 46 | void 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 |
20 | libgnunetgtkmodule_fs_la_LIBADD = \ | 21 | libgnunetgtkmodule_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 | */ | ||
41 | static int | ||
42 | addFilesToDirectory(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 | |||
94 | static void | ||
95 | refreshDirectoryViewFromDisk(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 | */ | ||
150 | DownloadList * | ||
151 | fs_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 | */ | ||
275 | void 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 | */ | ||
317 | void 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 | */ | ||
327 | void 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 | */ | ||
337 | void 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 | */ | ||
380 | static void | ||
381 | initiateDownload(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 | */ | ||
560 | void 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 | */ | ||
581 | void 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 | |||
642 | static void | ||
643 | clearCompletedDownloadCallback(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 | |||
660 | void 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 | |||
674 | static void | ||
675 | abortDownloadCallback(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 | |||
691 | void 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 | |||
34 | DownloadList * | ||
35 | fs_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 | |||
45 | void fs_download_update(DownloadList * downloadContext, | ||
46 | unsigned long long completed, | ||
47 | const char * data, | ||
48 | unsigned int size); | ||
49 | |||
50 | void fs_download_completed(DownloadList * downloadContext); | ||
51 | |||
52 | void fs_download_aborted(DownloadList * downloadContext); | ||
53 | |||
54 | void 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 | ||
36 | struct FSUI_Context * ctx; | 35 | struct FSUI_Context * ctx; |
37 | 36 | ||
38 | static struct GE_Context * ectx; | 37 | struct GE_Context * ectx; |
39 | 38 | ||
40 | static struct GC_Configuration * cfg; | 39 | struct GC_Configuration * cfg; |
40 | |||
41 | SearchList * search_head; | ||
42 | |||
43 | DownloadList * download_head; | ||
44 | |||
45 | GtkListStore * search_summary; | ||
46 | |||
47 | GtkTreeStore * download_summary; | ||
41 | 48 | ||
42 | typedef struct { | 49 | typedef 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 | */ | ||
201 | static 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 | */ | ||
332 | static 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 | |||
188 | void init_fs(struct GE_Context * e, | 348 | void 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 | */ | ||
137 | typedef 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 | |||
201 | typedef 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 | |||
132 | extern struct FSUI_Context * ctx; | 252 | extern struct FSUI_Context * ctx; |
133 | 253 | ||
254 | extern struct GE_Context * ectx; | ||
255 | |||
256 | extern struct GC_Configuration * cfg; | ||
257 | |||
258 | extern SearchList * search_head; | ||
259 | |||
260 | extern DownloadList * download_head; | ||
261 | |||
262 | extern GtkListStore * search_summary; | ||
263 | |||
264 | extern 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) { | |||
498 | char * getFileNameFromMetaData(const struct ECRS_MetaData * meta) { | 498 | char * 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) { | |||
522 | char * getDescriptionFromMetaData(const struct ECRS_MetaData * meta) { | 522 | char * 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 | ||
540 | GdkPixbuf * getThumbnailFromMetaData(const struct ECRS_MetaData * meta) { | 540 | GdkPixbuf * 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 | */ | ||
47 | typedef 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 | |||
110 | typedef 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 | |||
148 | static SearchList * search_head; | ||
149 | |||
150 | static DownloadList * download_head; | ||
151 | |||
152 | static GtkListStore * search_summary; | ||
153 | |||
154 | static GtkTreeStore * download_summary; | ||
155 | |||
156 | static struct GE_Context * ectx; | ||
157 | |||
158 | static 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 | */ |
395 | static void updateSearchSummary(struct SL * searchContext) { | 272 | static 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 | */ |
435 | void fs_search_result_received(struct SL * searchContext, | 308 | void 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 | */ | ||
352 | void 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 | */ |
483 | struct SL * | 374 | SearchList * |
484 | fs_search_started(struct FSUI_SearchList * fsui_list, | 375 | fs_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 | */ |
722 | void fs_search_stopped(SearchList * list) { | 614 | void 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 | ||
798 | static 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 | */ | ||
865 | struct DL * | ||
866 | fs_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 | |||
934 | static 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 | |||
1134 | void 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 | |||
1146 | void 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 | |||
1218 | void 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 | |||
1264 | void 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 | |||
1326 | void 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 | |||
1350 | void on_clearCompletedDownloadsButton_clicked_fs(void * unused, | ||
1351 | GtkWidget * clearButton) { | ||
1352 | /* FIXME */ | ||
1353 | } | ||
1354 | |||
1355 | static 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 | |||
1370 | void 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 | */ | ||
1400 | void 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 | */ | ||
1534 | void 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 | ||
33 | struct SL; | ||
34 | |||
35 | struct DL; | ||
36 | |||
37 | struct DL * | ||
38 | fs_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 | |||
48 | void fs_download_update(struct DL * downloadContext, | ||
49 | unsigned long long completed, | ||
50 | const char * data, | ||
51 | unsigned int size); | ||
52 | |||
53 | void fs_download_completed(struct DL * downloadContext); | ||
54 | |||
55 | void fs_download_aborted(struct DL * downloadContext); | ||
56 | |||
57 | void 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 | */ | ||
39 | void 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 | */ |
68 | void fs_search_result_received(struct SL * searchContext, | 52 | void 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 | */ |
77 | struct SL * | 61 | SearchList * |
78 | fs_search_started(struct FSUI_SearchList * list, | 62 | fs_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 | */ |
87 | void fs_search_aborted(struct SL * searchContext); | 71 | void 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 | */ |
92 | void fs_search_stopped(struct SL * searchContext); | 76 | void fs_search_stopped(SearchList * searchContext); |
93 | |||
94 | |||
95 | /** | ||
96 | * Initialize the search module. | ||
97 | */ | ||
98 | void fs_search_start(struct GE_Context * e, | ||
99 | struct GC_Configuration * c); | ||
100 | |||
101 | /** | ||
102 | * Shutdown the search module. | ||
103 | */ | ||
104 | void fs_search_stop(void); | ||
105 | |||
106 | |||
107 | void on_closeSearchButton_clicked_fs(GtkWidget * searchPage, | ||
108 | GtkWidget * closeButton); | ||
109 | |||
110 | 77 | ||
111 | #endif | 78 | #endif |