diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk-download.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk-download.c | 162 |
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 | */ | ||
30 | struct DownloadAsDialogContext | 33 | struct 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 | ||
38 | void | 58 | |
39 | GNUNET_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 | */ | ||
64 | static void | ||
65 | save_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 | */ | ||
53 | gboolean | 89 | gboolean |
54 | GNUNET_GTK_save_as_dialog_delete_event_cb (GtkWidget * widget, GdkEvent * event, | 90 | GNUNET_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 | */ | ||
99 | void | 136 | void |
100 | GNUNET_GTK_save_as_dialog_response_cb (GtkDialog * dialog, gint response_id, | 137 | GNUNET_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 | */ | ||
116 | void | 161 | void |
117 | GNUNET_FS_GTK_open_download_as_dialog (struct DownloadContext *dc) | 162 | GNUNET_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 | */ | ||
163 | void | 225 | void |
164 | GNUNET_FS_GTK_default_open_download_as_callback (struct DownloadContext *dc) | 226 | GNUNET_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 */ |