aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/fs')
-rw-r--r--src/plugins/fs/Makefile.am44
-rw-r--r--src/plugins/fs/collection.c166
-rw-r--r--src/plugins/fs/collection.h34
-rw-r--r--src/plugins/fs/content_tracking.c181
-rw-r--r--src/plugins/fs/content_tracking.h40
-rw-r--r--src/plugins/fs/directory.c155
-rw-r--r--src/plugins/fs/download.c1017
-rw-r--r--src/plugins/fs/download.h55
-rw-r--r--src/plugins/fs/extensions/musicinsert.c989
-rw-r--r--src/plugins/fs/extensions/musicinsert.glade760
-rw-r--r--src/plugins/fs/extensions/musicinsert.h130
-rw-r--r--src/plugins/fs/fs.c602
-rw-r--r--src/plugins/fs/fs.h333
-rw-r--r--src/plugins/fs/helper.c102
-rw-r--r--src/plugins/fs/helper.h54
-rw-r--r--src/plugins/fs/meta.c550
-rw-r--r--src/plugins/fs/meta.h90
-rw-r--r--src/plugins/fs/namespace.c844
-rw-r--r--src/plugins/fs/namespace.h42
-rw-r--r--src/plugins/fs/namespace_create.c280
-rw-r--r--src/plugins/fs/namespace_search.c323
-rw-r--r--src/plugins/fs/namespace_search.h45
-rw-r--r--src/plugins/fs/search.c1325
-rw-r--r--src/plugins/fs/search.h102
-rw-r--r--src/plugins/fs/status.c113
-rw-r--r--src/plugins/fs/status.h40
-rw-r--r--src/plugins/fs/upload.c752
-rw-r--r--src/plugins/fs/upload.h54
28 files changed, 0 insertions, 9222 deletions
diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am
deleted file mode 100644
index c8050b53..00000000
--- a/src/plugins/fs/Makefile.am
+++ /dev/null
@@ -1,44 +0,0 @@
1INCLUDES = \
2 -I$(top_srcdir)/intl \
3 -I$(top_srcdir)/src/include \
4 @GTK_CFLAGS@ \
5 @GIO_CFLAGS@ \
6 @GNUNETGTK_CFLAGS@
7
8plugindir = $(libdir)/GNUnet
9
10plugin_LTLIBRARIES = \
11 libgnunetgtkmodule_fs.la
12
13libgnunetgtkmodule_fs_la_SOURCES = \
14 collection.c collection.h \
15 content_tracking.c content_tracking.h \
16 directory.c \
17 fs.c fs.h \
18 helper.c helper.h \
19 meta.c meta.h \
20 namespace.c namespace.h \
21 namespace_create.c \
22 namespace_search.c namespace_search.h \
23 search.c search.h \
24 status.c status.h \
25 download.c download.h \
26 upload.c upload.h
27libgnunetgtkmodule_fs_la_LIBADD = \
28 $(top_builddir)/src/common/libgnunetgtk_common.la \
29 @GTK_LIBS@ \
30 @GIO_LIBS@ \
31 @GNUNETGTK_LIBS@ \
32 $(INTLLIBS) \
33 -lgthread-2.0 \
34 -lextractor \
35 -lgnunetutil \
36 -lgnunetcollection \
37 -lgnunetfsui \
38 -lgnunetnamespace \
39 -lgnuneturitrack \
40 -lgnunetecrs
41libgnunetgtkmodule_fs_la_LDFLAGS = \
42 -export-dynamic -avoid-version -module
43
44
diff --git a/src/plugins/fs/collection.c b/src/plugins/fs/collection.c
deleted file mode 100644
index 5009b0a2..00000000
--- a/src/plugins/fs/collection.c
+++ /dev/null
@@ -1,166 +0,0 @@
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/collection.c
23 * @brief code for operations with collections
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h"
30#include "helper.h"
31#include "meta.h"
32#include "collection.h"
33#include <GNUnet/gnunet_collection_lib.h>
34#include <extractor.h>
35
36static GladeXML *metaXML;
37
38void
39on_collectionDialogMetaDataAddButton_clicked_fs (gpointer dummy,
40 GtkWidget * uploadButton)
41{
42 handleMetaDataListUpdate (metaXML,
43 "collectionMetaDataTypeComboBox",
44 "collectionMetaDataValueEntry",
45 "collectionMetaDataTreeView");
46}
47
48void
49on_collectionMetaDataValueEntry_activate_fs (GtkWidget *
50 collectionMetaDataValueEntry,
51 gpointer dummy)
52{
53 const char *input;
54
55 input = gtk_entry_get_text (GTK_ENTRY (collectionMetaDataValueEntry));
56 if ((input == NULL) || (strlen (input) == 0))
57 return;
58 handleMetaDataListUpdate (metaXML,
59 "collectionMetaDataTypeComboBox",
60 "collectionMetaDataValueEntry",
61 "collectionMetaDataTreeView");
62}
63
64
65void
66createCollection_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
67{
68 GtkWidget *w;
69 GtkWidget *dialog;
70 GtkWidget *spin;
71 struct GNUNET_MetaData *meta;
72 struct GNUNET_ECRS_URI *root;
73
74 metaXML
75 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
76 "createCollectionDialog", PACKAGE_NAME);
77 GNUNET_GTK_connect_glade_with_plugins (metaXML);
78 dialog = glade_xml_get_widget (metaXML, "createCollectionDialog");
79 createMetaDataListTreeView (metaXML,
80 "collectionMetaDataTreeView", NULL, NULL);
81 createMetaTypeComboBox (metaXML, "collectionMetaDataTypeComboBox");
82 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
83 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
84 {
85 meta = getMetaDataFromList (metaXML,
86 "collectionMetaDataTreeView", NULL);
87 spin = glade_xml_get_widget (metaXML, "collectionAnonymityLevel");
88 root = NULL;
89 if (GNUNET_OK == GNUNET_CO_collection_start (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin)), 1000, /* priority */
90 meta))
91 {
92 w =
93 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
94 "createCollection");
95 gtk_widget_set_sensitive (w, FALSE);
96 w =
97 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
98 "deleteCollection");
99 gtk_widget_set_sensitive (w, TRUE);
100 }
101 else
102 {
103 GtkWidget *dialog;
104
105 dialog = gtk_message_dialog_new
106 (NULL,
107 GTK_DIALOG_MODAL,
108 GTK_MESSAGE_ERROR,
109 GTK_BUTTONS_CLOSE,
110 _("Failed to start collection (consult logs)."));
111 gtk_dialog_run (GTK_DIALOG (dialog));
112 gtk_widget_destroy (dialog);
113 }
114 GNUNET_meta_data_destroy (meta);
115 }
116 gtk_widget_destroy (dialog);
117 UNREF (metaXML);
118 metaXML = NULL;
119}
120
121void
122deleteCollection_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
123{
124 GtkWidget *w;
125
126 if (GNUNET_OK == GNUNET_CO_collection_stop ())
127 {
128 w =
129 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
130 "createCollection");
131 gtk_widget_set_sensitive (w, TRUE);
132 w =
133 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
134 "deleteCollection");
135 gtk_widget_set_sensitive (w, FALSE);
136 GNUNET_GTK_show_info_message (_("Collection stopped.\n"));
137 }
138 else
139 {
140 GNUNET_GTK_show_info_message (_
141 ("Failed to stop collection (consult logs).\n"));
142 }
143}
144
145void
146fs_collection_start ()
147{
148 GtkWidget *w;
149 struct GNUNET_MetaData *h;
150
151 h = GNUNET_CO_collection_get_name ();
152 if (NULL != h)
153 {
154 w =
155 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
156 "createCollection");
157 GNUNET_meta_data_destroy (h);
158 }
159 else
160 w =
161 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
162 "deleteCollection");
163 gtk_widget_set_sensitive (w, FALSE);
164}
165
166/* end of collection.c */
diff --git a/src/plugins/fs/collection.h b/src/plugins/fs/collection.h
deleted file mode 100644
index c236c4dc..00000000
--- a/src/plugins/fs/collection.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/collection.h
23 * @brief code for dealing with collections
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_COLLECTION_H
28#define GTK_COLLECTION_H
29
30#include <GNUnet/gnunet_util.h>
31
32void fs_collection_start (void);
33
34#endif
diff --git a/src/plugins/fs/content_tracking.c b/src/plugins/fs/content_tracking.c
deleted file mode 100644
index 29749909..00000000
--- a/src/plugins/fs/content_tracking.c
+++ /dev/null
@@ -1,181 +0,0 @@
1
2/*
3 This file is part of GNUnet.
4 (C) 2005, 2006 Christian Grothoff (and other contributing authors)
5
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
10
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22/**
23 * @file src/plugins/fs/content_tracking.c
24 * @brief code for tracking available content
25 * @author Christian Grothoff
26 */
27
28#include "platform.h"
29#include "gnunetgtk_common.h"
30#include "fs.h"
31#include "helper.h"
32#include "meta.h"
33#include "namespace.h"
34#include "content_tracking.h"
35#include <GNUnet/gnunet_util_crypto.h>
36#include <GNUnet/gnunet_uritrack_lib.h>
37#include <GNUnet/gnunet_namespace_lib.h>
38#include <extractor.h>
39
40static void *
41clearContentList (void *mdl)
42{
43 GtkTreeModel *model = GTK_TREE_MODEL (mdl);
44 struct GNUNET_ECRS_URI *uri;
45 struct GNUNET_MetaData *meta;
46 GtkTreeIter iter;
47
48 GNUNET_GTK_DEBUG_BEGIN ();
49 if (gtk_tree_model_get_iter_first (model, &iter))
50 {
51 do
52 {
53 gtk_tree_model_get (model,
54 &iter,
55 NAMESPACE_URI, &uri, NAMESPACE_META, &meta, -1);
56 GNUNET_ECRS_uri_destroy (uri);
57 GNUNET_meta_data_destroy (meta);
58 gtk_list_store_set (GTK_LIST_STORE (model),
59 &iter,
60 NAMESPACE_URI, NULL, NAMESPACE_META, NULL, -1);
61 }
62 while (gtk_list_store_remove (GTK_LIST_STORE (model), &iter));
63 }
64 GNUNET_GTK_DEBUG_END ();
65 return NULL;
66}
67
68
69void
70on_clearAvailableContentButton_clicked_fs (GtkWidget * dummy1,
71 GtkWidget * dummy2)
72{
73 GtkWidget *contentList;
74 GtkTreeModel *model;
75
76 GNUNET_GTK_DEBUG_BEGIN ();
77 contentList =
78 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
79 "availableContentList");
80 model = gtk_tree_view_get_model (GTK_TREE_VIEW (contentList));
81 GNUNET_URITRACK_clear (ectx, cfg);
82 GNUNET_GTK_save_call (&clearContentList, model);
83 GNUNET_GTK_DEBUG_END ();
84}
85
86void
87on_trackingCheckButton_toggled_fs (GtkWidget * dummy1, GtkWidget * dummy2)
88{
89 GtkWidget *trackCheckButton;
90
91 trackCheckButton
92 =
93 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
94 "trackingCheckButton");
95 GNUNET_URITRACK_toggle_tracking (ectx, cfg,
96 gtk_toggle_button_get_active
97 (GTK_TOGGLE_BUTTON (trackCheckButton)) ==
98 TRUE ? GNUNET_YES : GNUNET_NO);
99}
100
101
102
103/**
104 * Add the given content to the globally available
105 * content model. Check that it is not already
106 * present!
107 */
108static void *
109updateView (void *cls)
110{
111 const GNUNET_ECRS_FileInfo *fi = cls;
112 GtkTreeIter iter;
113 char *filename;
114 char *uriString;
115 unsigned long long size;
116 char *size_h;
117 GtkWidget *contentList;
118 GtkTreeModel *model;
119
120 contentList =
121 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
122 "availableContentList");
123 model = gtk_tree_view_get_model (GTK_TREE_VIEW (contentList));
124 filename = GNUNET_meta_data_get_first_by_types (fi->meta,
125 EXTRACTOR_FILENAME,
126 EXTRACTOR_TITLE,
127 EXTRACTOR_DESCRIPTION,
128 EXTRACTOR_SUBJECT,
129 EXTRACTOR_ARTIST,
130 EXTRACTOR_AUTHOR,
131 EXTRACTOR_PUBLISHER,
132 EXTRACTOR_CREATOR,
133 EXTRACTOR_PRODUCER,
134 EXTRACTOR_UNKNOWN, -1);
135 if (filename == NULL)
136 {
137 filename = GNUNET_strdup (_("no name given"));
138 }
139 else
140 {
141 char *dotdot;
142
143 while (NULL != (dotdot = strstr (filename, "..")))
144 dotdot[0] = dotdot[1] = '_';
145 filename = GNUNET_GTK_validate_utf8 (filename);
146 }
147
148 if (GNUNET_ECRS_uri_test_chk (fi->uri))
149 size = GNUNET_ECRS_uri_get_file_size (fi->uri);
150 else
151 size = 0;
152 uriString = GNUNET_ECRS_uri_to_string (fi->uri);
153 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
154 size_h = GNUNET_get_byte_size_as_fancy_string (size);
155 gtk_list_store_set (GTK_LIST_STORE (model),
156 &iter,
157 NAMESPACE_FILENAME, filename,
158 NAMESPACE_SIZE, size,
159 NAMESPACE_HSIZE, size_h,
160 NAMESPACE_URISTRING, uriString,
161 NAMESPACE_URI, GNUNET_ECRS_uri_duplicate (fi->uri),
162 NAMESPACE_META,
163 GNUNET_meta_data_duplicate (fi->meta), -1);
164 GNUNET_free (size_h);
165 GNUNET_free (filename);
166 GNUNET_free (uriString);
167 return NULL;
168}
169
170/**
171 * Add the given content to the globally available
172 * content model. Check that it is not already
173 * present!
174 */
175int
176updateViewSave (const GNUNET_ECRS_FileInfo * fi,
177 const GNUNET_HashCode * key, int isRoot, void *closure)
178{
179 GNUNET_GTK_save_call (&updateView, (void *) fi);
180 return GNUNET_OK;
181}
diff --git a/src/plugins/fs/content_tracking.h b/src/plugins/fs/content_tracking.h
deleted file mode 100644
index 54157422..00000000
--- a/src/plugins/fs/content_tracking.h
+++ /dev/null
@@ -1,40 +0,0 @@
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/content_tracking.h
23 * @brief code for tracking available content
24 * @author Christian Grothoff
25 */
26
27#ifndef CONTENT_TRACKING_H
28#define CONTENT_TRACKING_H
29
30#include <GNUnet/gnunet_ecrs_lib.h>
31
32/**
33 * Add the given content to the globally available
34 * content model. Check that it is not already
35 * present!
36 */
37int updateViewSave (const GNUNET_ECRS_FileInfo * fi,
38 const GNUNET_HashCode * key, int isRoot, void *closure);
39
40#endif
diff --git a/src/plugins/fs/directory.c b/src/plugins/fs/directory.c
deleted file mode 100644
index 5b03bd0a..00000000
--- a/src/plugins/fs/directory.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007 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/directory.c
23 * @brief code for opening directories
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h"
30#include "helper.h"
31#include "meta.h"
32#include "search.h"
33#include <GNUnet/gnunet_util_crypto.h>
34#include <GNUnet/gnunet_uritrack_lib.h>
35#include <GNUnet/gnunet_namespace_lib.h>
36#include <extractor.h>
37
38#ifndef MINGW
39static char *
40selectFile ()
41{
42 GladeXML *uploadXML;
43 GtkFileChooser *dialog;
44 char *ret;
45
46 uploadXML
47 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
48 "openDirectoryFileDialog", PACKAGE_NAME);
49 GNUNET_GTK_connect_glade_with_plugins (uploadXML);
50 dialog = GTK_FILE_CHOOSER (glade_xml_get_widget (uploadXML,
51 "openDirectoryFileDialog"));
52 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_CANCEL)
53 ret = gtk_file_chooser_get_filename (dialog);
54 else
55 ret = NULL;
56 gtk_widget_destroy (GTK_WIDGET (dialog));
57 UNREF (uploadXML);
58 return ret;
59}
60#else /* MINGW */
61static char *
62selectFile ()
63{
64 return plibc_ChooseFile (_("Choose the directory you want to open."),
65 OFN_FILEMUSTEXIST | OFN_SHAREAWARE);
66}
67#endif /* MINGW */
68
69static int
70spcb (const GNUNET_ECRS_FileInfo * fi,
71 const GNUNET_HashCode * key, int isRoot, void *closure)
72{
73 SearchList *list = closure;
74 fs_search_result_received (list, fi, list->uri);
75 return GNUNET_OK;
76}
77
78
79void
80on_open_menu_activate_fs (GtkWidget * dummy1, GtkWidget * dummy2)
81{
82 char *dn;
83 char *directory_data;
84 unsigned long long directory_data_len;
85 size_t dlen;
86 struct GNUNET_MetaData *md;
87 int fd;
88 SearchList *list;
89 struct GNUNET_ECRS_URI *uri;
90 GtkNotebook *notebook;
91
92 dn = selectFile ();
93 if (dn == NULL)
94 return;
95 if ((GNUNET_YES != GNUNET_disk_file_test (NULL,
96 dn)) ||
97 (GNUNET_OK !=
98 GNUNET_disk_file_size (NULL, dn, &directory_data_len, GNUNET_YES)))
99 {
100 GNUNET_GTK_add_log_entry (_("Error accessing file `%s'."), dn);
101 GNUNET_free (dn);
102 return;
103 }
104 fd = GNUNET_disk_file_open (NULL, dn, O_LARGEFILE | O_RDONLY);
105 if (fd == -1)
106 {
107 GNUNET_GTK_add_log_entry (_("Error opening file `%s'."), dn);
108 GNUNET_free (dn);
109 return;
110 }
111 dlen = (size_t) directory_data_len;
112 directory_data = MMAP (NULL, dlen, PROT_READ, MAP_SHARED, fd, 0);
113 if (directory_data == MAP_FAILED)
114 {
115 GNUNET_GTK_add_log_entry (_("Error mapping file `%s' into memory."),
116 dn);
117 CLOSE (fd);
118 GNUNET_free (dn);
119 return;
120 }
121 uri = GNUNET_ECRS_keyword_string_to_uri (NULL, dn);
122 md = NULL;
123 list = fs_search_started (NULL, uri, 0, 0, NULL, GNUNET_FSUI_COMPLETED);
124 GNUNET_ECRS_uri_destroy (uri);
125 GNUNET_ECRS_directory_list_contents (NULL,
126 directory_data, directory_data_len, NULL,
127 &md, &spcb, list);
128 if (md != NULL)
129 GNUNET_meta_data_destroy (md);
130 MUNMAP (directory_data, dlen);
131 CLOSE (fd);
132 GNUNET_free (dn);
133
134 /* switch view -- select directory */
135 notebook
136 =
137 GTK_NOTEBOOK (glade_xml_get_widget
138 (GNUNET_GTK_get_main_glade_XML (), "downloadNotebook"));
139 gtk_notebook_set_current_page (notebook,
140 gtk_notebook_page_num (notebook,
141 list->searchpage));
142
143 notebook
144 =
145 GTK_NOTEBOOK (glade_xml_get_widget
146 (GNUNET_GTK_get_main_glade_XML (), "fsnotebook"));
147 gtk_notebook_set_current_page (notebook,
148 gtk_notebook_page_num (notebook,
149 glade_xml_get_widget
150 (GNUNET_GTK_get_main_glade_XML
151 (),
152 "fsdownloadvbox")));
153}
154
155/* end of directory.c */
diff --git a/src/plugins/fs/download.c b/src/plugins/fs/download.c
deleted file mode 100644
index a2bc9b9e..00000000
--- a/src/plugins/fs/download.c
+++ /dev/null
@@ -1,1017 +0,0 @@
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 "platform.h"
29#include "fs.h"
30#include "search.h"
31#include "status.h"
32#include "meta.h"
33
34/* ****************** FSUI download events ****************** */
35
36/**
37 * We are iterating over the contents of a
38 * directory. Add the list of entries to
39 * the search page at the position indicated
40 * by the download list.
41 */
42static int
43addFilesToDirectory (const GNUNET_ECRS_FileInfo * fi,
44 const GNUNET_HashCode * key, int isRoot, void *closure)
45{
46 DownloadList *list = closure;
47 GtkTreeIter iter;
48 GtkTreeIter child;
49 int i;
50 GtkTreePath *path;
51 GtkTreeModel *model;
52
53 if (isRoot == GNUNET_YES)
54 return GNUNET_OK;
55 if (!gtk_tree_row_reference_valid (list->searchViewRowReference))
56 return GNUNET_SYSERR;
57 model = GTK_TREE_MODEL (list->searchList->tree);
58 path = gtk_tree_row_reference_get_path (list->searchViewRowReference);
59 if (path == NULL)
60 {
61 GNUNET_GE_BREAK (ectx, 0);
62 return GNUNET_SYSERR;
63 }
64 gtk_tree_model_get_iter (model, &iter, path);
65 gtk_tree_path_free (path);
66 /* check for existing entry -- this function maybe called multiple
67 times for the same directory entry */
68 for (i = gtk_tree_model_iter_n_children (model, &iter) - 1; i >= 0; i--)
69 {
70 if (TRUE == gtk_tree_model_iter_nth_child (model, &child, &iter, i))
71 {
72 struct GNUNET_ECRS_URI *uri;
73 uri = NULL;
74 gtk_tree_model_get (model, &child, SEARCH_URI, &uri, -1);
75 if ((uri != NULL) && (GNUNET_ECRS_uri_test_equal (uri, fi->uri)))
76 return GNUNET_OK;
77 }
78 }
79 gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
80 addEntryToSearchTree (list->searchList, list, fi, &child);
81 return GNUNET_OK;
82}
83
84static void
85refreshDirectoryViewFromDisk (DownloadList * list)
86{
87 unsigned long long size;
88 const char *data;
89 int fd;
90 char *fn;
91 struct GNUNET_MetaData *meta;
92 struct stat buf;
93 const char *f;
94
95 if ((list->is_directory != GNUNET_YES) ||
96 (list->searchList == NULL) ||
97 (list->searchViewRowReference == NULL) ||
98 (!gtk_tree_row_reference_valid (list->searchViewRowReference)))
99 return;
100
101 if (0 != stat (list->filename, &buf))
102 return;
103 if (S_ISDIR (buf.st_mode))
104 {
105 fn =
106 GNUNET_malloc (strlen (list->filename) +
107 strlen (GNUNET_DIRECTORY_EXT) + 1);
108 strcpy (fn, list->filename);
109 if (fn[strlen (fn) - 1] == '/')
110 fn[strlen (fn) - 1] = '\0';
111 strcat (fn, GNUNET_DIRECTORY_EXT);
112 if (0 != stat (list->filename, &buf))
113 {
114 GNUNET_free (fn);
115 return;
116 }
117 f = fn;
118 }
119 else
120 {
121 fn = NULL;
122 f = list->filename;
123 }
124 size = buf.st_size;
125 if (size == 0)
126 {
127 GNUNET_free_non_null (fn);
128 return;
129 }
130 fd = GNUNET_disk_file_open (ectx, f, O_RDONLY);
131 if (fd == -1)
132 {
133 GNUNET_free_non_null (fn);
134 return;
135 }
136 data = MMAP (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
137 if ((data == MAP_FAILED) || (data == NULL))
138 {
139 GNUNET_GE_LOG_STRERROR_FILE (ectx,
140 GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
141 GNUNET_GE_BULK, "mmap", f);
142 CLOSE (fd);
143 GNUNET_free_non_null (fn);
144 return;
145 }
146 GNUNET_free_non_null (fn);
147 meta = NULL;
148 GNUNET_ECRS_directory_list_contents (ectx, data, size, NULL, &meta,
149 &addFilesToDirectory, list);
150 MUNMAP ((void *) data, size);
151 CLOSE (fd);
152 if (meta != NULL)
153 GNUNET_meta_data_destroy (meta);
154}
155
156/**
157 * A download has been started. Add an entry
158 * to the search tree view (if applicable) and
159 * the download summary.
160 */
161DownloadList *
162fs_download_started (struct GNUNET_FSUI_DownloadList *fsui_dl,
163 DownloadList * dl_parent,
164 SearchList * sl_parent,
165 unsigned long long total,
166 unsigned int anonymityLevel,
167 const GNUNET_ECRS_FileInfo * fi,
168 const char *filename,
169 unsigned long long completed,
170 GNUNET_CronTime eta, GNUNET_FSUI_State state)
171{
172 DownloadList *list;
173 GtkTreeIter iter;
174 GtkTreeIter piter;
175 GtkTreePath *path;
176 unsigned long long size;
177 char *size_h;
178 const char *sname;
179 int progress;
180 char *uri_name;
181 gboolean valid;
182 struct GNUNET_ECRS_URI *u;
183 GtkTreeModel *model;
184
185 /* setup visualization */
186 list = GNUNET_malloc (sizeof (DownloadList));
187 memset (list, 0, sizeof (DownloadList));
188 list->uri = GNUNET_ECRS_uri_duplicate (fi->uri);
189 list->filename = GNUNET_strdup (filename);
190 if ((dl_parent != NULL) &&
191 (NULL !=
192 (path =
193 gtk_tree_row_reference_get_path
194 (dl_parent->summaryViewRowReference))))
195 {
196 valid = gtk_tree_model_get_iter (GTK_TREE_MODEL (download_summary),
197 &piter, path);
198 if (valid)
199 {
200 gtk_tree_store_append (download_summary, &iter, &piter);
201 }
202 else
203 {
204 gtk_tree_store_append (download_summary, &iter, NULL);
205 }
206 gtk_tree_path_free (path);
207 }
208 else
209 {
210 gtk_tree_store_append (download_summary, &iter, NULL);
211 }
212 size = GNUNET_ECRS_uri_get_file_size (fi->uri);
213 size_h = GNUNET_get_byte_size_as_fancy_string (size);
214 sname = &filename[strlen (filename) - 1];
215 while ((sname > filename) && (sname[-1] != '/') && (sname[-1] != '\\'))
216 sname--;
217 if (size != 0)
218 progress = completed * 100 / size;
219 else
220 progress = 100;
221 uri_name = GNUNET_ECRS_uri_to_string (fi->uri);
222 gtk_tree_store_set (download_summary,
223 &iter,
224 DOWNLOAD_FILENAME, filename,
225 DOWNLOAD_SHORTNAME, sname,
226 DOWNLOAD_SIZE, size,
227 DOWNLOAD_HSIZE, size_h,
228 DOWNLOAD_PROGRESS, progress,
229 DOWNLOAD_URISTRING, uri_name,
230 DOWNLOAD_INTERNAL, list,
231 DOWNLOAD_META_DATA, GNUNET_meta_data_duplicate(fi->meta),
232 -1);
233 GNUNET_free (uri_name);
234 GNUNET_free (size_h);
235 path = gtk_tree_model_get_path (GTK_TREE_MODEL (download_summary), &iter);
236 list->summaryViewRowReference
237 = gtk_tree_row_reference_new (GTK_TREE_MODEL (download_summary), path);
238 gtk_tree_path_free (path);
239 list->searchList = sl_parent;
240 list->searchViewRowReference = NULL;
241 if (sl_parent != NULL)
242 {
243 model = GTK_TREE_MODEL (sl_parent->tree);
244 if (dl_parent != NULL)
245 {
246 /* have parent, must be download from
247 directory inside of search */
248 /* FIXME: this requires GTK 2.8. Since it doesn't support Win9x, the quick
249 solution is to #ifndef it */
250#ifndef MINGW
251 GNUNET_GE_BREAK (ectx,
252 gtk_tree_row_reference_get_model
253 (dl_parent->searchViewRowReference) == model);
254#endif
255 path =
256 gtk_tree_row_reference_get_path
257 (dl_parent->searchViewRowReference);
258 if (path != NULL)
259 {
260 valid = gtk_tree_model_get_iter (model, &piter, path);
261 GNUNET_GE_BREAK (ectx, valid == TRUE);
262 if (valid == TRUE)
263 {
264 valid = gtk_tree_model_iter_children (model, &iter, &piter);
265 GNUNET_GE_BREAK (ectx, valid == TRUE);
266 }
267 }
268 else
269 {
270 GNUNET_GE_BREAK (ectx, 0);
271 valid = FALSE;
272 }
273 }
274 else
275 {
276 /* no download-parent, must be top-level entry in search */
277 valid = gtk_tree_model_get_iter_first (model, &iter);
278 GNUNET_GE_BREAK (ectx, valid == TRUE);
279 }
280 while (valid == TRUE)
281 {
282 /* find matching entry */
283 gtk_tree_model_get (model, &iter, SEARCH_URI, &u, -1);
284 if (GNUNET_ECRS_uri_test_equal (u, fi->uri))
285 {
286 path = gtk_tree_model_get_path (model, &iter);
287 list->searchViewRowReference
288 = gtk_tree_row_reference_new (model, path);
289 gtk_tree_path_free (path);
290 gtk_tree_store_set (sl_parent->tree,
291 &iter, SEARCH_STATUS,
292 getStatusName
293 (GNUNET_URITRACK_DOWNLOAD_STARTED),
294 SEARCH_STATUS_LOGO,
295 getStatusLogo
296 (GNUNET_URITRACK_DOWNLOAD_STARTED), -1);
297 break;
298 }
299 valid = gtk_tree_model_iter_next (model, &iter);
300 }
301 if (valid == FALSE)
302 {
303 /* did not find matching entry in search list -- bug! Continue
304 without adding to to search list! */
305 GNUNET_GE_BREAK (ectx, 0);
306 list->searchList = NULL;
307 }
308 }
309 list->fsui_list = fsui_dl;
310 list->total = total;
311 list->is_directory = GNUNET_meta_data_test_for_directory (fi->meta);
312 list->has_terminated = ((state != GNUNET_FSUI_ACTIVE)
313 && (state != GNUNET_FSUI_PENDING));
314 list->next = download_head;
315 download_head = list;
316 if ((list->is_directory == GNUNET_YES) && (completed != 0))
317 refreshDirectoryViewFromDisk (list);
318 return list;
319}
320
321/**
322 * The download has progressed. Update the
323 * summary and the preview of the directory
324 * contents in the search page (if applicable).
325 */
326void
327fs_download_update (DownloadList * list,
328 unsigned long long completed,
329 const char *data, unsigned int size)
330{
331 GtkTreeIter iter;
332 GtkTreePath *path;
333 unsigned int val;
334 struct GNUNET_MetaData *meta;
335
336 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
337 if (path == NULL)
338 {
339 GNUNET_GE_BREAK (ectx, 0);
340 return;
341 }
342 gtk_tree_model_get_iter (GTK_TREE_MODEL (download_summary), &iter, path);
343 gtk_tree_path_free (path);
344 if (list->total != 0)
345 val = completed * 100 / list->total;
346 else
347 val = 100;
348 gtk_tree_store_set (download_summary, &iter, DOWNLOAD_PROGRESS, val, -1);
349 if ((list->is_directory == GNUNET_YES) &&
350 (list->searchList != NULL) && (list->searchViewRowReference != NULL))
351 {
352 meta = NULL;
353 GNUNET_ECRS_directory_list_contents (ectx,
354 data, size, NULL, &meta,
355 &addFilesToDirectory, list);
356 if (meta != NULL)
357 GNUNET_meta_data_destroy (meta);
358 }
359}
360
361/**
362 * A download has terminated successfully. Update summary and
363 * possibly refresh directory listing.
364 */
365void
366fs_download_completed (DownloadList * downloadContext)
367{
368 GtkTreeIter iter;
369 GtkTreePath *path;
370
371 if (downloadContext->searchViewRowReference != NULL)
372 {
373 path =
374 gtk_tree_row_reference_get_path
375 (downloadContext->searchViewRowReference);
376 gtk_tree_model_get_iter (GTK_TREE_MODEL
377 (downloadContext->searchList->tree), &iter,
378 path);
379 gtk_tree_path_free (path);
380 gtk_tree_store_set (downloadContext->searchList->tree,
381 &iter,
382 SEARCH_STATUS,
383 getStatusName (GNUNET_URITRACK_DOWNLOAD_COMPLETED),
384 SEARCH_STATUS_LOGO,
385 getStatusLogo (GNUNET_URITRACK_DOWNLOAD_COMPLETED),
386 -1);
387 }
388 downloadContext->has_terminated = GNUNET_YES;
389 refreshDirectoryViewFromDisk (downloadContext);
390}
391
392/**
393 * A download has been aborted. Update summary and
394 * possibly refresh directory listing.
395 */
396void
397fs_download_aborted (DownloadList * downloadContext)
398{
399 GtkTreeIter iter;
400 GtkTreePath *path;
401
402 if (downloadContext->searchViewRowReference != NULL)
403 {
404 path =
405 gtk_tree_row_reference_get_path
406 (downloadContext->searchViewRowReference);
407 gtk_tree_model_get_iter (GTK_TREE_MODEL
408 (downloadContext->searchList->tree), &iter,
409 path);
410 gtk_tree_path_free (path);
411 gtk_tree_store_set (downloadContext->searchList->tree,
412 &iter,
413 SEARCH_STATUS,
414 getStatusName (GNUNET_URITRACK_DOWNLOAD_ABORTED),
415 SEARCH_STATUS_LOGO,
416 getStatusLogo (GNUNET_URITRACK_DOWNLOAD_ABORTED),
417 -1);
418 }
419 downloadContext->has_terminated = GNUNET_YES;
420 refreshDirectoryViewFromDisk (downloadContext);
421}
422
423
424
425/**
426 * A download has been stopped. Remove from summary
427 * and free associated resources.
428 */
429void
430fs_download_stopped (DownloadList * list)
431{
432 GtkTreeIter iter;
433 GtkTreeIter citer;
434 GtkTreePath *path;
435 DownloadList *prev;
436 GtkTreeModel *model;
437 struct GNUNET_MetaData * meta;
438
439 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
440 if (path == NULL)
441 {
442 GNUNET_GE_BREAK (ectx, 0);
443 }
444 else
445 {
446 gtk_tree_model_get_iter (GTK_TREE_MODEL (download_summary),
447 &iter, path);
448 gtk_tree_path_free (path);
449 gtk_tree_row_reference_free (list->summaryViewRowReference);
450 list->summaryViewRowReference = NULL;
451 gtk_tree_model_get(GTK_TREE_MODEL(download_summary),
452 &iter,
453 DOWNLOAD_META_DATA, &meta,
454 -1);
455 if (meta != NULL)
456 GNUNET_meta_data_destroy(meta);
457 gtk_tree_store_remove (download_summary, &iter);
458 }
459 GNUNET_free (list->filename);
460 GNUNET_ECRS_uri_destroy (list->uri);
461
462 if ((list->searchList != NULL) && (list->searchViewRowReference != NULL))
463 {
464 path = gtk_tree_row_reference_get_path (list->searchViewRowReference);
465 if (path == NULL)
466 {
467 GNUNET_GE_BREAK (ectx, 0);
468 }
469 else
470 {
471 model = GTK_TREE_MODEL (list->searchList->tree);
472 gtk_tree_model_get_iter (model, &iter, path);
473 gtk_tree_path_free (path);
474 gtk_tree_store_set (list->searchList->tree,
475 &iter,
476 SEARCH_STATUS,
477 getStatusName
478 (GNUNET_URITRACK_DOWNLOAD_ABORTED),
479 SEARCH_STATUS_LOGO,
480 getStatusLogo
481 (GNUNET_URITRACK_DOWNLOAD_ABORTED), -1);
482 if (gtk_tree_model_iter_children (model, &citer, &iter))
483 {
484 do
485 {
486 gtk_tree_store_set (list->searchList->tree,
487 &citer, SEARCH_INTERNAL_PARENT, NULL, -1);
488 }
489 while (gtk_tree_model_iter_next (model, &citer));
490 }
491 }
492 }
493 if (list->searchViewRowReference != NULL)
494 {
495 gtk_tree_row_reference_free (list->searchViewRowReference);
496 list->searchViewRowReference = NULL;
497 }
498
499 if (download_head == list)
500 {
501 download_head = list->next;
502 }
503 else
504 {
505 prev = download_head;
506 while ((prev != NULL) && (prev->next != list))
507 prev = prev->next;
508 if (prev != NULL)
509 prev->next = list->next;
510 else
511 GNUNET_GE_BREAK (ectx, 0);
512 }
513 GNUNET_free (list);
514}
515
516
517/* **************** user download events ******************** */
518
519
520/**
521 * Check if a download for the given filename is
522 * already running.
523 *
524 * @return GNUNET_OK if no download is pending, GNUNET_SYSERR if
525 * such a download is already active.
526 */
527static int
528check_pending (const char *filename, GtkTreeIter * parent)
529{
530 GtkTreeModel *model;
531 GtkTreeIter iter;
532 char *name;
533
534 model = GTK_TREE_MODEL (download_summary);
535 if (gtk_tree_model_iter_children (model, &iter, parent))
536 {
537 do
538 {
539 gtk_tree_model_get (model, &iter, DOWNLOAD_FILENAME, &name, -1);
540 if ((name != NULL) && (0 == strcmp (name, filename)))
541 {
542 free (name);
543 return GNUNET_SYSERR;
544 }
545 if (name != NULL)
546 free (name);
547 if (GNUNET_SYSERR == check_pending (filename, &iter))
548 return GNUNET_SYSERR;
549 }
550 while (gtk_tree_model_iter_next (model, &iter));
551 }
552 return GNUNET_OK;
553}
554
555typedef struct
556{
557 char *uri_name;
558 struct GNUNET_ECRS_URI *idc_uri;
559 struct GNUNET_MetaData *idc_meta;
560 char *idc_final_download_destination;
561 SearchList *searchContext;
562 DownloadList *parentContext;
563 unsigned int anonymity;
564 int recursive;
565} SDC;
566
567static void *
568init_download_helper (void *cls)
569{
570 SDC *sdc = cls;
571
572 GNUNET_FSUI_download_start (ctx,
573 sdc->anonymity,
574 sdc->recursive,
575 sdc->idc_uri,
576 sdc->idc_meta,
577 sdc->idc_final_download_destination,
578 (sdc->searchContext !=
579 NULL) ? sdc->searchContext->fsui_list : NULL,
580 (sdc->parentContext !=
581 NULL) ? sdc->parentContext->fsui_list : NULL);
582 return NULL;
583}
584
585/**
586 * The user clicked the download button.
587 * Start the download of the selected entry.
588 */
589static void
590initiateDownload (GtkTreeModel * model,
591 GtkTreePath * path, GtkTreeIter * iter, gpointer unused)
592{
593 SDC sdc;
594 char *final_download_dir;
595 GtkTreeIter iiter;
596 char *tmp;
597 char *cname;
598 char *dname;
599 GtkTreePath *dirTreePath;
600 char *dirPath;
601 unsigned int dirPathLen;
602 char *idc_name;
603
604 sdc.idc_uri = NULL;
605 sdc.idc_meta = NULL;
606 idc_name = NULL;
607 sdc.searchContext = NULL;
608 sdc.parentContext = NULL;
609 gtk_tree_model_get (model,
610 iter,
611 SEARCH_NAME, &idc_name,
612 SEARCH_URI, &sdc.idc_uri,
613 SEARCH_META, &sdc.idc_meta,
614 SEARCH_INTERNAL, &sdc.searchContext,
615 SEARCH_INTERNAL_PARENT, &sdc.parentContext, -1);
616 if ((sdc.idc_uri == NULL) ||
617 (!(GNUNET_ECRS_uri_test_chk (sdc.idc_uri)
618 || GNUNET_ECRS_uri_test_loc (sdc.idc_uri))))
619 {
620 GNUNET_GE_BREAK (ectx, 0);
621 GNUNET_free_non_null (idc_name);
622 return;
623 }
624 sdc.uri_name = GNUNET_ECRS_uri_to_string (sdc.idc_uri);
625 if ((sdc.uri_name == NULL) ||
626 (strlen (sdc.uri_name) <
627 strlen (GNUNET_ECRS_URI_PREFIX) + strlen (GNUNET_ECRS_FILE_INFIX)))
628 {
629 GNUNET_GE_BREAK (ectx, 0);
630 GNUNET_free_non_null (sdc.uri_name);
631 GNUNET_free_non_null (idc_name);
632 return;
633 }
634 /* reduce "//" to "/" */
635 if (idc_name != NULL)
636 {
637 while (strstr (idc_name, "//") != NULL)
638 memcpy (strstr (idc_name, "//"),
639 strstr (idc_name, "//") + 1,
640 strlen (strstr (idc_name, "//")));
641 }
642 /* if no name given or just "/", produce better name */
643 if ((idc_name == NULL) || (0 == strcmp ("/", idc_name)))
644 {
645#ifdef WINDOWS
646 char *filehash;
647
648 GNUNET_GE_ASSERT (NULL,
649 strlen (sdc.uri_name) >
650 strlen (GNUNET_ECRS_URI_PREFIX) +
651 strlen (GNUNET_ECRS_FILE_INFIX));
652 GNUNET_free_non_null (idc_name);
653 filehash =
654 GNUNET_strdup (&sdc.uri_name[strlen (GNUNET_ECRS_URI_PREFIX) +
655 strlen (GNUNET_ECRS_FILE_INFIX)]);
656 filehash[16] = 0;
657 idc_name = GNUNET_strdup (filehash);
658 GNUNET_free_non_null (filehash);
659#else
660 GNUNET_GE_ASSERT (NULL,
661 strlen (sdc.uri_name) >
662 strlen (GNUNET_ECRS_URI_PREFIX) +
663 strlen (GNUNET_ECRS_FILE_INFIX));
664 GNUNET_free_non_null (idc_name);
665 idc_name =
666 GNUNET_strdup (&sdc.uri_name[strlen (GNUNET_ECRS_URI_PREFIX) +
667 strlen (GNUNET_ECRS_FILE_INFIX)]);
668#endif
669 }
670
671 /* dname = directory portion of idc_name */
672 cname = idc_name;
673 dname = GNUNET_strdup (idc_name);
674 cname = &dname[strlen (dname) - 1];
675 if (cname != dname)
676 cname--; /* ignore tailing '/' */
677 while ((cname != dname) && (*cname != DIR_SEPARATOR))
678 cname--;
679 if (*cname == DIR_SEPARATOR)
680 {
681 *cname = '\0';
682 GNUNET_free (idc_name);
683 idc_name = GNUNET_strdup (cname + 1);
684 }
685 else
686 {
687 *cname = '\0';
688 }
689 cname = NULL;
690
691 GNUNET_GC_get_configuration_value_filename (cfg,
692 "FS",
693 "INCOMINGDIR",
694 "$HOME/gnunet-downloads/",
695 &final_download_dir);
696 if (strlen (dname) > 0)
697 {
698 tmp = GNUNET_malloc (strlen (final_download_dir) + strlen (dname) + 2);
699 strcpy (tmp, final_download_dir);
700 if (tmp[strlen (tmp)] != DIR_SEPARATOR)
701 strcat (tmp, DIR_SEPARATOR_STR);
702 if (dname[0] == DIR_SEPARATOR)
703 strcat (tmp, &dname[1]);
704 else
705 strcat (tmp, dname);
706 GNUNET_free (final_download_dir);
707 final_download_dir = tmp;
708 }
709 GNUNET_free (dname);
710 dname = NULL;
711 /* If file is inside a directory, get the full path */
712 dirTreePath = gtk_tree_path_copy (path);
713 dirPath = GNUNET_malloc (1);
714 dirPath[0] = '\0';
715 dirPathLen = 0;
716 while (gtk_tree_path_get_depth (dirTreePath) > 1)
717 {
718 char *dirname;
719 char *newPath;
720
721 if (!gtk_tree_path_up (dirTreePath))
722 break;
723 if (!gtk_tree_model_get_iter (model, &iiter, dirTreePath))
724 break;
725 gtk_tree_model_get (model, &iiter, SEARCH_NAME, &dirname, -1);
726 dirPathLen =
727 strlen (dirPath) + strlen (dirname) + strlen (DIR_SEPARATOR_STR) + 1;
728 newPath = GNUNET_malloc (dirPathLen + 1);
729 strcpy (newPath, dirname);
730 if (newPath[strlen (newPath) - 1] != DIR_SEPARATOR)
731 strcat (newPath, DIR_SEPARATOR_STR);
732 strcat (newPath, dirPath);
733 GNUNET_free (dirPath);
734 dirPath = newPath;
735 free (dirname);
736 }
737 gtk_tree_path_free (dirTreePath);
738
739 /* construct completed/directory/real-filename */
740 sdc.idc_final_download_destination =
741 GNUNET_malloc (strlen (final_download_dir) + 2 + strlen (idc_name) +
742 strlen (GNUNET_DIRECTORY_EXT) + strlen (dirPath));
743 strcpy (sdc.idc_final_download_destination, final_download_dir);
744 if (sdc.idc_final_download_destination[strlen
745 (sdc.idc_final_download_destination)
746 - 1] != DIR_SEPARATOR)
747 strcat (sdc.idc_final_download_destination, DIR_SEPARATOR_STR);
748 strcat (sdc.idc_final_download_destination, dirPath);
749 strcat (sdc.idc_final_download_destination, idc_name);
750 sdc.anonymity = getSpinButtonValue (sdc.searchContext->searchXML,
751 "downloadAnonymitySpinButton");
752 sdc.recursive = getToggleButtonValue (sdc.searchContext->searchXML,
753 "downloadRecursiveCheckButton");
754 if (GNUNET_OK == check_pending (sdc.idc_final_download_destination, NULL))
755 {
756 GNUNET_GTK_add_log_entry (_("Downloading `%s'\n"), idc_name);
757 GNUNET_GTK_run_with_save_calls (&init_download_helper, &sdc);
758 }
759 else
760 {
761 GNUNET_GTK_add_log_entry (_("ERROR: already downloading `%s'"),
762 idc_name);
763 }
764 GNUNET_free (sdc.uri_name);
765 GNUNET_free (dirPath);
766 GNUNET_free (sdc.idc_final_download_destination);
767 GNUNET_free_non_null (final_download_dir);
768 GNUNET_free_non_null (idc_name);
769}
770
771/**
772 * The download button in the search dialog was
773 * clicked. Download all selected entries.
774 */
775void
776on_downloadButton_clicked_fs (GtkWidget * treeview,
777 GtkWidget * downloadButton)
778{
779 GtkTreeSelection *selection;
780
781 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
782 GNUNET_GTK_tree_selection_selected_foreach (selection, &initiateDownload,
783 NULL);
784}
785
786/**
787 * Double-click on a search result
788 */
789gboolean
790on_searchResults_button_press_fs (GtkWidget * treeview,
791 GdkEventButton * event, gpointer data)
792{
793 if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (treeview)))
794 return FALSE;
795 if ( (event->type == GDK_2BUTTON_PRESS) &&
796 (TRUE == gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
797 event->x, event->y,
798 NULL, NULL,
799 NULL, NULL)) )
800 on_downloadButton_clicked_fs (treeview, NULL);
801 return FALSE;
802}
803
804
805/**
806 * User used the URI download entry. Start download
807 * that is NOT rooted within a search or directory.
808 *
809 * TODO:
810 * - support for recursive downloads
811 * - support for user-specified filename
812 * - enable button only if valid URI is entered
813 */
814void
815on_statusDownloadURIEntry_editing_done_fs (GtkWidget * entry,
816 GtkWidget * downloadButton)
817{
818 const char *uris;
819 char *urid;
820 char *final_download_dir;
821 const char *dname;
822 SDC sdc;
823
824 uris = gtk_entry_get_text (GTK_ENTRY (entry));
825 urid = GNUNET_strdup (uris);
826 gtk_entry_set_text (GTK_ENTRY (entry), GNUNET_ECRS_URI_PREFIX);
827 sdc.idc_uri = GNUNET_ECRS_string_to_uri (ectx, urid);
828 if (sdc.idc_uri == NULL)
829 {
830 GNUNET_GTK_add_log_entry (_("Invalid URI `%s'"), urid);
831 GNUNET_free (urid);
832 return;
833 }
834 if (GNUNET_ECRS_uri_test_ksk (sdc.idc_uri))
835 {
836 GNUNET_GTK_add_log_entry (_
837 ("Please use the search function for keyword (KSK) URIs!"));
838 GNUNET_free (urid);
839 GNUNET_ECRS_uri_destroy (sdc.idc_uri);
840 return;
841 }
842 GNUNET_GC_get_configuration_value_filename (cfg,
843 "FS",
844 "INCOMINGDIR",
845 "$HOME/gnunet-downloads/",
846 &final_download_dir);
847 GNUNET_disk_directory_create (ectx, final_download_dir);
848 dname =
849 &uris[strlen (GNUNET_ECRS_URI_PREFIX) + strlen (GNUNET_ECRS_FILE_INFIX)];
850 sdc.idc_final_download_destination =
851 GNUNET_malloc (strlen (final_download_dir) + strlen (dname) + 2);
852 strcpy (sdc.idc_final_download_destination, final_download_dir);
853 GNUNET_free (final_download_dir);
854 if (sdc.idc_final_download_destination[strlen
855 (sdc.idc_final_download_destination)]
856 != DIR_SEPARATOR)
857 strcat (sdc.idc_final_download_destination, DIR_SEPARATOR_STR);
858 strcat (sdc.idc_final_download_destination, dname);
859
860 GNUNET_GTK_add_log_entry (_("Downloading `%s'\n"), uris);
861 sdc.idc_meta = GNUNET_meta_data_create ();
862 sdc.anonymity =
863 getSpinButtonValue (GNUNET_GTK_get_main_glade_XML (),
864 "fsstatusAnonymitySpin");
865 sdc.recursive = GNUNET_NO;
866 sdc.searchContext = NULL;
867 sdc.parentContext = NULL;
868 GNUNET_GTK_run_with_save_calls (&init_download_helper, &sdc);
869 GNUNET_meta_data_destroy (sdc.idc_meta);
870 GNUNET_free (sdc.idc_final_download_destination);
871 GNUNET_free (urid);
872}
873
874struct FCBC
875{
876 int (*method) (struct GNUNET_FSUI_DownloadList * list);
877 struct GNUNET_FSUI_DownloadList *argument;
878};
879
880static void *
881fsui_callback (void *cls)
882{
883 struct FCBC *fcbc = cls;
884 fcbc->method (fcbc->argument);
885 return NULL;
886}
887
888static void
889clearCompletedDownloadCallback (GtkTreeModel * model,
890 GtkTreePath * path,
891 GtkTreeIter * iter, gpointer unused)
892{
893 DownloadList *dl;
894 struct FCBC fcbc;
895
896 GNUNET_GE_ASSERT (ectx, model == GTK_TREE_MODEL (download_summary));
897 gtk_tree_model_get (model, iter, DOWNLOAD_INTERNAL, &dl, -1);
898 if ((FALSE == gtk_tree_model_iter_has_child (model,
899 iter)) && (dl->has_terminated))
900 {
901 fcbc.method = &GNUNET_FSUI_download_stop;
902 fcbc.argument = dl->fsui_list;
903 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
904 }
905}
906
907void
908on_clearCompletedDownloads_clicked_fs (void *unused, GtkWidget * clearButton)
909{
910 GNUNET_GTK_tree_model_foreach (GTK_TREE_MODEL (download_summary),
911 &clearCompletedDownloadCallback, NULL);
912}
913
914static void
915fsuiCallDownloadCallback (GtkTreeModel * model,
916 GtkTreePath * path,
917 GtkTreeIter * iter, gpointer fsui_call)
918{
919 DownloadList *dl;
920 struct FCBC fcbc;
921
922 GNUNET_GE_ASSERT (ectx, model == GTK_TREE_MODEL (download_summary));
923 gtk_tree_model_get (model, iter, DOWNLOAD_INTERNAL, &dl, -1);
924 fcbc.method = fsui_call;
925 fcbc.argument = dl->fsui_list;
926 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
927}
928
929void
930on_abortDownload_clicked_fs (void *unused, GtkWidget * dummy)
931{
932 GtkTreeSelection *selection;
933 GtkWidget *downloadList;
934
935 downloadList =
936 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
937 "activeDownloadsList");
938 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (downloadList));
939 GNUNET_GTK_tree_selection_selected_foreach
940 (selection, &fsuiCallDownloadCallback, &GNUNET_FSUI_download_abort);
941 GNUNET_GTK_tree_selection_selected_foreach
942 (selection, &fsuiCallDownloadCallback, &GNUNET_FSUI_download_stop);
943}
944
945void
946on_stopDownload_clicked_fs (void *unused, GtkWidget * dummy)
947{
948 GtkTreeSelection *selection;
949 GtkWidget *downloadList;
950
951 downloadList =
952 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
953 "activeDownloadsList");
954 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (downloadList));
955 GNUNET_GTK_tree_selection_selected_foreach
956 (selection, &fsuiCallDownloadCallback, &GNUNET_FSUI_download_stop);
957}
958
959
960static void
961fsuiShowMetaDataCallback (GtkTreeModel * model,
962 GtkTreePath * path,
963 GtkTreeIter * iter, gpointer fsui_call)
964{
965 struct GNUNET_MetaData * meta;
966 char * name;
967
968 GNUNET_GE_ASSERT (ectx,
969 model == GTK_TREE_MODEL (download_summary));
970 gtk_tree_model_get (model,
971 iter,
972 DOWNLOAD_META_DATA, &meta,
973 DOWNLOAD_SHORTNAME, &name,
974 -1);
975 if (meta != NULL)
976 open_meta_data_display_dialog(meta, name);
977 GNUNET_free_non_null(name);
978}
979
980void
981on_showDownloadMetaData_clicked_fs (void *unused, GtkWidget * dummy)
982{
983 GtkTreeSelection *selection;
984 GtkWidget *downloadList;
985
986 downloadList =
987 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
988 "activeDownloadsList");
989 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (downloadList));
990 GNUNET_GTK_tree_selection_selected_foreach
991 (selection, &fsuiShowMetaDataCallback, NULL);
992}
993
994/**
995 * Right-click on an active download
996 */
997gboolean
998on_activeDownloadsList_button_press_fs (GtkWidget * treeview,
999 GdkEventButton * event_button,
1000 gpointer dummy)
1001{
1002 GtkWidget *menu;
1003 GladeXML *contextMenuXML;
1004
1005 contextMenuXML =
1006 glade_xml_new (GNUNET_GTK_get_glade_filename (),
1007 "downloadsContextMenu", PACKAGE_NAME);
1008 GNUNET_GTK_connect_glade_with_plugins (contextMenuXML);
1009 menu = glade_xml_get_widget (contextMenuXML, "downloadsContextMenu");
1010 if (event_button->button == 3)
1011 gtk_menu_popup (GTK_MENU (menu),
1012 NULL, NULL, NULL, NULL,
1013 event_button->button, event_button->time);
1014 return FALSE;
1015}
1016
1017/* end of download.c */
diff --git a/src/plugins/fs/download.h b/src/plugins/fs/download.h
deleted file mode 100644
index 5baf4c6e..00000000
--- a/src/plugins/fs/download.h
+++ /dev/null
@@ -1,55 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/plugins/fs/download.h
23 * @brief code for searching with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_DOWNLOAD_H
28#define GTK_DOWNLOAD_H
29
30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h>
32#include "fs.h"
33
34DownloadList *fs_download_started (struct GNUNET_FSUI_DownloadList *fsui_dl,
35 DownloadList * dl_parent,
36 SearchList * sl_parent,
37 unsigned long long total,
38 unsigned int anonymityLevel,
39 const GNUNET_ECRS_FileInfo * fi,
40 const char *filename,
41 unsigned long long completed,
42 GNUNET_CronTime eta,
43 GNUNET_FSUI_State state);
44
45void fs_download_update (DownloadList * downloadContext,
46 unsigned long long completed,
47 const char *data, unsigned int size);
48
49void fs_download_completed (DownloadList * downloadContext);
50
51void fs_download_aborted (DownloadList * downloadContext);
52
53void fs_download_stopped (DownloadList * downloadContext);
54
55#endif
diff --git a/src/plugins/fs/extensions/musicinsert.c b/src/plugins/fs/extensions/musicinsert.c
deleted file mode 100644
index bd60154e..00000000
--- a/src/plugins/fs/extensions/musicinsert.c
+++ /dev/null
@@ -1,989 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/musicinsert.c
23 * @brief Music insertion dialog for gnunet-gtk
24 * @author Milan Bouchet
25 */
26
27
28#ifdef HAVE_CONFIG_H
29# include <config.h>
30#endif
31
32#include <gtk/gtk.h>
33#include <glade/glade.h>
34#include <glib-object.h>
35#include <glib.h>
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41
42#include <extractor.h>
43
44#include "fs.h"
45#include "ecrs.h"
46#include "gnunet_ecrs_lib.h"
47#include "platform.h"
48#include "main.h"
49
50
51GladeXML *musicinsertXML;
52GtkListStore *filelist_store;
53GList *AlbumList, *ArtistList, *TypeList;
54GtkComboBoxEntry *artistcombobox, *albumcombobox, *typecombobox;
55EXTRACTOR_ExtractorList *Extractors;
56GtkWidget *musicinsertdialog;
57
58GtkTreeViewColumn *filename_list_col, *title_list_col, *artist_list_col,
59 *album_list_col, *type_list_col, *format_list_col, *keywords_list_col;
60
61GtkWidget *filelist_popup;
62
63int
64main (int argc, char *argv[])
65{
66
67
68
69 gtk_init (&argc, &argv);
70
71 show_musicinsertdialog ();
72
73 gtk_main ();
74 return 0;
75}
76
77void
78show_musicinsertdialog ()
79{
80 musicinsertXML =
81 glade_xml_new (MUSICINSERTXMLFILE, "musicinsertdialog",
82 PACKAGNUNET_GE_NAME);
83 glade_xml_signal_autoconnect (musicinsertXML);
84/* libglade*/
85
86
87 gtk_set_locale ();
88
89 musicinsertdialog =
90 glade_xml_get_widget (musicinsertXML, "musicinsertdialog");
91
92/*
93 * Create the 3 ComboBoxEntry manually (libglade doesn't handle this well :
94 * should use gtk_combo_box_entry_new_text instead of gtk_combo_box_entry_new)
95 */
96 artistcombobox = GTK_COMBO_BOX_ENTRY (gtk_combo_box_entry_new_text ());
97 albumcombobox = GTK_COMBO_BOX_ENTRY (gtk_combo_box_entry_new_text ());
98 typecombobox = GTK_COMBO_BOX_ENTRY (gtk_combo_box_entry_new_text ());
99
100 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
101 "Ogg (application/ogg)");
102 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
103 "MP3 (audio/mpeg)");
104 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
105 "MPC (application/x-musepack)");
106 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox), "AAC");
107 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
108 "WMA (audio/x-ms-wma)");
109 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
110 "FLAC (audio/flac)");
111 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox), "APE");
112 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
113 "WAV (application/x-wav)");
114 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
115 "REAL (audio/vnd.rn-realaudio)");
116 gtk_combo_box_append_text (GTK_COMBO_BOX (typecombobox),
117 "MIDI (audio/x-midi)");
118
119 GtkWidget *globaltable =
120 glade_xml_get_widget (musicinsertXML, "globaltable");
121 gtk_table_attach (GTK_TABLE (globaltable),
122 GTK_WIDGET (artistcombobox), 1, 3, 1, 2,
123 GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
124 gtk_table_attach (GTK_TABLE (globaltable), GTK_WIDGET (albumcombobox),
125 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
126 gtk_table_attach (GTK_TABLE (globaltable), GTK_WIDGET (typecombobox),
127 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
128
129 gtk_widget_show (GTK_WIDGET (artistcombobox));
130 gtk_widget_show (GTK_WIDGET (albumcombobox));
131 gtk_widget_show (GTK_WIDGET (typecombobox));
132
133 /*
134 * treeview creation
135 */
136
137 /* liststore model */
138 filelist_store =
139 gtk_list_store_new (COLS_NUMBER, G_TYPE_STRING, G_TYPE_STRING,
140 G_TYPE_STRING, G_TYPE_STRING,
141 G_TYPE_STRING, G_TYPE_STRING,
142 G_TYPE_STRING, G_TYPE_STRING);
143
144 /* view */
145 GtkWidget *filelist = glade_xml_get_widget (musicinsertXML, "filelist");
146 gtk_tree_view_set_model (GTK_TREE_VIEW (filelist),
147 GTK_TREE_MODEL (filelist_store));
148
149 /* cells definition */
150 GtkCellRenderer *filename_renderer = gtk_cell_renderer_text_new ();
151 g_object_set (filename_renderer, "editable", TRUE, NULL);
152 GtkCellRenderer *title_renderer = gtk_cell_renderer_text_new ();
153 g_object_set (title_renderer, "editable", TRUE, NULL);
154 GtkCellRenderer *artist_renderer = gtk_cell_renderer_text_new ();
155 g_object_set (artist_renderer, "editable", TRUE, NULL);
156 GtkCellRenderer *album_renderer = gtk_cell_renderer_text_new ();
157 g_object_set (album_renderer, "editable", TRUE, NULL);
158 GtkCellRenderer *type_renderer = gtk_cell_renderer_text_new ();
159 g_object_set (type_renderer, "editable", TRUE, NULL);
160 GtkCellRenderer *format_renderer = gtk_cell_renderer_text_new ();
161 g_object_set (format_renderer, "editable", TRUE, NULL);
162 GtkCellRenderer *keywords_renderer = gtk_cell_renderer_text_new ();
163 g_object_set (keywords_renderer, "editable", TRUE, NULL);
164
165
166 g_signal_connect ((gpointer) filename_renderer, "edited",
167 G_CALLBACK (on_renderer_edited),
168 (gpointer) & filename_col_num);
169 g_signal_connect ((gpointer) title_renderer, "edited",
170 G_CALLBACK (on_renderer_edited),
171 (gpointer) & title_col_num);
172 g_signal_connect ((gpointer) artist_renderer, "edited",
173 G_CALLBACK (on_renderer_edited),
174 (gpointer) & artist_col_num);
175 g_signal_connect ((gpointer) album_renderer, "edited",
176 G_CALLBACK (on_renderer_edited),
177 (gpointer) & album_col_num);
178 g_signal_connect ((gpointer) type_renderer, "edited",
179 G_CALLBACK (on_renderer_edited),
180 (gpointer) & type_col_num);
181 g_signal_connect ((gpointer) format_renderer, "edited",
182 G_CALLBACK (on_renderer_edited),
183 (gpointer) & format_col_num);
184 g_signal_connect ((gpointer) keywords_renderer, "edited",
185 G_CALLBACK (on_renderer_edited),
186 (gpointer) & keywords_col_num);
187
188 /* columns definition */
189 filename_list_col =
190 gtk_tree_view_column_new_with_attributes (_
191 ("Published filename"),
192 filename_renderer,
193 "text", FILENAME_COL, NULL);
194 title_list_col =
195 gtk_tree_view_column_new_with_attributes (_("Title"),
196 title_renderer,
197 "text", TITLE_COL, NULL);
198 artist_list_col =
199 gtk_tree_view_column_new_with_attributes (_("Artist"),
200 artist_renderer,
201 "text", ARTIST_COL, NULL);
202 album_list_col =
203 gtk_tree_view_column_new_with_attributes (_("Album"),
204 album_renderer,
205 "text", ALBUM_COL, NULL);
206 type_list_col =
207 gtk_tree_view_column_new_with_attributes (_("Type"),
208 type_renderer,
209 "text", TYPE_COL, NULL);
210 format_list_col =
211 gtk_tree_view_column_new_with_attributes (_("Format"),
212 format_renderer,
213 "text", FORMAT_COL, NULL);
214 keywords_list_col =
215 gtk_tree_view_column_new_with_attributes (_("Keywords"),
216 keywords_renderer,
217 "text", KEYWORDS_COL, NULL);
218
219/* Allow sorting for all columns */
220 gtk_tree_view_column_set_sort_column_id (filename_list_col, FILENAME_COL);
221 gtk_tree_view_column_set_sort_column_id (title_list_col, TITLE_COL);
222 gtk_tree_view_column_set_sort_column_id (artist_list_col, ARTIST_COL);
223 gtk_tree_view_column_set_sort_column_id (album_list_col, ALBUM_COL);
224 gtk_tree_view_column_set_sort_column_id (type_list_col, TYPE_COL);
225 gtk_tree_view_column_set_sort_column_id (format_list_col, FORMAT_COL);
226 gtk_tree_view_column_set_sort_column_id (keywords_list_col, KEYWORDS_COL);
227
228 /* Allow to resize all columns */
229 gtk_tree_view_column_set_resizable (filename_list_col, TRUE);
230 gtk_tree_view_column_set_resizable (title_list_col, TRUE);
231 gtk_tree_view_column_set_resizable (artist_list_col, TRUE);
232 gtk_tree_view_column_set_resizable (album_list_col, TRUE);
233 gtk_tree_view_column_set_resizable (type_list_col, TRUE);
234 gtk_tree_view_column_set_resizable (format_list_col, TRUE);
235 gtk_tree_view_column_set_resizable (keywords_list_col, TRUE);
236
237 /* Hide unedeed columns */
238 gtk_tree_view_column_set_visible (artist_list_col, FALSE);
239 gtk_tree_view_column_set_visible (album_list_col, FALSE);
240 gtk_tree_view_column_set_visible (type_list_col, FALSE);
241 gtk_tree_view_column_set_visible (keywords_list_col, FALSE);
242
243 /* Set a smart option */
244 gtk_tree_view_get_hover_expand (GTK_TREE_VIEW (filelist));
245
246 /* add columns to view */
247 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), filename_list_col);
248 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), title_list_col);
249 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), artist_list_col);
250 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), album_list_col);
251 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), type_list_col);
252 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), format_list_col);
253 gtk_tree_view_append_column (GTK_TREE_VIEW (filelist), keywords_list_col);
254
255 /* Expand columns */
256 gtk_tree_view_column_set_expand (filename_list_col, TRUE);
257 gtk_tree_view_column_set_expand (artist_list_col, TRUE);
258 gtk_tree_view_column_set_expand (album_list_col, TRUE);
259 gtk_tree_view_column_set_expand (type_list_col, TRUE);
260 gtk_tree_view_column_set_expand (format_list_col, TRUE);
261 gtk_tree_view_column_set_expand (keywords_list_col, TRUE);
262
263 /* Allow multiple selections */
264 GtkTreeSelection *filelist_selection =
265 gtk_tree_view_get_selection (GTK_TREE_VIEW (filelist));
266 gtk_tree_selection_set_mode (filelist_selection, GTK_SELECTION_MULTIPLE);
267
268
269
270 AlbumList = NULL;
271 ArtistList = NULL;
272
273 Extractors = EXTRACTOR_loadDefaultLibraries ();
274 Extractors =
275 EXTRACTOR_loadConfigLibraries (Extractors, "libextractor_filename");
276
277/* Create the popup menu */
278 filelist_popup = gtk_menu_new ();
279 GtkWidget *select_all_menu_item =
280 gtk_menu_item_new_with_label (_("Select all files"));
281 GtkWidget *delete_menu_item =
282 gtk_menu_item_new_with_label (_("Remove selected files"));
283 gtk_menu_attach (GTK_MENU (filelist_popup), select_all_menu_item, 0,
284 1, 0, 1);
285 gtk_menu_attach (GTK_MENU (filelist_popup), delete_menu_item, 0, 1, 1, 2);
286 gtk_widget_show (select_all_menu_item);
287 gtk_widget_show (delete_menu_item);
288 gtk_signal_connect (GTK_OBJECT (filelist), "button-press-event",
289 GTK_SIGNAL_FUNC (popup_delete), (gpointer) NULL);
290 gtk_signal_connect (GTK_OBJECT (select_all_menu_item), "activate",
291 GTK_SIGNAL_FUNC (select_all_files), (gpointer) TRUE);
292 gtk_signal_connect (GTK_OBJECT (delete_menu_item), "activate",
293 GTK_SIGNAL_FUNC (remove_file_from_list),
294 (gpointer) NULL);
295
296 /*
297 * show the main window
298 */
299 gtk_widget_show (musicinsertdialog);
300}
301
302/**
303 * @brief Get an EXTRACTOR_KeywordList for a specified file
304 * @param a pointer to the extractors used to get the keywords
305 * @param the name of the file to extract the keywords from
306 */
307EXTRACTOR_KeywordList *
308get_EXTRACTORKeywords (const EXTRACTOR_ExtractorList
309 * exList, const char *filename)
310{
311 EXTRACTOR_KeywordList *keyList;
312
313 keyList =
314 EXTRACTOR_getKeywords ((EXTRACTOR_ExtractorList *) exList, filename);
315 keyList =
316 EXTRACTOR_removeDuplicateKeywords (keyList,
317 EXTRACTOR_DUPLICATES_REMOVE_UNKNOWN);
318 keyList = EXTRACTOR_removeEmptyKeywords (keyList);
319 return keyList;
320}
321
322
323
324/**
325 * @brief Get an EXTRACTOR_KeywordList for a specified file
326 * @param the name of the file to extract the keywords from
327 */
328void
329set_File_Keywords (const gchar * filename)
330{
331 char *keywords[7];
332 GtkTreeIter pIter;
333
334 EXTRACTOR_KeywordList *KeywordList =
335 get_EXTRACTORKeywords (Extractors, filename);
336
337
338 keywords[0] =
339 (char *) EXTRACTOR_extractLast (EXTRACTOR_FILENAME, KeywordList);
340
341 keywords[1] =
342 (char *) EXTRACTOR_extractLast (EXTRACTOR_FILENAME, KeywordList);
343
344 keywords[2] = (char *) EXTRACTOR_extractLast (EXTRACTOR_TITLE, KeywordList);
345
346 keywords[3] =
347 (char *) EXTRACTOR_extractLast (EXTRACTOR_ARTIST, KeywordList);
348 if (keywords[3] != '\0'
349 &&
350 (g_list_find_custom
351 (ArtistList, keywords[3], (GCompareFunc) strcmp) == NULL))
352 {
353 ArtistList = g_list_append (ArtistList, GNUNET_strdup (keywords[3]));
354 gtk_combo_box_append_text (GTK_COMBO_BOX (artistcombobox), keywords[3]);
355 }
356
357 keywords[4] = (char *) EXTRACTOR_extractLast (EXTRACTOR_ALBUM, KeywordList);
358 if (keywords[4] != '\0'
359 &&
360 (g_list_find_custom
361 (AlbumList, keywords[4], (GCompareFunc) strcmp)) == NULL)
362 {
363 AlbumList = g_list_append (AlbumList, GNUNET_strdup (keywords[4]));
364 gtk_combo_box_append_text (GTK_COMBO_BOX (albumcombobox), keywords[4]);
365 }
366
367 keywords[5] =
368 (char *) EXTRACTOR_extractLast (EXTRACTOR_MIMETYPE, KeywordList);
369 if (keywords[5] != '\0')
370 {
371 if ((g_list_find_custom
372 (TypeList, keywords[5], (GCompareFunc) strcmp)) == NULL)
373 TypeList = g_list_append (TypeList, GNUNET_strdup (keywords[5]));
374
375 if (strcmp (keywords[5], "application/ogg") == 0)
376 gtk_combo_box_set_active (GTK_COMBO_BOX (typecombobox), FORMAT_OGG);
377 else if (strcmp (keywords[5], "audio/mpeg") == 0)
378 gtk_combo_box_set_active (GTK_COMBO_BOX (typecombobox), FORMAT_MP3);
379 else if (strcmp (keywords[5], "application/x-wav") == 0)
380 gtk_combo_box_set_active (GTK_COMBO_BOX (typecombobox), FORMAT_WAV);
381 else if (strcmp (keywords[5], "audio/vnd.rn-realaudio") == 0)
382 gtk_combo_box_set_active (GTK_COMBO_BOX (typecombobox), FORMAT_REAL);
383 }
384 else
385 {
386 TypeList = g_list_append (TypeList, GNUNET_strdup ("unspecified"));
387 }
388
389 keywords[6] =
390 (char *) EXTRACTOR_extractLast (EXTRACTOR_FORMAT, KeywordList);
391
392 gtk_list_store_append (filelist_store, &pIter);
393 gtk_list_store_set (filelist_store, &pIter, REAL_FILENAME_COL,
394 keywords[0], FILENAME_COL, keywords[1], TITLE_COL,
395 keywords[2], ARTIST_COL, keywords[3], ALBUM_COL,
396 keywords[4], TYPE_COL, keywords[5], FORMAT_COL,
397 keywords[6], KEYWORDS_COL, "", -1);
398 EXTRACTOR_freeKeywords (KeywordList);
399 return;
400}
401
402/**
403 * @brief Select entries in combo boxes based on per-file infos
404 */
405void
406activateComboBoxes ()
407{
408
409 if (gtk_combo_box_get_active (GTK_COMBO_BOX (albumcombobox)) < 0
410 &&
411 gtk_tree_model_iter_n_children (gtk_combo_box_get_model
412 (GTK_COMBO_BOX (albumcombobox)),
413 NULL) != 0)
414 gtk_combo_box_set_active (GTK_COMBO_BOX (albumcombobox), 0);
415
416 if (gtk_combo_box_get_active (GTK_COMBO_BOX (artistcombobox)) < 0
417 &&
418 gtk_tree_model_iter_n_children (gtk_combo_box_get_model
419 (GTK_COMBO_BOX (artistcombobox)),
420 NULL) != 0)
421 gtk_combo_box_set_active (GTK_COMBO_BOX (artistcombobox), 0);
422
423 if (gtk_combo_box_get_active (GTK_COMBO_BOX (typecombobox)) < 0
424 &&
425 gtk_tree_model_iter_n_children (gtk_combo_box_get_model
426 (GTK_COMBO_BOX (typecombobox)),
427 NULL) != 0)
428 gtk_combo_box_set_active (GTK_COMBO_BOX (typecombobox), 0);
429
430 return;
431}
432
433/**
434 * @brief Hide or show specific columns if needed
435 */
436void
437updateColumns ()
438{
439 if (g_list_length (ArtistList) > 1)
440 gtk_tree_view_column_set_visible (type_list_col, TRUE);
441 else
442 gtk_tree_view_column_set_visible (type_list_col, FALSE);
443
444 if (g_list_length (AlbumList) > 1)
445 gtk_tree_view_column_set_visible (type_list_col, TRUE);
446 else
447 gtk_tree_view_column_set_visible (type_list_col, FALSE);
448
449 if (g_list_length (TypeList) > 1)
450 gtk_tree_view_column_set_visible (type_list_col, TRUE);
451 else
452 gtk_tree_view_column_set_visible (type_list_col, FALSE);
453
454 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE
455 (filelist_store), FILENAME_COL,
456 GTK_SORT_ASCENDING);
457}
458
459gboolean
460insertfiles ()
461{
462 struct GNUNET_MetaData *dirmetadata;
463 struct GNUNET_MetaData *tempmetadata;
464 GArray *filesmetadatas, *files;
465 gchar *temptext;
466 gchar **dirkeywords;
467 gchararray *tempkeywords;
468 gchar **tempmetas, *dirmetas[8];
469 gchar *separator = ";";
470 int i, n;
471 guint useforallflags;
472 GtkWidget *keywordsentry;
473 GtkTreeIter fileiter;
474 GtkToggleButton *artisttogglebutton;
475 GtkToggleButton *albumtogglebutton;
476 GtkToggleButton *keywordstogglebutton;
477 GtkToggleButton *commentstogglebutton;
478
479 /* Test if files are present */
480 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (filelist_store),
481 &fileiter))
482 {
483 gchar *error_message =
484 GNUNET_strdup (_
485 ("No files to insert ! Please add files to the list before validating."));
486 GtkWidget *message_dialog =
487 gtk_message_dialog_new (GTK_WINDOW (musicinsertdialog),
488 GTK_DIALOG_DESTROY_WITH_PARENT,
489 GTK_MESSAGE_ERROR,
490 GTK_BUTTONS_CLOSE,
491 "%s", error_message);
492 gtk_dialog_run (GTK_DIALOG (message_dialog));
493 gtk_widget_destroy (message_dialog);
494 GNUNET_free (error_message);
495 return FALSE;
496 }
497
498
499 /* Manage album metadatas */
500
501 dirmetadata = GNUNET_meta_data_create ();
502
503 dirmetas[0] =
504 gtk_combo_box_get_active_text (GTK_COMBO_BOX (artistcombobox));
505 if (dirmetas[0])
506 GNUNET_meta_data_insert (dirmetadata, EXTRACTOR_ARTIST, dirmetas[0]);
507
508 dirmetas[1] = gtk_combo_box_get_active_text (GTK_COMBO_BOX (albumcombobox));
509 if (dirmetas[1])
510 GNUNET_meta_data_insert (dirmetadata, EXTRACTOR_ALBUM, dirmetas[1]);
511
512 keywordsentry = glade_xml_get_widget (musicinsertXML, "keywordsentry");
513 temptext = (gchar *) gtk_entry_get_text (GTK_ENTRY (keywordsentry));
514 dirkeywords = NULL;
515 if (temptext)
516 dirkeywords = g_strsplit (temptext, separator, 255);
517 n = 0;
518 while (dirkeywords[n])
519 {
520 GNUNET_meta_data_insert (dirmetadata, EXTRACTOR_KEYWORDS,
521 dirkeywords[n]);
522 n++;
523 }
524 /* Add a standard keyword to allow finding all available music albums
525 * on AFS in one search */
526 GNUNET_meta_data_insert (dirmetadata, EXTRACTOR_KEYWORDS, "music album");
527
528
529 /* Manage files metadatas */
530 artisttogglebutton =
531 GTK_TOGGLE_BUTTON (glade_xml_get_widget
532 (musicinsertXML, "artisttogglebutton"));
533 albumtogglebutton =
534 GTK_TOGGLE_BUTTON (glade_xml_get_widget
535 (musicinsertXML, "albumtogglebutton"));
536 keywordstogglebutton =
537 GTK_TOGGLE_BUTTON (glade_xml_get_widget
538 (musicinsertXML, "keywordstogglebutton"));
539 commentstogglebutton =
540 GTK_TOGGLE_BUTTON (glade_xml_get_widget
541 (musicinsertXML, "commentstogglebutton"));
542
543 useforallflags = 0;
544 useforallflags = gtk_toggle_button_get_active (artisttogglebutton) << 0;
545 useforallflags = gtk_toggle_button_get_active (albumtogglebutton) << 1;
546 useforallflags = gtk_toggle_button_get_active (keywordstogglebutton) << 2;
547 useforallflags = gtk_toggle_button_get_active (commentstogglebutton) << 3;
548
549 filesmetadatas =
550 g_array_sized_new (FALSE, FALSE, sizeof (struct GNUNET_MetaData *), 20);
551 files = g_array_sized_new (FALSE, FALSE, sizeof (gchar *), 20);
552 i = 0;
553 do
554 {
555 tempmetadata = GNUNET_meta_data_create ();
556 tempmetas = malloc (sizeof (gchar *) * 8);
557 g_array_append_val (filesmetadatas, tempmetadata);
558 gtk_tree_model_get (GTK_TREE_MODEL (filelist_store),
559 &fileiter,
560 REAL_FILENAME_COL, &tempmetas[0],
561 FILENAME_COL, &tempmetas[1],
562 TITLE_COL, &tempmetas[2],
563 ARTIST_COL, &tempmetas[3],
564 ALBUM_COL, &tempmetas[4],
565 TYPE_COL, &tempmetas[5],
566 FORMAT_COL, &tempmetas[6],
567 KEYWORDS_COL, &tempmetas[7], -1);
568 g_array_append_val (files, tempmetas[0]);
569
570
571 if (tempmetas[1])
572 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_FILENAME,
573 tempmetas[1]);
574 if ((useforallflags & 0x1) && dirmetas[0])
575 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_FILENAME,
576 dirmetas[0]);
577 else if (!(useforallflags & 0x1) && tempmetas[2])
578 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_TITLE, tempmetas[2]);
579 if ((useforallflags & 0x2) && dirmetas[1])
580 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_ARTIST, dirmetas[1]);
581 else if (!(useforallflags & 0x2) && tempmetas[3])
582 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_FILENAME,
583 tempmetas[3]);
584 if (tempmetas[4])
585 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_ALBUM, tempmetas[4]);
586 if (tempmetas[5])
587 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_MIMETYPE,
588 tempmetas[5]);
589 if (tempmetas[6])
590 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_FORMAT,
591 tempmetas[6]);
592
593 if (!(useforallflags & 0x1))
594 {
595 n = 0;
596 while (dirkeywords[n])
597 {
598 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_KEYWORDS,
599 dirkeywords[n]);
600 n++;
601 }
602 }
603 else if (tempmetas[7])
604 {
605 tempkeywords = g_strsplit (temptext, separator, 255);
606 n = 0;
607 while (tempkeywords[n])
608 {
609 GNUNET_meta_data_insert (tempmetadata,
610 EXTRACTOR_KEYWORDS, tempkeywords[n]);
611 n++;
612 }
613 g_strfreev (tempkeywords);
614 /* Add a standard keyword to allow finding all available music files
615 * on AFS in one search */
616 GNUNET_meta_data_insert (tempmetadata, EXTRACTOR_KEYWORDS, "music");
617 }
618
619 GNUNET_free (tempmetas);
620 i++;
621 }
622 while (gtk_tree_model_iter_next
623 (GTK_TREE_MODEL (filelist_store), &fileiter));
624
625 g_strfreev (dirkeywords);
626
627 /* TODO : take care of the 'Insert as an album'/'Insert files separately' options
628 * and create or not a gnunet directory containing the files
629 *
630 * TODO : Create a file and album description from metadatas - an idea :
631 * Artist: Song (Album) - Type and Format # for files
632 * Artist: Album - Type and number of the files # or album
633 *
634 * TODO : really call GNUNET_FSUI_upload() to insert these files */
635
636 return TRUE;
637}
638
639/* Callback functions */
640
641/**
642 * @brief Called when musicinsertdialog is destroyed (callback)
643 */
644void
645on_musicinsertdialog_destroy (GtkObject * object, gpointer user_data)
646{
647 EXTRACTOR_removeAll (Extractors);
648 UNREF (musicinsertXML);
649 musicinsertXML = NULL;
650}
651
652/**
653 * @brief Called when 'Cancel' button is clicked (callback)
654 */
655void
656on_cancelbutton_clicked (GtkButton * button, gpointer user_data)
657{
658 gtk_widget_destroy (musicinsertdialog);
659 return;
660}
661
662/**
663 * @brief Called when the user validates the insertion (callback)
664 */
665void
666on_okbutton_clicked (GtkButton * button, gpointer user_data)
667{
668 if (insertfiles ())
669 gtk_widget_destroy (musicinsertdialog);
670 return;
671}
672
673/**
674 * @brief Called when the 'Add a directory' button is clicked (callback)
675 */
676void
677on_diraddbutton_clicked (GtkButton * button, gpointer user_data)
678{
679 gchar *path;
680 GtkWidget *musicinsertdialog =
681 glade_xml_get_widget (musicinsertXML, "musicinsertdialog");
682 /* choose the directory to list */
683 GtkWidget *filechooser =
684 gtk_file_chooser_dialog_new (_("Choose the directory to insert..."),
685 GTK_WINDOW (musicinsertdialog),
686 GTK_FILE_CHOOSER_ACTION_OPEN,
687 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
688 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
689 NULL);
690 gtk_file_chooser_set_action (GTK_FILE_CHOOSER (filechooser),
691 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
692 gtk_window_set_modal (GTK_WINDOW (filechooser), TRUE);
693 switch (gtk_dialog_run (GTK_DIALOG (filechooser)))
694 {
695 case GTK_RESPONSE_ACCEPT:
696 /* get the path */
697 path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
698 gtk_widget_destroy (filechooser);
699 break;
700 default:
701 gtk_widget_destroy (filechooser);
702 return;
703 }
704
705 /* list directory and fill the fields */
706 GDir *directory;
707 GString *long_filename;
708 GError *dir_opening_error;
709 GSList *file_error_list = NULL;
710 gchar *filename;
711 if ((directory = g_dir_open (path, 0, &dir_opening_error)))
712 {
713 while ((filename = (gchar *) g_dir_read_name (directory)))
714 {
715 long_filename = g_string_new (path);
716 g_string_append_c (long_filename, DIR_SEPARATOR);
717 g_string_append (long_filename, filename);
718 if (!(ACCESS (long_filename->str, F_OK | R_OK)))
719 {
720 if (!(g_file_test (long_filename->str, G_FILE_TEST_IS_DIR)))
721 set_File_Keywords (long_filename->str);
722 }
723 else
724 {
725 file_error_list = g_slist_append (file_error_list, filename);
726 g_string_free (long_filename, TRUE);
727 }
728 }
729
730 g_free (path);
731 activateComboBoxes ();
732 updateColumns ();
733 if (g_slist_length (file_error_list) > 0)
734 {
735 GString *file_error_message =
736 g_string_new (_
737 ("The following files won't be added for I could not read them :"));
738 while ((file_error_list = g_slist_next (file_error_list)))
739 {
740 g_string_append_c (file_error_message, '\n');
741 g_string_append (file_error_message,
742 (gchar *) file_error_list->data);
743 }
744 GtkWidget *file_error_dialog =
745 gtk_message_dialog_new (GTK_WINDOW (musicinsertdialog),
746 GTK_DIALOG_DESTROY_WITH_PARENT,
747 GTK_MESSAGE_ERROR,
748 GTK_BUTTONS_CLOSE,
749 file_error_message->str);
750 gtk_dialog_run (GTK_DIALOG (file_error_dialog));
751 gtk_widget_destroy (file_error_dialog);
752 g_string_free (file_error_message, TRUE);
753 }
754 g_dir_close (directory);
755 }
756 else
757 {
758 gchar *error_message =
759 GNUNET_strdup (_("Could not open the directory :\n"));
760 GtkWidget *message_dialog =
761 gtk_message_dialog_new (GTK_WINDOW (musicinsertdialog),
762 GTK_DIALOG_DESTROY_WITH_PARENT,
763 GTK_MESSAGE_ERROR,
764 GTK_BUTTONS_CLOSE,
765 "%s%s", error_message,
766 dir_opening_error->message);
767 gtk_dialog_run (GTK_DIALOG (message_dialog));
768 gtk_widget_destroy (message_dialog);
769 g_free (error_message);
770 g_error_free (dir_opening_error);
771 }
772}
773
774/**
775 * @brief Called when the 'Add a file' button is clicked (callback)
776 */
777void
778on_fileaddbutton_clicked (GtkButton * button, gpointer user_data)
779{
780 GSList *pathlist;
781 GtkWidget *musicinsertdialog =
782 glade_xml_get_widget (musicinsertXML, "musicinsertdialog");
783 /* choose the file to add */
784 GtkWidget *filechooser =
785 gtk_file_chooser_dialog_new (_("Choose files to insert..."),
786 GTK_WINDOW (musicinsertdialog),
787 GTK_FILE_CHOOSER_ACTION_OPEN,
788 GTK_STOCK_CANCEL,
789 GTK_RESPONSE_CANCEL,
790 GTK_STOCK_OPEN,
791 GTK_RESPONSE_ACCEPT, NULL);
792 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (filechooser), TRUE);
793 gtk_window_set_modal (GTK_WINDOW (filechooser), TRUE);
794
795 if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT)
796 {
797 GSList *file_error_list = NULL;
798 /* get the path */
799 pathlist =
800 gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (filechooser));
801 gtk_widget_destroy (filechooser);
802 do
803 {
804 if (!(ACCESS (pathlist->data, F_OK | R_OK)))
805 {
806 set_File_Keywords (pathlist->data);
807 }
808 else
809 {
810 file_error_list =
811 g_slist_append (file_error_list, pathlist->data);
812 }
813 }
814 while ((pathlist = g_slist_next (pathlist)));
815 g_slist_free (pathlist);
816
817 activateComboBoxes ();
818 updateColumns ();
819
820 if (g_slist_length (file_error_list) > 0)
821 {
822 GString *file_error_message =
823 g_string_new (_
824 ("The following files won't be added for I could not read them :"));
825 while ((file_error_list = g_slist_next (file_error_list)))
826 {
827 g_string_append_c (file_error_message, '\n');
828 g_string_append (file_error_message,
829 (gchar *) file_error_list->data);
830 }
831
832 GtkWidget *file_error_dialog =
833 gtk_message_dialog_new (GTK_WINDOW (musicinsertdialog),
834 GTK_DIALOG_DESTROY_WITH_PARENT,
835 GTK_MESSAGE_ERROR,
836 GTK_BUTTONS_CLOSE,
837 file_error_message->str);
838 gtk_dialog_run (GTK_DIALOG (file_error_dialog));
839 g_string_free (file_error_message, TRUE);
840 gtk_widget_destroy (file_error_dialog);
841 }
842 return;
843 }
844 else
845 {
846 gtk_widget_destroy (filechooser);
847 return;
848 }
849}
850
851/**
852 * @brief Called when the user chooses the 'Full insertion' toggle button
853 */
854void
855on_radioinsert_toggled (GtkRadioButton * radiobutton, gpointer user_data)
856{
857 gtk_widget_set_sensitive (GTK_WIDGET
858 (glade_xml_get_widget
859 (musicinsertXML, "copyfilesbutton")), FALSE);
860}
861
862/**
863 * @brief Called when the user chooses the 'Index only' toggle button
864 */
865void
866on_radioindex_toggled (GtkRadioButton * radiobutton, gpointer user_data)
867{
868 gtk_widget_set_sensitive
869 (GTK_WIDGET
870 (glade_xml_get_widget (musicinsertXML, "copyfilesbutton")), TRUE);
871}
872
873/**
874 * @brief Hide or show the album column when needed
875 */
876void on_albumtogglebutton_toggled
877 (GtkToggleButton * togglebutton, gpointer user_data)
878{
879 if (gtk_toggle_button_get_active (togglebutton))
880 gtk_tree_view_column_set_visible (album_list_col, FALSE);
881 else
882 gtk_tree_view_column_set_visible (album_list_col, TRUE);
883}
884
885/**
886 * @brief Hide or show the artist column when needed
887 */
888void on_artisttogglebutton_toggled
889 (GtkToggleButton * togglebutton, gpointer user_data)
890{
891 if (gtk_toggle_button_get_active (togglebutton))
892 gtk_tree_view_column_set_visible (artist_list_col, FALSE);
893 else
894 gtk_tree_view_column_set_visible (artist_list_col, TRUE);
895}
896
897/**
898 * @brief Hide or show the keywords column when needed
899 */
900void on_keywordstogglebutton_toggled
901 (GtkToggleButton * togglebutton, gpointer user_data)
902{
903 if (gtk_toggle_button_get_active (togglebutton))
904 gtk_tree_view_column_set_visible (keywords_list_col, FALSE);
905 else
906 gtk_tree_view_column_set_visible (keywords_list_col, TRUE);
907}
908
909/**
910 * @brief Make to user able to modify the per-file data
911 */
912void on_renderer_edited
913 (GtkCellRendererText *
914 cellrenderertext,
915 gchar * path_string, gchar * new_text, gpointer user_data)
916{
917 GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
918 GtkTreeIter iter;
919 gtk_tree_model_get_iter (GTK_TREE_MODEL (filelist_store), &iter, path);
920 gtk_list_store_set (filelist_store, &iter,
921 (gint) * ((gint *) user_data), new_text, -1);
922 gtk_tree_path_free (path);
923}
924
925gboolean
926popup_delete (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
927{
928 if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3))
929 {
930 gtk_menu_popup (GTK_MENU (filelist_popup), NULL, NULL, NULL,
931 NULL, event->button, event->time);
932 return TRUE;
933 }
934 return FALSE;
935}
936
937/**
938 * @brief Remove a file from the list to insert
939 */
940void
941remove_file_from_list (gpointer user_data)
942{
943 GtkTreeIter iter;
944 GtkWidget *filelist = glade_xml_get_widget (musicinsertXML, "filelist");
945 GtkTreeSelection *selection =
946 gtk_tree_view_get_selection (GTK_TREE_VIEW (filelist));
947 GList *selected_paths = gtk_tree_selection_get_selected_rows (selection,
948 (GtkTreeModel
949 **) &
950 filelist_store);
951 GList *selected_refs = NULL;
952 GtkTreePath *path;
953/* Get static references from paths */
954 while (selected_paths)
955 {
956 selected_refs = g_list_append (selected_refs,
957 gtk_tree_row_reference_new
958 (GTK_TREE_MODEL
959 (filelist_store),
960 selected_paths->data));
961 selected_paths = g_list_next (selected_paths);
962 }
963 g_list_foreach (selected_paths, (GFunc) gtk_tree_path_free, NULL);
964 g_list_free (selected_paths);
965
966/* Remove items from references */
967 while (selected_refs)
968 {
969 path = gtk_tree_row_reference_get_path (selected_refs->data);
970 gtk_tree_model_get_iter (GTK_TREE_MODEL (filelist_store), &iter, path);
971 gtk_list_store_remove (filelist_store, &iter);
972 gtk_tree_path_free (path);
973 selected_refs = g_list_next (selected_refs);
974 }
975 g_list_foreach (selected_paths, (GFunc) gtk_tree_row_reference_free, NULL);
976 g_list_free (selected_paths);
977}
978
979/**
980 * @brief Select all the entries of the list view
981 */
982void
983select_all_files (gpointer user_data)
984{
985 GtkWidget *filelist = glade_xml_get_widget (musicinsertXML, "filelist");
986 GtkTreeSelection *selection =
987 gtk_tree_view_get_selection (GTK_TREE_VIEW (filelist));
988 gtk_tree_selection_select_all (selection);
989}
diff --git a/src/plugins/fs/extensions/musicinsert.glade b/src/plugins/fs/extensions/musicinsert.glade
deleted file mode 100644
index 4effd14f..00000000
--- a/src/plugins/fs/extensions/musicinsert.glade
+++ /dev/null
@@ -1,760 +0,0 @@
1<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3
4<glade-interface>
5
6<widget class="GtkWindow" id="musicinsertdialog">
7 <property name="visible">True</property>
8 <property name="title" translatable="yes">Insert an album into GNUnet AFS</property>
9 <property name="type">GTK_WINDOW_TOPLEVEL</property>
10 <property name="window_position">GTK_WIN_POS_NONE</property>
11 <property name="modal">False</property>
12 <property name="resizable">True</property>
13 <property name="destroy_with_parent">False</property>
14 <property name="decorated">True</property>
15 <property name="skip_taskbar_hint">False</property>
16 <property name="skip_pager_hint">False</property>
17 <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
18 <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
19 <signal name="destroy" handler="on_musicinsertdialog_destroy" last_modification_time="Sat, 06 Nov 2004 17:51:42 GMT"/>
20
21 <child>
22 <widget class="GtkVBox" id="vbox">
23 <property name="visible">True</property>
24 <property name="homogeneous">False</property>
25 <property name="spacing">0</property>
26
27 <child>
28 <widget class="GtkTable" id="globaltable">
29 <property name="border_width">14</property>
30 <property name="visible">True</property>
31 <property name="n_rows">7</property>
32 <property name="n_columns">4</property>
33 <property name="homogeneous">False</property>
34 <property name="row_spacing">16</property>
35 <property name="column_spacing">24</property>
36
37 <child>
38 <widget class="GtkLabel" id="keywordslabel">
39 <property name="visible">True</property>
40 <property name="label" translatable="yes">Additional _keywords :</property>
41 <property name="use_underline">True</property>
42 <property name="use_markup">False</property>
43 <property name="justify">GTK_JUSTIFY_LEFT</property>
44 <property name="wrap">False</property>
45 <property name="selectable">False</property>
46 <property name="xalign">0</property>
47 <property name="yalign">0.5</property>
48 <property name="xpad">0</property>
49 <property name="ypad">0</property>
50 <property name="mnemonic_widget">keywordsentry</property>
51 </widget>
52 <packing>
53 <property name="left_attach">0</property>
54 <property name="right_attach">1</property>
55 <property name="top_attach">4</property>
56 <property name="bottom_attach">5</property>
57 <property name="x_options">fill</property>
58 <property name="y_options"></property>
59 </packing>
60 </child>
61
62 <child>
63 <widget class="GtkEntry" id="keywordsentry">
64 <property name="visible">True</property>
65 <property name="tooltip" translatable="yes">Add here your misc keywords, comma-separated.</property>
66 <property name="can_focus">True</property>
67 <property name="editable">True</property>
68 <property name="visibility">True</property>
69 <property name="max_length">0</property>
70 <property name="text" translatable="yes"></property>
71 <property name="has_frame">True</property>
72 <property name="invisible_char">*</property>
73 <property name="activates_default">False</property>
74 </widget>
75 <packing>
76 <property name="left_attach">1</property>
77 <property name="right_attach">3</property>
78 <property name="top_attach">4</property>
79 <property name="bottom_attach">5</property>
80 <property name="y_options"></property>
81 </packing>
82 </child>
83
84 <child>
85 <widget class="GtkToggleButton" id="keywordstogglebutton">
86 <property name="visible">True</property>
87 <property name="tooltip" translatable="yes">Use these keywords for all files in the album. When pressed, this overpass the file-by-file keywords.</property>
88 <property name="can_focus">True</property>
89 <property name="relief">GTK_RELIEF_NORMAL</property>
90 <property name="focus_on_click">True</property>
91 <property name="active">True</property>
92 <property name="inconsistent">False</property>
93 <signal name="toggled" handler="on_keywordstogglebutton_toggled" last_modification_time="Sat, 26 Feb 2005 19:56:04 GMT"/>
94
95 <child>
96 <widget class="GtkImage" id="image12">
97 <property name="visible">True</property>
98 <property name="stock">gtk-dnd-multiple</property>
99 <property name="icon_size">4</property>
100 <property name="xalign">0.5</property>
101 <property name="yalign">0.5</property>
102 <property name="xpad">0</property>
103 <property name="ypad">0</property>
104 </widget>
105 </child>
106 </widget>
107 <packing>
108 <property name="left_attach">3</property>
109 <property name="right_attach">4</property>
110 <property name="top_attach">4</property>
111 <property name="bottom_attach">5</property>
112 <property name="x_options">fill</property>
113 <property name="y_options"></property>
114 </packing>
115 </child>
116
117 <child>
118 <widget class="GtkLabel" id="typelabel">
119 <property name="visible">True</property>
120 <property name="label" translatable="yes">_Type :</property>
121 <property name="use_underline">True</property>
122 <property name="use_markup">False</property>
123 <property name="justify">GTK_JUSTIFY_LEFT</property>
124 <property name="wrap">False</property>
125 <property name="selectable">False</property>
126 <property name="xalign">0</property>
127 <property name="yalign">0.5</property>
128 <property name="xpad">0</property>
129 <property name="ypad">0</property>
130 </widget>
131 <packing>
132 <property name="left_attach">0</property>
133 <property name="right_attach">1</property>
134 <property name="top_attach">3</property>
135 <property name="bottom_attach">4</property>
136 <property name="x_options">fill</property>
137 <property name="y_options"></property>
138 </packing>
139 </child>
140
141 <child>
142 <widget class="GtkLabel" id="fileslinklabel">
143 <property name="visible">True</property>
144 <property name="label" translatable="yes">_Insert these files :</property>
145 <property name="use_underline">True</property>
146 <property name="use_markup">False</property>
147 <property name="justify">GTK_JUSTIFY_LEFT</property>
148 <property name="wrap">False</property>
149 <property name="selectable">False</property>
150 <property name="xalign">0</property>
151 <property name="yalign">0.5</property>
152 <property name="xpad">0</property>
153 <property name="ypad">0</property>
154 <property name="mnemonic_widget">linkalbumradio</property>
155 </widget>
156 <packing>
157 <property name="left_attach">0</property>
158 <property name="right_attach">1</property>
159 <property name="top_attach">0</property>
160 <property name="bottom_attach">1</property>
161 <property name="x_options">fill</property>
162 <property name="y_options"></property>
163 </packing>
164 </child>
165
166 <child>
167 <widget class="GtkRadioButton" id="linkalbumradio">
168 <property name="visible">True</property>
169 <property name="tooltip" translatable="yes">Create a GNUnet directory to be able to find and download all the files together.</property>
170 <property name="can_focus">True</property>
171 <property name="label" translatable="yes">As an al_bum</property>
172 <property name="use_underline">True</property>
173 <property name="relief">GTK_RELIEF_NORMAL</property>
174 <property name="focus_on_click">True</property>
175 <property name="active">False</property>
176 <property name="inconsistent">False</property>
177 <property name="draw_indicator">True</property>
178 </widget>
179 <packing>
180 <property name="left_attach">1</property>
181 <property name="right_attach">2</property>
182 <property name="top_attach">0</property>
183 <property name="bottom_attach">1</property>
184 <property name="x_options">fill</property>
185 <property name="y_options"></property>
186 </packing>
187 </child>
188
189 <child>
190 <widget class="GtkRadioButton" id="linkseparateradio">
191 <property name="visible">True</property>
192 <property name="tooltip" translatable="yes">Don't create any link between these files. They won't be found together.</property>
193 <property name="can_focus">True</property>
194 <property name="label" translatable="yes">_Separately</property>
195 <property name="use_underline">True</property>
196 <property name="relief">GTK_RELIEF_NORMAL</property>
197 <property name="focus_on_click">True</property>
198 <property name="active">False</property>
199 <property name="inconsistent">False</property>
200 <property name="draw_indicator">True</property>
201 <property name="group">linkalbumradio</property>
202 </widget>
203 <packing>
204 <property name="left_attach">2</property>
205 <property name="right_attach">3</property>
206 <property name="top_attach">0</property>
207 <property name="bottom_attach">1</property>
208 <property name="x_options">fill</property>
209 <property name="y_options"></property>
210 </packing>
211 </child>
212
213 <child>
214 <widget class="GtkLabel" id="insertlabel">
215 <property name="visible">True</property>
216 <property name="label" translatable="yes">Insertion method :</property>
217 <property name="use_underline">True</property>
218 <property name="use_markup">False</property>
219 <property name="justify">GTK_JUSTIFY_LEFT</property>
220 <property name="wrap">False</property>
221 <property name="selectable">False</property>
222 <property name="xalign">0</property>
223 <property name="yalign">0.5</property>
224 <property name="xpad">0</property>
225 <property name="ypad">0</property>
226 <property name="mnemonic_widget">radioinsert</property>
227 </widget>
228 <packing>
229 <property name="left_attach">0</property>
230 <property name="right_attach">1</property>
231 <property name="top_attach">6</property>
232 <property name="bottom_attach">7</property>
233 <property name="x_options">fill</property>
234 <property name="y_options"></property>
235 </packing>
236 </child>
237
238 <child>
239 <widget class="GtkHBox" id="hbox4">
240 <property name="visible">True</property>
241 <property name="homogeneous">True</property>
242 <property name="spacing">0</property>
243
244 <child>
245 <widget class="GtkRadioButton" id="radioinsert">
246 <property name="visible">True</property>
247 <property name="tooltip" translatable="yes">Encrypt the files into GNUnet database. You won't be able to remove the files in the future.</property>
248 <property name="can_focus">True</property>
249 <property name="label" translatable="yes">Full _insertion</property>
250 <property name="use_underline">True</property>
251 <property name="relief">GTK_RELIEF_NORMAL</property>
252 <property name="focus_on_click">True</property>
253 <property name="active">False</property>
254 <property name="inconsistent">False</property>
255 <property name="draw_indicator">True</property>
256 <signal name="toggled" handler="on_radioinsert_toggled" last_modification_time="Fri, 25 Feb 2005 20:58:38 GMT"/>
257 </widget>
258 <packing>
259 <property name="padding">0</property>
260 <property name="expand">False</property>
261 <property name="fill">False</property>
262 </packing>
263 </child>
264
265 <child>
266 <widget class="GtkRadioButton" id="radioindex">
267 <property name="visible">True</property>
268 <property name="tooltip" translatable="yes">You should choose this option if you want to save disk space or remove the file from AFS later. But you mustn't move an indexed file before it has been removed from GNUnet.</property>
269 <property name="can_focus">True</property>
270 <property name="label" translatable="yes">Index _only</property>
271 <property name="use_underline">True</property>
272 <property name="relief">GTK_RELIEF_NORMAL</property>
273 <property name="focus_on_click">True</property>
274 <property name="active">True</property>
275 <property name="inconsistent">False</property>
276 <property name="draw_indicator">True</property>
277 <property name="group">radioinsert</property>
278 <signal name="toggled" handler="on_radioindex_toggled" last_modification_time="Fri, 25 Feb 2005 20:59:18 GMT"/>
279 </widget>
280 <packing>
281 <property name="padding">0</property>
282 <property name="expand">False</property>
283 <property name="fill">False</property>
284 </packing>
285 </child>
286
287 <child>
288 <widget class="GtkCheckButton" id="copyfilesbutton">
289 <property name="visible">True</property>
290 <property name="tooltip" translatable="yes">Copy files to shared folder to allow you to move them after indexation. You need free disk space to do this.</property>
291 <property name="can_focus">True</property>
292 <property name="label" translatable="yes">Co_py files</property>
293 <property name="use_underline">True</property>
294 <property name="relief">GTK_RELIEF_NORMAL</property>
295 <property name="focus_on_click">True</property>
296 <property name="active">False</property>
297 <property name="inconsistent">False</property>
298 <property name="draw_indicator">True</property>
299 </widget>
300 <packing>
301 <property name="padding">0</property>
302 <property name="expand">False</property>
303 <property name="fill">False</property>
304 </packing>
305 </child>
306 </widget>
307 <packing>
308 <property name="left_attach">1</property>
309 <property name="right_attach">3</property>
310 <property name="top_attach">6</property>
311 <property name="bottom_attach">7</property>
312 <property name="x_options">fill</property>
313 <property name="y_options">fill</property>
314 </packing>
315 </child>
316
317 <child>
318 <widget class="GtkLabel" id="commentslabel">
319 <property name="visible">True</property>
320 <property name="label" translatable="yes">Additional _comments :</property>
321 <property name="use_underline">True</property>
322 <property name="use_markup">False</property>
323 <property name="justify">GTK_JUSTIFY_LEFT</property>
324 <property name="wrap">False</property>
325 <property name="selectable">False</property>
326 <property name="xalign">0</property>
327 <property name="yalign">0.5</property>
328 <property name="xpad">0</property>
329 <property name="ypad">0</property>
330 <property name="mnemonic_widget">commentsentry</property>
331 </widget>
332 <packing>
333 <property name="left_attach">0</property>
334 <property name="right_attach">1</property>
335 <property name="top_attach">5</property>
336 <property name="bottom_attach">6</property>
337 <property name="x_options">fill</property>
338 <property name="y_options"></property>
339 </packing>
340 </child>
341
342 <child>
343 <widget class="GtkEntry" id="commentsentry">
344 <property name="visible">True</property>
345 <property name="tooltip" translatable="yes">Add here your misc comments.</property>
346 <property name="can_focus">True</property>
347 <property name="editable">True</property>
348 <property name="visibility">True</property>
349 <property name="max_length">0</property>
350 <property name="text" translatable="yes"></property>
351 <property name="has_frame">True</property>
352 <property name="invisible_char">*</property>
353 <property name="activates_default">False</property>
354 </widget>
355 <packing>
356 <property name="left_attach">1</property>
357 <property name="right_attach">3</property>
358 <property name="top_attach">5</property>
359 <property name="bottom_attach">6</property>
360 <property name="y_options"></property>
361 </packing>
362 </child>
363
364 <child>
365 <widget class="GtkToggleButton" id="commentstogglebutton">
366 <property name="visible">True</property>
367 <property name="tooltip" translatable="yes">Use these comments for all files in the album, and not only for the album.</property>
368 <property name="can_focus">True</property>
369 <property name="relief">GTK_RELIEF_NORMAL</property>
370 <property name="focus_on_click">True</property>
371 <property name="active">False</property>
372 <property name="inconsistent">False</property>
373
374 <child>
375 <widget class="GtkImage" id="image13">
376 <property name="visible">True</property>
377 <property name="stock">gtk-dnd-multiple</property>
378 <property name="icon_size">4</property>
379 <property name="xalign">0.5</property>
380 <property name="yalign">0.5</property>
381 <property name="xpad">0</property>
382 <property name="ypad">0</property>
383 </widget>
384 </child>
385 </widget>
386 <packing>
387 <property name="left_attach">3</property>
388 <property name="right_attach">4</property>
389 <property name="top_attach">5</property>
390 <property name="bottom_attach">6</property>
391 <property name="x_options">fill</property>
392 <property name="y_options"></property>
393 </packing>
394 </child>
395
396 <child>
397 <widget class="GtkLabel" id="albumlabel">
398 <property name="visible">True</property>
399 <property name="label" translatable="yes">Alb_um name :</property>
400 <property name="use_underline">True</property>
401 <property name="use_markup">False</property>
402 <property name="justify">GTK_JUSTIFY_LEFT</property>
403 <property name="wrap">False</property>
404 <property name="selectable">False</property>
405 <property name="xalign">0</property>
406 <property name="yalign">0.5</property>
407 <property name="xpad">0</property>
408 <property name="ypad">0</property>
409 </widget>
410 <packing>
411 <property name="left_attach">0</property>
412 <property name="right_attach">1</property>
413 <property name="top_attach">2</property>
414 <property name="bottom_attach">3</property>
415 <property name="x_options">fill</property>
416 <property name="y_options"></property>
417 </packing>
418 </child>
419
420 <child>
421 <widget class="GtkLabel" id="artistlabel">
422 <property name="visible">True</property>
423 <property name="label" translatable="yes">_Artist :</property>
424 <property name="use_underline">True</property>
425 <property name="use_markup">False</property>
426 <property name="justify">GTK_JUSTIFY_LEFT</property>
427 <property name="wrap">False</property>
428 <property name="selectable">False</property>
429 <property name="xalign">0</property>
430 <property name="yalign">0.5</property>
431 <property name="xpad">0</property>
432 <property name="ypad">0</property>
433 </widget>
434 <packing>
435 <property name="left_attach">0</property>
436 <property name="right_attach">1</property>
437 <property name="top_attach">1</property>
438 <property name="bottom_attach">2</property>
439 <property name="x_options">fill</property>
440 <property name="y_options"></property>
441 </packing>
442 </child>
443
444 <child>
445 <widget class="GtkToggleButton" id="albumtogglebutton">
446 <property name="visible">True</property>
447 <property name="tooltip" translatable="yes">All the files listed below are part of the same album. When pressed, this overpass the file-by-file album name.</property>
448 <property name="can_focus">True</property>
449 <property name="relief">GTK_RELIEF_NORMAL</property>
450 <property name="focus_on_click">True</property>
451 <property name="active">True</property>
452 <property name="inconsistent">False</property>
453 <signal name="toggled" handler="on_albumtogglebutton_toggled" last_modification_time="Sat, 26 Feb 2005 19:55:05 GMT"/>
454
455 <child>
456 <widget class="GtkImage" id="image9">
457 <property name="visible">True</property>
458 <property name="stock">gtk-dnd-multiple</property>
459 <property name="icon_size">4</property>
460 <property name="xalign">0.5</property>
461 <property name="yalign">0.5</property>
462 <property name="xpad">0</property>
463 <property name="ypad">0</property>
464 </widget>
465 </child>
466 </widget>
467 <packing>
468 <property name="left_attach">3</property>
469 <property name="right_attach">4</property>
470 <property name="top_attach">2</property>
471 <property name="bottom_attach">3</property>
472 <property name="x_options">fill</property>
473 <property name="y_options"></property>
474 </packing>
475 </child>
476
477 <child>
478 <widget class="GtkToggleButton" id="artisttogglebutton">
479 <property name="visible">True</property>
480 <property name="tooltip" translatable="yes">All the files are by the same artist. When pressed, this overpass the file-by-file artist name.</property>
481 <property name="can_focus">True</property>
482 <property name="relief">GTK_RELIEF_NORMAL</property>
483 <property name="focus_on_click">True</property>
484 <property name="active">True</property>
485 <property name="inconsistent">False</property>
486 <signal name="toggled" handler="on_artisttogglebutton_toggled" last_modification_time="Sat, 26 Feb 2005 19:55:24 GMT"/>
487
488 <child>
489 <widget class="GtkImage" id="image10">
490 <property name="visible">True</property>
491 <property name="stock">gtk-dnd-multiple</property>
492 <property name="icon_size">4</property>
493 <property name="xalign">0.5</property>
494 <property name="yalign">0.5</property>
495 <property name="xpad">0</property>
496 <property name="ypad">0</property>
497 </widget>
498 </child>
499 </widget>
500 <packing>
501 <property name="left_attach">3</property>
502 <property name="right_attach">4</property>
503 <property name="top_attach">1</property>
504 <property name="bottom_attach">2</property>
505 <property name="x_options">fill</property>
506 <property name="y_options"></property>
507 </packing>
508 </child>
509 </widget>
510 <packing>
511 <property name="padding">0</property>
512 <property name="expand">False</property>
513 <property name="fill">True</property>
514 </packing>
515 </child>
516
517 <child>
518 <widget class="GtkScrolledWindow" id="scrolledwindow">
519 <property name="visible">True</property>
520 <property name="can_focus">True</property>
521 <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
522 <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
523 <property name="shadow_type">GTK_SHADOW_IN</property>
524 <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
525
526 <child>
527 <widget class="GtkTreeView" id="filelist">
528 <property name="height_request">167</property>
529 <property name="visible">True</property>
530 <property name="tooltip" translatable="yes">The files you are going to insert. Edit the entries if they aren't correctly filled.</property>
531 <property name="can_focus">True</property>
532 <property name="headers_visible">True</property>
533 <property name="rules_hint">True</property>
534 <property name="reorderable">False</property>
535 <property name="enable_search">True</property>
536 </widget>
537 </child>
538 </widget>
539 <packing>
540 <property name="padding">0</property>
541 <property name="expand">True</property>
542 <property name="fill">True</property>
543 </packing>
544 </child>
545
546 <child>
547 <widget class="GtkHBox" id="hbox1">
548 <property name="visible">True</property>
549 <property name="homogeneous">False</property>
550 <property name="spacing">0</property>
551
552 <child>
553 <widget class="GtkHButtonBox" id="hbuttonbox1">
554 <property name="border_width">4</property>
555 <property name="visible">True</property>
556 <property name="layout_style">GTK_BUTTONBOX_START</property>
557 <property name="spacing">16</property>
558
559 <child>
560 <widget class="GtkButton" id="fileaddbutton">
561 <property name="visible">True</property>
562 <property name="can_default">True</property>
563 <property name="can_focus">True</property>
564 <property name="relief">GTK_RELIEF_NORMAL</property>
565 <property name="focus_on_click">True</property>
566 <signal name="clicked" handler="on_fileaddbutton_clicked" last_modification_time="Tue, 08 Feb 2005 17:41:33 GMT"/>
567
568 <child>
569 <widget class="GtkAlignment" id="alignment1">
570 <property name="visible">True</property>
571 <property name="xalign">0.5</property>
572 <property name="yalign">0.5</property>
573 <property name="xscale">0</property>
574 <property name="yscale">0</property>
575 <property name="top_padding">0</property>
576 <property name="bottom_padding">0</property>
577 <property name="left_padding">0</property>
578 <property name="right_padding">0</property>
579
580 <child>
581 <widget class="GtkHBox" id="hbox2">
582 <property name="visible">True</property>
583 <property name="homogeneous">False</property>
584 <property name="spacing">2</property>
585
586 <child>
587 <widget class="GtkImage" id="image1">
588 <property name="visible">True</property>
589 <property name="stock">gtk-file</property>
590 <property name="icon_size">4</property>
591 <property name="xalign">0.5</property>
592 <property name="yalign">0.5</property>
593 <property name="xpad">0</property>
594 <property name="ypad">0</property>
595 </widget>
596 <packing>
597 <property name="padding">0</property>
598 <property name="expand">False</property>
599 <property name="fill">False</property>
600 </packing>
601 </child>
602
603 <child>
604 <widget class="GtkLabel" id="fileaddbuttonlabel">
605 <property name="visible">True</property>
606 <property name="label" translatable="yes">Add _files</property>
607 <property name="use_underline">True</property>
608 <property name="use_markup">False</property>
609 <property name="justify">GTK_JUSTIFY_LEFT</property>
610 <property name="wrap">False</property>
611 <property name="selectable">False</property>
612 <property name="xalign">0.5</property>
613 <property name="yalign">0.460000008345</property>
614 <property name="xpad">0</property>
615 <property name="ypad">0</property>
616 </widget>
617 <packing>
618 <property name="padding">0</property>
619 <property name="expand">False</property>
620 <property name="fill">False</property>
621 </packing>
622 </child>
623 </widget>
624 </child>
625 </widget>
626 </child>
627 </widget>
628 </child>
629
630 <child>
631 <widget class="GtkButton" id="diraddbutton">
632 <property name="visible">True</property>
633 <property name="can_default">True</property>
634 <property name="can_focus">True</property>
635 <property name="relief">GTK_RELIEF_NORMAL</property>
636 <property name="focus_on_click">True</property>
637 <signal name="clicked" handler="on_diraddbutton_clicked" last_modification_time="Tue, 08 Feb 2005 17:41:51 GMT"/>
638
639 <child>
640 <widget class="GtkAlignment" id="alignment2">
641 <property name="visible">True</property>
642 <property name="xalign">0.5</property>
643 <property name="yalign">0.5</property>
644 <property name="xscale">0</property>
645 <property name="yscale">0</property>
646 <property name="top_padding">0</property>
647 <property name="bottom_padding">0</property>
648 <property name="left_padding">0</property>
649 <property name="right_padding">0</property>
650
651 <child>
652 <widget class="GtkHBox" id="hbox3">
653 <property name="visible">True</property>
654 <property name="homogeneous">False</property>
655 <property name="spacing">2</property>
656
657 <child>
658 <widget class="GtkImage" id="image2">
659 <property name="visible">True</property>
660 <property name="stock">gtk-directory</property>
661 <property name="icon_size">4</property>
662 <property name="xalign">0.5</property>
663 <property name="yalign">0.5</property>
664 <property name="xpad">0</property>
665 <property name="ypad">0</property>
666 </widget>
667 <packing>
668 <property name="padding">0</property>
669 <property name="expand">False</property>
670 <property name="fill">False</property>
671 </packing>
672 </child>
673
674 <child>
675 <widget class="GtkLabel" id="diraddbuttonlabel">
676 <property name="visible">True</property>
677 <property name="label">Add a _directory</property>
678 <property name="use_underline">True</property>
679 <property name="use_markup">False</property>
680 <property name="justify">GTK_JUSTIFY_LEFT</property>
681 <property name="wrap">False</property>
682 <property name="selectable">False</property>
683 <property name="xalign">0.5</property>
684 <property name="yalign">0.5</property>
685 <property name="xpad">0</property>
686 <property name="ypad">0</property>
687 </widget>
688 <packing>
689 <property name="padding">0</property>
690 <property name="expand">False</property>
691 <property name="fill">False</property>
692 </packing>
693 </child>
694 </widget>
695 </child>
696 </widget>
697 </child>
698 </widget>
699 </child>
700 </widget>
701 <packing>
702 <property name="padding">0</property>
703 <property name="expand">True</property>
704 <property name="fill">True</property>
705 </packing>
706 </child>
707
708 <child>
709 <widget class="GtkHButtonBox" id="hbuttonbox">
710 <property name="border_width">4</property>
711 <property name="visible">True</property>
712 <property name="layout_style">GTK_BUTTONBOX_END</property>
713 <property name="spacing">15</property>
714
715 <child>
716 <widget class="GtkButton" id="cancelbutton">
717 <property name="visible">True</property>
718 <property name="tooltip" translatable="yes">Quit this window without inserting the files. All keywords data will be lost.</property>
719 <property name="can_default">True</property>
720 <property name="can_focus">True</property>
721 <property name="label">gtk-cancel</property>
722 <property name="use_stock">True</property>
723 <property name="relief">GTK_RELIEF_NORMAL</property>
724 <property name="focus_on_click">True</property>
725 <signal name="clicked" handler="on_cancelbutton_clicked" last_modification_time="Sat, 06 Nov 2004 17:49:25 GMT"/>
726 </widget>
727 </child>
728
729 <child>
730 <widget class="GtkButton" id="okbutton">
731 <property name="visible">True</property>
732 <property name="tooltip" translatable="yes">Insert files into GNUnet AFS now.</property>
733 <property name="can_default">True</property>
734 <property name="can_focus">True</property>
735 <property name="label">gtk-ok</property>
736 <property name="use_stock">True</property>
737 <property name="relief">GTK_RELIEF_NORMAL</property>
738 <property name="focus_on_click">True</property>
739 <signal name="clicked" handler="on_okbutton_clicked" last_modification_time="Sat, 06 Nov 2004 17:49:08 GMT"/>
740 </widget>
741 </child>
742 </widget>
743 <packing>
744 <property name="padding">0</property>
745 <property name="expand">True</property>
746 <property name="fill">True</property>
747 </packing>
748 </child>
749 </widget>
750 <packing>
751 <property name="padding">0</property>
752 <property name="expand">False</property>
753 <property name="fill">True</property>
754 </packing>
755 </child>
756 </widget>
757 </child>
758</widget>
759
760</glade-interface>
diff --git a/src/plugins/fs/extensions/musicinsert.h b/src/plugins/fs/extensions/musicinsert.h
deleted file mode 100644
index 40d6ef55..00000000
--- a/src/plugins/fs/extensions/musicinsert.h
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/musicinsert.h
23 * @brief Music insertion dialog for gnunet-gtk
24 * @author Milan Bouchet
25 */
26
27#ifndef MUSICINSERT_MAIN_H
28#define MUSICINSERT_MAIN_H
29
30#include <extractor.h>
31#include <gtk/gtk.h>
32#include <glade/glade.h>
33
34#include "platform.h"
35
36#define MUSICINSERTXMLFILE "musicinsert.glade"
37
38/* Know music files mimetypes to list in the format ComboBoxEntry */
39enum Types
40{
41 FORMAT_OGG = 0,
42 FORMAT_MP3,
43 FORMAT_MPC,
44 FORMAT_AAC,
45 FORMAT_WMA,
46 FORMAT_FLAC,
47 FORMAT_APE,
48 FORMAT_WAV,
49 FORMAT_MIDI,
50 FORMAT_REAL
51};
52
53/* Columns IDs constants */
54enum
55{
56 REAL_FILENAME_COL = 0,
57 FILENAME_COL,
58 TITLE_COL,
59 ARTIST_COL,
60 ALBUM_COL,
61 TYPE_COL,
62 FORMAT_COL,
63 KEYWORDS_COL,
64 COLS_NUMBER
65};
66
67/* Columns IDs : need to be stored in a variable to be passed using a (void *) */
68const gint filename_col_num = FILENAME_COL;
69const gint title_col_num = TITLE_COL;
70const gint artist_col_num = ARTIST_COL;
71const gint album_col_num = ALBUM_COL;
72const gint type_col_num = TYPE_COL;
73const gint format_col_num = FORMAT_COL;
74const gint keywords_col_num = KEYWORDS_COL;
75
76
77
78EXTRACTOR_KeywordList *get_EXTRACTORKeywords (const EXTRACTOR_ExtractorList *
79 exList, const gchar * filename);
80void set_File_Keywords (const gchar * filename);
81void activateComboBoxes ();
82void updateColumns ();
83void show_musicinsertdialog ();
84gboolean insertfiles ();
85
86/* Callback functions declaration */
87void on_musicinsertdialog_destroy (GtkObject * object, gpointer user_data);
88
89void on_cancelbutton_clicked (GtkButton * button, gpointer user_data);
90
91void on_okbutton_clicked (GtkButton * button, gpointer user_data);
92
93void on_fileaddbutton_clicked (GtkButton * button, gpointer user_data);
94
95void on_diraddbutton_clicked (GtkButton * button, gpointer user_data);
96
97void
98on_radioinsert_toggled (GtkRadioButton * radiobutton, gpointer user_data);
99
100void on_radioindex_toggled (GtkRadioButton * radiobutton, gpointer user_data);
101
102void
103on_albumtogglebutton_toggled (GtkToggleButton * togglebutton,
104 gpointer user_data);
105
106void
107on_artisttogglebutton_toggled (GtkToggleButton * togglebutton,
108 gpointer user_data);
109
110void
111on_typetogglebutton_toggled (GtkToggleButton * togglebutton,
112 gpointer user_data);
113
114void
115on_keywordstogglebutton_toggled (GtkToggleButton * togglebutton,
116 gpointer user_data);
117
118void
119on_renderer_edited (GtkCellRendererText * cellrenderertext,
120 gchar * arg1, gchar * arg2, gpointer user_data);
121
122gboolean popup_delete (GtkWidget * widget,
123 GdkEventButton * event, gpointer user_data);
124
125void remove_file_from_list (gpointer user_data);
126
127void select_all_files (gpointer user_data);
128
129
130#endif
diff --git a/src/plugins/fs/fs.c b/src/plugins/fs/fs.c
deleted file mode 100644
index 93a173be..00000000
--- a/src/plugins/fs/fs.c
+++ /dev/null
@@ -1,602 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/fs.c
23 * @brief main file-sharing code of gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include <GNUnet/gnunet_collection_lib.h>
29#include <gdk/gdk.h>
30#include "fs.h"
31#include "meta.h"
32#include "download.h"
33#include "search.h"
34#include "upload.h"
35#include "collection.h"
36#include "namespace.h"
37
38struct GNUNET_FSUI_Context *ctx;
39
40struct GNUNET_GE_Context *ectx;
41
42struct GNUNET_GC_Configuration *cfg;
43
44SearchList *search_head;
45
46DownloadList *download_head;
47
48UploadList *upload_head;
49
50GtkListStore *search_summary;
51
52GtkTreeStore *download_summary;
53
54GtkTreeStore *upload_summary;
55
56void
57on_updateIntervalComboEntry_changed_fs (GtkWidget * button,
58 GtkWidget * entryBox)
59{
60 const char *time;
61 GNUNET_Int32Time t;
62 GtkEntry *entry;
63
64 entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (entryBox)));
65 time = gtk_entry_get_text (entry);
66 if (GNUNET_OK != parseTimeInterval (time, &t))
67 {
68 gtk_widget_set_sensitive (button, FALSE);
69 }
70 else
71 {
72 gtk_widget_set_sensitive (button, TRUE);
73 }
74}
75
76
77/**
78 * The selection of the download summary changed.
79 * Update button status.
80 */
81void
82on_anonymity_spin_changed_fs (GtkWidget * w, gpointer dummy)
83{
84 gint val;
85 GdkColor bcolor;
86 GdkColor fcolor;
87 GtkSpinButton *spin;
88
89 spin = GTK_SPIN_BUTTON (w);
90 if (spin == NULL)
91 {
92 GNUNET_GE_BREAK (NULL, 0);
93 return;
94 }
95 val = gtk_spin_button_get_value_as_int (spin);
96 if (val == 0)
97 {
98 if ((TRUE == gdk_color_parse ("red",
99 &bcolor)) &&
100 (TRUE == gdk_colormap_alloc_color (gdk_colormap_get_system (),
101 &bcolor, FALSE, TRUE)) &&
102 (TRUE == gdk_color_parse ("black",
103 &fcolor)) &&
104 (TRUE == gdk_colormap_alloc_color (gdk_colormap_get_system (),
105 &fcolor, FALSE, TRUE)))
106 {
107 gtk_widget_modify_base (w, GTK_STATE_NORMAL, &bcolor);
108 gtk_widget_modify_text (w, GTK_STATE_NORMAL, &fcolor);
109 }
110 }
111 else
112 {
113 gtk_widget_modify_base (w, GTK_STATE_NORMAL, NULL);
114 gtk_widget_modify_text (w, GTK_STATE_NORMAL, NULL);
115 }
116}
117
118static void *
119saveEventProcessor (void *cls)
120{
121 const GNUNET_FSUI_Event *event = cls;
122 void *ret;
123 unsigned int i;
124
125 ret = NULL;
126 switch (event->type)
127 {
128 /* search events */
129 case GNUNET_FSUI_search_started:
130 ret = fs_search_started (event->data.SearchStarted.sc.pos,
131 event->data.SearchStarted.searchURI,
132 event->data.SearchStarted.anonymityLevel,
133 0, NULL, GNUNET_FSUI_ACTIVE);
134 break;
135 case GNUNET_FSUI_search_result:
136 fs_search_result_received (event->data.SearchResult.sc.cctx,
137 &event->data.SearchResult.fi,
138 event->data.SearchResult.searchURI);
139 break;
140 case GNUNET_FSUI_search_aborted:
141 fs_search_aborted (event->data.SearchAborted.sc.cctx);
142 break;
143 case GNUNET_FSUI_search_paused:
144 fs_search_paused (event->data.SearchPaused.sc.cctx);
145 break;
146 case GNUNET_FSUI_search_restarted:
147 fs_search_restarted (event->data.SearchRestarted.sc.cctx);
148 break;
149 case GNUNET_FSUI_search_suspended:
150 fs_search_aborted (event->data.SearchSuspended.sc.cctx);
151 break;
152 case GNUNET_FSUI_search_resumed:
153 ret = fs_search_started (event->data.SearchResumed.sc.pos,
154 event->data.SearchResumed.searchURI,
155 event->data.SearchResumed.anonymityLevel,
156 event->data.SearchResumed.fisSize,
157 event->data.SearchResumed.fis,
158 event->data.SearchResumed.state);
159 for (i = 0; i < event->data.SearchResumed.fisSize; i++)
160 fs_search_update (ret,
161 &event->data.SearchResumed.fis[i],
162 event->data.SearchResumed.availability_rank[i],
163 event->data.SearchResumed.availability_certainty[i],
164 event->data.SearchResumed.applicability_rank[i]);
165 break;
166 case GNUNET_FSUI_search_stopped:
167 fs_search_stopped (event->data.SearchStopped.sc.cctx);
168 break;
169 case GNUNET_FSUI_search_update:
170 fs_search_update (event->data.SearchUpdate.sc.cctx,
171 &event->data.SearchUpdate.fi,
172 event->data.SearchUpdate.availability_rank,
173 event->data.SearchUpdate.availability_certainty,
174 event->data.SearchUpdate.applicability_rank);
175 break;
176 /* download events */
177 case GNUNET_FSUI_download_aborted:
178 fs_download_aborted (event->data.DownloadAborted.dc.cctx);
179 break;
180 case GNUNET_FSUI_download_error:
181 fs_download_aborted (event->data.DownloadError.dc.cctx);
182 break;
183 case GNUNET_FSUI_download_suspended:
184 fs_download_stopped (event->data.DownloadSuspended.dc.cctx);
185 break;
186 case GNUNET_FSUI_download_progress:
187 fs_download_update (event->data.DownloadProgress.dc.cctx,
188 event->data.DownloadProgress.completed,
189 event->data.DownloadProgress.last_block,
190 event->data.DownloadProgress.last_size);
191 break;
192 case GNUNET_FSUI_download_completed:
193 fs_download_completed (event->data.DownloadCompleted.dc.cctx);
194 break;
195 case GNUNET_FSUI_download_stopped:
196 fs_download_stopped (event->data.DownloadStopped.dc.cctx);
197 break;
198 case GNUNET_FSUI_download_started:
199 ret = fs_download_started (event->data.DownloadStarted.dc.pos,
200 event->data.DownloadStarted.dc.pcctx,
201 event->data.DownloadStarted.dc.sctx,
202 event->data.DownloadStarted.total,
203 event->data.DownloadStarted.anonymityLevel,
204 &event->data.DownloadStarted.fi,
205 event->data.DownloadStarted.filename,
206 0, GNUNET_get_time (), GNUNET_FSUI_ACTIVE);
207 break;
208 case GNUNET_FSUI_download_resumed:
209 ret = fs_download_started (event->data.DownloadResumed.dc.pos,
210 event->data.DownloadResumed.dc.pcctx,
211 event->data.DownloadResumed.dc.sctx,
212 event->data.DownloadResumed.total,
213 event->data.DownloadResumed.anonymityLevel,
214 &event->data.DownloadResumed.fi,
215 event->data.DownloadResumed.filename,
216 event->data.DownloadResumed.completed,
217 event->data.DownloadResumed.eta,
218 event->data.DownloadResumed.state);
219 break;
220
221 /* upload events */
222 case GNUNET_FSUI_upload_progress:
223 fs_upload_update (event->data.UploadProgress.uc.cctx,
224 event->data.UploadProgress.completed,
225 event->data.UploadProgress.total);
226 break;
227 case GNUNET_FSUI_upload_completed:
228 fs_upload_complete (event->data.UploadCompleted.uc.cctx,
229 event->data.UploadCompleted.uri);
230 break;
231 case GNUNET_FSUI_upload_error:
232 fs_upload_error (event->data.UploadError.uc.cctx,
233 event->data.UploadError.message);
234 break;
235 case GNUNET_FSUI_upload_aborted:
236 fs_upload_aborted (event->data.UploadAborted.uc.cctx);
237 break;
238 case GNUNET_FSUI_upload_stopped:
239 fs_upload_stopped (event->data.UploadStopped.uc.cctx);
240 break;
241 case GNUNET_FSUI_upload_suspended:
242 fs_upload_stopped (event->data.UploadSuspended.uc.cctx);
243 break;
244 case GNUNET_FSUI_upload_started:
245 ret = fs_upload_started (event->data.UploadStarted.uc.pos,
246 event->data.UploadStarted.uc.pcctx,
247 event->data.UploadStarted.filename,
248 NULL,
249 event->data.UploadStarted.total,
250 0, GNUNET_FSUI_ACTIVE);
251 break;
252 case GNUNET_FSUI_upload_resumed:
253 ret = fs_upload_started (event->data.UploadResumed.uc.pos,
254 event->data.UploadResumed.uc.pcctx,
255 event->data.UploadResumed.filename,
256 event->data.UploadResumed.uri,
257 event->data.UploadResumed.total,
258 event->data.UploadResumed.completed,
259 event->data.UploadResumed.state);
260 break;
261 /* TODO: unindex events */
262 default:
263 GNUNET_GE_BREAK (ectx, 0);
264 GNUNET_GE_LOG (ectx,
265 GNUNET_GE_ERROR,
266 _("Unhandled (unknown) FSUI event: %u.\n"), event->type);
267 break;
268 }
269 return ret;
270}
271
272static void *
273eventProcessor (void *unused, const GNUNET_FSUI_Event * event)
274{
275 return GNUNET_GTK_save_call (&saveEventProcessor, (void *) event);
276}
277
278/**
279 * The selection of the upload summary changed.
280 * Update button status.
281 */
282static void
283on_upload_summary_selection_changed (gpointer signal, gpointer cls)
284{
285 GtkTreeSelection *selection;
286 GtkWidget *button;
287
288 selection =
289 gtk_tree_view_get_selection (GTK_TREE_VIEW
290 (glade_xml_get_widget
291 (GNUNET_GTK_get_main_glade_XML (),
292 "activeUploadsList")));
293 button =
294 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
295 "stopUploadButton");
296 gtk_widget_set_sensitive (button,
297 gtk_tree_selection_count_selected_rows (selection)
298 > 0);
299}
300
301/**
302 * The selection of the download summary changed.
303 * Update button status.
304 */
305static void
306on_download_summary_selection_changed (gpointer signal, gpointer cls)
307{
308 GtkTreeSelection *selection;
309 GtkWidget *button;
310
311 selection =
312 gtk_tree_view_get_selection (GTK_TREE_VIEW
313 (glade_xml_get_widget
314 (GNUNET_GTK_get_main_glade_XML (),
315 "activeDownloadsList")));
316 button =
317 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
318 "abortDownloadButton");
319 gtk_widget_set_sensitive (button,
320 gtk_tree_selection_count_selected_rows (selection)
321 > 0);
322 button =
323 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
324 "stopDownloadButton");
325 gtk_widget_set_sensitive (button,
326 gtk_tree_selection_count_selected_rows (selection)
327 > 0);
328}
329
330/**
331 * Setup the summary views (in particular the models
332 * and the renderers).
333 */
334static void
335fs_summary_start ()
336{
337 GtkComboBoxEntry *searchCB;
338 GtkWidget *uploadEntry;
339 GtkTreeView *downloadList;
340 GtkTreeView *uploadList;
341 GtkListStore *model;
342 GtkCellRenderer *renderer;
343 GtkTreeViewColumn *column;
344 int col;
345 GladeXML *contextMenuXML;
346 GtkTreeIter iter;
347
348 /* keyword list setup */
349 searchCB
350 =
351 GTK_COMBO_BOX_ENTRY (glade_xml_get_widget
352 (GNUNET_GTK_get_main_glade_XML (),
353 "fssearchKeywordComboBoxEntry"));
354 model = gtk_list_store_new (1, G_TYPE_STRING /* search string */ );
355 gtk_combo_box_set_model (GTK_COMBO_BOX (searchCB), GTK_TREE_MODEL (model));
356 gtk_combo_box_entry_set_text_column (searchCB, 0);
357
358 /* search namespace selection setup */
359 searchCB
360 =
361 GTK_COMBO_BOX_ENTRY (glade_xml_get_widget
362 (GNUNET_GTK_get_main_glade_XML (),
363 "searchNamespaceComboBoxEntry"));
364
365 model = gtk_list_store_new (NS_SEARCH_NUM, G_TYPE_STRING, /* what we show */
366 G_TYPE_STRING, /* GNUNET_EncName of namespace */
367 G_TYPE_POINTER, /* ECRS MetaData */
368 G_TYPE_INT); /* Meta-data about namespace */
369 gtk_list_store_append (model, &iter);
370 gtk_list_store_set (model,
371 &iter,
372 NS_SEARCH_DESCRIPTION, _("globally"),
373 NS_SEARCH_NAME, _("globally"),
374 NS_SEARCH_METADATA, NULL,
375 NS_SEARCH_RATING, 0, -1);
376 gtk_combo_box_set_model (GTK_COMBO_BOX (searchCB), GTK_TREE_MODEL (model));
377 gtk_combo_box_entry_set_text_column (searchCB, NS_SEARCH_DESCRIPTION);
378
379 /* download summary setup */
380 downloadList =
381 GTK_TREE_VIEW (glade_xml_get_widget
382 (GNUNET_GTK_get_main_glade_XML (), "activeDownloadsList"));
383 download_summary = gtk_tree_store_new (DOWNLOAD_NUM, G_TYPE_STRING, /* name (full-path file name) */
384 G_TYPE_STRING, /* name (user-friendly name) */
385 G_TYPE_UINT64, /* size */
386 G_TYPE_STRING, /* human readable size */
387 G_TYPE_INT, /* progress */
388 G_TYPE_STRING, /* uri as string */
389 G_TYPE_POINTER, /* meta data */
390 G_TYPE_POINTER); /* internal download list ptr */
391 gtk_tree_view_set_model (downloadList, GTK_TREE_MODEL (download_summary));
392 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (downloadList),
393 GTK_SELECTION_MULTIPLE);
394 g_signal_connect_data (gtk_tree_view_get_selection (downloadList),
395 "changed",
396 G_CALLBACK (&on_download_summary_selection_changed),
397 NULL, NULL, 0);
398 contextMenuXML =
399 glade_xml_new (GNUNET_GTK_get_glade_filename (),
400 "downloadsContextMenu", PACKAGE_NAME);
401 GNUNET_GTK_connect_glade_with_plugins (contextMenuXML);
402
403 renderer = gtk_cell_renderer_text_new ();
404 col = gtk_tree_view_insert_column_with_attributes (downloadList,
405 -1,
406 _("Name"),
407 renderer,
408 "text",
409 DOWNLOAD_SHORTNAME,
410 NULL);
411
412 column = gtk_tree_view_get_column (downloadList, col - 1);
413 gtk_tree_view_column_set_resizable (column, TRUE);
414 gtk_tree_view_column_set_clickable (column, TRUE);
415 gtk_tree_view_column_set_reorderable (column, TRUE);
416 gtk_tree_view_column_set_sort_column_id (column, DOWNLOAD_SHORTNAME);
417 gtk_tree_view_column_set_resizable (column, TRUE);
418
419 renderer = gtk_cell_renderer_text_new ();
420 g_object_set (renderer, "xalign", 1.00, NULL);
421 col = gtk_tree_view_insert_column_with_attributes (downloadList,
422 -1,
423 _("Size"),
424 renderer,
425 "text", DOWNLOAD_HSIZE,
426 NULL);
427
428 column = gtk_tree_view_get_column (downloadList, col - 1);
429 gtk_tree_view_column_set_resizable (column, TRUE);
430 gtk_tree_view_column_set_clickable (column, TRUE);
431 gtk_tree_view_column_set_reorderable (column, TRUE);
432 gtk_tree_view_column_set_sort_column_id (column, DOWNLOAD_SIZE);
433 gtk_tree_view_column_set_resizable (column, TRUE);
434
435 renderer = gtk_cell_renderer_progress_new ();
436 col = gtk_tree_view_insert_column_with_attributes (downloadList,
437 -1,
438 _("Progress"),
439 renderer,
440 "value",
441 DOWNLOAD_PROGRESS, NULL);
442 g_object_set (G_OBJECT (renderer), "width", 400, NULL);
443 column = gtk_tree_view_get_column (downloadList, col - 1);
444 gtk_tree_view_column_set_resizable (column, TRUE);
445 gtk_tree_view_column_set_clickable (column, TRUE);
446 gtk_tree_view_column_set_reorderable (column, TRUE);
447 gtk_tree_view_column_set_sort_column_id (column, DOWNLOAD_PROGRESS);
448 gtk_tree_view_column_set_resizable (column, TRUE);
449
450 renderer = gtk_cell_renderer_text_new ();
451 col = gtk_tree_view_insert_column_with_attributes (downloadList,
452 -1,
453 _("URI"),
454 renderer,
455 "text",
456 DOWNLOAD_URISTRING,
457 NULL);
458 g_object_set (G_OBJECT (renderer), "wrap-width", 30, "width-chars", 30,
459 "ellipsize", PANGO_ELLIPSIZE_END, NULL);
460 column = gtk_tree_view_get_column (downloadList, col - 1);
461 gtk_tree_view_column_set_resizable (column, TRUE);
462 gtk_tree_view_column_set_reorderable (column, TRUE);
463 gtk_tree_view_column_set_resizable (column, TRUE);
464
465 /* upload summary setup */
466 uploadList =
467 GTK_TREE_VIEW (glade_xml_get_widget
468 (GNUNET_GTK_get_main_glade_XML (), "activeUploadsList"));
469 upload_summary = gtk_tree_store_new (UPLOAD_NUM, G_TYPE_STRING, /* filename */
470 G_TYPE_INT, /* progress */
471 G_TYPE_STRING, /* URI as string */
472 G_TYPE_POINTER); /* UploadList */
473 gtk_tree_view_set_model (uploadList, GTK_TREE_MODEL (upload_summary));
474 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (uploadList),
475 GTK_SELECTION_MULTIPLE);
476 g_signal_connect_data (gtk_tree_view_get_selection (uploadList),
477 "changed",
478 G_CALLBACK (&on_upload_summary_selection_changed),
479 NULL, NULL, 0);
480 contextMenuXML =
481 glade_xml_new (GNUNET_GTK_get_glade_filename (),
482 "uploadsContextMenu", PACKAGE_NAME);
483 GNUNET_GTK_connect_glade_with_plugins (contextMenuXML);
484
485 renderer = gtk_cell_renderer_progress_new ();
486 col = gtk_tree_view_insert_column_with_attributes (uploadList,
487 -1,
488 _("Filename"),
489 renderer,
490 "text", UPLOAD_FILENAME,
491 "value", UPLOAD_PROGRESS,
492 NULL);
493 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (uploadList,
494 col - 1),
495 TRUE);
496
497 renderer = gtk_cell_renderer_text_new ();
498 col = gtk_tree_view_insert_column_with_attributes (uploadList,
499 -1,
500 _("URI"),
501 renderer,
502 "text", UPLOAD_URISTRING,
503 NULL);
504 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column (uploadList,
505 col - 1),
506 TRUE);
507 /* upload entry setup */
508 uploadEntry
509 =
510 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
511 "uploadFilenameComboBoxEntry");
512
513 model = gtk_list_store_new (1, G_TYPE_STRING);
514 gtk_combo_box_set_model (GTK_COMBO_BOX (uploadEntry),
515 GTK_TREE_MODEL (model));
516 gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (uploadEntry), 0);
517}
518
519/**
520 * Shutdown the summary dialogs.
521 */
522static void
523fs_summary_stop ()
524{
525 struct GNUNET_MetaData *meta;
526 GtkComboBox *searchCB;
527 GtkTreeModel *model;
528 GtkTreeIter iter;
529
530 searchCB
531 = GTK_COMBO_BOX (glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
532 "searchNamespaceComboBoxEntry"));
533 model = gtk_combo_box_get_model (searchCB);
534 if (gtk_tree_model_get_iter_first (model, &iter))
535 {
536 do
537 {
538 gtk_tree_model_get (model, &iter, NS_SEARCH_METADATA, &meta, -1);
539 gtk_list_store_set (GTK_LIST_STORE (model),
540 &iter, NS_SEARCH_METADATA, NULL, -1);
541 if (meta != NULL)
542 GNUNET_meta_data_destroy (meta);
543 }
544 while (gtk_list_store_remove (GTK_LIST_STORE (model), &iter));
545 }
546
547}
548
549static void
550init_cron_job (void *arg)
551{
552 GtkWidget *tab = arg;
553
554 ctx = GNUNET_FSUI_start (ectx, cfg, "gnunet-gtk", 64, /* FIXME: allow user to configure download parallelism */
555 GNUNET_YES, &eventProcessor, NULL);
556 GNUNET_GTK_save_call ((GNUNET_ThreadMainFunction) & gtk_widget_show, tab);
557}
558
559void
560init_fs (struct GNUNET_GE_Context *e, struct GNUNET_GC_Configuration *c)
561{
562 GtkWidget *tab;
563 struct GNUNET_CronManager *cron;
564
565 ectx = e;
566 cfg = c;
567 GNUNET_CO_init (ectx, cfg);
568 fs_summary_start ();
569 fs_collection_start ();
570 fs_namespace_start ();
571 tab = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (), "fsnotebook");
572 cron = GNUNET_GTK_get_cron_manager ();
573 GNUNET_cron_add_job (cron, &init_cron_job, 0, 0, tab);
574}
575
576static void *
577cleanup_save_call (void *arg)
578{
579 GtkWidget *tab = arg;
580
581 fs_summary_stop ();
582 fs_namespace_stop ();
583 gtk_widget_hide (tab);
584 return NULL;
585}
586
587void
588done_fs ()
589{
590 struct GNUNET_CronManager *cron;
591 GtkWidget *tab;
592
593 tab = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (), "fsnotebook");
594 cron = GNUNET_GTK_get_cron_manager ();
595 GNUNET_cron_del_job (cron, &init_cron_job, 0, tab);
596 if (ctx != NULL)
597 GNUNET_FSUI_stop (ctx);
598 GNUNET_GTK_save_call (&cleanup_save_call, tab);
599 GNUNET_CO_done ();
600}
601
602/* end of fs.c */
diff --git a/src/plugins/fs/fs.h b/src/plugins/fs/fs.h
deleted file mode 100644
index 4241df69..00000000
--- a/src/plugins/fs/fs.h
+++ /dev/null
@@ -1,333 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/fs.h
23 * @brief file-sharing globals of gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_FS_H
28#define GTK_FS_H
29
30#include "platform.h"
31#include <GNUnet/gnunet_ecrs_lib.h>
32#include <GNUnet/gnunet_fsui_lib.h>
33#include <GNUnet/gnunet_uritrack_lib.h>
34#include "gnunetgtk_common.h"
35
36/**
37 * On search box, for namespace selection
38 * (for input of search URI; lists known namespaces).
39 */
40enum
41{
42 NS_SEARCH_DESCRIPTION = 0,
43 NS_SEARCH_NAME,
44 NS_SEARCH_METADATA,
45 NS_SEARCH_RATING,
46 NS_SEARCH_NUM,
47};
48
49/**
50 * For listing of search results for main search.
51 * Represents a search result.
52 */
53enum
54{
55 SEARCH_NAME = 0,
56 SEARCH_SIZE,
57 SEARCH_HSIZE,
58 SEARCH_MIME,
59 SEARCH_RAW_MIME,
60 SEARCH_DESC,
61 SEARCH_PIXBUF,
62 SEARCH_URI,
63 SEARCH_META,
64 SEARCH_INTERNAL,
65 SEARCH_INTERNAL_PARENT,
66 SEARCH_STATUS,
67 SEARCH_STATUS_LOGO,
68 SEARCH_AVAILABILITY_RANK,
69 SEARCH_AVAILABILITY_CERTAINTY,
70 SEARCH_APPLICABILITY_RANK,
71 SEARCH_RANK_PIXBUF,
72 SEARCH_RANK_SORT,
73#ifdef HAVE_GIO
74 SEARCH_ICON,
75#endif
76 SEARCH_NUM,
77};
78
79/**
80 * Entry in download summary.
81 */
82enum
83{
84 DOWNLOAD_FILENAME = 0,
85 DOWNLOAD_SHORTNAME,
86 DOWNLOAD_SIZE,
87 DOWNLOAD_HSIZE,
88 DOWNLOAD_PROGRESS,
89 DOWNLOAD_URISTRING,
90 DOWNLOAD_INTERNAL, /* struct DL */
91 DOWNLOAD_META_DATA,
92 DOWNLOAD_NUM
93};
94
95enum
96{
97 NAMESPACE_FILENAME = 0,
98 NAMESPACE_SIZE,
99 NAMESPACE_HSIZE,
100 NAMESPACE_URISTRING,
101 NAMESPACE_URI,
102 NAMESPACE_META,
103 NAMESPACE_NUM
104};
105
106enum
107{
108 IN_NAMESPACE_FILENAME = 0,
109 IN_NAMESPACE_SIZE,
110 IN_NAMESPACE_HSIZE,
111 IN_NAMESPACE_DESCRIPTION,
112 IN_NAMESPACE_MIMETYPE,
113 IN_NAMESPACE_LAST_STRING,
114 IN_NAMESPACE_NEXT_STRING,
115 IN_NAMESPACE_URI,
116 IN_NAMESPACE_META,
117 IN_NAMESPACE_NUM
118};
119
120/**
121 * Entry in upload summary.
122 */
123enum
124{
125 UPLOAD_FILENAME = 0,
126 UPLOAD_PROGRESS,
127 UPLOAD_URISTRING,
128 UPLOAD_INTERNAL,
129 UPLOAD_NUM
130};
131
132enum
133{
134 META_TYPE = 0,
135 META_STYPE,
136 META_VALUE,
137 META_NUM,
138};
139
140enum
141{
142 KTYPE_STRING = 0,
143 KTYPE_TYPE,
144 KTYPE_NUM,
145};
146
147
148/**
149 * @brief linked list of pages in the search notebook
150 */
151typedef struct SL
152{
153 struct SL *next;
154 /**
155 * Reference to the glade XML context that was
156 * used to create the search page.
157 */
158 GladeXML *searchXML;
159
160 /**
161 * Reference to the glade XML context that was
162 * used to create the search label.
163 */
164 GladeXML *labelXML;
165
166 /**
167 * Tree view widget that is used to display the
168 * search results.
169 */
170 GtkTreeView *treeview;
171
172 /**
173 * Model of the tree view.
174 */
175 GtkTreeStore *tree;
176
177 /**
178 * The label used in the notebook page.
179 */
180 GtkWidget *tab_label;
181
182 /**
183 * The notebook page that is associated with this
184 * search.
185 */
186 GtkWidget *searchpage;
187
188 /**
189 * URI for this search.
190 */
191 struct GNUNET_ECRS_URI *uri;
192
193 /**
194 * String describing the search.
195 */
196 char *searchString;
197
198 /**
199 * FSUI search handle.
200 */
201 struct GNUNET_FSUI_SearchList *fsui_list;
202
203 /**
204 * Maximum runtime for the search.
205 */
206 GNUNET_CronTime max_delay;
207
208 /**
209 * Number of results received so far.
210 */
211 unsigned int resultsReceived;
212
213 /**
214 * X-coordinate of the last right-click in the search list.
215 */
216 unsigned int last_x;
217
218 /**
219 * Y-coordinate of the last right-click in the search list.
220 */
221 unsigned int last_y;
222
223 /**
224 * Desired anonymity level.
225 */
226 unsigned int anonymityLevel;
227
228} SearchList;
229
230
231typedef struct DL
232{
233 struct DL *next;
234
235 /**
236 * URI of the download.
237 */
238 struct GNUNET_ECRS_URI *uri;
239
240 /**
241 * Where is the download being saved to?
242 */
243 char *filename;
244
245 /**
246 * Path in the summary view for this download.
247 */
248 GtkTreeRowReference *summaryViewRowReference;
249
250 /**
251 * Search that this download belongs to.
252 * Maybe NULL.
253 */
254 struct SL *searchList;
255
256 /**
257 * Path in the search view that this
258 * download is represented by. Maybe NULL
259 * if search has been closed or if download
260 * was initiated from URI without search.
261 */
262 GtkTreeRowReference *searchViewRowReference;
263
264 /**
265 * FSUI reference for the download.
266 */
267 struct GNUNET_FSUI_DownloadList *fsui_list;
268
269 /**
270 * Total size of the download.
271 */
272 unsigned long long total;
273
274 /**
275 * Is this a GNUnet directory? (by mime-type)
276 */
277 int is_directory;
278
279 int has_terminated;
280
281} DownloadList;
282
283typedef struct UL
284{
285 struct UL *next;
286
287 /**
288 * Which file or directory are we uploading?
289 */
290 char *filename;
291
292 /**
293 * Path in the summary view for this download.
294 */
295 GtkTreeRowReference *summaryViewRowReference;
296
297 struct GNUNET_FSUI_UploadList *fsui_list;
298
299 /**
300 * Set to final URI upon successful completion.
301 */
302 struct GNUNET_ECRS_URI *uri;
303
304 /**
305 * Total size of the upload.
306 */
307 unsigned long long total;
308
309 int has_terminated;
310
311 int is_top;
312
313} UploadList;
314
315extern struct GNUNET_FSUI_Context *ctx;
316
317extern struct GNUNET_GE_Context *ectx;
318
319extern struct GNUNET_GC_Configuration *cfg;
320
321extern SearchList *search_head;
322
323extern DownloadList *download_head;
324
325extern UploadList *upload_head;
326
327extern GtkListStore *search_summary;
328
329extern GtkTreeStore *download_summary;
330
331extern GtkTreeStore *upload_summary;
332
333#endif
diff --git a/src/plugins/fs/helper.c b/src/plugins/fs/helper.c
deleted file mode 100644
index a5a642dc..00000000
--- a/src/plugins/fs/helper.c
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/helper.c
23 * @brief helper functions (parsing)
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "helper.h"
30#include "fs.h"
31#include "search.h"
32#include <ctype.h>
33
34/**
35 * Parse a time given in the form
36 * "XX seconds yy days zz months".
37 *
38 * @param val set to the computed time
39 * @return GNUNET_OK on success, GNUNET_SYSERR on error
40 */
41int
42parseTime (const char *t, GNUNET_Int32Time * param)
43{
44 int pos;
45 int start;
46 unsigned int val;
47 char *tmp;
48 GNUNET_CronTime ret;
49
50 ret = 0;
51 pos = 0;
52
53 while (t[pos] != '\0')
54 {
55 start = pos;
56 while ((isdigit (t[pos])) && (t[pos] != '\0'))
57 pos++;
58 tmp = GNUNET_strdup (&t[start]);
59 tmp[pos - start] = '\0';
60 if (1 != sscanf (tmp, "%u", &val))
61 return -1; /* parse error */
62 GNUNET_free (tmp);
63 while (t[pos] == ' ')
64 pos++;
65 start = pos;
66 while ((t[pos] != ' ') && (t[pos] != '\0'))
67 pos++;
68 if (0 == strncasecmp (&t[start], _("ms"), strlen (_("ms"))))
69 ret += GNUNET_CRON_MILLISECONDS * val;
70 if (0 == strncasecmp (&t[start], _("minutes"), strlen (_("minutes"))))
71 ret += GNUNET_CRON_MINUTES * val;
72 else if (0 == strncasecmp (&t[start],
73 _("seconds"), strlen (_("seconds"))))
74 ret += GNUNET_CRON_SECONDS * val;
75 else if (0 == strncasecmp (&t[start], _("hours"), strlen (_("hours"))))
76 ret += GNUNET_CRON_HOURS * val;
77 else if (0 == strncasecmp (&t[start], _("days"), strlen (_("days"))))
78 ret += GNUNET_CRON_DAYS * val;
79 else
80 if (0 == strncasecmp (&t[start], _("minute"), strlen (_("minute"))))
81 ret += GNUNET_CRON_MINUTES * val;
82 else if (0 == strncasecmp (&t[start],
83 _("second"), strlen (_("second"))))
84 ret += GNUNET_CRON_SECONDS * val;
85 else if (0 == strncasecmp (&t[start], _("hour"), strlen (_("hour"))))
86 ret += GNUNET_CRON_HOURS * val;
87 else if (0 == strncasecmp (&t[start], _("day"), strlen (_("day"))))
88 ret += GNUNET_CRON_DAYS * val;
89 else if (0 == strncasecmp (&t[start], "m", strlen ("m")))
90 ret += GNUNET_CRON_MINUTES * val;
91 else if (0 == strncasecmp (&t[start], "s", strlen ("s")))
92 ret += GNUNET_CRON_SECONDS * val;
93 else if (0 == strncasecmp (&t[start], "h", strlen ("h")))
94 ret += GNUNET_CRON_HOURS * val;
95 else
96 return GNUNET_SYSERR; /* parse error */
97 while (t[pos] == ' ')
98 pos++;
99 }
100 *param = ret / GNUNET_CRON_SECONDS;
101 return GNUNET_OK;
102}
diff --git a/src/plugins/fs/helper.h b/src/plugins/fs/helper.h
deleted file mode 100644
index da89a385..00000000
--- a/src/plugins/fs/helper.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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#ifndef FS_HELPER_H
22#define FS_HELPER_H
23
24/**
25 * @file src/plugins/fs/helper.h
26 * @brief helper functions (parsing)
27 * @author Christian Grothoff
28 */
29
30/* Create the tab label and icon,
31 * adding a little button to close the search
32 * This function is a modified version of an Epiphany/Gedit code,
33 * part of this work is copyrighted (GPL license) by its authors.
34 *
35 * @param the title of the new label
36 * @returns the created widget to pack into the page header
37 */
38GtkWidget *buildSearchTabLabel (GtkWidget * searchPage, const char *title);
39
40
41GtkWidget *makeSearchResultFrame (struct GNUNET_GC_Configuration *cfg,
42 GtkWidget ** treeview,
43 GtkWidget ** anonSpin);
44
45/**
46 * Parse a time given in the form
47 * "XX seconds yy days zz months".
48 *
49 * @param val set to the computed time
50 * @return GNUNET_OK on success, GNUNET_SYSERR on error
51 */
52int parseTime (const char *t, GNUNET_Int32Time * val);
53
54#endif
diff --git a/src/plugins/fs/meta.c b/src/plugins/fs/meta.c
deleted file mode 100644
index 3f95d446..00000000
--- a/src/plugins/fs/meta.c
+++ /dev/null
@@ -1,550 +0,0 @@
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/meta.c
23 * @brief code for dealing with meta and keyword tree views
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "helper.h"
30#include "meta.h"
31#include "fs.h"
32#include <extractor.h>
33
34static int
35publishMetaData (EXTRACTOR_KeywordType type, const char *data, void *cls)
36{
37 GtkListStore *store = cls;
38 const char *stype;
39 GtkTreeIter iter;
40
41 if (EXTRACTOR_isBinaryType (type))
42 return GNUNET_OK;
43 stype = EXTRACTOR_getKeywordTypeAsString (type);
44 if (stype == NULL) /* wrong LE version!? */
45 stype = _("unknown");
46 gtk_list_store_append (store, &iter);
47 gtk_list_store_set (store,
48 &iter,
49 META_TYPE, type,
50 META_STYPE, stype, META_VALUE, data, -1);
51 return GNUNET_OK;
52}
53
54void
55createMetaDataListTreeView (GladeXML * xml,
56 const char *name,
57 const char *previewName,
58 const struct GNUNET_MetaData *init)
59{
60 GtkTreeView *metaList;
61 GtkListStore *metamodel;
62 GtkCellRenderer *renderer;
63 GtkWidget *preview;
64 GdkPixbuf *pixbuf;
65 GdkPixbufLoader *loader;
66 unsigned char *thumb;
67 size_t ts;
68 GtkTreeViewColumn *column;
69 int col;
70
71 GNUNET_GTK_DEBUG_BEGIN ();
72 metamodel
73 = gtk_list_store_new (META_NUM, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
74 metaList = GTK_TREE_VIEW (glade_xml_get_widget (xml, name));
75 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (metaList),
76 GTK_SELECTION_MULTIPLE);
77 renderer = gtk_cell_renderer_text_new ();
78 col = gtk_tree_view_insert_column_with_attributes (metaList,
79 -1,
80 _("Category"),
81 renderer,
82 "text", META_STYPE,
83 NULL);
84 column = gtk_tree_view_get_column (metaList, col - 1);
85 gtk_tree_view_column_set_resizable (column, TRUE);
86 gtk_tree_view_column_set_clickable (column, TRUE);
87 gtk_tree_view_column_set_reorderable (column, TRUE);
88 gtk_tree_view_column_set_sort_column_id (column, META_STYPE);
89 renderer = gtk_cell_renderer_text_new ();
90 col = gtk_tree_view_insert_column_with_attributes (metaList,
91 -1,
92 _("Value"),
93 renderer,
94 "text", META_VALUE,
95 NULL);
96 column = gtk_tree_view_get_column (metaList, col - 1);
97 gtk_tree_view_column_set_resizable (column, TRUE);
98 gtk_tree_view_column_set_clickable (column, TRUE);
99 gtk_tree_view_column_set_reorderable (column, TRUE);
100 gtk_tree_view_column_set_sort_column_id (column, META_VALUE);
101 gtk_tree_view_set_model (metaList, GTK_TREE_MODEL (metamodel));
102
103 if (init != NULL)
104 GNUNET_meta_data_get_contents (init, &publishMetaData, metamodel);
105 if ((previewName == NULL) || (init == NULL))
106 return;
107 thumb = NULL;
108 ts = GNUNET_meta_data_get_thumbnail (init, &thumb);
109 preview = glade_xml_get_widget (xml, previewName);
110 if (ts != 0)
111 {
112 loader = gdk_pixbuf_loader_new ();
113 gdk_pixbuf_loader_write (loader, (const guchar *) thumb, ts, NULL);
114 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
115 g_object_ref (pixbuf);
116 gdk_pixbuf_loader_close (loader, NULL);
117 if (pixbuf != NULL)
118 {
119 gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
120 g_object_unref (pixbuf);
121 }
122 UNREF (loader);
123 }
124 GNUNET_GTK_DEBUG_END ();
125}
126
127static int
128publishKeyword (const char *data, int is_mandatory, void *cls)
129{
130 GtkListStore *store = cls;
131 GtkTreeIter iter;
132
133 GNUNET_GTK_DEBUG_BEGIN ();
134 gtk_list_store_append (store, &iter);
135 gtk_list_store_set (store, &iter, 0, data, -1);
136 GNUNET_GTK_DEBUG_END ();
137 return GNUNET_OK;
138}
139
140void
141createKeywordListTreeView (GladeXML * xml,
142 const char *name,
143 const struct GNUNET_ECRS_URI *init)
144{
145 GtkTreeView *keywordList;
146 GtkListStore *keymodel;
147 GtkCellRenderer *renderer;
148 GtkTreeViewColumn *column;
149
150 GNUNET_GTK_DEBUG_BEGIN ();
151 keymodel = gtk_list_store_new (1, G_TYPE_STRING);
152 keywordList = GTK_TREE_VIEW (glade_xml_get_widget (xml, name));
153 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (keywordList),
154 GTK_SELECTION_MULTIPLE);
155 renderer = gtk_cell_renderer_text_new ();
156 gtk_tree_view_insert_column_with_attributes (keywordList,
157 -1,
158 _("Keyword"),
159 renderer, "text", 0, NULL);
160 column = gtk_tree_view_get_column (keywordList, 0);
161 gtk_tree_view_column_set_resizable (column, TRUE);
162 gtk_tree_view_column_set_clickable (column, TRUE);
163 gtk_tree_view_column_set_reorderable (column, TRUE);
164 gtk_tree_view_column_set_sort_column_id (column, 0);
165 gtk_tree_view_set_model (keywordList, GTK_TREE_MODEL (keymodel));
166 if (init != NULL)
167 GNUNET_ECRS_uri_get_keywords_from_ksk (init, &publishKeyword, keymodel);
168 GNUNET_GTK_DEBUG_END ();
169}
170
171void
172createMetaTypeComboBox (GladeXML * xml, const char *name)
173{
174 const char *stype;
175 GtkWidget *metaType;
176 GtkCellRenderer *renderer;
177 GtkListStore *keywordTypeModel;
178 GtkTreeIter iter;
179 EXTRACTOR_KeywordType type;
180
181 GNUNET_GTK_DEBUG_BEGIN ();
182 keywordTypeModel
183 = gtk_list_store_new (KTYPE_NUM, G_TYPE_STRING, G_TYPE_INT);
184 metaType = glade_xml_get_widget (xml, name);
185 gtk_combo_box_set_model (GTK_COMBO_BOX (metaType),
186 GTK_TREE_MODEL (keywordTypeModel));
187 for (type = 0; type < EXTRACTOR_getHighestKeywordTypeNumber (); type++)
188 {
189 if ((type == EXTRACTOR_SPLIT) ||
190 (type == EXTRACTOR_LOWERCASE) || (EXTRACTOR_isBinaryType (type)))
191 continue; /* these are not legal... */
192 stype = EXTRACTOR_getKeywordTypeAsString (type);
193 gtk_list_store_append (keywordTypeModel, &iter);
194 gtk_list_store_set (keywordTypeModel,
195 &iter, KTYPE_STRING, stype, KTYPE_TYPE, type, -1);
196 }
197 renderer = gtk_cell_renderer_text_new ();
198 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (metaType), renderer, FALSE);
199 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (metaType),
200 renderer, "text", KTYPE_STRING);
201 gtk_combo_box_set_active (GTK_COMBO_BOX (metaType), 0);
202 GNUNET_GTK_DEBUG_END ();
203}
204
205void
206handleKeywordListUpdate (GladeXML * xml,
207 const char *inputLineName,
208 const char *keywordListName)
209{
210 const char *keyword;
211 GtkWidget *keywordList;
212 GtkWidget *entryLine;
213 GtkListStore *keymodel;
214 GtkTreeIter iter;
215
216 GNUNET_GTK_DEBUG_BEGIN ();
217 keywordList = glade_xml_get_widget (xml, keywordListName);
218 keymodel
219 = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (keywordList)));
220
221 entryLine = glade_xml_get_widget (xml, inputLineName);
222 keyword = gtk_entry_get_text (GTK_ENTRY (entryLine));
223 gtk_list_store_append (keymodel, &iter);
224 gtk_list_store_set (keymodel, &iter, 0, keyword, -1);
225 gtk_entry_set_text (GTK_ENTRY (entryLine), "");
226 GNUNET_GTK_DEBUG_END ();
227}
228
229void
230handleMetaDataListUpdate (GladeXML * xml,
231 const char *typeInputLineName,
232 const char *valueInputLineName,
233 const char *metaDataListName)
234{
235 const char *value;
236 GtkWidget *metaList;
237 GtkWidget *entryLine;
238 GtkWidget *typeCB;
239 EXTRACTOR_KeywordType type;
240 GtkListStore *metamodel;
241 GtkListStore *typemodel;
242 GtkTreeIter iter;
243 char *stype;
244
245 GNUNET_GTK_DEBUG_BEGIN ();
246 metaList = glade_xml_get_widget (xml, metaDataListName);
247 metamodel
248 = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (metaList)));
249
250 entryLine = glade_xml_get_widget (xml, valueInputLineName);
251 value = gtk_entry_get_text (GTK_ENTRY (entryLine));
252 if ((value == NULL) || (strlen (value) == 0))
253 return;
254 typeCB = glade_xml_get_widget (xml, typeInputLineName);
255 typemodel
256 = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (typeCB)));
257 if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (typeCB), &iter))
258 return; /* oops */
259 gtk_tree_model_get (GTK_TREE_MODEL (typemodel),
260 &iter, KTYPE_STRING, &stype, KTYPE_TYPE, &type, -1);
261 gtk_list_store_append (metamodel, &iter);
262 gtk_list_store_set (metamodel,
263 &iter,
264 META_TYPE, type,
265 META_STYPE, stype, META_VALUE, value, -1);
266 gtk_entry_set_text (GTK_ENTRY (entryLine), "");
267 GNUNET_free_non_null (stype);
268 GNUNET_GTK_DEBUG_END ();
269}
270
271static void
272removeRow (GtkTreeModel * model,
273 GtkTreePath * path, GtkTreeIter * iter, gpointer unused)
274{
275 gtk_list_store_remove (GTK_LIST_STORE (model), iter);
276}
277
278void
279handleListRemove (GladeXML * xml, const char *listName)
280{
281 GtkWidget *list;
282
283 list = glade_xml_get_widget (xml, listName);
284 GNUNET_GTK_tree_selection_selected_foreach
285 (gtk_tree_view_get_selection (GTK_TREE_VIEW (list)), &removeRow, NULL);
286}
287
288#define THUMBSIZE 128
289
290
291struct GNUNET_MetaData *
292getMetaDataFromList (GladeXML * xml,
293 const char *name, const char *previewName)
294{
295 GtkWidget *metaList;
296 GtkWidget *preview;
297 GtkTreeModel *metamodel;
298 GtkTreeIter iter;
299 struct GNUNET_MetaData *meta;
300 EXTRACTOR_KeywordType type;
301 GdkPixbuf *pixbuf;
302 GdkPixbuf *out;
303 char *mvalue;
304 size_t length;
305 unsigned long width;
306 unsigned long height;
307 char *thumb;
308
309 metaList = glade_xml_get_widget (xml, name);
310 metamodel = gtk_tree_view_get_model (GTK_TREE_VIEW (metaList));
311 meta = GNUNET_meta_data_create ();
312 if (gtk_tree_model_get_iter_first (metamodel, &iter))
313 {
314 do
315 {
316 gtk_tree_model_get (metamodel,
317 &iter,
318 META_TYPE, &type, META_VALUE, &mvalue, -1);
319 GNUNET_meta_data_insert (meta, type, mvalue);
320 GNUNET_free_non_null (mvalue);
321 }
322 while (gtk_tree_model_iter_next (metamodel, &iter));
323 }
324 if (previewName == NULL)
325 return meta;
326
327 preview = glade_xml_get_widget (xml, previewName);
328
329 if (GTK_IMAGE_PIXBUF == gtk_image_get_storage_type (GTK_IMAGE (preview)))
330 {
331 pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (preview));
332 if (pixbuf == NULL)
333 return meta;
334 height = gdk_pixbuf_get_height (pixbuf);
335 width = gdk_pixbuf_get_width (pixbuf);
336 if ((height > THUMBSIZE) || (width > THUMBSIZE))
337 {
338 if (height > THUMBSIZE)
339 {
340 width = width * THUMBSIZE / height;
341 height = THUMBSIZE;
342 }
343 if (width > THUMBSIZE)
344 {
345 height = height * THUMBSIZE / width;
346 width = THUMBSIZE;
347 }
348 out = gdk_pixbuf_scale_simple (pixbuf,
349 width, height, GDK_INTERP_BILINEAR);
350 g_object_unref (pixbuf);
351 pixbuf = out;
352 }
353 if (pixbuf != NULL)
354 {
355 thumb = NULL;
356 if (gdk_pixbuf_save_to_buffer (pixbuf,
357 &thumb, &length, "png", NULL, NULL))
358 {
359 char *binary;
360
361 binary = EXTRACTOR_binaryEncode ((const unsigned char *) thumb,
362 length);
363 free (thumb);
364 GNUNET_meta_data_insert (meta, EXTRACTOR_THUMBNAIL_DATA,
365 binary);
366 GNUNET_free (binary);
367 }
368 }
369 }
370 return meta;
371}
372
373struct GNUNET_ECRS_URI *
374getKeywordURIFromList (GladeXML * xml, const char *name)
375{
376 GtkTreeModel *keymodel;
377 GtkTreeView *keyList;
378 GtkTreeIter iter;
379 struct GNUNET_ECRS_URI *keywordURI;
380 char *mvalue;
381 char **keywords;
382 unsigned int kpos;
383 unsigned int ksize;
384
385 GNUNET_GTK_DEBUG_BEGIN ();
386 keyList = GTK_TREE_VIEW (glade_xml_get_widget (xml, name));
387 keymodel = gtk_tree_view_get_model (keyList);
388
389 keywords = NULL;
390 ksize = 0;
391 GNUNET_array_grow (keywords, ksize, 64);
392 kpos = 0;
393 if (gtk_tree_model_get_iter_first (keymodel, &iter))
394 {
395 do
396 {
397 gtk_tree_model_get (keymodel, &iter, 0, &mvalue, -1);
398 keywords[kpos++] = mvalue;
399 if (kpos == ksize)
400 GNUNET_array_grow (keywords, ksize, kpos * 2);
401 }
402 while (gtk_tree_model_iter_next (keymodel, &iter));
403 }
404 keywordURI =
405 GNUNET_ECRS_keyword_command_line_to_uri (NULL, kpos,
406 (const char **) keywords);
407 while (kpos > 0)
408 GNUNET_free (keywords[--kpos]);
409 GNUNET_array_grow (keywords, ksize, 0);
410 GNUNET_GTK_DEBUG_END ();
411 return keywordURI;
412}
413
414unsigned int
415getSpinButtonValue (GladeXML * xml, const char *spinButtonName)
416{
417 GtkWidget *spin;
418
419 spin = glade_xml_get_widget (xml, spinButtonName);
420 return gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
421}
422
423
424
425char *
426getMimeTypeFromMetaData (const struct GNUNET_MetaData *meta)
427{
428 char *mime;
429
430 mime = GNUNET_meta_data_get_by_type (meta, EXTRACTOR_MIMETYPE);
431 if (mime == NULL)
432 mime = GNUNET_strdup (_("unknown"));
433 return GNUNET_GTK_validate_utf8 (mime);
434}
435
436char *
437getFileNameFromMetaData (const struct GNUNET_MetaData *meta)
438{
439 char *name;
440
441 name = GNUNET_meta_data_get_first_by_types (meta,
442 EXTRACTOR_FILENAME,
443 EXTRACTOR_TITLE,
444 EXTRACTOR_ARTIST,
445 EXTRACTOR_AUTHOR,
446 EXTRACTOR_PUBLISHER,
447 EXTRACTOR_CREATOR,
448 EXTRACTOR_PRODUCER,
449 EXTRACTOR_UNKNOWN, -1);
450 if (name == NULL)
451 {
452 name = GNUNET_strdup (_("no name given"));
453 }
454 else
455 {
456 char *dotdot;
457
458 while (NULL != (dotdot = strstr (name, "..")))
459 dotdot[0] = dotdot[1] = '_';
460 }
461 return GNUNET_GTK_validate_utf8 (name);
462}
463
464char *
465getDescriptionFromMetaData (const struct GNUNET_MetaData *meta)
466{
467 char *desc;
468
469 desc = GNUNET_meta_data_get_first_by_types (meta,
470 EXTRACTOR_DESCRIPTION,
471 EXTRACTOR_GENRE,
472 EXTRACTOR_ALBUM,
473 EXTRACTOR_COMMENT,
474 EXTRACTOR_SUBJECT,
475 EXTRACTOR_FORMAT,
476 EXTRACTOR_SIZE,
477 EXTRACTOR_KEYWORDS, -1);
478 if (desc == NULL)
479 desc = GNUNET_strdup ("");
480 return GNUNET_GTK_validate_utf8 (desc);
481}
482
483GdkPixbuf *
484getThumbnailFromMetaData (const struct GNUNET_MetaData * meta)
485{
486 GdkPixbuf *pixbuf;
487 GdkPixbufLoader *loader;
488 size_t ts;
489 unsigned char *thumb;
490
491 thumb = NULL;
492 ts = GNUNET_meta_data_get_thumbnail (meta, &thumb);
493 if (ts != 0)
494 {
495 loader = gdk_pixbuf_loader_new ();
496 gdk_pixbuf_loader_write (loader, (const guchar *) thumb, ts, NULL);
497 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
498 gdk_pixbuf_loader_close (loader, NULL);
499 if (pixbuf != NULL)
500 g_object_ref (pixbuf);
501 UNREF (loader);
502 }
503 else
504 {
505 pixbuf = NULL;
506 }
507 GNUNET_free_non_null (thumb);
508 return pixbuf;
509}
510
511int
512getToggleButtonValue (GladeXML * xml, const char *widgetName)
513{
514 return
515 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
516 (glade_xml_get_widget (xml, widgetName)));
517}
518
519const char *
520getEntryLineValue (GladeXML * xml, const char *widgetName)
521{
522 GtkBin *line;
523 GtkEntry *entry;
524
525 line = GTK_BIN (glade_xml_get_widget (xml, widgetName));
526 entry = GTK_ENTRY (gtk_bin_get_child (line));
527 return gtk_entry_get_text (entry);
528}
529
530
531void
532open_meta_data_display_dialog(const struct GNUNET_MetaData * meta,
533 const char * title)
534{
535 GladeXML *xml;
536 GtkWidget *dialog;
537
538 xml = glade_xml_new (GNUNET_GTK_get_glade_filename (),
539 "metaDisplayDialog", PACKAGE_NAME);
540 GNUNET_GTK_connect_glade_with_plugins (xml);
541 dialog = glade_xml_get_widget (xml, "metaDisplayDialog");
542 gtk_window_set_title (GTK_WINDOW (dialog), title);
543 createMetaDataListTreeView (xml, "metaDisplayDialogTreeView", NULL, meta);
544 gtk_dialog_run (GTK_DIALOG (dialog));
545 gtk_widget_destroy (dialog);
546 UNREF (xml);
547}
548
549
550/* end of meta.c */
diff --git a/src/plugins/fs/meta.h b/src/plugins/fs/meta.h
deleted file mode 100644
index b6743041..00000000
--- a/src/plugins/fs/meta.h
+++ /dev/null
@@ -1,90 +0,0 @@
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/meta.h
23 * @brief code for dealing with meta and keyword tree views
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_META_H
28#define GTK_META_H
29
30#include "gnunetgtk_common.h"
31#include <GNUnet/gnunet_ecrs_lib.h>
32
33void createMetaDataListTreeView (GladeXML * xml,
34 const char *name,
35 const char *previewName,
36 const struct GNUNET_MetaData *init);
37
38void createKeywordListTreeView (GladeXML * xml,
39 const char *name,
40 const struct GNUNET_ECRS_URI *init);
41
42void createMetaTypeComboBox (GladeXML * xml, const char *name);
43
44void handleKeywordListUpdate (GladeXML * xml,
45 const char *inputLineName,
46 const char *keywordListName);
47
48void handleMetaDataListUpdate (GladeXML * xml,
49 const char *typeInputLineName,
50 const char *valueInputLineName,
51 const char *metaDataListName);
52
53void handleListRemove (GladeXML * xml, const char *listName);
54
55struct GNUNET_MetaData *getMetaDataFromList (GladeXML * xml,
56 const char *name,
57 const char *preview);
58
59struct GNUNET_ECRS_URI *getKeywordURIFromList (GladeXML * xml,
60 const char *name);
61
62char *updateIntervalToString (GNUNET_Int32Time interval);
63
64int tryParseTimeInterval (GladeXML * xml,
65 const char *intervalComboBoxEntry,
66 GNUNET_Int32Time * interval);
67
68int parseTimeInterval (const char *frequency, GNUNET_Int32Time * interval);
69
70char *getMimeTypeFromMetaData (const struct GNUNET_MetaData *meta);
71
72char *getFileNameFromMetaData (const struct GNUNET_MetaData *meta);
73
74char *getDescriptionFromMetaData (const struct GNUNET_MetaData *meta);
75
76unsigned int getSpinButtonValue (GladeXML * xml, const char *spinButtonName);
77
78int getToggleButtonValue (GladeXML * xml, const char *widgetName);
79
80const char *getEntryLineValue (GladeXML * xml, const char *widgetName);
81
82GdkPixbuf *getThumbnailFromMetaData (const struct GNUNET_MetaData *meta);
83
84
85void
86open_meta_data_display_dialog(const struct GNUNET_MetaData * meta,
87 const char * title);
88
89/* end of meta.h */
90#endif
diff --git a/src/plugins/fs/namespace.c b/src/plugins/fs/namespace.c
deleted file mode 100644
index 87a75b05..00000000
--- a/src/plugins/fs/namespace.c
+++ /dev/null
@@ -1,844 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/namespace.c
23 * @brief operations for deleting and adding to/updating namespaces
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h"
30#include "helper.h"
31#include "meta.h"
32#include "namespace.h"
33#include "namespace_search.h"
34#include "content_tracking.h"
35#include <GNUnet/gnunet_util_crypto.h>
36#include <GNUnet/gnunet_util_pseudonym.h>
37#include <GNUnet/gnunet_uritrack_lib.h>
38#include <GNUnet/gnunet_namespace_lib.h>
39#include <extractor.h>
40
41/**
42 * @brief linked list of pages in the namespace notebook
43 */
44typedef struct NL
45{
46 struct NL *next;
47 GtkWidget *treeview;
48 GtkWidget *namespacepage;
49 GtkWidget *addButton;
50 GtkWidget *updateButton;
51 GtkTreeModel *model;
52 char *name;
53 GNUNET_HashCode id;
54 struct GNUNET_MetaData *meta;
55} NamespaceList;
56
57/**
58 * Content selection in main list of available content.
59 */
60static GtkTreeSelection *content_selection;
61
62static NamespaceList *head;
63
64static GladeXML *metaXML;
65
66/**
67 * The user has changed the selection either in the
68 * namespace content list or the global content list.
69 * Update search button status values (add/change).
70 */
71static void
72on_namespaceContentSelectionChanged (gpointer signal, gpointer cls)
73{
74 NamespaceList *list = head;
75 int count;
76 int ncount;
77 GtkTreeSelection *ns;
78 GtkTreeIter iter;
79 char *next;
80 int ok;
81
82 count = gtk_tree_selection_count_selected_rows (content_selection);
83 while (list != NULL)
84 {
85 ns = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->treeview));
86 ncount = gtk_tree_selection_count_selected_rows (ns);
87 gtk_widget_set_sensitive (list->addButton, count > 0);
88 /* now check if update is legal */
89 ok = 0;
90 if ((count == 1) &&
91 (ncount == 1) &&
92 (TRUE == gtk_tree_selection_get_selected (ns, NULL, &iter)))
93 {
94 next = NULL;
95 gtk_tree_model_get (list->model,
96 &iter, IN_NAMESPACE_NEXT_STRING, &next, -1);
97 if ((next != NULL) && (0 != strlen (next)))
98 ok = 1;
99 GNUNET_free_non_null (next);
100 }
101 gtk_widget_set_sensitive (list->updateButton, ok);
102 list = list->next;
103 }
104}
105
106
107static void
108makeNamespaceFrame (NamespaceList * entry)
109{
110 GtkWidget *child;
111 GtkWidget *resultList;
112 GtkCellRenderer *renderer;
113 GtkListStore *model;
114 GladeXML *namespaceXML;
115 GtkTreeViewColumn *column;
116 int col;
117
118 GNUNET_GTK_DEBUG_BEGIN ();
119 namespaceXML
120 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
121 "namespaceContentFrame", PACKAGE_NAME);
122 GNUNET_GTK_connect_glade_with_plugins (namespaceXML);
123 child =
124 GNUNET_GTK_extract_main_widget_from_window (namespaceXML,
125 "namespaceContentFrame");
126 resultList =
127 glade_xml_get_widget (namespaceXML, "namespaceContentFrameTreeView");
128 entry->addButton = glade_xml_get_widget (namespaceXML, "addButton");
129 entry->updateButton = glade_xml_get_widget (namespaceXML,
130 "namespaceUpdateButton");
131 entry->treeview = GTK_WIDGET (GTK_TREE_VIEW (resultList));
132 model = gtk_list_store_new (IN_NAMESPACE_NUM, G_TYPE_STRING, /* (file)name */
133 G_TYPE_UINT64, /* size */
134 G_TYPE_STRING, /* human-readable size */
135 G_TYPE_STRING, /* description */
136 G_TYPE_STRING, /* mime-type */
137 G_TYPE_STRING, /* last-ID */
138 G_TYPE_STRING, /* next-ID */
139 G_TYPE_POINTER, /* URI */
140 G_TYPE_POINTER); /* META */
141 entry->model = GTK_TREE_MODEL (model);
142 gtk_tree_view_set_model (GTK_TREE_VIEW (resultList),
143 GTK_TREE_MODEL (model));
144 gtk_tree_selection_set_mode (gtk_tree_view_get_selection
145 (GTK_TREE_VIEW (resultList)),
146 GTK_SELECTION_SINGLE);
147 g_signal_connect_data (gtk_tree_view_get_selection
148 (GTK_TREE_VIEW (resultList)), "changed",
149 G_CALLBACK (&on_namespaceContentSelectionChanged),
150 NULL, NULL, 0);
151
152
153
154 renderer = gtk_cell_renderer_text_new ();
155 col =
156 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
157 -1, _("Filename"), renderer,
158 "text",
159 IN_NAMESPACE_FILENAME, NULL);
160 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
161 gtk_tree_view_column_set_resizable (column, TRUE);
162 gtk_tree_view_column_set_clickable (column, TRUE);
163 gtk_tree_view_column_set_reorderable (column, TRUE);
164 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_FILENAME);
165 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
166
167 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
168 (GTK_TREE_VIEW (resultList), col - 1),
169 TRUE);
170 renderer = gtk_cell_renderer_text_new ();
171 g_object_set (renderer, "xalign", 1.00, NULL);
172 col =
173 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
174 -1, _("Filesize"), renderer,
175 "text", IN_NAMESPACE_HSIZE,
176 NULL);
177 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
178 gtk_tree_view_column_set_resizable (column, TRUE);
179 gtk_tree_view_column_set_clickable (column, TRUE);
180 gtk_tree_view_column_set_reorderable (column, TRUE);
181 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_SIZE);
182 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
183 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
184 (GTK_TREE_VIEW (resultList), col - 1),
185 TRUE);
186 renderer = gtk_cell_renderer_text_new ();
187 col =
188 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
189 -1, _("Description"),
190 renderer, "text",
191 IN_NAMESPACE_DESCRIPTION,
192 NULL);
193 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
194 gtk_tree_view_column_set_resizable (column, TRUE);
195 gtk_tree_view_column_set_clickable (column, TRUE);
196 gtk_tree_view_column_set_reorderable (column, TRUE);
197 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_DESCRIPTION);
198 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
199 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
200 (GTK_TREE_VIEW (resultList), col - 1),
201 TRUE);
202 renderer = gtk_cell_renderer_text_new ();
203 col =
204 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
205 -1, _("Mime-type"), renderer,
206 "text",
207 IN_NAMESPACE_MIMETYPE, NULL);
208 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
209 gtk_tree_view_column_set_resizable (column, TRUE);
210 gtk_tree_view_column_set_clickable (column, TRUE);
211 gtk_tree_view_column_set_reorderable (column, TRUE);
212 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_MIMETYPE);
213 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
214 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
215 (GTK_TREE_VIEW (resultList), col - 1),
216 TRUE);
217 renderer = gtk_cell_renderer_text_new ();
218 col =
219 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
220 -1, _("Identifier"),
221 renderer, "text",
222 IN_NAMESPACE_LAST_STRING,
223 NULL);
224 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
225 gtk_tree_view_column_set_reorderable (column, TRUE);
226 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_LAST_STRING);
227 gtk_tree_view_column_set_clickable (column, TRUE);
228 gtk_tree_view_column_set_resizable (column, TRUE);
229 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
230 (GTK_TREE_VIEW (resultList), col - 1),
231 TRUE);
232
233 renderer = gtk_cell_renderer_text_new ();
234 col =
235 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (resultList),
236 -1, _("Next Identifier"),
237 renderer, "text",
238 IN_NAMESPACE_NEXT_STRING,
239 NULL);
240 column = gtk_tree_view_get_column (GTK_TREE_VIEW (resultList), col - 1);
241 gtk_tree_view_column_set_clickable (column, TRUE);
242 gtk_tree_view_column_set_reorderable (column, TRUE);
243 gtk_tree_view_column_set_sort_column_id (column, IN_NAMESPACE_NEXT_STRING);
244 gtk_tree_view_column_set_resizable (column, TRUE);
245 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
246 (GTK_TREE_VIEW (resultList), col - 1),
247 TRUE);
248
249
250 UNREF (namespaceXML);
251 GNUNET_GTK_DEBUG_END ();
252
253 entry->namespacepage = child;
254}
255
256
257
258/**
259 * Update the model that lists the content of a namespace:
260 * add this content.
261 *
262 * @param uri URI of the last content published
263 * @param lastId the ID of the last publication
264 * @param nextId the ID of the next update
265 * @param publicationFrequency how often are updates scheduled?
266 * @param nextPublicationTime the scheduled time for the
267 * next update (0 for sporadic updates)
268 * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
269 */
270static int
271addNamespaceContentToModel (void *cls,
272 const GNUNET_ECRS_FileInfo * fi,
273 const char *lastId, const char *nextId)
274{
275 GtkListStore *model = GTK_LIST_STORE (cls);
276 GtkTreeIter iter;
277 char *filename;
278 char *desc;
279 char *mime;
280 char *uriString;
281 unsigned long long size;
282 char *size_h;
283
284 GNUNET_GTK_DEBUG_BEGIN ();
285 filename = GNUNET_meta_data_get_first_by_types (fi->meta,
286 EXTRACTOR_FILENAME,
287 EXTRACTOR_TITLE,
288 EXTRACTOR_ARTIST,
289 EXTRACTOR_AUTHOR,
290 EXTRACTOR_PUBLISHER,
291 EXTRACTOR_CREATOR,
292 EXTRACTOR_PRODUCER,
293 EXTRACTOR_UNKNOWN, -1);
294 if (filename == NULL)
295 filename = GNUNET_strdup (_("no name given"));
296 else
297 {
298 char *dotdot;
299
300 while (NULL != (dotdot = strstr (filename, "..")))
301 dotdot[0] = dotdot[1] = '_';
302 }
303 desc = GNUNET_meta_data_get_first_by_types (fi->meta,
304 EXTRACTOR_DESCRIPTION,
305 EXTRACTOR_GENRE,
306 EXTRACTOR_ALBUM,
307 EXTRACTOR_COMMENT,
308 EXTRACTOR_SUBJECT,
309 EXTRACTOR_FORMAT,
310 EXTRACTOR_SIZE,
311 EXTRACTOR_KEYWORDS, -1);
312 if (desc == NULL)
313 desc = GNUNET_strdup ("");
314 mime = GNUNET_meta_data_get_by_type (fi->meta, EXTRACTOR_MIMETYPE);
315 if (mime == NULL)
316 mime = GNUNET_strdup (_("unknown"));
317 if (GNUNET_ECRS_uri_test_chk (fi->uri))
318 size = GNUNET_ECRS_uri_get_file_size (fi->uri);
319 else
320 size = 0;
321 uriString = GNUNET_ECRS_uri_to_string (fi->uri);
322 if (nextId == NULL)
323 nextId = "";
324 size_h = GNUNET_get_byte_size_as_fancy_string (size);
325 gtk_list_store_append (model, &iter);
326 gtk_list_store_set (model,
327 &iter,
328 IN_NAMESPACE_FILENAME, filename,
329 IN_NAMESPACE_SIZE, size,
330 IN_NAMESPACE_HSIZE, size_h,
331 IN_NAMESPACE_DESCRIPTION, desc,
332 IN_NAMESPACE_MIMETYPE, mime,
333 IN_NAMESPACE_LAST_STRING, lastId,
334 IN_NAMESPACE_NEXT_STRING, nextId,
335 IN_NAMESPACE_URI, GNUNET_ECRS_uri_duplicate (fi->uri),
336 IN_NAMESPACE_META,
337 GNUNET_meta_data_duplicate (fi->meta), -1);
338 GNUNET_free (size_h);
339 GNUNET_free (filename);
340 GNUNET_free (uriString);
341 GNUNET_free (mime);
342 GNUNET_free (desc);
343 GNUNET_GTK_DEBUG_END ();
344 return GNUNET_OK;
345}
346
347/**
348 * Add a tab for the given namespace.
349 */
350int
351addTabForNamespace (void *unused,
352 const GNUNET_HashCode * namespaceId,
353 const struct GNUNET_MetaData *md, int rating)
354{
355 NamespaceList *list;
356 GtkWidget *label;
357 GtkWidget *notebook;
358 GtkWidget *del_menu;
359 char *namespaceName;
360
361 if (GNUNET_OK != GNUNET_ECRS_namespace_test_exists (NULL, cfg, namespaceId))
362 return GNUNET_OK;
363 GNUNET_GTK_DEBUG_BEGIN ();
364 namespaceName = GNUNET_pseudonym_id_to_name (ectx, cfg, namespaceId);
365 label = gtk_label_new (namespaceName);
366 list = GNUNET_malloc (sizeof (NamespaceList));
367 list->name = GNUNET_strdup (namespaceName);
368 list->id = *namespaceId;
369 list->meta = GNUNET_meta_data_duplicate (md);
370 makeNamespaceFrame (list);
371 list->next = head;
372 head = list;
373 /* update sensitivity of add button */
374 on_namespaceContentSelectionChanged (NULL, NULL);
375 notebook =
376 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
377 "localNamespacesNotebook");
378 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), list->namespacepage,
379 label);
380 gtk_widget_show (notebook);
381 GNUNET_NS_namespace_list_contents
382 (ectx, cfg, namespaceId, &addNamespaceContentToModel, list->model);
383 GNUNET_GTK_DEBUG_END ();
384 /* enable "delete" menu entry */
385
386 del_menu =
387 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
388 "namespaceDelete");
389 gtk_widget_set_sensitive (del_menu, TRUE);
390 GNUNET_free (namespaceName);
391 return GNUNET_OK;
392}
393
394
395static void
396frame_destroy (GtkWidget * tree)
397{
398 GtkTreeIter iter;
399 struct GNUNET_ECRS_URI *u;
400 struct GNUNET_MetaData *m;
401 NamespaceList *prev;
402 NamespaceList *pos;
403 NamespaceList *next;
404 GtkWidget *del_menu;
405
406 pos = head;
407 prev = NULL;
408 while (pos != NULL)
409 {
410 next = pos->next;
411 if (pos->treeview == tree)
412 break;
413 prev = pos;
414 pos = next;
415 }
416 if (pos == NULL)
417 {
418 GNUNET_GE_BREAK (NULL, 0);
419 return;
420 }
421 if (prev == NULL)
422 head = pos->next;
423 else
424 prev->next = pos->next;
425 GNUNET_free (pos->name);
426 GNUNET_meta_data_destroy (pos->meta);
427 if (gtk_tree_model_get_iter_first (pos->model, &iter))
428 {
429 do
430 {
431 gtk_tree_model_get (pos->model,
432 &iter,
433 IN_NAMESPACE_URI, &u,
434 IN_NAMESPACE_META, &m, -1);
435 gtk_list_store_set (GTK_LIST_STORE (pos->model),
436 &iter,
437 IN_NAMESPACE_URI, NULL,
438 IN_NAMESPACE_META, NULL, -1);
439 if (u != NULL)
440 GNUNET_ECRS_uri_destroy (u);
441 if (m != NULL)
442 GNUNET_meta_data_destroy (m);
443 }
444 while (gtk_tree_model_iter_next (pos->model, &iter));
445 }
446 GNUNET_free (pos);
447 del_menu =
448 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
449 "namespaceDelete");
450 gtk_widget_set_sensitive (del_menu, head != NULL);
451}
452
453
454
455void
456namespaceDelete_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
457{
458 GtkWidget *notebook;
459 NamespaceList *list;
460 NamespaceList *prev;
461 gint num;
462 GtkWidget *page;
463 GtkWidget *dialog;
464 gint ret;
465
466 GNUNET_GTK_DEBUG_BEGIN ();
467 notebook =
468 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
469 "localNamespacesNotebook");
470 num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
471 if (num == -1)
472 {
473 /* IMPROVE-ME: disable the menu item
474 as long as this may happen! */
475 dialog = gtk_message_dialog_new
476 (NULL,
477 GTK_DIALOG_MODAL,
478 GTK_MESSAGE_ERROR,
479 GTK_BUTTONS_CLOSE,
480 _("No local namespaces available that could be deleted!"));
481 gtk_dialog_run (GTK_DIALOG (dialog));
482 gtk_widget_destroy (dialog);
483 return;
484 }
485 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), num);
486 list = head;
487 prev = NULL;
488 while ((list != NULL) && (list->namespacepage != page))
489 {
490 prev = list;
491 list = list->next;
492 }
493 if (list == NULL)
494 {
495 GNUNET_GE_BREAK (ectx, 0);
496 return;
497 }
498 /* open window to ask for confirmation,
499 only then delete */
500
501 dialog = gtk_message_dialog_new
502 (NULL,
503 GTK_DIALOG_MODAL,
504 GTK_MESSAGE_ERROR,
505 GTK_BUTTONS_YES_NO,
506 _("Should the namespace `%s' really be deleted?"), list->name);
507 ret = gtk_dialog_run (GTK_DIALOG (dialog));
508 gtk_widget_destroy (dialog);
509 if (GTK_RESPONSE_YES != ret)
510 return;
511 gtk_notebook_remove_page (GTK_NOTEBOOK (notebook), num);
512 GNUNET_NS_namespace_delete (ectx, cfg, &list->id);
513 frame_destroy (list->treeview);
514 GNUNET_GTK_DEBUG_END ();
515}
516
517typedef struct
518{
519 unsigned int anonymityLevel;
520 char *namespaceName;
521 GNUNET_HashCode nsid;
522 const char *thisId;
523 const char *nextId;
524} IUC;
525
526/**
527 * Publish the selected file in the
528 * selected namespace.
529 */
530static void
531addToNamespaceCB (GtkTreeModel * model,
532 GtkTreePath * path, GtkTreeIter * iter, gpointer data)
533{
534 IUC *cls = data;
535 struct GNUNET_ECRS_URI *resultURI;
536 struct GNUNET_ECRS_URI *dst;
537 struct GNUNET_MetaData *meta;
538 NamespaceList *list;
539 GNUNET_ECRS_FileInfo fi;
540
541 GNUNET_GTK_DEBUG_BEGIN ();
542 dst = NULL;
543 gtk_tree_model_get (model,
544 iter, NAMESPACE_URI, &dst, NAMESPACE_META, &meta, -1);
545 if (dst == NULL)
546 {
547 GNUNET_GE_BREAK (ectx, 0);
548 return;
549 }
550 resultURI = GNUNET_NS_add_to_namespace (ectx, cfg, cls->anonymityLevel, 1000, /* FIXME: priority */
551 GNUNET_get_time () + 2 * GNUNET_CRON_YEARS, /* FIXME: expiration */
552 &cls->nsid,
553 cls->thisId, cls->nextId, dst,
554 meta);
555 if (resultURI != NULL)
556 {
557 list = head;
558 while ((list != NULL) && (0 != strcmp (cls->namespaceName, list->name)))
559 list = list->next;
560 if (list == NULL)
561 {
562 GNUNET_GE_BREAK (ectx, 0);
563 }
564 else
565 {
566 /* update namespace content list! */
567 fi.uri = dst;
568 fi.meta = meta;
569 addNamespaceContentToModel (list->model,
570 &fi, cls->thisId, cls->nextId);
571 }
572 GNUNET_ECRS_uri_destroy (resultURI);
573 }
574 else
575 {
576 GNUNET_GTK_show_info_message (_
577 ("Failed to insert content into namespace "
578 "(consult logs).\n"));
579 }
580 GNUNET_GTK_DEBUG_END ();
581}
582
583void
584on_namespaceInsertMetaDataDialogMetaDataAddButton_clicked_fs (GtkWidget *
585 dummy1,
586 GtkWidget *
587 dummy2)
588{
589 handleMetaDataListUpdate (metaXML,
590 "namespaceInsertMetaTypeComboBox",
591 "metaDataValueEntry", "metaDataTreeView");
592}
593
594/**
595 * User clicked the "add" button, add content from
596 * available content list to the currently selected
597 * namespace.
598 */
599void
600on_namespaceInsertButton_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
601{
602
603 NamespaceList *list;
604 GtkWidget *nameLine;
605 GtkWidget *page;
606 GtkWidget *notebook;
607 GtkWidget *dialog;
608 IUC cls;
609 gint num;
610
611 notebook =
612 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
613 "localNamespacesNotebook");
614 num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
615 GNUNET_GE_ASSERT (ectx, num != -1);
616 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), num);
617 list = head;
618 while ((list != NULL) && (list->namespacepage != page))
619 list = list->next;
620 if (list == NULL)
621 {
622 GNUNET_GE_BREAK (ectx, 0);
623 return;
624 }
625 cls.namespaceName = list->name;
626 cls.nsid = list->id;
627
628 metaXML
629 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
630 "namespaceInsertDialog", PACKAGE_NAME);
631 GNUNET_GTK_connect_glade_with_plugins (metaXML);
632 dialog = glade_xml_get_widget (metaXML, "namespaceInsertDialog");
633 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
634 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
635 {
636 cls.anonymityLevel
637 = getSpinButtonValue (metaXML, "anonymitySpinButton");
638 nameLine = glade_xml_get_widget (metaXML,
639 "namespaceContentIdentifierEntry");
640 cls.thisId = gtk_entry_get_text (GTK_ENTRY (nameLine));
641 nameLine = glade_xml_get_widget (metaXML, "nextIdentifierEntry");
642 cls.nextId = gtk_entry_get_text (GTK_ENTRY (nameLine));
643 GNUNET_GTK_tree_selection_selected_foreach
644 (content_selection, &addToNamespaceCB, &cls);
645 }
646 gtk_widget_destroy (dialog);
647 UNREF (metaXML);
648 metaXML = NULL;
649}
650
651
652/**
653 * User clicked on update; launch update dialog
654 * and perform namespace content update.
655 */
656void
657on_namespaceUpdateButton_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
658{
659 NamespaceList *list;
660 GtkTreeIter iter;
661 GtkTreeSelection *selection;
662 IUC cls;
663 char *next;
664 GtkWidget *nextEntryLine;
665 GtkWidget *identifierLabel;
666 GtkWidget *dialog;
667 GtkWidget *notebook;
668 GtkWidget *page;
669 gint num;
670
671 GNUNET_GTK_DEBUG_BEGIN ();
672 /* find out which namespace this is about */
673 notebook =
674 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
675 "localNamespacesNotebook");
676 num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
677 GNUNET_GE_ASSERT (ectx, num != -1);
678 page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), num);
679 list = head;
680 while ((list != NULL) && (list->namespacepage != page))
681 list = list->next;
682 if (list == NULL)
683 {
684 GNUNET_GE_BREAK (ectx, 0);
685 return;
686 }
687 cls.namespaceName = list->name;
688 cls.nsid = list->id;
689
690 /* find out what we are updating */
691 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list->treeview));
692 if (TRUE != gtk_tree_selection_get_selected (selection, NULL, &iter))
693 {
694 GNUNET_GE_BREAK (ectx, 0);
695 return;
696 }
697 gtk_tree_model_get (list->model,
698 &iter, IN_NAMESPACE_NEXT_STRING, &next, -1);
699 if (next == NULL)
700 {
701 GNUNET_GE_BREAK (NULL, 0);
702 return;
703 }
704 /* create update dialog */
705 metaXML
706 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
707 "namespaceUpdateDialog", PACKAGE_NAME);
708 GNUNET_GTK_connect_glade_with_plugins (metaXML);
709 dialog = glade_xml_get_widget (metaXML, "namespaceUpdateDialog");
710 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
711 identifierLabel = glade_xml_get_widget (metaXML, "identifierLabel");
712 gtk_label_set_text (GTK_LABEL (identifierLabel), next);
713 cls.thisId = next;
714 nextEntryLine = glade_xml_get_widget (metaXML, "nextIdentifierEntry1");
715 /* run update dialog */
716 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_OK)
717 goto CLEANUP;
718 gtk_widget_hide (dialog);
719
720 /* get data from update dialog */
721 cls.nextId = gtk_entry_get_text (GTK_ENTRY (nextEntryLine));
722 if (cls.nextId == NULL)
723 cls.nextId = "";
724 cls.anonymityLevel
725 = getSpinButtonValue (metaXML, "namespaceUpdateAnonymitySpinButton");
726
727 /* run actual update */
728 GNUNET_GTK_tree_selection_selected_foreach
729 (content_selection, &addToNamespaceCB, &cls);
730CLEANUP:
731 gtk_widget_destroy (dialog);
732 UNREF (metaXML);
733 metaXML = NULL;
734 free (next);
735 GNUNET_GTK_DEBUG_END ();
736}
737
738
739
740void
741fs_namespace_start ()
742{
743 GtkWidget *contentList;
744 GtkListStore *model;
745 GtkCellRenderer *renderer;
746 GtkWidget *trackCheckButton;
747 GtkTreeViewColumn *column;
748 int col;
749
750 GNUNET_GTK_DEBUG_BEGIN ();
751 trackCheckButton
752 =
753 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
754 "trackingCheckButton");
755 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (trackCheckButton),
756 GNUNET_URITRACK_get_tracking_status (ectx,
757 cfg) ==
758 GNUNET_YES ? TRUE : FALSE);
759
760 contentList =
761 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
762 "availableContentList");
763
764 model = gtk_list_store_new (NAMESPACE_NUM, G_TYPE_STRING, /* name */
765 G_TYPE_UINT64, /* size */
766 G_TYPE_STRING, /* human-readable size */
767 G_TYPE_STRING, /* uri-string */
768 G_TYPE_POINTER, G_TYPE_POINTER); /* uri */
769 gtk_tree_view_set_model (GTK_TREE_VIEW (contentList),
770 GTK_TREE_MODEL (model));
771 content_selection =
772 gtk_tree_view_get_selection (GTK_TREE_VIEW (contentList));
773 gtk_tree_selection_set_mode (content_selection, GTK_SELECTION_MULTIPLE);
774
775 g_signal_connect_data (content_selection,
776 "changed",
777 G_CALLBACK (&on_namespaceContentSelectionChanged),
778 NULL, NULL, 0);
779
780
781 renderer = gtk_cell_renderer_text_new ();
782 col =
783 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (contentList),
784 -1, _("Filename"), renderer,
785 "text", NAMESPACE_FILENAME,
786 NULL);
787 column = gtk_tree_view_get_column (GTK_TREE_VIEW (contentList), col - 1);
788 gtk_tree_view_column_set_resizable (column, TRUE);
789 gtk_tree_view_column_set_clickable (column, TRUE);
790 gtk_tree_view_column_set_reorderable (column, TRUE);
791 gtk_tree_view_column_set_sort_column_id (column, NAMESPACE_FILENAME);
792 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
793
794 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
795 (GTK_TREE_VIEW (contentList), col - 1),
796 TRUE);
797 renderer = gtk_cell_renderer_text_new ();
798 g_object_set (renderer, "xalign", 1.00, NULL);
799 col =
800 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (contentList),
801 -1, _("Filesize"), renderer,
802 "text", NAMESPACE_HSIZE,
803 NULL);
804 column = gtk_tree_view_get_column (GTK_TREE_VIEW (contentList), col - 1);
805 gtk_tree_view_column_set_resizable (column, TRUE);
806 gtk_tree_view_column_set_clickable (column, TRUE);
807 gtk_tree_view_column_set_reorderable (column, TRUE);
808 gtk_tree_view_column_set_sort_column_id (column, NAMESPACE_SIZE);
809 /*gtk_tree_view_column_set_sort_indicator(column, TRUE); */
810 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
811 (GTK_TREE_VIEW (contentList), col - 1),
812 TRUE);
813 renderer = gtk_cell_renderer_text_new ();
814 col =
815 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (contentList),
816 -1, _("URI"), renderer,
817 "text", NAMESPACE_URISTRING,
818 NULL);
819 column = gtk_tree_view_get_column (GTK_TREE_VIEW (contentList), col - 1);
820 gtk_tree_view_column_set_reorderable (column, TRUE);
821 gtk_tree_view_column_set_resizable (column, TRUE);
822 gtk_tree_view_column_set_resizable (gtk_tree_view_get_column
823 (GTK_TREE_VIEW (contentList), col - 1),
824 TRUE);
825 GNUNET_URITRACK_register_track_callback (ectx, cfg, &updateViewSave, NULL);
826 GNUNET_pseudonym_list_all (ectx, cfg, &addTabForNamespace, NULL);
827 GNUNET_pseudonym_register_discovery_callback (ectx, cfg,
828 &namespace_discovered_cb,
829 NULL);
830 GNUNET_GTK_DEBUG_END ();
831}
832
833
834void
835fs_namespace_stop ()
836{
837 GNUNET_pseudonym_unregister_discovery_callback (&namespace_discovered_cb,
838 NULL);
839 while (head != NULL)
840 frame_destroy (head->treeview);
841 GNUNET_URITRACK_unregister_track_callback (&updateViewSave, NULL);
842}
843
844/* end of namespace.c */
diff --git a/src/plugins/fs/namespace.h b/src/plugins/fs/namespace.h
deleted file mode 100644
index 0b7663f9..00000000
--- a/src/plugins/fs/namespace.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/namespace.h
23 * @brief code for dealing with namespaces
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_NAMESPACE_H
28#define GTK_NAMESPACE_H
29
30/**
31 * Add a tab for the given namespace.
32 */
33int addTabForNamespace (void *unused,
34 const GNUNET_HashCode * namespaceId,
35 const struct GNUNET_MetaData *md, int rating);
36
37
38void fs_namespace_start (void);
39
40void fs_namespace_stop (void);
41
42#endif
diff --git a/src/plugins/fs/namespace_create.c b/src/plugins/fs/namespace_create.c
deleted file mode 100644
index 9738c7ea..00000000
--- a/src/plugins/fs/namespace_create.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/namespace.c
23 * @brief operations creating namespaces
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h"
30#include "helper.h"
31#include "meta.h"
32#include "namespace.h"
33#include "content_tracking.h"
34#include <GNUnet/gnunet_util_crypto.h>
35#include <GNUnet/gnunet_uritrack_lib.h>
36#include <GNUnet/gnunet_namespace_lib.h>
37#include <extractor.h>
38
39
40static GladeXML *metaXML;
41
42
43void
44on_namespacemetaDataDialogKeywordRemoveButton_clicked_fs (gpointer dummy,
45 GtkWidget *
46 uploadButton)
47{
48 handleListRemove (metaXML, "namespaceMetaDataDialogKeywordList");
49}
50
51void
52on_namespacemetaDataDialogMetaDataRemoveButton_clicked_fs (gpointer dummy,
53 GtkWidget *
54 uploadButton)
55{
56 handleListRemove (metaXML, "namespaceMetaDataDialogMetaDataList");
57}
58
59void
60on_namespacemetaDataDialogKeywordAddButton_clicked_fs (gpointer dummy,
61 GtkWidget *
62 uploadButton)
63{
64 handleKeywordListUpdate (metaXML,
65 "namespaceKeywordEntry",
66 "namespaceMetaDataDialogKeywordList");
67}
68
69void
70on_namespacemetaDataDialogMetaDataAddButton_clicked_fs (gpointer dummy,
71 GtkWidget *
72 uploadButton)
73{
74 handleMetaDataListUpdate (metaXML,
75 "namespaceMetaDataDialogMetaTypeComboBox",
76 "namespaceMetaDataValueEntry",
77 "namespaceMetaDataDialogMetaDataList");
78}
79
80void
81on_namespaceKeywordEntry_activate_fs (GtkWidget *
82 namespaceKeywordEntry, gpointer dummy)
83{
84 const char *input;
85
86 input = gtk_entry_get_text (GTK_ENTRY (namespaceKeywordEntry));
87 if ((input == NULL) || (strlen (input) == 0))
88 return;
89 handleKeywordListUpdate (metaXML,
90 "namespaceKeywordEntry",
91 "namespaceMetaDataDialogKeywordList");
92}
93
94void
95on_namespaceMetaDataEntry_activate_fs (GtkWidget *
96 namespaceMetaDataEntry, gpointer dummy)
97{
98 const char *input;
99
100 input = gtk_entry_get_text (GTK_ENTRY (namespaceMetaDataEntry));
101 if ((input == NULL) || (strlen (input) == 0))
102 return;
103 handleMetaDataListUpdate (metaXML,
104 "namespaceMetaDataDialogMetaTypeComboBox",
105 "namespaceMetaDataValueEntry",
106 "namespaceMetaDataDialogMetaDataList");
107}
108
109
110/**
111 * The selection of the keyword list changed.
112 * Update button status.
113 */
114static void
115on_keyword_list_selection_changed (gpointer signal, gpointer cls)
116{
117 GtkTreeSelection *selection;
118 GtkWidget *button;
119
120 selection =
121 gtk_tree_view_get_selection (GTK_TREE_VIEW
122 (glade_xml_get_widget
123 (metaXML,
124 "namespaceMetaDataDialogKeywordList")));
125 button =
126 glade_xml_get_widget (metaXML, "nsMetaDataDialogKeywordRemoveButton");
127 gtk_widget_set_sensitive (button,
128 gtk_tree_selection_count_selected_rows (selection)
129 > 0);
130}
131
132/**
133 * The selection of the metadata list changed.
134 * Update button status.
135 */
136static void
137on_metadata_list_selection_changed (gpointer signal, gpointer cls)
138{
139 GtkTreeSelection *selection;
140 GtkWidget *button;
141
142 selection =
143 gtk_tree_view_get_selection (GTK_TREE_VIEW
144 (glade_xml_get_widget
145 (metaXML,
146 "namespaceMetaDataDialogMetaDataList")));
147 button =
148 glade_xml_get_widget (metaXML, "nsMetaDataDialogMetaDataRemoveButton");
149 gtk_widget_set_sensitive (button,
150 gtk_tree_selection_count_selected_rows (selection)
151 > 0);
152}
153
154/**
155 * The user has edited the metadata entry.
156 * Update add button status.
157 */
158void
159on_namespaceMetaDataValueEntry_changed_fs (gpointer dummy2,
160 GtkWidget * searchEntry)
161{
162 const char *input;
163 GtkWidget *button;
164
165 input = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (metaXML,
166 "namespaceMetaDataValueEntry")));
167 if (input == NULL)
168 return;
169 button
170 = glade_xml_get_widget (metaXML, "nsMetaDataDialogMetaDataAddButton");
171 gtk_widget_set_sensitive (button, strlen (input) > 0);
172}
173
174/**
175 * The user has edited the keyword entry.
176 * Update add button status.
177 */
178void
179on_namespaceKeywordEntry_changed_fs (gpointer dummy2, GtkWidget * searchEntry)
180{
181 const char *input;
182 GtkWidget *button;
183
184 input = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (metaXML,
185 "namespaceKeywordEntry")));
186 if (input == NULL)
187 return;
188 button = glade_xml_get_widget (metaXML, "nsMetaDataDialogKeywordAddButton");
189 gtk_widget_set_sensitive (button, strlen (input) > 0);
190}
191
192
193void
194create_namespace_clicked_fs (GtkWidget * dummy1, GtkWidget * dummy2)
195{
196 const char *rootName;
197 GtkWidget *nameLine;
198 GtkWidget *dialog;
199 GtkWidget *spin;
200 struct GNUNET_MetaData *meta;
201 struct GNUNET_ECRS_URI *keywordURI;
202 struct GNUNET_ECRS_URI *root;
203 GNUNET_HashCode namespaceId;
204
205 GNUNET_GTK_DEBUG_BEGIN ();
206 metaXML
207 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
208 "namespaceMetaDataDialog", PACKAGE_NAME);
209 GNUNET_GTK_connect_glade_with_plugins (metaXML);
210 dialog = glade_xml_get_widget (metaXML, "namespaceMetaDataDialog");
211 createMetaDataListTreeView (metaXML,
212 "namespaceMetaDataDialogMetaDataList",
213 NULL, NULL);
214 g_signal_connect_data (gtk_tree_view_get_selection
215 (GTK_TREE_VIEW
216 (glade_xml_get_widget
217 (metaXML, "namespaceMetaDataDialogMetaDataList"))),
218 "changed",
219 G_CALLBACK (&on_metadata_list_selection_changed),
220 NULL, NULL, 0);
221 createKeywordListTreeView (metaXML, "namespaceMetaDataDialogKeywordList",
222 NULL);
223 g_signal_connect_data (gtk_tree_view_get_selection
224 (GTK_TREE_VIEW
225 (glade_xml_get_widget
226 (metaXML, "namespaceMetaDataDialogKeywordList"))),
227 "changed",
228 G_CALLBACK (&on_keyword_list_selection_changed),
229 NULL, NULL, 0);
230
231 createMetaTypeComboBox (metaXML, "namespaceMetaDataDialogMetaTypeComboBox");
232 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
233 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
234 {
235 meta
236 = getMetaDataFromList (metaXML,
237 "namespaceMetaDataDialogMetaDataList", NULL);
238 keywordURI
239 = getKeywordURIFromList (metaXML,
240 "namespaceMetaDataDialogKeywordList");
241 spin = glade_xml_get_widget (metaXML, "namespaceAnonymityspinbutton");
242 nameLine = glade_xml_get_widget (metaXML, "namespaceRootEntry");
243 rootName = gtk_entry_get_text (GTK_ENTRY (nameLine));
244 if (rootName == NULL)
245 rootName = "root"; /* do NOT translate "root"! */
246 root = GNUNET_NS_namespace_create (ectx, cfg, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin)), 1000, /* FIXME: priority */
247 GNUNET_get_time () + 2 * GNUNET_CRON_YEARS, /* FIXME: expiration */
248 meta, keywordURI, rootName);
249 if (root != NULL)
250 {
251 GNUNET_ECRS_uri_get_namespace_from_sks (root, &namespaceId);
252 addTabForNamespace (NULL, &namespaceId, meta, 0);
253 GNUNET_ECRS_uri_destroy (root);
254 }
255 else
256 {
257 GtkWidget *dialog;
258
259 /* IMPROVE-ME: we could check if the
260 namespace exists as the user
261 enters its name and disable the
262 "Ok" button unless the name is unique */
263 dialog = gtk_message_dialog_new
264 (NULL,
265 GTK_DIALOG_MODAL,
266 GTK_MESSAGE_ERROR,
267 GTK_BUTTONS_CLOSE,
268 _("Failed to create namespace." "Consult logs."));
269 gtk_dialog_run (GTK_DIALOG (dialog));
270 gtk_widget_destroy (dialog);
271 }
272 GNUNET_meta_data_destroy (meta);
273 if (keywordURI != NULL)
274 GNUNET_ECRS_uri_destroy (keywordURI);
275 }
276 gtk_widget_destroy (dialog);
277 UNREF (metaXML);
278 metaXML = NULL;
279 GNUNET_GTK_DEBUG_END ();
280}
diff --git a/src/plugins/fs/namespace_search.c b/src/plugins/fs/namespace_search.c
deleted file mode 100644
index 5ac91a80..00000000
--- a/src/plugins/fs/namespace_search.c
+++ /dev/null
@@ -1,323 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/namespace_search.c
23 * @brief code for namespace-related operations on the search frame
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "fs.h"
30#include "helper.h"
31#include "meta.h"
32#include <GNUnet/gnunet_util_crypto.h>
33#include <GNUnet/gnunet_util_pseudonym.h>
34#include <GNUnet/gnunet_uritrack_lib.h>
35#include <GNUnet/gnunet_namespace_lib.h>
36#include <extractor.h>
37
38
39/**
40 * The spin button giving the rating for a particular namespace
41 * has been changed. Store the new rating for the namespace.
42 */
43void
44on_namespaceRatingSpinButton_changed_fs (GtkWidget * dummy,
45 GtkWidget * dummy2)
46{
47 GtkWidget *spin;
48 GtkWidget *ncbe;
49 GtkTreeModel *model;
50 GtkTreeIter iter;
51 char *nsName;
52 char *description;
53 int rating;
54 int newrating;
55 GNUNET_HashCode nsid;
56
57 GNUNET_GTK_DEBUG_BEGIN ();
58 spin =
59 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
60 "namespaceRatingSpinButton");
61 ncbe =
62 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
63 "searchNamespaceComboBoxEntry");
64 model = gtk_combo_box_get_model (GTK_COMBO_BOX (ncbe));
65 description = NULL;
66 nsName = NULL;
67 if (TRUE == gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ncbe), &iter))
68 {
69 gtk_tree_model_get (model,
70 &iter,
71 NS_SEARCH_DESCRIPTION, &description,
72 NS_SEARCH_NAME, &nsName,
73 NS_SEARCH_RATING, &rating, -1);
74 if ((description != NULL) &&
75 ( (0 == strcmp (description, "")) ||
76 (0 == strcmp (description, _("globally")))))
77 {
78 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0);
79 gtk_widget_set_sensitive (spin, FALSE);
80 }
81 else
82 {
83 if (nsName != NULL)
84 {
85 GNUNET_GE_ASSERT (NULL,
86 GNUNET_OK ==
87 GNUNET_pseudonym_name_to_id (ectx, cfg,
88 nsName, &nsid));
89 newrating = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
90 rating = GNUNET_pseudonym_rank (ectx,
91 cfg, &nsid, newrating - rating);
92 if (rating != newrating)
93 {
94 /* concurrent modification? */
95 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), rating);
96 GNUNET_GE_BREAK (ectx, 0);
97 }
98 gtk_list_store_set (GTK_LIST_STORE (model),
99 &iter, NS_SEARCH_RATING, rating, -1);
100 }
101 }
102 }
103 else
104 {
105 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0);
106 gtk_widget_set_sensitive (spin, FALSE);
107 }
108 if (description != NULL)
109 free (description);
110 if (nsName != NULL)
111 free (nsName);
112 GNUNET_GTK_DEBUG_END ();
113}
114
115
116/**
117 * The namespace in the search window has changed.
118 * Update the trust level (possibly changing sensitivity)
119 * and set the search string to the root (if available).
120 */
121void
122on_searchNamespaceComboBoxEntry_changed_fs (GtkWidget * dummy,
123 GtkWidget * dummy2)
124{
125 GtkWidget *keyword;
126 GtkWidget *spin;
127 GtkWidget *ncbe;
128 GtkTreeModel *model;
129 GtkTreeIter iter;
130 int rating;
131 char *nsName;
132 char *descStr;
133 GNUNET_HashCode ns;
134 char *root;
135
136 GNUNET_GTK_DEBUG_BEGIN ();
137 spin =
138 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
139 "namespaceRatingSpinButton");
140 ncbe =
141 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
142 "searchNamespaceComboBoxEntry");
143 model = gtk_combo_box_get_model (GTK_COMBO_BOX (ncbe));
144 descStr = NULL;
145 nsName = NULL;
146 if (TRUE == gtk_combo_box_get_active_iter (GTK_COMBO_BOX (ncbe), &iter))
147 {
148 gtk_tree_model_get (model,
149 &iter,
150 NS_SEARCH_DESCRIPTION, &descStr,
151 NS_SEARCH_NAME, &nsName,
152 NS_SEARCH_RATING, &rating, -1);
153 if ((descStr != NULL) &&
154 ( (0 == strcmp (descStr, "")) ||
155 (0 == strcmp (descStr, _("globally"))) ) )
156 {
157 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0);
158 gtk_widget_set_sensitive (spin, FALSE);
159 }
160 else if (nsName != NULL)
161 {
162 GNUNET_GE_ASSERT (NULL,
163 GNUNET_OK ==
164 GNUNET_pseudonym_name_to_id (ectx, cfg,
165 nsName, &ns));
166 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), rating);
167 gtk_widget_set_sensitive (spin, TRUE);
168 keyword
169 = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
170 "fssearchKeywordComboBoxEntry");
171 root = GNUNET_NS_namespace_get_root (ectx, cfg, &ns);
172 if (root != NULL)
173 {
174 gtk_entry_set_text (GTK_ENTRY
175 (gtk_bin_get_child (GTK_BIN (keyword))),
176 root);
177 GNUNET_free (root);
178 }
179 else
180 {
181 gtk_entry_set_text (GTK_ENTRY
182 (gtk_bin_get_child (GTK_BIN (keyword))),
183 "");
184 }
185 }
186 }
187 else
188 {
189 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0);
190 gtk_widget_set_sensitive (spin, FALSE);
191 }
192 if (descStr != NULL)
193 free (descStr);
194 if (nsName != NULL)
195 free (nsName);
196 GNUNET_GTK_DEBUG_END ();
197}
198
199struct NewNamespaceInfo
200{
201 char *namespaceName;
202 const GNUNET_HashCode *namespaceId;
203 const struct GNUNET_MetaData *md;
204 int rating;
205};
206
207static void *
208saveDiscovery (void *cls)
209{
210 struct NewNamespaceInfo *nni = cls;
211 GtkListStore *model;
212 GtkTreeIter iter;
213 struct GNUNET_MetaData *dmd;
214 GtkWidget *ncbe;
215 char *desc;
216 char *haveName;
217 int found;
218 char *fulldesc;
219
220 GNUNET_GTK_DEBUG_BEGIN ();
221 ncbe =
222 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
223 "searchNamespaceComboBoxEntry");
224 model = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (ncbe)));
225 if (nni->md == NULL)
226 {
227 dmd = NULL;
228 desc = GNUNET_strdup ("");
229 }
230 else
231 {
232 dmd = GNUNET_meta_data_duplicate (nni->md);
233 desc = GNUNET_meta_data_get_first_by_types (dmd,
234 EXTRACTOR_DESCRIPTION,
235 EXTRACTOR_TITLE,
236 EXTRACTOR_AUTHOR,
237 EXTRACTOR_GENRE,
238 EXTRACTOR_SUBJECT,
239 EXTRACTOR_CREATOR,
240 EXTRACTOR_PRODUCER,
241 EXTRACTOR_GROUP,
242 EXTRACTOR_CREATED_FOR,
243 EXTRACTOR_SUMMARY,
244 EXTRACTOR_OWNER, -1);
245 if (desc == NULL)
246 desc = GNUNET_strdup ("");
247 }
248
249 /* check if present! */
250 found = GNUNET_NO;
251 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
252 {
253 do
254 {
255 gtk_tree_model_get (GTK_TREE_MODEL (model),
256 &iter, NS_SEARCH_NAME, &haveName, -1);
257 if ((haveName != NULL) &&
258 (0 == strcmp (haveName, nni->namespaceName)))
259 found = GNUNET_YES;
260 GNUNET_free_non_null (haveName);
261 }
262 while ((found == GNUNET_NO) &&
263 (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter)));
264 }
265 if (found == GNUNET_NO)
266 {
267 GNUNET_GTK_show_info_message (_("Namespace `%s' found: %s.\n"),
268 nni->namespaceName, desc);
269 fulldesc =
270 GNUNET_malloc (strlen (desc) + strlen (nni->namespaceName) + 3);
271 strcpy (fulldesc, nni->namespaceName);
272 if (NULL == strstr (nni->namespaceName, desc))
273 {
274 /* append only if desc adds something new! */
275 strcat (fulldesc, ": ");
276 strcat (fulldesc, desc);
277 }
278 gtk_list_store_append (model, &iter);
279 gtk_list_store_set (model,
280 &iter,
281 NS_SEARCH_DESCRIPTION, fulldesc,
282 NS_SEARCH_NAME, nni->namespaceName,
283 NS_SEARCH_METADATA, dmd,
284 NS_SEARCH_RATING, nni->rating, -1);
285 GNUNET_free (fulldesc);
286 }
287 else
288 {
289 GNUNET_meta_data_destroy (dmd);
290 }
291 GNUNET_free (desc);
292 GNUNET_GTK_DEBUG_END ();
293
294 return NULL;
295}
296
297
298
299/**
300 * Call this function to inform the user about
301 * newly found namespaces and to add them to the
302 * list of available namespaces in the search
303 * dialog.
304 *
305 * @param cls pass NULL
306 * @param rating the local rating of the namespace
307 * @return GNUNET_OK (always)
308 */
309int
310namespace_discovered_cb (void *cls,
311 const GNUNET_HashCode * namespaceId,
312 const struct GNUNET_MetaData *md, int rating)
313{
314 struct NewNamespaceInfo nni;
315
316 nni.namespaceName = GNUNET_pseudonym_id_to_name (ectx, cfg, namespaceId);
317 nni.namespaceId = namespaceId;
318 nni.md = md;
319 nni.rating = rating;
320 GNUNET_GTK_save_call (&saveDiscovery, &nni);
321 GNUNET_free (nni.namespaceName);
322 return GNUNET_OK;
323}
diff --git a/src/plugins/fs/namespace_search.h b/src/plugins/fs/namespace_search.h
deleted file mode 100644
index 06c553e4..00000000
--- a/src/plugins/fs/namespace_search.h
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007 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/namespace_search.h
23 * @brief code for namespace-related operations on the search frame
24 * @author Christian Grothoff
25 */
26#ifndef NAMESPACE_SEARCH_H
27#define NAMESPACE_SEARCH_H
28
29/**
30 * Call this function to inform the user about
31 * newly found namespaces and to add them to the
32 * list of available namespaces in the search
33 * dialog.
34 *
35 * @param cls pass NULL
36 * @param rating the local rating of the namespace
37 * @return GNUNET_OK (always)
38 */
39int namespace_discovered_cb (void *cls,
40 const GNUNET_HashCode * namespaceId,
41 const struct GNUNET_MetaData *md, int rating);
42
43
44
45#endif
diff --git a/src/plugins/fs/search.c b/src/plugins/fs/search.c
deleted file mode 100644
index f789e43f..00000000
--- a/src/plugins/fs/search.c
+++ /dev/null
@@ -1,1325 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2007, 2008 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/search.c
23 * @brief code for searching with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "search.h"
30#include "status.h"
31#include "helper.h"
32#include "fs.h"
33#include "meta.h"
34#include <extractor.h>
35#include <GNUnet/gnunet_util_crypto.h>
36#include <GNUnet/gnunet_namespace_lib.h>
37#ifdef HAVE_GIO
38#include <gio/gio.h>
39#endif
40
41
42/**
43 * The user has edited the search entry.
44 * Update search button status.
45 */
46static void
47on_fssearchSelectionChanged (gpointer signal, gpointer cls)
48{
49 SearchList *list = cls;
50 GtkTreeSelection *selection;
51 GtkWidget *downloadButton;
52
53 selection = gtk_tree_view_get_selection (list->treeview);
54 downloadButton = glade_xml_get_widget (list->searchXML, "downloadButton");
55 gtk_widget_set_sensitive (downloadButton,
56 gtk_tree_selection_count_selected_rows (selection)
57 > 0);
58}
59
60
61/* **************** FSUI event handling ****************** */
62
63/**
64 * Update the number of results received in the label of the tab.
65 */
66static void
67updateResultsCount (SearchList * searchContext)
68{
69 char *new_title;
70 GtkLabel *label;
71
72 /* update tab title with the number of results */
73 new_title =
74 g_strdup_printf ("%.*s%s (%u)",
75 20,
76 searchContext->searchString,
77 strlen (searchContext->searchString) > 20 ? "..." : "",
78 searchContext->resultsReceived);
79 if (new_title == NULL)
80 new_title =
81 g_strdup_printf (_("invalid characters (%u)"),
82 searchContext->resultsReceived);
83 label = GTK_LABEL (glade_xml_get_widget (searchContext->labelXML,
84 "searchTabLabel"));
85 if (new_title != NULL)
86 {
87 gtk_label_set (label, new_title);
88 GNUNET_free (new_title);
89 }
90 else
91 {
92 gtk_label_set (label, _("Internal error"));
93 }
94}
95
96static GdkPixbuf *
97make_ranking_pixbuf (int availability_rank,
98 unsigned int availability_certainty,
99 unsigned int applicability_rank, unsigned int kwords)
100{
101 GdkPixbuf *pixbuf;
102 guchar *pixels;
103 guchar *pixel;
104 int n_channels;
105 int rowstride;
106 unsigned int x;
107 unsigned int y;
108
109#define P_HEIGHT 21
110#define P_WIDTH 60
111 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, /* alpha */
112 8, /* bits per sample */
113 P_WIDTH, /* width */
114 P_HEIGHT /* height */
115 );
116 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
117 pixels = gdk_pixbuf_get_pixels (pixbuf);
118 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
119 for (x = 0; x < P_WIDTH; x++)
120 for (y = 0; y < P_HEIGHT; y++)
121 {
122 pixel = pixels + y * rowstride + x * n_channels;
123#define PX_RED 0
124#define PX_GREEN 1
125#define PX_BLUE 2
126#define PX_ALPHA 3
127 pixel[PX_RED] = 0;
128 pixel[PX_GREEN] = 0;
129 pixel[PX_BLUE] = 0;
130 pixel[PX_ALPHA] = 0;
131 if (y < P_HEIGHT / 2)
132 {
133 /* applicability */
134 if (x * kwords < applicability_rank * P_WIDTH)
135 {
136 pixel[PX_RED] = 0;
137 pixel[PX_GREEN] = 0;
138 pixel[PX_BLUE] = 255;
139 pixel[PX_ALPHA] = 255;
140 }
141 }
142 else if ((y > P_HEIGHT / 2) &&
143 ((y - P_HEIGHT / 2) * GNUNET_FSUI_MAX_PROBES
144 < availability_certainty * P_HEIGHT / 2))
145 {
146 /* availability */
147 if (availability_rank < 0)
148 {
149 if ((x * GNUNET_FSUI_MAX_PROBES >
150 ((unsigned int) (GNUNET_FSUI_MAX_PROBES +
151 availability_rank)) * P_WIDTH / 2)
152 && (x <= P_WIDTH / 2))
153 {
154 pixel[PX_RED] = 255;
155 pixel[PX_GREEN] = 0;
156 pixel[PX_BLUE] = 0;
157 pixel[PX_ALPHA] = 255;
158 }
159 }
160 else if (availability_rank > 0)
161 {
162 if ((x >= P_WIDTH / 2) &&
163 ((x - (P_WIDTH / 2)) * GNUNET_FSUI_MAX_PROBES <
164 ((unsigned int) availability_rank) * P_WIDTH / 2))
165 {
166 pixel[PX_RED] = 0;
167 pixel[PX_GREEN] = 255;
168 pixel[PX_BLUE] = 0;
169 pixel[PX_ALPHA] = 255;
170 }
171 }
172 else
173 {
174 if (x == P_WIDTH / 2)
175 {
176 /* yellow */
177 pixel[PX_RED] = 255;
178 pixel[PX_GREEN] = 255;
179 pixel[PX_BLUE] = 0;
180 pixel[PX_ALPHA] = 255;
181 }
182 }
183 }
184 }
185 return pixbuf;
186}
187
188/**
189 * Add the given search result to the search
190 * tree at the specified position.
191 */
192void
193addEntryToSearchTree (SearchList * searchContext,
194 DownloadList * downloadParent,
195 const GNUNET_ECRS_FileInfo * info, GtkTreeIter * iter)
196{
197 char *name;
198 char *rawMime;
199 char *mime;
200 char *desc;
201 unsigned long long size;
202 char *size_h;
203 GdkPixbuf *pixbuf;
204 GdkPixbuf *rankbuf;
205 GdkPixbuf *statusLogo;
206#ifdef HAVE_GIO
207 GdkPixbuf *icon = NULL;
208 GIcon *gicon = NULL;
209 const gchar **iconNames;
210 int i = 0;
211#endif
212 enum GNUNET_URITRACK_STATE state;
213
214 state = GNUNET_URITRACK_get_state (ectx, cfg, info->uri);
215 rawMime = getMimeTypeFromMetaData (info->meta);
216 desc = getDescriptionFromMetaData (info->meta);
217 statusLogo = getStatusLogo (state);
218 name = getFileNameFromMetaData (info->meta);
219 size = GNUNET_ECRS_uri_test_chk (info->uri)
220 || GNUNET_ECRS_uri_test_loc (info->uri) ?
221 GNUNET_ECRS_uri_get_file_size (info->uri) : 0;
222 pixbuf = getThumbnailFromMetaData (info->meta);
223 size_h = GNUNET_get_byte_size_as_fancy_string (size);
224 rankbuf = make_ranking_pixbuf (0, 0, 1,
225 GNUNET_ECRS_uri_get_keyword_count_from_ksk
226 (searchContext->uri));
227#ifdef HAVE_GIO
228 if (0 == strcmp (rawMime, GNUNET_DIRECTORY_MIME))
229 {
230 mime = GNUNET_strdup (_("Directory"));
231 icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
232 GTK_STOCK_DIRECTORY, 16, 0,
233 (GError **) NULL);
234 }
235 else
236 {
237 mime = g_content_type_get_description (rawMime);
238 gicon = g_content_type_get_icon (rawMime);
239 if (G_IS_THEMED_ICON (gicon))
240 {
241 iconNames = (const gchar **) g_themed_icon_get_names
242 (G_THEMED_ICON (gicon));
243 do
244 {
245 icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
246 iconNames[i], 16, 0,
247 (GError **) NULL);
248 i++;
249 }
250 while ((icon == NULL) && iconNames[i]);
251 }
252 }
253#else
254 mime = GNUNET_strdup (rawMime);
255#endif
256
257 gtk_tree_store_set (searchContext->tree, iter,
258 SEARCH_NAME, name, SEARCH_SIZE, size, SEARCH_HSIZE,
259 size_h, SEARCH_MIME, mime,
260 SEARCH_RAW_MIME, rawMime, SEARCH_DESC, desc,
261 SEARCH_PIXBUF, pixbuf, SEARCH_URI,
262 GNUNET_ECRS_uri_duplicate (info->uri), SEARCH_META,
263 GNUNET_meta_data_duplicate (info->meta),
264 SEARCH_INTERNAL, searchContext,
265 SEARCH_INTERNAL_PARENT, downloadParent,
266 SEARCH_STATUS, getStatusName (state),
267 SEARCH_STATUS_LOGO, statusLogo,
268 SEARCH_APPLICABILITY_RANK, 1, SEARCH_RANK_SORT,
269 (long long) 1, SEARCH_RANK_PIXBUF, rankbuf,
270#ifdef HAVE_GIO
271 SEARCH_ICON, icon,
272#endif
273 -1);
274 g_object_unref (rankbuf);
275 if (pixbuf != NULL)
276 g_object_unref (pixbuf);
277 if (statusLogo != NULL)
278 g_object_unref (statusLogo);
279#ifdef HAVE_GIO
280 if (gicon != NULL)
281 g_object_unref (gicon);
282 if (icon != NULL)
283 g_object_unref (icon);
284#endif
285 GNUNET_free (size_h);
286 GNUNET_free (name);
287 GNUNET_free (desc);
288 GNUNET_free (rawMime);
289 GNUNET_free (mime);
290}
291
292/**
293 * Add the given result to the model (search result
294 * list).
295 *
296 * @param info the information to add to the model
297 * @param uri the search URI
298 * @param searchContext identifies the search page
299 */
300void
301fs_search_result_received (SearchList * searchContext,
302 const GNUNET_ECRS_FileInfo * info,
303 const struct GNUNET_ECRS_URI *uri)
304{
305 GtkTreeStore *model;
306 GtkTreeIter iter;
307 enum GNUNET_URITRACK_STATE state;
308 struct GNUNET_ECRS_URI *have;
309
310 state = GNUNET_URITRACK_get_state (ectx, cfg, info->uri);
311 if ((state & (GNUNET_URITRACK_INSERTED |
312 GNUNET_URITRACK_INDEXED)) &&
313 (GNUNET_YES == GNUNET_GC_get_configuration_value_yesno (cfg,
314 "GNUNET-GTK",
315 "DISABLE-OWN",
316 GNUNET_NO)))
317 return;
318 model = GTK_TREE_STORE (gtk_tree_view_get_model (searchContext->treeview));
319 /* Check that the entry does not already exist (for resume!) */
320 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
321 {
322 do
323 {
324 have = NULL;
325 gtk_tree_model_get (GTK_TREE_MODEL (model),
326 &iter, SEARCH_URI, &have, -1);
327 if ((have != NULL) && (GNUNET_ECRS_uri_test_equal (have, uri)))
328 return; /* duplicate */
329 }
330 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
331 }
332 gtk_tree_store_append (model, &iter, NULL);
333 addEntryToSearchTree (searchContext, NULL, info, &iter);
334 searchContext->resultsReceived++;
335 updateResultsCount (searchContext);
336}
337
338/**
339 * Update the applicability and availability rating
340 * for the given search result.
341 *
342 * @param info the search result (and metadata)
343 * @param availability_rank availability estimate
344 * @param applicability_rank relevance
345 */
346void
347fs_search_update (SearchList * searchContext,
348 const GNUNET_ECRS_FileInfo * info,
349 int availability_rank,
350 unsigned int availability_certainty,
351 unsigned int applicability_rank)
352{
353 enum GNUNET_URITRACK_STATE state;
354 GtkTreeStore *model;
355 GtkTreeIter iter;
356 struct GNUNET_ECRS_URI *have;
357 GdkPixbuf *pixbuf;
358 long long rank;
359 unsigned int kwords;
360
361 state = GNUNET_URITRACK_get_state (ectx, cfg, info->uri);
362 if ((state & (GNUNET_URITRACK_INSERTED |
363 GNUNET_URITRACK_INDEXED)) &&
364 (GNUNET_YES == GNUNET_GC_get_configuration_value_yesno (cfg,
365 "GNUNET-GTK",
366 "DISABLE-OWN",
367 GNUNET_NO)))
368 return;
369 kwords = GNUNET_ECRS_uri_get_keyword_count_from_ksk (searchContext->uri);
370 model = GTK_TREE_STORE (gtk_tree_view_get_model (searchContext->treeview));
371 /* find existing entry */
372 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter))
373 {
374 do
375 {
376 have = NULL;
377 gtk_tree_model_get (GTK_TREE_MODEL (model),
378 &iter, SEARCH_URI, &have, -1);
379 if ((have != NULL) &&
380 (GNUNET_ECRS_uri_test_equal (have, info->uri)))
381 {
382 /* gotcha, create pixbuf and rank info! */
383 rank =
384 (int) applicability_rank +
385 (int) (availability_rank * (int) availability_certainty *
386 65536);
387 pixbuf =
388 make_ranking_pixbuf (availability_rank,
389 availability_certainty,
390 applicability_rank, kwords);
391 gtk_tree_store_set (searchContext->tree, &iter,
392 SEARCH_AVAILABILITY_RANK, availability_rank,
393 SEARCH_AVAILABILITY_CERTAINTY,
394 availability_certainty,
395 SEARCH_APPLICABILITY_RANK,
396 applicability_rank, SEARCH_RANK_PIXBUF,
397 pixbuf, SEARCH_RANK_SORT, rank, -1);
398 g_object_unref (pixbuf);
399 return; /* done! */
400 }
401 }
402 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));
403 }
404 /* not found!? */
405 GNUNET_GE_BREAK (NULL, 0);
406}
407
408
409static int
410on_search_display_metadata_activate (void *cls, GtkWidget * searchEntry)
411{
412 SearchList *list = cls;
413 GtkTreePath *path;
414 GtkTreeIter iter;
415 struct GNUNET_ECRS_URI *uri;
416 struct GNUNET_MetaData *meta;
417 char *str;
418
419 path = NULL;
420 if (FALSE == gtk_tree_view_get_path_at_pos (list->treeview,
421 list->last_x,
422 list->last_y,
423 &path, NULL, NULL, NULL))
424 {
425 /* nothing selected */
426 return FALSE;
427 }
428 if (FALSE == gtk_tree_model_get_iter (GTK_TREE_MODEL (list->tree),
429 &iter, path))
430 {
431 GNUNET_GE_BREAK (NULL, 0);
432 gtk_tree_path_free (path);
433 return FALSE;
434 }
435 gtk_tree_path_free (path);
436 uri = NULL;
437 meta = NULL;
438 gtk_tree_model_get (GTK_TREE_MODEL (list->tree),
439 &iter, SEARCH_URI, &uri, SEARCH_META, &meta, -1);
440 str = GNUNET_ECRS_uri_to_string (uri);
441 open_meta_data_display_dialog(meta, str);
442 GNUNET_free_non_null (str);
443 return FALSE;
444}
445
446
447static int
448on_search_copy_uri_activate (void *cls, GtkWidget * searchEntry)
449{
450 SearchList *list = cls;
451 GtkTreePath *path;
452 GtkTreeIter iter;
453 struct GNUNET_ECRS_URI *uri;
454 char *str;
455 GtkClipboard *clip;
456
457 path = NULL;
458 if (FALSE == gtk_tree_view_get_path_at_pos (list->treeview,
459 list->last_x,
460 list->last_y,
461 &path, NULL, NULL, NULL))
462 {
463 GNUNET_GE_BREAK (NULL, 0);
464 return FALSE;
465 }
466 if (FALSE == gtk_tree_model_get_iter (GTK_TREE_MODEL (list->tree),
467 &iter, path))
468 {
469 GNUNET_GE_BREAK (NULL, 0);
470 gtk_tree_path_free (path);
471 return FALSE;
472 }
473 gtk_tree_path_free (path);
474 uri = NULL;
475 gtk_tree_model_get (GTK_TREE_MODEL (list->tree),
476 &iter, SEARCH_URI, &uri, -1);
477 str = GNUNET_ECRS_uri_to_string (uri);
478 clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
479 gtk_clipboard_set_text (clip, str, strlen (str));
480 GNUNET_free (str);
481 return FALSE;
482}
483
484
485#ifndef MINGW
486static char *
487selectFile ()
488{
489 GladeXML *uploadXML;
490 GtkFileChooser *dialog;
491 char *ret;
492 gint gret;
493
494 uploadXML
495 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
496 "directorySaveDialog", PACKAGE_NAME);
497 GNUNET_GTK_connect_glade_with_plugins (uploadXML);
498 dialog = GTK_FILE_CHOOSER (glade_xml_get_widget (uploadXML,
499 "directorySaveDialog"));
500 gret = gtk_dialog_run (GTK_DIALOG (dialog));
501 gtk_widget_destroy (GTK_WIDGET (dialog));
502 if (gret != GTK_RESPONSE_CANCEL)
503 ret = gtk_file_chooser_get_filename (dialog);
504 else
505 ret = NULL;
506 UNREF (uploadXML);
507 return ret;
508}
509
510#else /* MINGW */
511
512static char *
513selectFile ()
514{
515 return
516 plibc_ChooseFile (_
517 ("Choose the name under which you want to save the search results."),
518 OFN_SHAREAWARE);
519}
520#endif /* MINGW */
521
522static int
523on_save_search_activate (void *cls, GtkWidget * searchEntry)
524{
525 SearchList *list = cls;
526 char *name;
527 char *directory;
528 unsigned long long dir_len;
529 unsigned int fis_size;
530 GNUNET_ECRS_FileInfo *fis;
531 struct GNUNET_MetaData *meta;
532 GtkTreeModel *model;
533 GtkTreeIter iter;
534 unsigned int pos;
535
536 model = gtk_tree_view_get_model (list->treeview);
537 if (TRUE != gtk_tree_model_get_iter_first (model, &iter))
538 {
539 GNUNET_GTK_add_log_entry (_("No search results yet, cannot save!"));
540 return FALSE;
541 }
542
543 name = selectFile ("");
544 if (name == NULL)
545 return FALSE;
546 fis = NULL;
547 fis_size = 0;
548 GNUNET_array_grow (fis, fis_size, list->resultsReceived);
549 pos = 0;
550 do
551 {
552 if (pos == fis_size)
553 GNUNET_array_grow (fis, fis_size, pos + 1);
554 gtk_tree_model_get (model,
555 &iter,
556 SEARCH_URI, &fis[pos].uri,
557 SEARCH_META, &fis[pos].meta, -1);
558 pos++;
559 }
560 while (gtk_tree_model_iter_next (model, &iter));
561 meta = GNUNET_meta_data_create ();
562 GNUNET_meta_data_insert (meta, EXTRACTOR_KEYWORDS, list->searchString);
563 GNUNET_meta_data_insert (meta, EXTRACTOR_DESCRIPTION,
564 _("Saved search results"));
565 GNUNET_meta_data_insert (meta, EXTRACTOR_SOFTWARE, "gnunet-gtk");
566 if (GNUNET_OK != GNUNET_ECRS_directory_create (NULL,
567 &directory, &dir_len,
568 fis_size, fis, meta))
569 {
570 GNUNET_GTK_add_log_entry (_("Internal error."));
571 GNUNET_GE_BREAK (NULL, 0);
572 GNUNET_meta_data_destroy (meta);
573 GNUNET_array_grow (fis, fis_size, 0);
574 GNUNET_free (name);
575 return FALSE;
576 }
577 GNUNET_meta_data_destroy (meta);
578 GNUNET_array_grow (fis, fis_size, 0);
579 if (GNUNET_OK !=
580 GNUNET_disk_file_write (NULL, name, directory, dir_len, "644"))
581 {
582 GNUNET_GTK_add_log_entry (_("Error writing file `%s'."), name);
583 }
584 GNUNET_free (directory);
585 GNUNET_free (name);
586 return FALSE;
587}
588
589static gint
590search_click_handler (void *cls, GdkEvent * event)
591{
592 SearchList *list = cls;
593 GtkMenu *menu;
594 GtkWidget *entry;
595 GdkEventButton *event_button;
596
597 if ((event == NULL) || (event->type != GDK_BUTTON_PRESS))
598 return FALSE;
599 event_button = (GdkEventButton *) event;
600 if (event_button->button != 3)
601 return FALSE;
602 list->last_x = event_button->x;
603 list->last_y = event_button->y;
604 menu = GTK_MENU (gtk_menu_new ());
605
606 entry = gtk_menu_item_new_with_label (_("_Display metadata"));
607 g_signal_connect_swapped (entry,
608 "activate",
609 G_CALLBACK (on_search_display_metadata_activate),
610 list);
611 gtk_label_set_use_underline (GTK_LABEL
612 (gtk_bin_get_child (GTK_BIN (entry))), TRUE);
613 gtk_widget_show (entry);
614 gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
615
616 entry = gtk_menu_item_new_with_label (_("_Copy URI to Clipboard"));
617 g_signal_connect_swapped (entry,
618 "activate",
619 G_CALLBACK (on_search_copy_uri_activate), list);
620 gtk_label_set_use_underline (GTK_LABEL
621 (gtk_bin_get_child (GTK_BIN (entry))), TRUE);
622 gtk_widget_show (entry);
623 gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
624
625 entry = gtk_menu_item_new_with_label (_("_Save results as directory"));
626 g_signal_connect_swapped (entry,
627 "activate",
628 G_CALLBACK (on_save_search_activate), list);
629 gtk_label_set_use_underline (GTK_LABEL
630 (gtk_bin_get_child (GTK_BIN (entry))), TRUE);
631 gtk_widget_show (entry);
632 gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
633
634
635 gtk_menu_popup (menu,
636 NULL,
637 NULL, NULL, NULL, event_button->button, event_button->time);
638 return TRUE;
639}
640
641/**
642 * FSUI event: a search was started; create the tab
643 */
644SearchList *
645fs_search_started (struct GNUNET_FSUI_SearchList * fsui_list,
646 const struct GNUNET_ECRS_URI * uri,
647 unsigned int anonymityLevel,
648 unsigned int resultCount,
649 const GNUNET_ECRS_FileInfo * results,
650 GNUNET_FSUI_State state)
651{
652 SearchList *list;
653 gint pages;
654 char *description;
655 GtkTreeViewColumn *column;
656 GtkCellRenderer *renderer;
657 GtkNotebook *notebook;
658 int col;
659 unsigned int i;
660
661 /* check that search does not already exist
662 with fsui_list == NULL;
663 (and if so, hijack!) */
664 list = search_head;
665 while (list != NULL)
666 {
667 if ((list->fsui_list == NULL) &&
668 (list->uri != NULL) &&
669 (GNUNET_ECRS_uri_test_equal (list->uri, uri)))
670 {
671 list->fsui_list = fsui_list;
672 for (i = 0; i < resultCount; i++)
673 fs_search_result_received (list, &results[i], uri);
674 if (resultCount == 0) /* otherwise already done! */
675 updateResultsCount (list);
676 return list;
677 }
678 list = list->next;
679 }
680
681 /* build new entry */
682 if (GNUNET_ECRS_uri_test_ksk (uri))
683 description = GNUNET_ECRS_ksk_uri_to_human_readable_string (uri);
684 else
685 description = GNUNET_NS_sks_uri_to_human_readable_string (ectx, cfg, uri);
686 if (description == NULL)
687 {
688 GNUNET_GE_BREAK (ectx, 0);
689 return NULL;
690 }
691 list = GNUNET_malloc (sizeof (SearchList));
692 memset (list, 0, sizeof (SearchList));
693 list->searchString = description;
694 list->uri = GNUNET_ECRS_uri_duplicate (uri);
695 list->fsui_list = fsui_list;
696 list->next = search_head;
697 list->anonymityLevel = anonymityLevel;
698
699 search_head = list;
700 list->searchXML
701 =
702 glade_xml_new (GNUNET_GTK_get_glade_filename (), "searchResultsFrame",
703 PACKAGE_NAME);
704 GNUNET_GTK_connect_glade_with_plugins (list->searchXML);
705 list->searchpage
706 =
707 GNUNET_GTK_extract_main_widget_from_window (list->searchXML,
708 "searchResultsFrame");
709 /* setup tree view and renderers */
710 list->treeview = GTK_TREE_VIEW (glade_xml_get_widget (list->searchXML,
711 "searchResults"));
712 g_signal_connect_swapped (list->treeview,
713 "button-press-event",
714 G_CALLBACK (search_click_handler), list);
715 list->tree = gtk_tree_store_new (SEARCH_NUM, G_TYPE_STRING, /* name */
716 G_TYPE_UINT64, /* size */
717 G_TYPE_STRING, /* human-readable size */
718 G_TYPE_STRING, /* mime-type */
719 G_TYPE_STRING, /* raw mime-type */
720 G_TYPE_STRING, /* meta-data (some) */
721 GDK_TYPE_PIXBUF, /* preview */
722 G_TYPE_POINTER, /* url */
723 G_TYPE_POINTER, /* meta */
724 G_TYPE_POINTER, /* internal: search list */
725 G_TYPE_POINTER, /* internal: download parent list */
726 G_TYPE_STRING, /* status */
727 GDK_TYPE_PIXBUF, /* status (icon) */
728 G_TYPE_INT, /* availability rank */
729 G_TYPE_UINT, /* availability certainty */
730 G_TYPE_UINT, /* applicability rank */
731 GDK_TYPE_PIXBUF, /* ranking visualization */
732 G_TYPE_INT64 /* numeric sort */
733#ifdef HAVE_GIO
734 , GDK_TYPE_PIXBUF /* icon */
735#endif
736 );
737
738 gtk_tree_view_set_model (list->treeview, GTK_TREE_MODEL (list->tree));
739 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (list->treeview),
740 GTK_SELECTION_MULTIPLE);
741
742 g_signal_connect_data (gtk_tree_view_get_selection (list->treeview),
743 "changed",
744 G_CALLBACK (&on_fssearchSelectionChanged),
745 list, NULL, 0);
746
747 column = gtk_tree_view_column_new ();
748 gtk_tree_view_column_set_title (column, _("Name"));
749#ifdef HAVE_GIO
750 renderer = gtk_cell_renderer_pixbuf_new ();
751 gtk_tree_view_column_pack_start (column, renderer, FALSE);
752 gtk_tree_view_column_set_attributes (column, renderer, "pixbuf",
753 SEARCH_ICON, NULL);
754#endif
755 renderer = gtk_cell_renderer_text_new ();
756 gtk_tree_view_column_pack_start (column, renderer, TRUE);
757 g_object_set (G_OBJECT (renderer),
758 "wrap-width", 45,
759 "width-chars", 45, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
760 gtk_tree_view_column_set_attributes (column, renderer, "text",
761 SEARCH_NAME, NULL);
762 col = gtk_tree_view_insert_column (list->treeview, column, 0);
763 gtk_tree_view_column_set_resizable (column, TRUE);
764 gtk_tree_view_column_set_clickable (column, TRUE);
765 gtk_tree_view_column_set_reorderable (column, TRUE);
766 gtk_tree_view_column_set_sort_column_id (column, SEARCH_NAME);
767
768 renderer = gtk_cell_renderer_pixbuf_new ();
769 col = gtk_tree_view_insert_column_with_attributes (list->treeview,
770 -1,
771 _("Status"),
772 renderer,
773 "pixbuf",
774 SEARCH_STATUS_LOGO,
775 NULL);
776 column = gtk_tree_view_get_column (list->treeview, col - 1);
777 gtk_tree_view_column_set_resizable (column, TRUE);
778 gtk_tree_view_column_set_clickable (column, TRUE);
779 gtk_tree_view_column_set_reorderable (column, TRUE);
780 gtk_tree_view_column_set_sort_column_id (column, SEARCH_STATUS);
781 gtk_tree_view_column_set_min_width (column, 20);
782
783 renderer = gtk_cell_renderer_text_new ();
784 g_object_set (renderer, "xalign", 1.00, NULL);
785 col = gtk_tree_view_insert_column_with_attributes (list->treeview,
786 -1,
787 _("Size"),
788 renderer,
789 "text", SEARCH_HSIZE,
790 NULL);
791 column = gtk_tree_view_get_column (list->treeview, col - 1);
792 gtk_tree_view_column_set_resizable (column, TRUE);
793 gtk_tree_view_column_set_clickable (column, TRUE);
794 gtk_tree_view_column_set_reorderable (column, TRUE);
795 gtk_tree_view_column_set_sort_column_id (column, SEARCH_SIZE);
796
797#if 0
798 /* colums for data visualized graphically */
799 renderer = gtk_cell_renderer_text_new ();
800 gtk_tree_view_insert_column_with_attributes (list->treeview,
801 -1,
802 _("Availability"),
803 renderer,
804 "text",
805 SEARCH_AVAILABILITY_RANK,
806 NULL);
807 renderer = gtk_cell_renderer_text_new ();
808 gtk_tree_view_insert_column_with_attributes (list->treeview,
809 -1,
810 _("Certainty"),
811 renderer,
812 "text",
813 SEARCH_AVAILABILITY_CERTAINTY,
814 NULL);
815 renderer = gtk_cell_renderer_text_new ();
816 gtk_tree_view_insert_column_with_attributes (list->treeview,
817 -1,
818 _("Applicability"),
819 renderer,
820 "text",
821 SEARCH_APPLICABILITY_RANK,
822 NULL);
823 renderer = gtk_cell_renderer_text_new ();
824 gtk_tree_view_insert_column_with_attributes (list->treeview,
825 -1,
826 _("Sort"),
827 renderer,
828 "text", SEARCH_RANK_SORT,
829 NULL);
830#endif
831
832 renderer = gtk_cell_renderer_pixbuf_new ();
833 col = gtk_tree_view_insert_column_with_attributes (list->treeview,
834 -1,
835 _("Ranking"),
836 renderer,
837 "pixbuf",
838 SEARCH_RANK_PIXBUF,
839 NULL);
840 column = gtk_tree_view_get_column (list->treeview, col - 1);
841 gtk_tree_view_column_set_resizable (column, FALSE);
842 gtk_tree_view_column_set_clickable (column, TRUE);
843 gtk_tree_view_column_set_reorderable (column, TRUE);
844 gtk_tree_view_column_set_sort_column_id (column, SEARCH_RANK_SORT);
845
846
847 if (GNUNET_YES != GNUNET_GC_get_configuration_value_yesno (cfg,
848 "GNUNET-GTK",
849 "DISABLE-PREVIEWS",
850 GNUNET_NO))
851 {
852 renderer = gtk_cell_renderer_pixbuf_new ();
853 col = gtk_tree_view_insert_column_with_attributes (list->treeview,
854 -1,
855 _("Preview"),
856 renderer,
857 "pixbuf",
858 SEARCH_PIXBUF, NULL);
859 column = gtk_tree_view_get_column (list->treeview, col - 1);
860 gtk_tree_view_column_set_resizable (column, TRUE);
861 gtk_tree_view_column_set_reorderable (column, TRUE);
862 gtk_tree_view_column_set_resizable (column, TRUE);
863 }
864
865 renderer = gtk_cell_renderer_text_new ();
866 col = gtk_tree_view_insert_column_with_attributes (list->treeview,
867 -1,
868 _("Meta-data"),
869 renderer,
870 "text", SEARCH_DESC,
871 NULL);
872 column = gtk_tree_view_get_column (list->treeview, col - 1);
873 g_object_set (G_OBJECT (renderer),
874 "wrap-width", 60,
875 "width-chars", 60,
876 "wrap-mode", PANGO_WRAP_WORD_CHAR,
877 "ellipsize", PANGO_ELLIPSIZE_END,
878 "ellipsize-set", TRUE, NULL);
879 gtk_tree_view_column_set_resizable (column, TRUE);
880 gtk_tree_view_column_set_clickable (column, TRUE);
881 gtk_tree_view_column_set_reorderable (column, TRUE);
882 gtk_tree_view_column_set_sort_column_id (column, SEARCH_DESC);
883
884 /* load label */
885 list->labelXML
886 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
887 "searchTabLabelWindow", PACKAGE_NAME);
888 GNUNET_GTK_connect_glade_with_plugins (list->labelXML);
889 list->tab_label
890 =
891 GNUNET_GTK_extract_main_widget_from_window (list->labelXML,
892 "searchTabLabelWindow");
893 /* process existing results */
894 for (i = 0; i < resultCount; i++)
895 fs_search_result_received (list, &results[i], uri);
896 if (resultCount == 0) /* otherwise already done! */
897 updateResultsCount (list);
898
899 /* insert new page into search notebook */
900 notebook
901 =
902 GTK_NOTEBOOK (glade_xml_get_widget
903 (GNUNET_GTK_get_main_glade_XML (), "downloadNotebook"));
904 pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
905 gtk_notebook_append_page (notebook, list->searchpage, list->tab_label);
906 gtk_notebook_set_current_page (notebook, pages);
907 gtk_widget_show (GTK_WIDGET (notebook)); /* may have been hidden! */
908
909 return list;
910}
911
912/**
913 * Recursively free the (internal) model data fields
914 * (uri and meta) from the search tree model.
915 */
916static void
917freeIterSubtree (GtkTreeModel * tree, GtkTreeIter * iter)
918{
919 GtkTreeIter child;
920 struct GNUNET_ECRS_URI *uri;
921 struct GNUNET_MetaData *meta;
922
923 do
924 {
925 uri = NULL;
926 meta = NULL;
927 gtk_tree_model_get (tree,
928 iter, SEARCH_URI, &uri, SEARCH_META, &meta, -1);
929 if (uri != NULL)
930 GNUNET_ECRS_uri_destroy (uri);
931 if (meta != NULL)
932 GNUNET_meta_data_destroy (meta);
933 gtk_tree_store_set (GTK_TREE_STORE (tree),
934 iter, SEARCH_URI, NULL, SEARCH_META, NULL, -1);
935 if (gtk_tree_model_iter_children (tree, &child, iter))
936 freeIterSubtree (tree, &child);
937 }
938 while (gtk_tree_model_iter_next (tree, iter));
939}
940
941/**
942 * FSUI event: a search was aborted.
943 * Update views accordingly.
944 */
945void
946fs_search_aborted (SearchList * list)
947{
948 gtk_widget_show (glade_xml_get_widget (list->searchXML,
949 "searchResumeButton"));
950 gtk_widget_show (glade_xml_get_widget (list->searchXML,
951 "searchPauseButton"));
952}
953
954void
955fs_search_paused (SearchList * list)
956{
957 /* nothing to be done */
958}
959
960void
961fs_search_restarted (SearchList * list)
962{
963 /* nothing to be done */
964}
965
966/**
967 * FSUI event: a search was stopped.
968 * Remove the respective tab.
969 */
970void
971fs_search_stopped (SearchList * list)
972{
973 GtkTreeIter iter;
974 GtkNotebook *notebook;
975 SearchList *prev;
976 DownloadList *downloads;
977 int index;
978 int i;
979
980 /* remove from linked list */
981 if (search_head == list)
982 {
983 search_head = search_head->next;
984 }
985 else
986 {
987 prev = search_head;
988 while (prev->next != list)
989 prev = prev->next;
990 prev->next = list->next;
991 }
992
993 /* remove links from download views */
994 downloads = download_head;
995 while (downloads != NULL)
996 {
997 if (downloads->searchList == list)
998 {
999 gtk_tree_row_reference_free (downloads->searchViewRowReference);
1000 downloads->searchViewRowReference = NULL;
1001 downloads->searchList = NULL;
1002 }
1003 downloads = downloads->next;
1004 }
1005
1006 /* remove page from notebook */
1007 notebook
1008 =
1009 GTK_NOTEBOOK (glade_xml_get_widget
1010 (GNUNET_GTK_get_main_glade_XML (), "downloadNotebook"));
1011 index = -1;
1012 for (i = gtk_notebook_get_n_pages (notebook) - 1; i >= 0; i--)
1013 if (list->searchpage == gtk_notebook_get_nth_page (notebook, i))
1014 index = i;
1015 GNUNET_GE_BREAK (ectx, index != -1);
1016 gtk_notebook_remove_page (notebook, index);
1017 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list->tree), &iter))
1018 freeIterSubtree (GTK_TREE_MODEL (list->tree), &iter);
1019 /* free list state itself */
1020 UNREF (list->searchXML);
1021 UNREF (list->labelXML);
1022 GNUNET_free (list->searchString);
1023 GNUNET_ECRS_uri_destroy (list->uri);
1024 GNUNET_free (list);
1025}
1026
1027/* ****************** User event handling ************* */
1028
1029
1030/**
1031 * The user has edited the search entry.
1032 * Update search button status.
1033 */
1034void
1035on_fssearchKeywordComboBoxEntry_changed_fs (gpointer dummy2,
1036 GtkWidget * searchEntry)
1037{
1038 const char *searchString;
1039 GtkWidget *searchButton;
1040
1041 searchString = getEntryLineValue (GNUNET_GTK_get_main_glade_XML (),
1042 "fssearchKeywordComboBoxEntry");
1043 searchButton =
1044 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (), "fssearchbutton");
1045 gtk_widget_set_sensitive (searchButton, strlen (searchString) > 0);
1046}
1047
1048typedef struct
1049{
1050 unsigned int anonymity;
1051 struct GNUNET_ECRS_URI *uri;
1052} FSSS;
1053
1054static void *
1055search_start_helper (void *cls)
1056{
1057 FSSS *fsss = cls;
1058 GNUNET_FSUI_search_start (ctx, fsss->anonymity, fsss->uri);
1059 return NULL;
1060}
1061
1062/**
1063 * The user has clicked the "SEARCH" button.
1064 * Initiate a search.
1065 */
1066void
1067on_fssearchbutton_clicked_fs (gpointer dummy2, GtkWidget * searchButton)
1068{
1069 FSSS fsss;
1070 const char *searchString;
1071 gint pages;
1072 gint i;
1073 SearchList *list;
1074 GtkTreeIter iter;
1075 GtkComboBox *searchKeywordGtkCB;
1076 GtkWidget *searchNamespaceGtkCB;
1077 GtkNotebook *notebook;
1078
1079 searchString = getEntryLineValue (GNUNET_GTK_get_main_glade_XML (),
1080 "fssearchKeywordComboBoxEntry");
1081 if ((searchString == NULL) || (strlen (searchString) == 0))
1082 {
1083 GNUNET_GE_LOG (ectx,
1084 GNUNET_GE_ERROR | GNUNET_GE_USER | GNUNET_GE_IMMEDIATE,
1085 _("Need a keyword to search!\n"));
1086 return;
1087 }
1088 /* add the keyword to the list of keywords that have
1089 been used so far */
1090 searchKeywordGtkCB
1091 = GTK_COMBO_BOX (glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
1092 "fssearchKeywordComboBoxEntry"));
1093 i = gtk_combo_box_get_active (searchKeywordGtkCB);
1094 if (i == -1)
1095 {
1096 GtkListStore *model;
1097
1098 model = GTK_LIST_STORE (gtk_combo_box_get_model (searchKeywordGtkCB));
1099 gtk_list_store_prepend (model, &iter);
1100 gtk_list_store_set (model, &iter, 0, searchString, -1);
1101 }
1102 fsss.uri = NULL;
1103 /* check for namespace search */
1104 searchNamespaceGtkCB
1105 =
1106 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
1107 "searchNamespaceComboBoxEntry");
1108 if (TRUE ==
1109 gtk_combo_box_get_active_iter (GTK_COMBO_BOX (searchNamespaceGtkCB),
1110 &iter))
1111 {
1112 char *descStr;
1113 char *nsName;
1114
1115 nsName = NULL;
1116 descStr = NULL;
1117 gtk_tree_model_get (gtk_combo_box_get_model
1118 (GTK_COMBO_BOX (searchNamespaceGtkCB)), &iter,
1119 NS_SEARCH_DESCRIPTION, &descStr, NS_SEARCH_NAME,
1120 &nsName, -1);
1121
1122 if ((descStr != NULL) &&
1123 ( (0 == strcmp (descStr, "")) ||
1124 (0 == strcmp (descStr, _("globally")))))
1125 {
1126 nsName = NULL;
1127 }
1128 else
1129 {
1130 if ((descStr == NULL) && (nsName != NULL))
1131 descStr = GNUNET_strdup (nsName);
1132 }
1133 if (nsName != NULL)
1134 {
1135 char *ustring;
1136 GNUNET_EncName enc;
1137 GNUNET_HashCode nsid;
1138
1139 GNUNET_GE_ASSERT (NULL,
1140 GNUNET_OK ==
1141 GNUNET_pseudonym_name_to_id (ectx, cfg,
1142 nsName, &nsid));
1143 GNUNET_hash_to_enc (&nsid, &enc);
1144
1145 ustring =
1146 GNUNET_malloc (strlen (searchString) + sizeof (GNUNET_EncName) +
1147 strlen (GNUNET_ECRS_URI_PREFIX) +
1148 strlen (GNUNET_ECRS_SUBSPACE_INFIX) + 10);
1149 strcpy (ustring, GNUNET_ECRS_URI_PREFIX);
1150 strcat (ustring, GNUNET_ECRS_SUBSPACE_INFIX);
1151 strcat (ustring, (const char *) &enc);
1152 strcat (ustring, "/");
1153 strcat (ustring, searchString);
1154 fsss.uri = GNUNET_ECRS_string_to_uri (ectx, ustring);
1155 if (fsss.uri == NULL)
1156 {
1157 GNUNET_GE_LOG (ectx,
1158 GNUNET_GE_ERROR | GNUNET_GE_BULK |
1159 GNUNET_GE_USER,
1160 _("Failed to create namespace URI from `%s'.\n"),
1161 ustring);
1162 }
1163 GNUNET_free (ustring);
1164 }
1165 if (descStr != NULL)
1166 free (descStr);
1167 if (nsName != NULL)
1168 free (nsName);
1169 }
1170 else
1171 {
1172 /* FIXME: may still be namespace-search
1173 -- where user manually entered NS name*/
1174 }
1175 if (fsss.uri == NULL)
1176 fsss.uri = GNUNET_ECRS_keyword_string_to_uri (ectx, searchString);
1177 if (fsss.uri == NULL)
1178 {
1179 GNUNET_GE_BREAK (ectx, 0);
1180 return;
1181 }
1182 /* check if search is already running */
1183 notebook
1184 =
1185 GTK_NOTEBOOK (glade_xml_get_widget
1186 (GNUNET_GTK_get_main_glade_XML (), "downloadNotebook"));
1187 pages = gtk_notebook_get_n_pages (notebook);
1188 list = search_head;
1189 while (list != NULL)
1190 {
1191 if (GNUNET_ECRS_uri_test_equal (list->uri, fsss.uri))
1192 {
1193 for (i = 0; i < pages; i++)
1194 {
1195 if (gtk_notebook_get_nth_page (notebook, i) == list->searchpage)
1196 {
1197 gtk_notebook_set_current_page (notebook, i);
1198 GNUNET_ECRS_uri_destroy (fsss.uri);
1199 return;
1200 }
1201 }
1202 GNUNET_GE_BREAK (ectx, 0);
1203 }
1204 list = list->next;
1205 }
1206 fsss.anonymity = getSpinButtonValue (GNUNET_GTK_get_main_glade_XML (),
1207 "searchAnonymitySelectionSpinButton");
1208 GNUNET_GTK_run_with_save_calls (search_start_helper, &fsss);
1209 GNUNET_ECRS_uri_destroy (fsss.uri);
1210}
1211
1212struct FCBC
1213{
1214 int (*method) (struct GNUNET_FSUI_SearchList * list);
1215 struct GNUNET_FSUI_SearchList *argument;
1216};
1217
1218static void *
1219fsui_callback (void *cls)
1220{
1221 struct FCBC *fcbc = cls;
1222 fcbc->method (fcbc->argument);
1223 return NULL;
1224}
1225
1226/**
1227 * This method is called when the user clicks on either
1228 * the "CLOSE" button (at the bottom of the search page)
1229 * or on the "CANCEL (X)" button in the TAB of the
1230 * search notebook. Note that "searchPage" can thus
1231 * either refer to the main page in the tab or to the
1232 * main entry of the tab label.
1233 */
1234void
1235on_closeSearchButton_clicked_fs (GtkWidget * searchPage,
1236 GtkWidget * closeButton)
1237{
1238 SearchList *list;
1239 struct FCBC fcbc;
1240
1241 list = search_head;
1242 while (list != NULL)
1243 {
1244 if ((list->searchpage == searchPage) || (list->tab_label == searchPage))
1245 break;
1246 list = list->next;
1247 }
1248 GNUNET_GE_ASSERT (ectx, list != NULL);
1249 if (list->fsui_list == NULL)
1250 {
1251 /* open directory or paused search;
1252 close directly */
1253 fs_search_stopped (list);
1254 }
1255 else
1256 {
1257 /* actual search - close via FSUI */
1258 fcbc.method = &GNUNET_FSUI_search_abort;
1259 fcbc.argument = list->fsui_list;
1260 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
1261 fcbc.method = &GNUNET_FSUI_search_stop;
1262 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
1263 }
1264}
1265
1266
1267/**
1268 * The pause button in a search results tab was clicked.
1269 */
1270void
1271on_searchPauseButton_clicked_fs (GtkWidget * searchPage,
1272 GtkWidget * pauseButton)
1273{
1274 SearchList *list;
1275 struct FCBC fcbc;
1276
1277 list = search_head;
1278 while (list != NULL)
1279 {
1280 if (list->searchpage == searchPage)
1281 break;
1282 list = list->next;
1283 }
1284 GNUNET_GE_ASSERT (ectx, list != NULL);
1285 gtk_widget_hide (pauseButton);
1286 gtk_widget_show (glade_xml_get_widget (list->searchXML,
1287 "searchResumeButton"));
1288 if (list->fsui_list != NULL)
1289 {
1290 fcbc.method = &GNUNET_FSUI_search_pause;
1291 fcbc.argument = list->fsui_list;
1292 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
1293 }
1294}
1295
1296/**
1297 * The resume button in a search results tab was clicked.
1298 */
1299void
1300on_searchResumeButton_clicked_fs (GtkWidget * searchPage,
1301 GtkWidget * resumeButton)
1302{
1303 SearchList *list;
1304 struct FCBC fcbc;
1305
1306 list = search_head;
1307 while (list != NULL)
1308 {
1309 if (list->searchpage == searchPage)
1310 break;
1311 list = list->next;
1312 }
1313 GNUNET_GE_ASSERT (ectx, list != NULL);
1314 gtk_widget_hide (resumeButton);
1315 gtk_widget_show (glade_xml_get_widget (list->searchXML,
1316 "searchPauseButton"));
1317 if (list->fsui_list != NULL)
1318 {
1319 fcbc.method = &GNUNET_FSUI_search_restart;
1320 fcbc.argument = list->fsui_list;
1321 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
1322 }
1323}
1324
1325/* end of search.c */
diff --git a/src/plugins/fs/search.h b/src/plugins/fs/search.h
deleted file mode 100644
index 3c7d26e7..00000000
--- a/src/plugins/fs/search.h
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2008 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/search.h
23 * @brief code for searching with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_SEARCH_H
28#define GTK_SEARCH_H
29
30#include <GNUnet/gnunet_ecrs_lib.h>
31#include <GNUnet/gnunet_fsui_lib.h>
32#include "fs.h"
33
34
35/**
36 * Add the given search result to the search
37 * tree at the specified position.
38 */
39void addEntryToSearchTree (SearchList * searchContext,
40 DownloadList * downloadParent,
41 const GNUNET_ECRS_FileInfo * info,
42 GtkTreeIter * iter);
43
44/**
45 * Add the given result to the model (search result
46 * list).
47 * @param info the information to add to the model
48 * @param uri the search URI
49 * @param path the tree path that selects where to add
50 * the information, NULL for top-level
51 */
52void fs_search_result_received (SearchList * searchContext,
53 const GNUNET_ECRS_FileInfo * info,
54 const struct GNUNET_ECRS_URI *uri);
55
56/**
57 * Update the applicability and availability rating
58 * for the given search result.
59 *
60 * @param info the search result (and metadata)
61 * @param availability_rank availability estimate
62 * @param applicability_rank relevance
63 */
64void fs_search_update (SearchList * searchContext,
65 const GNUNET_ECRS_FileInfo * info,
66 int availability_rank,
67 unsigned int availability_certainty,
68 unsigned int applicability_rank);
69
70/**
71 * A search has been started. Open tab.
72 *
73 * @return internal search context
74 */
75SearchList *fs_search_started (struct GNUNET_FSUI_SearchList *list,
76 const struct GNUNET_ECRS_URI *uri,
77 unsigned int anonymityLevel,
78 unsigned int resultCount,
79 const GNUNET_ECRS_FileInfo * results,
80 GNUNET_FSUI_State state);
81
82/**
83 * A search process has been aborted. Update display.
84 */
85void fs_search_aborted (SearchList * searchContext);
86
87/**
88 * A search process has been aborted. Update display.
89 */
90void fs_search_paused (SearchList * searchContext);
91
92/**
93 * A search process has been aborted. Update display.
94 */
95void fs_search_restarted (SearchList * searchContext);
96
97/**
98 * A search process has stopped. Clean up.
99 */
100void fs_search_stopped (SearchList * searchContext);
101
102#endif
diff --git a/src/plugins/fs/status.c b/src/plugins/fs/status.c
deleted file mode 100644
index aed88032..00000000
--- a/src/plugins/fs/status.c
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007, 2008 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/status.c
23 * @brief status codes for files
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include <GNUnet/gnunet_uritrack_lib.h>
29#include "status.h"
30
31
32
33const char *
34getColorCode (enum GNUNET_URITRACK_STATE state)
35{
36 if (state & (GNUNET_URITRACK_DIRECTORY_ADDED))
37 return "blue";
38 if (state & (GNUNET_URITRACK_INSERTED || GNUNET_URITRACK_INDEXED))
39 return "cyan";
40 if ((state & GNUNET_URITRACK_DOWNLOAD_STARTED) &&
41 (0 == (state &
42 (GNUNET_URITRACK_DOWNLOAD_COMPLETED |
43 GNUNET_URITRACK_DOWNLOAD_ABORTED))))
44 return "yellow";
45 if (state & GNUNET_URITRACK_DOWNLOAD_COMPLETED)
46 return "springgreen";
47 if (state & GNUNET_URITRACK_DOWNLOAD_ABORTED)
48 return "red";
49 if (state &
50 (GNUNET_URITRACK_SEARCH_RESULT | GNUNET_URITRACK_DIRECTORY_FOUND))
51 return "gray";
52 if (0 == state)
53 return "aquamarine";
54 return NULL;
55}
56
57
58const char *
59getStatusName (enum GNUNET_URITRACK_STATE state)
60{
61 if (state & (GNUNET_URITRACK_DIRECTORY_ADDED))
62 return _("added");
63 if (state & (GNUNET_URITRACK_INSERTED || GNUNET_URITRACK_INDEXED))
64 return _("shared");
65 if ((state & GNUNET_URITRACK_DOWNLOAD_STARTED) &&
66 (0 == (state &
67 (GNUNET_URITRACK_DOWNLOAD_COMPLETED |
68 GNUNET_URITRACK_DOWNLOAD_ABORTED))))
69 return _("started");
70 if (state & GNUNET_URITRACK_DOWNLOAD_COMPLETED)
71 return _("completed");
72 if (state & GNUNET_URITRACK_DOWNLOAD_ABORTED)
73 return _("aborted");
74 if (state &
75 (GNUNET_URITRACK_SEARCH_RESULT | GNUNET_URITRACK_DIRECTORY_FOUND))
76 return "";
77 if (0 == state)
78 return _("new");
79 return "";
80}
81
82GdkPixbuf *
83getStatusLogo (enum GNUNET_URITRACK_STATE state)
84{
85 if (state & (GNUNET_URITRACK_DIRECTORY_ADDED))
86 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
87 GTK_STOCK_ADD, 16, 0, (GError **) NULL);
88 if (state & (GNUNET_URITRACK_INSERTED || GNUNET_URITRACK_INDEXED))
89 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
90 GTK_STOCK_ADD, 16, 0, (GError **) NULL);
91 if ((state & GNUNET_URITRACK_DOWNLOAD_STARTED) &&
92 (0 == (state &
93 (GNUNET_URITRACK_DOWNLOAD_COMPLETED |
94 GNUNET_URITRACK_DOWNLOAD_ABORTED))))
95 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
96 GTK_STOCK_GO_DOWN, 16, 0,
97 (GError **) NULL);
98 if (state & GNUNET_URITRACK_DOWNLOAD_COMPLETED)
99 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
100 GTK_STOCK_APPLY, 16, 0,
101 (GError **) NULL);
102 if (state & GNUNET_URITRACK_DOWNLOAD_ABORTED)
103 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
104 GTK_STOCK_CANCEL, 16, 0,
105 (GError **) NULL);
106 if (0 == state)
107 return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
108 GTK_STOCK_NEW, 16, 0, (GError **) NULL);
109 return NULL;
110}
111
112
113/* end of status.c */
diff --git a/src/plugins/fs/status.h b/src/plugins/fs/status.h
deleted file mode 100644
index 4726a0c4..00000000
--- a/src/plugins/fs/status.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2007, 2008 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/status.h
23 * @brief status codes for files
24 * @author Christian Grothoff
25 */
26
27#ifndef FS_STATUS_H
28#define FS_STATUS_H
29
30#include "platform.h"
31#include <GNUnet/gnunet_uritrack_lib.h>
32#include "status.h"
33
34const char *getColorCode (enum GNUNET_URITRACK_STATE state);
35
36const char *getStatusName (enum GNUNET_URITRACK_STATE state);
37
38GdkPixbuf *getStatusLogo (enum GNUNET_URITRACK_STATE state);
39
40#endif
diff --git a/src/plugins/fs/upload.c b/src/plugins/fs/upload.c
deleted file mode 100644
index 82a8ca0c..00000000
--- a/src/plugins/fs/upload.c
+++ /dev/null
@@ -1,752 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005, 2006, 2008 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/upload.c
23 * @brief code for uploading with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunetgtk_common.h"
29#include "search.h"
30#include "upload.h"
31#include "fs.h"
32#include "meta.h"
33#include <extractor.h>
34
35#ifdef MINGW
36#include <shlobj.h>
37#ifndef BIF_NONEWFOLDERBUTTON
38#define BIF_NONEWFOLDERBUTTON 0x200
39#endif
40#endif
41
42/**
43 * XML tree for the meta-data dialog of upload.
44 * (there can only be one at a time;
45 * maybe NULL at times where there is no dialog)
46 */
47static GladeXML *metaXML;
48
49/* ************ FSUI event handlers ************ */
50
51void
52fs_upload_update (UploadList * list, unsigned long long completed,
53 unsigned long long total)
54{
55 GtkTreeIter iter;
56 GtkTreePath *path;
57 int progress;
58
59 list->total = total;
60 if (list->total != 0)
61 progress = 100 * completed / list->total;
62 else
63 progress = 100;
64 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
65 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &iter, path);
66 gtk_tree_path_free (path);
67 gtk_tree_store_set (upload_summary, &iter, UPLOAD_PROGRESS, progress, -1);
68}
69
70void
71fs_upload_complete (UploadList * list, struct GNUNET_ECRS_URI *uri)
72{
73 GtkTreeIter iter;
74 GtkTreePath *path;
75 char *us;
76
77 list->has_terminated = GNUNET_YES;
78 list->uri = GNUNET_ECRS_uri_duplicate (uri);
79 us = GNUNET_ECRS_uri_to_string (uri);
80 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
81 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &iter, path);
82 gtk_tree_path_free (path);
83 gtk_tree_store_set (upload_summary, &iter,
84 UPLOAD_URISTRING, us, UPLOAD_PROGRESS, 100, -1);
85 GNUNET_free (us);
86}
87
88void
89fs_upload_aborted (UploadList * list)
90{
91 GtkTreeIter iter;
92 GtkTreePath *path;
93
94 list->has_terminated = GNUNET_YES;
95 list->uri = NULL;
96 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
97 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &iter, path);
98 gtk_tree_path_free (path);
99 gtk_tree_store_set (upload_summary, &iter,
100 UPLOAD_URISTRING, _("Aborted."),
101 UPLOAD_PROGRESS, 0, -1);
102}
103
104void
105fs_upload_error (UploadList * list, const char *emsg)
106{
107 GtkTreeIter iter;
108 GtkTreePath *path;
109 char *us;
110 size_t len;
111
112 list->has_terminated = GNUNET_YES;
113 list->uri = NULL;
114 len = strlen (_("Error uploading file: `%s'")) + strlen (emsg) + 2;
115 us = GNUNET_malloc (len);
116 GNUNET_snprintf (us, len, _("Error uploading file: `%s'"), emsg);
117 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
118 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &iter, path);
119 gtk_tree_path_free (path);
120 gtk_tree_store_set (upload_summary, &iter,
121 UPLOAD_URISTRING, us, UPLOAD_PROGRESS, 0, -1);
122 GNUNET_free (us);
123}
124
125void
126fs_upload_stopped (UploadList * list)
127{
128 GtkTreeIter iter;
129 GtkTreePath *path;
130 UploadList *prev;
131
132 path = gtk_tree_row_reference_get_path (list->summaryViewRowReference);
133 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &iter, path);
134 gtk_tree_path_free (path);
135 gtk_tree_row_reference_free (list->summaryViewRowReference);
136 list->summaryViewRowReference = NULL;
137 gtk_tree_store_remove (upload_summary, &iter);
138 GNUNET_free (list->filename);
139 if (list->uri != NULL)
140 {
141 GNUNET_ECRS_uri_destroy (list->uri);
142 list->uri = NULL;
143 }
144 if (upload_head == list)
145 upload_head = list->next;
146 else
147 {
148 prev = upload_head;
149 while ((prev != NULL) && (prev->next != list))
150 prev = prev->next;
151 if (prev != NULL)
152 prev->next = list->next;
153 else
154 GNUNET_GE_BREAK (ectx, 0);
155 }
156 GNUNET_free (list);
157}
158
159UploadList *
160fs_upload_started (struct GNUNET_FSUI_UploadList *fsui,
161 UploadList * parent,
162 const char *filename,
163 const struct GNUNET_ECRS_URI *uri,
164 unsigned long long total,
165 unsigned long long completed, GNUNET_FSUI_State state)
166{
167 UploadList *ret;
168 GtkTreeIter iter;
169 GtkTreePath *path;
170 int progress;
171 GtkTreeIter par;
172 char *u;
173
174 ret = GNUNET_malloc (sizeof (UploadList));
175 memset (ret, 0, sizeof (UploadList));
176 ret->filename = GNUNET_strdup (filename);
177 ret->fsui_list = fsui;
178 ret->total = total;
179 ret->is_top = parent == NULL;
180 if ((parent != NULL) &&
181 (NULL !=
182 (path =
183 gtk_tree_row_reference_get_path (parent->summaryViewRowReference))))
184 {
185 gtk_tree_model_get_iter (GTK_TREE_MODEL (upload_summary), &par, path);
186 gtk_tree_path_free (path);
187 gtk_tree_store_append (upload_summary, &iter, &par);
188 }
189 else
190 {
191 gtk_tree_store_append (upload_summary, &iter, NULL);
192 }
193 if ((total != 0) && (state != GNUNET_FSUI_COMPLETED_JOINED))
194 progress = 100 * completed / total;
195 else
196 progress = 100;
197 if (uri != NULL)
198 u = GNUNET_ECRS_uri_to_string (uri);
199 else
200 u = GNUNET_strdup ("");
201 gtk_tree_store_set (upload_summary, &iter, UPLOAD_FILENAME, filename,
202 UPLOAD_PROGRESS, progress, UPLOAD_URISTRING, u,
203 UPLOAD_INTERNAL, ret, -1);
204 GNUNET_free (u);
205 path = gtk_tree_model_get_path (GTK_TREE_MODEL (upload_summary), &iter);
206 ret->summaryViewRowReference
207 = gtk_tree_row_reference_new (GTK_TREE_MODEL (upload_summary), path);
208 gtk_tree_path_free (path);
209 ret->has_terminated = ((state != GNUNET_FSUI_ACTIVE)
210 && (state != GNUNET_FSUI_PENDING));
211
212 ret->next = upload_head;
213 upload_head = ret;
214 return ret;
215}
216
217/* *************** user upload event handling ************** */
218
219
220void
221on_selectAlternativePreviewButton_selection_changed_fs (GtkWidget * preview,
222 GtkWidget *
223 fileChooser)
224{
225 char *fn;
226
227 fn = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser));
228 if (fn == NULL)
229 {
230 gtk_image_set_from_pixbuf (GTK_IMAGE (preview), NULL);
231 }
232 else
233 {
234 GdkPixbuf *buf;
235
236 buf = gdk_pixbuf_new_from_file (fn, NULL);
237 gtk_image_set_from_pixbuf (GTK_IMAGE (preview), buf);
238 g_object_unref (buf);
239 free (fn);
240 }
241}
242
243void
244on_metaDataDialogKeywordAddButton_clicked_fs (gpointer dummy,
245 GtkWidget * button)
246{
247 handleKeywordListUpdate (metaXML,
248 "fileInformationKeywordEntry",
249 "metaDataDialogKeywordList");
250}
251
252void
253on_metaDataDialogMetaDataAddButton_clicked_fs (gpointer dummy,
254 GtkWidget * button)
255{
256 handleMetaDataListUpdate (metaXML,
257 "metaDataDialogMetaTypeComboBox",
258 "metaDataDialogValueEntry",
259 "metaDataDialogMetaDataList");
260}
261
262void
263on_fileInformationKeywordEntry_activate_fs (GtkWidget *
264 fileInformationKeywordEntry,
265 gpointer dummy)
266{
267 const char *input;
268
269 input = gtk_entry_get_text (GTK_ENTRY (fileInformationKeywordEntry));
270 if ((input == NULL) || (strlen (input) == 0))
271 return;
272 handleKeywordListUpdate (metaXML,
273 "fileInformationKeywordEntry",
274 "metaDataDialogKeywordList");
275}
276
277void
278on_metaDataDialogValueEntry_activate_fs (GtkWidget * metaDataDialogValueEntry,
279 gpointer dummy)
280{
281 const char *input;
282
283 input = gtk_entry_get_text (GTK_ENTRY (metaDataDialogValueEntry));
284 if ((input == NULL) || (strlen (input) == 0))
285 return;
286 handleMetaDataListUpdate (metaXML,
287 "metaDataDialogMetaTypeComboBox",
288 "metaDataDialogValueEntry",
289 "metaDataDialogMetaDataList");
290}
291
292
293void
294on_metaDataDialogKeywordRemoveButton_clicked_fs (gpointer dummy,
295 GtkWidget * button)
296{
297 handleListRemove (metaXML, "metaDataDialogKeywordList");
298}
299
300void
301on_metaDataDialogMetaDataRemoveButton_clicked_fs (gpointer dummy,
302 GtkWidget * button)
303{
304 handleListRemove (metaXML, "metaDataDialogMetaDataList");
305}
306
307/**
308 * The selection of the keyword list changed.
309 * Update button status.
310 */
311void
312on_keyword_list_selection_changed (gpointer signal, gpointer cls)
313{
314 GtkTreeSelection *selection;
315 GtkWidget *button;
316
317 selection =
318 gtk_tree_view_get_selection (GTK_TREE_VIEW
319 (glade_xml_get_widget
320 (metaXML, "metaDataDialogKeywordList")));
321 button =
322 glade_xml_get_widget (metaXML, "metaDataDialogKeywordRemoveButton");
323 gtk_widget_set_sensitive (button,
324 gtk_tree_selection_count_selected_rows (selection)
325 > 0);
326}
327
328/**
329 * The selection of the metadata list changed.
330 * Update button status.
331 */
332void
333on_metadata_list_selection_changed (gpointer signal, gpointer cls)
334{
335 GtkTreeSelection *selection;
336 GtkWidget *button;
337
338 selection =
339 gtk_tree_view_get_selection (GTK_TREE_VIEW
340 (glade_xml_get_widget
341 (metaXML, "metaDataDialogMetaDataList")));
342 button =
343 glade_xml_get_widget (metaXML, "metaDataDialogMetaDataRemoveButton");
344 gtk_widget_set_sensitive (button,
345 gtk_tree_selection_count_selected_rows (selection)
346 > 0);
347}
348
349/**
350 * The user has edited the metadata entry.
351 * Update add button status.
352 */
353void
354on_metaDataDialogValueEntry_changed_fs (gpointer dummy2,
355 GtkWidget * searchEntry)
356{
357 const char *input;
358 GtkWidget *button;
359
360 input = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (metaXML,
361 "metaDataDialogValueEntry")));
362 if (input == NULL)
363 return;
364 button = glade_xml_get_widget (metaXML, "metaDataDialogMetaDataAddButton");
365 gtk_widget_set_sensitive (button, strlen (input) > 0);
366}
367
368/**
369 * The user has edited the keyword entry.
370 * Update add button status.
371 */
372void
373on_fileInformationKeywordEntry_changed_fs (gpointer dummy2,
374 GtkWidget * searchEntry)
375{
376 const char *input;
377 GtkWidget *button;
378
379 input = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (metaXML,
380 "fileInformationKeywordEntry")));
381 if (input == NULL)
382 return;
383 button = glade_xml_get_widget (metaXML, "metaDataDialogKeywordAddButton");
384 gtk_widget_set_sensitive (button, strlen (input) > 0);
385}
386
387typedef struct
388{
389 char *filename;
390 unsigned int anonymity;
391 unsigned int priority;
392 int index;
393 int extract;
394 int deep_index;
395 GNUNET_CronTime expire;
396 struct GNUNET_MetaData *meta;
397 struct GNUNET_ECRS_URI *gkeywordURI;
398 struct GNUNET_ECRS_URI *keywordURI;
399} FSUC;
400
401static void *
402start_upload_helper (void *cls)
403{
404 FSUC *fsuc = cls;
405
406 GNUNET_FSUI_upload_start (ctx,
407 fsuc->filename,
408 (GNUNET_FSUI_DirectoryScanCallback) &
409 GNUNET_disk_directory_scan, ectx, fsuc->anonymity,
410 fsuc->priority, fsuc->index, fsuc->extract,
411 fsuc->deep_index, fsuc->expire, fsuc->meta,
412 fsuc->gkeywordURI, fsuc->keywordURI);
413 return NULL;
414}
415
416void
417on_fsinsertuploadbutton_clicked_fs (gpointer dummy, GtkWidget * uploadButton)
418{
419 FSUC fsuc;
420 const char *filename;
421 const char *filenamerest;
422 GtkWidget *dialog;
423 EXTRACTOR_ExtractorList *extractors;
424 char *config;
425 struct GNUNET_MetaData *meta;
426 struct GNUNET_ECRS_URI *keywordURI;
427
428 extractors = EXTRACTOR_loadDefaultLibraries ();
429 config = NULL;
430 GNUNET_GC_get_configuration_value_string (cfg, "FS", "EXTRACTORS", "",
431 &config);
432 if (strlen (config) > 0)
433 extractors = EXTRACTOR_loadConfigLibraries (extractors, config);
434 GNUNET_free (config);
435 filename =
436 getEntryLineValue (GNUNET_GTK_get_main_glade_XML (),
437 "uploadFilenameComboBoxEntry");
438 metaXML =
439 glade_xml_new (GNUNET_GTK_get_glade_filename (), "metaDataDialog",
440 PACKAGE_NAME);
441 GNUNET_GTK_connect_glade_with_plugins (metaXML);
442 dialog = glade_xml_get_widget (metaXML, "metaDataDialog");
443 meta = GNUNET_meta_data_create ();
444 GNUNET_meta_data_extract_from_file (ectx, meta, filename, extractors);
445 EXTRACTOR_removeAll (extractors);
446 filenamerest = &filename[strlen (filename) - 1];
447 while ((filenamerest > filename) && (filenamerest[-1] != DIR_SEPARATOR))
448 filenamerest--;
449 GNUNET_meta_data_insert (meta, EXTRACTOR_FILENAME, filenamerest);
450 keywordURI = GNUNET_meta_data_to_uri (meta);
451 while (GNUNET_OK == GNUNET_meta_data_delete (meta, EXTRACTOR_SPLIT, NULL));
452 while (GNUNET_OK ==
453 GNUNET_meta_data_delete (meta, EXTRACTOR_LOWERCASE, NULL));
454 createMetaDataListTreeView (metaXML,
455 "metaDataDialogMetaDataList",
456 "previewImage", meta);
457 GNUNET_meta_data_destroy (meta);
458 createKeywordListTreeView (metaXML,
459 "metaDataDialogKeywordList", keywordURI);
460 GNUNET_ECRS_uri_destroy (keywordURI);
461 createMetaTypeComboBox (metaXML, "metaDataDialogMetaTypeComboBox");
462 g_signal_connect_data (gtk_tree_view_get_selection
463 (GTK_TREE_VIEW
464 (glade_xml_get_widget
465 (metaXML, "metaDataDialogKeywordList"))),
466 "changed",
467 G_CALLBACK (&on_keyword_list_selection_changed),
468 NULL, NULL, 0);
469 g_signal_connect_data (gtk_tree_view_get_selection
470 (GTK_TREE_VIEW
471 (glade_xml_get_widget
472 (metaXML, "metaDataDialogMetaDataList"))),
473 "changed",
474 G_CALLBACK (&on_metadata_list_selection_changed),
475 NULL, NULL, 0);
476 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
477 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_CANCEL)
478 {
479 fsuc.anonymity = getSpinButtonValue (GNUNET_GTK_get_main_glade_XML (),
480 "uploadAnonymityLevelSpinButton");
481 fsuc.priority = getSpinButtonValue (GNUNET_GTK_get_main_glade_XML (),
482 "contentPrioritySpinButton");
483 fsuc.index =
484 getToggleButtonValue (GNUNET_GTK_get_main_glade_XML (),
485 "indexbutton");
486 fsuc.extract =
487 getToggleButtonValue (GNUNET_GTK_get_main_glade_XML (),
488 "doExtractCheckButton");
489 fsuc.deep_index =
490 getToggleButtonValue (GNUNET_GTK_get_main_glade_XML (),
491 "deepIndexCheckButton");
492 fsuc.expire = GNUNET_get_time () + 2 * GNUNET_CRON_YEARS;
493 fsuc.meta = getMetaDataFromList (metaXML,
494 "metaDataDialogMetaDataList",
495 "previewImage");
496 fsuc.keywordURI = getKeywordURIFromList (metaXML,
497 "metaDataDialogKeywordList");
498 fsuc.gkeywordURI = GNUNET_ECRS_string_to_uri (ectx,
499 GNUNET_ECRS_URI_PREFIX
500 GNUNET_ECRS_SEARCH_INFIX);
501 fsuc.filename = GNUNET_strdup (filename);
502 GNUNET_GTK_run_with_save_calls (&start_upload_helper, &fsuc);
503 GNUNET_free (fsuc.filename);
504 GNUNET_meta_data_destroy (fsuc.meta);
505 if (fsuc.gkeywordURI != NULL)
506 GNUNET_ECRS_uri_destroy (fsuc.gkeywordURI);
507 if (fsuc.keywordURI != NULL)
508 GNUNET_ECRS_uri_destroy (fsuc.keywordURI);
509 }
510 gtk_widget_destroy (dialog);
511 UNREF (metaXML);
512 metaXML = NULL;
513}
514
515#ifndef MINGW
516static char *
517selectFile (const char *oldfilename)
518{
519 GladeXML *uploadXML;
520 GtkFileChooser *dialog;
521 char *ret;
522
523 uploadXML
524 = glade_xml_new (GNUNET_GTK_get_glade_filename (),
525 "uploadfilechooserdialog", PACKAGE_NAME);
526 GNUNET_GTK_connect_glade_with_plugins (uploadXML);
527 dialog = GTK_FILE_CHOOSER (glade_xml_get_widget (uploadXML,
528 "uploadfilechooserdialog"));
529 gtk_file_chooser_set_filename (dialog, oldfilename);
530 if (getToggleButtonValue
531 (GNUNET_GTK_get_main_glade_XML (), "scopeRecursiveButton"))
532 gtk_file_chooser_set_action (dialog,
533 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
534 if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_CANCEL)
535 ret = gtk_file_chooser_get_filename (dialog);
536 else
537 ret = NULL;
538 gtk_widget_destroy (GTK_WIDGET (dialog));
539 UNREF (uploadXML);
540 return ret;
541}
542
543#else /* MINGW */
544
545static char *
546selectFile (const char *oldfilename)
547{
548 if (getToggleButtonValue
549 (GNUNET_GTK_get_main_glade_XML (), "scopeFileOnlyButton"))
550 return plibc_ChooseFile (_("Choose the file you want to publish."),
551 OFN_FILEMUSTEXIST | OFN_SHAREAWARE);
552 return plibc_ChooseDir (_("Choose the directory you want to publish."),
553 BIF_USENEWUI | BIF_SHAREABLE |
554 BIF_NONEWFOLDERBUTTON);
555}
556#endif /* MINGW */
557
558void
559on_mainFileSharingInsertBrowseButton_clicked_fs (GtkWidget * browseButton,
560 gpointer dummy)
561{
562 char *filename;
563 char *ofn;
564 const char *oldfilename;
565 GtkWidget *uploadLine;
566 GtkEntry *entry;
567 GtkListStore *model;
568 GtkTreeIter iter;
569
570 uploadLine = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
571 "uploadFilenameComboBoxEntry");
572 entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (uploadLine)));
573 oldfilename = gtk_entry_get_text (entry);
574 if (oldfilename == NULL)
575 oldfilename = getenv ("PWD");
576 if (oldfilename == NULL)
577 oldfilename = getenv ("HOME");
578 if (oldfilename == NULL)
579 oldfilename = "/";
580 ofn = GNUNET_expand_file_name (ectx, oldfilename);
581 filename = selectFile (ofn);
582 GNUNET_free (ofn);
583 if (NULL == filename)
584 return;
585 gtk_entry_set_text (entry, filename);
586 model =
587 GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (uploadLine)));
588 gtk_list_store_prepend (model, &iter);
589 gtk_list_store_set (model, &iter, 0, filename, -1);
590 free (filename);
591}
592
593struct FCBC
594{
595 int (*method) (struct GNUNET_FSUI_UploadList * list);
596 struct GNUNET_FSUI_UploadList *argument;
597};
598
599static void *
600fsui_callback (void *cls)
601{
602 struct FCBC *fcbc = cls;
603 fcbc->method (fcbc->argument);
604 return NULL;
605}
606
607static void
608clearCompletedUploadCallback (GtkTreeModel * model,
609 GtkTreePath * path,
610 GtkTreeIter * iter, gpointer unused)
611{
612 UploadList *ul;
613 struct FCBC fcbc;
614
615 GNUNET_GE_ASSERT (ectx, model == GTK_TREE_MODEL (upload_summary));
616 gtk_tree_model_get (model, iter, UPLOAD_INTERNAL, &ul, -1);
617 if ((ul->has_terminated) && (ul->is_top))
618 {
619 fcbc.method = &GNUNET_FSUI_upload_stop;
620 fcbc.argument = ul->fsui_list;
621 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
622 }
623}
624
625/**
626 * The user has edited the search entry.
627 * Update search button status.
628 */
629void
630on_uploadFilenameComboBoxEntry_changed_fs (gpointer dummy2,
631 GtkWidget * searchEntry)
632{
633 const char *filename;
634 GtkWidget *uploadButton;
635 struct stat buf;
636 int ok;
637 GtkWidget *toggle;
638
639 filename =
640 getEntryLineValue (GNUNET_GTK_get_main_glade_XML (),
641 "uploadFilenameComboBoxEntry");
642 ok = (0 == stat (filename, &buf));
643 if (ok)
644 ok = (0 == ACCESS (filename, R_OK));
645 if (ok)
646 {
647 if (S_ISDIR (buf.st_mode))
648 {
649 toggle = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
650 "scopeRecursiveButton");
651 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), 1);
652 }
653 else
654 {
655 toggle = glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
656 "scopeFileOnlyButton");
657 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), 1);
658 }
659 }
660 uploadButton =
661 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
662 "fsinsertuploadbutton");
663 gtk_widget_set_sensitive (uploadButton, ok);
664}
665
666void
667on_clearCompletedUploads_clicked_fs (void *unused, GtkWidget * clearButton)
668{
669 GNUNET_GTK_tree_model_foreach (GTK_TREE_MODEL (upload_summary),
670 &clearCompletedUploadCallback, NULL);
671}
672
673static void
674do_copy_uri (GtkTreeModel * model,
675 GtkTreePath * path, GtkTreeIter * iter, gpointer unused)
676{
677 char *str;
678 GtkClipboard *clip;
679
680 gtk_tree_model_get (model, iter, UPLOAD_URISTRING, &str, -1);
681 clip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
682 gtk_clipboard_set_text (clip, str, strlen (str));
683 GNUNET_free (str);
684}
685
686int
687on_upload_copy_uri_activate_fs (void *dummy1, GtkWidget * dummy2)
688{
689 GtkTreeSelection *selection;
690 GtkWidget *uploadList;
691
692 uploadList =
693 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
694 "activeUploadsList");
695 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (uploadList));
696 GNUNET_GTK_tree_selection_selected_foreach (selection, &do_copy_uri, NULL);
697 return FALSE;
698}
699
700static void
701fsuiCallUploadCallback (GtkTreeModel * model,
702 GtkTreePath * path,
703 GtkTreeIter * iter, gpointer fsui_call)
704{
705 UploadList *ul;
706 struct FCBC fcbc;
707
708 GNUNET_GE_ASSERT (ectx, model == GTK_TREE_MODEL (upload_summary));
709 gtk_tree_model_get (model, iter, UPLOAD_INTERNAL, &ul, -1);
710 fcbc.method = fsui_call;
711 fcbc.argument = ul->fsui_list;
712 GNUNET_GTK_run_with_save_calls (&fsui_callback, &fcbc);
713}
714
715void
716on_stopUpload_clicked_fs (void *unused, GtkWidget * clearButton)
717{
718 GtkTreeSelection *selection;
719 GtkWidget *uploadList;
720
721 uploadList =
722 glade_xml_get_widget (GNUNET_GTK_get_main_glade_XML (),
723 "activeUploadsList");
724 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (uploadList));
725 GNUNET_GTK_tree_selection_selected_foreach
726 (selection, &fsuiCallUploadCallback, &GNUNET_FSUI_upload_abort);
727}
728
729/**
730 * Right-click on the active uploads list
731 */
732gboolean
733on_activeUploadsList_button_press_fs (GtkWidget * treeview,
734 GdkEventButton * event_button,
735 gpointer dummy)
736{
737 GtkWidget *menu;
738 GladeXML *contextMenuXML;
739
740 contextMenuXML =
741 glade_xml_new (GNUNET_GTK_get_glade_filename (),
742 "uploadsContextMenu", PACKAGE_NAME);
743 GNUNET_GTK_connect_glade_with_plugins (contextMenuXML);
744 menu = glade_xml_get_widget (contextMenuXML, "uploadsContextMenu");
745 if (event_button->button == 3)
746 gtk_menu_popup (GTK_MENU (menu),
747 NULL, NULL, NULL, NULL,
748 event_button->button, event_button->time);
749 return FALSE;
750}
751
752/* end of upload.c */
diff --git a/src/plugins/fs/upload.h b/src/plugins/fs/upload.h
deleted file mode 100644
index 888dd807..00000000
--- a/src/plugins/fs/upload.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2005 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/upload.h
23 * @brief code for uploading with gnunet-gtk
24 * @author Christian Grothoff
25 */
26
27#ifndef GTK_UPLOAD_H
28#define GTK_UPLOAD_H
29
30#include "fs.h"
31
32void fs_upload_update (UploadList * list, unsigned long long completed,
33 unsigned long long total);
34
35void fs_upload_complete (UploadList * list, struct GNUNET_ECRS_URI *uri);
36
37void fs_upload_error (UploadList * list, const char *emsg);
38
39void fs_upload_aborted (UploadList * list);
40
41void fs_upload_stopped (UploadList * list);
42
43/**
44 * @param uri NULL if upload is not yet finished
45 */
46UploadList *fs_upload_started (struct GNUNET_FSUI_UploadList *fsui,
47 UploadList * parent,
48 const char *filename,
49 const struct GNUNET_ECRS_URI *uri,
50 unsigned long long total,
51 unsigned long long completed,
52 GNUNET_FSUI_State state);
53
54#endif