aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk-download.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk-download.c')
-rw-r--r--src/fs/gnunet-fs-gtk-download.c162
1 files changed, 115 insertions, 47 deletions
diff --git a/src/fs/gnunet-fs-gtk-download.c b/src/fs/gnunet-fs-gtk-download.c
index 233f3fcc..8781de8b 100644
--- a/src/fs/gnunet-fs-gtk-download.c
+++ b/src/fs/gnunet-fs-gtk-download.c
@@ -20,23 +20,49 @@
20 20
21/** 21/**
22 * @file src/fs/gnunet-fs-gtk-download.c 22 * @file src/fs/gnunet-fs-gtk-download.c
23 * @brief functions for downloading 23 * @brief functions for managing the 'save as' dialog
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "gnunet-fs-gtk-download.h" 26#include "gnunet-fs-gtk-download.h"
27#include "gnunet-fs-gtk.h" 27#include "gnunet-fs-gtk.h"
28#include "gnunet-fs-gtk-event_handler.h" 28#include "gnunet-fs-gtk-event_handler.h"
29 29
30/**
31 * State for a 'save as' dialog of a download.
32 */
30struct DownloadAsDialogContext 33struct DownloadAsDialogContext
31{ 34{
35
36 /**
37 * Download context for which this dialog determines the
38 * filename (and other options).
39 */
40 struct DownloadContext *dc;
41
42 /**
43 * Builder for the dialog.
44 */
32 GtkBuilder *builder; 45 GtkBuilder *builder;
46
47 /**
48 * Main dialog object.
49 */
33 GtkWidget *dialog; 50 GtkWidget *dialog;
51
52 /**
53 * Final response code from the dialog.
54 */
34 gint response; 55 gint response;
35 struct DownloadContext *dc;
36}; 56};
37 57
38void 58
39GNUNET_GTK_save_as_dialog_free_download_context (struct DownloadContext *dc) 59/**
60 * Free resources associated with the given download context.
61 *
62 * @param dc context to free
63 */
64static void
65save_as_dialog_free_download_context (struct DownloadContext *dc)
40{ 66{
41 if (NULL != dc->rr) 67 if (NULL != dc->rr)
42 gtk_tree_row_reference_free (dc->rr); 68 gtk_tree_row_reference_free (dc->rr);
@@ -50,6 +76,16 @@ GNUNET_GTK_save_as_dialog_free_download_context (struct DownloadContext *dc)
50} 76}
51 77
52 78
79/**
80 * The 'save_as' dialog is being deleted. Check which state we're in
81 * and either simply clean up or start the download with the
82 * respective options (by calling the respective continuation).
83 *
84 * @param widget the dialog object
85 * @param event the deletion event
86 * @param user_data the 'structDownloadAsDialogContext' of the dialog
87 * @return always FALSE
88 */
53gboolean 89gboolean
54GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget * widget, GdkEvent * event, 90GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget * widget, GdkEvent * event,
55 gpointer user_data) 91 gpointer user_data)
@@ -59,18 +95,13 @@ GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget * widget, GdkEvent * event,
59 struct DownloadContext *dc; 95 struct DownloadContext *dc;
60 GtkWidget *cb; 96 GtkWidget *cb;
61 97
62 if (dlc == NULL)
63 {
64 GNUNET_break (0);
65 return FALSE;
66 }
67 builder = dlc->builder; 98 builder = dlc->builder;
68 dc = dlc->dc; 99 dc = dlc->dc;
69 cb = GTK_WIDGET (gtk_builder_get_object 100 cb = GTK_WIDGET (gtk_builder_get_object
70 (builder, "GNUNET_GTK_save_as_recursive_check_button")); 101 (builder, "GNUNET_GTK_save_as_recursive_check_button"));
71 if (GTK_RESPONSE_OK != dlc->response) 102 if (GTK_RESPONSE_OK != dlc->response)
72 { 103 {
73 GNUNET_GTK_save_as_dialog_free_download_context (dc); 104 save_as_dialog_free_download_context (dc);
74 g_object_unref (G_OBJECT (dlc->builder)); 105 g_object_unref (G_OBJECT (dlc->builder));
75 GNUNET_free (dlc); 106 GNUNET_free (dlc);
76 return FALSE; 107 return FALSE;
@@ -88,86 +119,116 @@ GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget * widget, GdkEvent * event,
88 (builder, 119 (builder,
89 "GNUNET_GTK_save_as_dialog_anonymity_spin_button"))); 120 "GNUNET_GTK_save_as_dialog_anonymity_spin_button")));
90 g_object_unref (G_OBJECT (builder)); 121 g_object_unref (G_OBJECT (builder));
91
92 GNUNET_free (dlc); 122 GNUNET_free (dlc);
93 123 GNUNET_FS_GTK_download_context_start_download (dc);
94 dc->cb (dc);
95 return FALSE; 124 return FALSE;
96} 125}
97 126
98 127
128/**
129 * The user clicked on the 'save as' button of the dialog.
130 * Delete the window and start the download.
131 *
132 * @param dialog the dialog object
133 * @param response_id response_id associated with the button
134 * @param user_data the 'structDownloadAsDialogContext' of the dialog
135 */
99void 136void
100GNUNET_GTK_save_as_dialog_response_cb (GtkDialog * dialog, gint response_id, 137GNUNET_GTK_save_as_dialog_response_cb (GtkDialog * dialog,
138 gint response_id,
101 gpointer user_data) 139 gpointer user_data)
102{ 140{
103 struct DownloadAsDialogContext *dlc = user_data; 141 struct DownloadAsDialogContext *dlc = user_data;
104 142
105 if (dlc != NULL) 143 dlc->response = response_id;
106 dlc->response = response_id;
107 /* dialogs don't get delete-event the way normal windows do, 144 /* dialogs don't get delete-event the way normal windows do,
108 * call the handler manually 145 call the handler manually */
109 */
110 GNUNET_GTK_save_as_dialog_delete_event_cb (GTK_WIDGET (dialog), NULL, 146 GNUNET_GTK_save_as_dialog_delete_event_cb (GTK_WIDGET (dialog), NULL,
111 user_data); 147 user_data);
148 /* FIXME: isn't the dialog going to be destroyed with the builder?
149 Is this legal and/or required? */
112 gtk_widget_destroy (GTK_WIDGET (dialog)); 150 gtk_widget_destroy (GTK_WIDGET (dialog));
113} 151}
114 152
115 153
154/**
155 * Open the 'save as' dialog for a download. Calls the 'dc->cb'
156 * continutation when the dialog is complete. Will release the 'dc'
157 * resources if the dialog is cancelled.
158 *
159 * @param dc download context for the file/directory
160 */
116void 161void
117GNUNET_FS_GTK_open_download_as_dialog (struct DownloadContext *dc) 162GNUNET_FS_GTK_open_download_as_dialog (struct DownloadContext *dc)
118{ 163{
119 GtkWidget *ad;
120 GtkBuilder *builder;
121 GtkWidget *cb;
122 struct DownloadAsDialogContext *dlc; 164 struct DownloadAsDialogContext *dlc;
165 GtkWidget *cb;
123 166
124 dlc = GNUNET_malloc (sizeof (struct DownloadAsDialogContext)); 167 dlc = GNUNET_malloc (sizeof (struct DownloadAsDialogContext));
125 builder = 168 dlc->dc = dc;
169 dlc->builder =
126 GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_download_as_dialog.glade", 170 GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_download_as_dialog.glade",
127 dlc); 171 dlc);
128 if (builder == NULL) 172 if (NULL == dlc->builder)
129 { 173 {
130 GNUNET_break (0); 174 GNUNET_break (0);
131 GNUNET_GTK_save_as_dialog_free_download_context (dc); 175 save_as_dialog_free_download_context (dc);
132 GNUNET_free (dlc); 176 GNUNET_free (dlc);
133 return; 177 return;
134 } 178 }
179 dlc->dialog = GTK_WIDGET (gtk_builder_get_object
180 (dlc->builder, "GNUNET_GTK_save_as_dialog"));
181
182 /* Enable recursive button for directories and
183 set recursive 'default' value based on what the 'dc' tells us */
135 cb = GTK_WIDGET (gtk_builder_get_object 184 cb = GTK_WIDGET (gtk_builder_get_object
136 (builder, "GNUNET_GTK_save_as_recursive_check_button")); 185 (dlc->builder, "GNUNET_GTK_save_as_recursive_check_button"));
137 if (GNUNET_FS_meta_data_test_for_directory (dc->meta)) 186 if (GNUNET_FS_meta_data_test_for_directory (dc->meta))
138 gtk_widget_set_sensitive (cb, TRUE); 187 gtk_widget_set_sensitive (cb, TRUE);
139 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb), dc->is_recursive); 188 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb),
140 189 dc->is_recursive);
141 ad = GTK_WIDGET (gtk_builder_get_object 190
142 (builder, "GNUNET_GTK_save_as_dialog")); 191 /* initialize filename based on filename from 'dc' */
143 if (dc->filename != NULL) 192 if (dc->filename != NULL)
144 { 193 {
145 char *dirname; 194 char *dirname;
146 char *basename; 195 char *basename;
196
147 dirname = GNUNET_strdup (dc->filename); 197 dirname = GNUNET_strdup (dc->filename);
148 basename = (char *) GNUNET_STRINGS_get_short_name (dirname); 198 basename = (char *) GNUNET_STRINGS_get_short_name (dirname);
199 /* basename now points into 'dirname'; cut 'dirname' off at the '/' before basename */
149 if (basename > dirname) 200 if (basename > dirname)
150 basename[-1] = '\0'; 201 basename[-1] = '\0';
151 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (ad), dirname); 202
152 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (ad), basename); 203 fprintf (stderr,
204 "Splitting `%s' into `%s' + `%s' for file chooser dialog.\n",
205 dc->filename,
206 dirname,
207 basename);
208
209 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlc->dialog), dirname);
210 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dlc->dialog), basename);
153 GNUNET_free (dirname); 211 GNUNET_free (dirname);
154 } 212 }
155 dlc->builder = builder; 213 gtk_window_present (GTK_WINDOW (dlc->dialog));
156 dlc->dialog = ad;
157 dlc->response = 0;
158 dlc->dc = dc;
159 gtk_window_present (GTK_WINDOW (ad));
160} 214}
161 215
162 216
217/**
218 * Actually start the download that is specified by the given download
219 * context and its options. Will add a download entry to the
220 * respective tree model and trigger a start of the download using the
221 * FS-API.
222 *
223 * @param dc download context of the download to execute
224 */
163void 225void
164GNUNET_FS_GTK_default_open_download_as_callback (struct DownloadContext *dc) 226GNUNET_FS_GTK_download_context_start_download (struct DownloadContext *dc)
165{ 227{
166 enum GNUNET_FS_DownloadOptions opt; 228 enum GNUNET_FS_DownloadOptions opt;
167 struct GNUNET_FS_Handle *fs; 229 struct GNUNET_FS_Handle *fs;
168 struct DownloadEntry *de; 230 struct DownloadEntry *de;
169 uint64_t len; 231 uint64_t len;
170
171 GtkTreeIter iter; 232 GtkTreeIter iter;
172 GtkTreePath *path; 233 GtkTreePath *path;
173 234
@@ -176,7 +237,6 @@ GNUNET_FS_GTK_default_open_download_as_callback (struct DownloadContext *dc)
176 if (dc->is_recursive) 237 if (dc->is_recursive)
177 opt |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE; 238 opt |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE;
178 len = GNUNET_FS_uri_chk_get_file_size (dc->uri); 239 len = GNUNET_FS_uri_chk_get_file_size (dc->uri);
179
180 de = GNUNET_malloc (sizeof (struct DownloadEntry)); 240 de = GNUNET_malloc (sizeof (struct DownloadEntry));
181 de->uri = dc->uri; 241 de->uri = dc->uri;
182 dc->uri = NULL; 242 dc->uri = NULL;
@@ -184,22 +244,29 @@ GNUNET_FS_GTK_default_open_download_as_callback (struct DownloadContext *dc)
184 dc->meta = NULL; 244 dc->meta = NULL;
185 if (dc->rr != NULL) 245 if (dc->rr != NULL)
186 { 246 {
187 /* We're going to free "dc" very soon */
188 de->rr = gtk_tree_row_reference_copy (dc->rr); 247 de->rr = gtk_tree_row_reference_copy (dc->rr);
189 de->ts = GTK_TREE_STORE (gtk_tree_row_reference_get_model (dc->rr)); 248 de->ts = GTK_TREE_STORE (gtk_tree_row_reference_get_model (dc->rr));
190
191 path = gtk_tree_row_reference_get_path (de->rr); 249 path = gtk_tree_row_reference_get_path (de->rr);
192 GNUNET_assert (NULL != path); 250 if ( (NULL != path) &&
193 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path)) 251 (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path)) )
194 { 252 {
195 /* Store filename and anonymity as specified by the user. 253 /* Store filename and anonymity as specified by the user.
196 * These will be re-used when this is a directory, and the user 254 * These will be re-used when this is a directory, and the user
197 * downloads its children. 255 * downloads its children.
198 */ 256 */
199 gtk_tree_store_set (de->ts, &iter, 15, dc->filename, 16, dc->anonymity, -1); 257 gtk_tree_store_set (de->ts, &iter, 15, dc->filename, 16, dc->anonymity, -1);
258 }
259 else
260 {
261 /* We could not find the referenced row in the search tab; this is
262 conceivable as the search tab might have been closed by the
263 user while the 'save as' dialog was open. In this case, this
264 is equivalent to having no search, so we drop the (now invalid)
265 'sr' reference */
266 dc->sr = NULL;
200 } 267 }
201 gtk_tree_path_free (path); 268 if (NULL != path)
202 269 gtk_tree_path_free (path);
203 } 270 }
204 if (dc->sr != NULL) 271 if (dc->sr != NULL)
205 { 272 {
@@ -220,7 +287,8 @@ GNUNET_FS_GTK_default_open_download_as_callback (struct DownloadContext *dc)
220 len, dc->anonymity, opt, de, 287 len, dc->anonymity, opt, de,
221 NULL /* parent download ctx */ )); 288 NULL /* parent download ctx */ ));
222 } 289 }
223 GNUNET_GTK_save_as_dialog_free_download_context (dc); 290 save_as_dialog_free_download_context (dc);
224} 291}
225 292
293
226/* end of gnunet-fs-gtk-download.c */ 294/* end of gnunet-fs-gtk-download.c */