aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk_publish-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk_publish-dialog.c')
-rw-r--r--src/fs/gnunet-fs-gtk_publish-dialog.c1396
1 files changed, 895 insertions, 501 deletions
diff --git a/src/fs/gnunet-fs-gtk_publish-dialog.c b/src/fs/gnunet-fs-gtk_publish-dialog.c
index b3c4bd32..def302cf 100644
--- a/src/fs/gnunet-fs-gtk_publish-dialog.c
+++ b/src/fs/gnunet-fs-gtk_publish-dialog.c
@@ -30,73 +30,219 @@
30 30
31#define MARKER_DIR_FILE_SIZE "-" 31#define MARKER_DIR_FILE_SIZE "-"
32 32
33/**
34 * Be very verbose when reporting progress (usually bad as it takes more time
35 * to display this than to make progress).
36 */
33#define VERBOSE_PROGRESS GNUNET_NO 37#define VERBOSE_PROGRESS GNUNET_NO
34 38
39
40/**
41 * Context we create when we are scanning a directory.
42 */
35struct AddDirClientContext; 43struct AddDirClientContext;
36 44
45
46/**
47 * Main handle of the dialog for a publish operation.
48 */
37struct MainPublishingDialogContext 49struct MainPublishingDialogContext
38{ 50{
51 /**
52 * Main builder for the publishing dialog.
53 */
39 GtkBuilder *builder; 54 GtkBuilder *builder;
55
56 /**
57 * Builder for the master window (FIXME: remove)
58 */
40 GtkBuilder *main_window_builder; 59 GtkBuilder *main_window_builder;
41 GtkTreeView *pseudonym_treeview; 60
61 /**
62 * Handle to the main window of the publishing dialog.
63 */
64 GtkWindow *master_pubdialog;
65
66 /**
67 * Selected pseudonym.
68 */
42 GtkTreeSelection *pseudonym_selection; 69 GtkTreeSelection *pseudonym_selection;
70
71 /**
72 * Model with the list of (our) pseudonyms.
73 */
43 GtkTreeModel *pseudonym_treemodel; 74 GtkTreeModel *pseudonym_treemodel;
75
76 /**
77 * Tree view listing files to be published.
78 */
79 GtkTreeView *file_info_treeview;
80
81 /**
82 * Selected file in the 'file_info_treeview'
83 */
84 GtkTreeSelection *file_info_selection;
85
86 /**
87 * Model with the list of files to be shared.
88 */
89 GtkTreeModel *file_info_treemodel;
90
91 /**
92 * Button to move selected file upwards
93 */
44 GtkWidget *up_button; 94 GtkWidget *up_button;
95
96 /**
97 * Button to move selected file downwards
98 */
45 GtkWidget *down_button; 99 GtkWidget *down_button;
100
101 /**
102 * Button to move selected file left (make sibling of current parent)
103 */
46 GtkWidget *left_button; 104 GtkWidget *left_button;
105
106 /**
107 * Button to move selected file right (make child of predecessor)
108 */
47 GtkWidget *right_button; 109 GtkWidget *right_button;
110
111 /**
112 * Button to delete selected file from the list
113 */
48 GtkWidget *delete_button; 114 GtkWidget *delete_button;
115
116 /**
117 * Button to edit meta data of the selected file
118 */
49 GtkWidget *edit_button; 119 GtkWidget *edit_button;
120
121 /**
122 * Button to publish all files from the dialog
123 */
50 GtkWidget *execute_button; 124 GtkWidget *execute_button;
125
126 /**
127 * Button to abort the publishing operation
128 */
51 GtkWidget *cancel_button; 129 GtkWidget *cancel_button;
52 GtkTreeView *file_info_treeview;
53 GtkTreeSelection *file_info_selection;
54 GtkTreeModel *file_info_treemodel;
55 GtkWindow *master_pubdialog;
56 130
131 /**
132 * FIXME: ugly, keep?
133 */
57 gulong open_directory_handler_id; 134 gulong open_directory_handler_id;
135
136 /**
137 * FIXME: ugly, keep?
138 */
58 GtkBuilder *open_directory_builder; 139 GtkBuilder *open_directory_builder;
59 140
141 /**
142 * FIXME: ugly, keep?
143 */
60 gulong open_file_handler_id; 144 gulong open_file_handler_id;
145
146 /**
147 * FIXME: ugly, keep?
148 */
61 GtkBuilder *open_file_builder; 149 GtkBuilder *open_file_builder;
62 150
63 /* To keep multiple scanners running */ 151 /**
152 * Head of linked list of active open-directory operations.
153 */
64 struct AddDirClientContext *adddir_head; 154 struct AddDirClientContext *adddir_head;
155
156 /**
157 * Tail of linked list of active open-directory operations.
158 */
65 struct AddDirClientContext *adddir_tail; 159 struct AddDirClientContext *adddir_tail;
66}; 160};
67 161
68/* One of these is kept for every directory being opened */ 162
163/**
164 * Context we create when we are scanning a directory.
165 */
69struct AddDirClientContext 166struct AddDirClientContext
70{ 167{
71 struct AddDirClientContext *prev; 168 /**
169 * This is a doubly-linked list.
170 */
72 struct AddDirClientContext *next; 171 struct AddDirClientContext *next;
73 172
74 struct GNUNET_FS_ProcessMetadataContext *pmc; 173 /**
174 * This is a doubly-linked list.
175 */
176 struct AddDirClientContext *prev;
75 177
178 /**
179 * Handle of the master publish window.
180 */
76 struct MainPublishingDialogContext *ctx; 181 struct MainPublishingDialogContext *ctx;
77 struct GNUNET_FS_DirScanner *ds;
78
79 struct GNUNET_FS_ShareTreeItem *directory_scan_result;
80
81 struct GNUNET_FS_BlockOptions directory_scan_bo;
82 int directory_scan_do_index;
83 182
183 /**
184 * Builder for the progress dialog that is displayed during the scan.
185 */
84 GtkBuilder *progress_dialog_builder; 186 GtkBuilder *progress_dialog_builder;
187
188 /**
189 * The progress dialog itself.
190 */
85 GtkWidget *progress_dialog; 191 GtkWidget *progress_dialog;
192
193 /**
194 * The progress bar of the progress dialog.
195 */
86 GtkProgressBar *progress_dialog_bar; 196 GtkProgressBar *progress_dialog_bar;
87 GtkButton *progress_dialog_cancel; 197
198 /**
199 * Text view in the progress dialog (for error messages).
200 */
88 GtkTextView *progress_dialog_textview; 201 GtkTextView *progress_dialog_textview;
202
203 /**
204 * Text buffer of the text view in the progress dialog.
205 */
89 GtkTextBuffer *progress_dialog_textbuffer; 206 GtkTextBuffer *progress_dialog_textbuffer;
90 GtkTextMark *progress_dialog_textmark;
91 GtkAdjustment *textview_vertial_adjustment;
92 207
208 /**
209 * Adjustment (for scrolling) of the text view in the progress dialog.
210 */
211 GtkAdjustment *textview_vertical_adjustment;
212
213 /**
214 * Handle to the active directory scanning operation.
215 */
216 struct GNUNET_FS_DirScanner *ds;
217
218 /**
219 * Default options to use for sharing when adding files during the scan.
220 */
221 struct GNUNET_FS_BlockOptions directory_scan_bo;
222
223 /**
224 * Default "index" option to use for sharing when adding files during the scan.
225 */
226 int directory_scan_do_index;
227
228 /**
229 * Number of files that have had their meta data extracted (once done==total
230 * we're finished processing).
231 */
93 unsigned int done; 232 unsigned int done;
233
234 /**
235 * Total number of files that we have found in the directory structure and that
236 * will need to be processed.
237 */
94 unsigned int total; 238 unsigned int total;
239
95}; 240};
96 241
97 242
98static void 243
99selection_changed_cb (GtkTreeSelection * ts, struct MainPublishingDialogContext *ctx); 244/* ************************ editing operations inside the master dialog ********************* */
245
100 246
101 247
102/** 248/**
@@ -108,7 +254,9 @@ selection_changed_cb (GtkTreeSelection * ts, struct MainPublishingDialogContext
108 * @return GNUNET_YES if they are equal 254 * @return GNUNET_YES if they are equal
109 */ 255 */
110static int 256static int
111gtk_tree_iter_equals (GtkTreeModel * tm, GtkTreeIter * i1, GtkTreeIter * i2) 257gtk_tree_iter_equals (GtkTreeModel * tm,
258 GtkTreeIter * i1,
259 GtkTreeIter * i2)
112{ 260{
113 GtkTreePath *p1; 261 GtkTreePath *p1;
114 GtkTreePath *p2; 262 GtkTreePath *p2;
@@ -122,49 +270,11 @@ gtk_tree_iter_equals (GtkTreeModel * tm, GtkTreeIter * i1, GtkTreeIter * i2)
122 return (0 == ret) ? GNUNET_YES : GNUNET_NO; 270 return (0 == ret) ? GNUNET_YES : GNUNET_NO;
123} 271}
124 272
125/* Fill out the main publishing dialog context structure */
126static void
127init_ctx (struct MainPublishingDialogContext *ctx)
128{
129 ctx->pseudonym_treeview = GTK_TREE_VIEW (gtk_builder_get_object
130 (ctx->builder, "GNUNET_GTK_master_publish_dialog_pseudonym_tree_view"));
131
132 ctx->up_button = GTK_WIDGET (gtk_builder_get_object
133 (ctx->builder, "GNUNET_GTK_master_publish_dialog_up_button"));
134 ctx->down_button = GTK_WIDGET (gtk_builder_get_object
135 (ctx->builder, "GNUNET_GTK_master_publish_dialog_down_button"));
136 ctx->left_button = GTK_WIDGET (gtk_builder_get_object
137 (ctx->builder, "GNUNET_GTK_master_publish_dialog_left_button"));
138 ctx->right_button = GTK_WIDGET (gtk_builder_get_object
139 (ctx->builder, "GNUNET_GTK_master_publish_dialog_right_button"));
140 ctx->delete_button = GTK_WIDGET (gtk_builder_get_object
141 (ctx->builder, "GNUNET_GTK_master_publish_dialog_delete_button"));
142 ctx->edit_button = GTK_WIDGET (gtk_builder_get_object
143 (ctx->builder, "GNUNET_GTK_master_publish_dialog_edit_button"));
144 ctx->execute_button = GTK_WIDGET (gtk_builder_get_object
145 (ctx->builder, "GNUNET_GTK_master_publish_dialog_execute_button"));
146 ctx->cancel_button = GTK_WIDGET (gtk_builder_get_object
147 (ctx->builder , "GNUNET_GTK_master_publish_dialog_cancel_button"));
148 ctx->file_info_treeview = GTK_TREE_VIEW (gtk_builder_get_object
149 (ctx->builder, "GNUNET_GTK_master_publish_dialog_file_information_tree_view"));
150
151 ctx->master_pubdialog =
152 GTK_WINDOW (gtk_builder_get_object
153 (ctx->builder, "GNUNET_GTK_master_publish_dialog"));
154
155 ctx->file_info_selection = gtk_tree_view_get_selection (ctx->file_info_treeview);
156 ctx->file_info_treemodel = gtk_tree_view_get_model (ctx->file_info_treeview);
157 ctx->pseudonym_selection = gtk_tree_view_get_selection (ctx->pseudonym_treeview);
158 ctx->pseudonym_treemodel = gtk_tree_view_get_model (ctx->pseudonym_treeview);
159
160 g_signal_connect (G_OBJECT (ctx->file_info_selection), "changed",
161 G_CALLBACK (selection_changed_cb), ctx);
162 g_signal_connect (G_OBJECT (ctx->pseudonym_selection), "changed",
163 G_CALLBACK (selection_changed_cb), ctx);
164}
165 273
166/** 274/**
167 * Update selectivity in the master dialog. 275 * Update selectivity of buttons (up/down/left/right/cancel/execute) in the master dialog.
276 *
277 * @param ctx master dialog to update selectivity for
168 */ 278 */
169static void 279static void
170update_selectivity (struct MainPublishingDialogContext *ctx) 280update_selectivity (struct MainPublishingDialogContext *ctx)
@@ -177,8 +287,9 @@ update_selectivity (struct MainPublishingDialogContext *ctx)
177 int ns_ok; 287 int ns_ok;
178 gchar *namespace_id; 288 gchar *namespace_id;
179 289
290 /* find out if a namespace was selected */
180 ns_ok = GNUNET_YES; 291 ns_ok = GNUNET_YES;
181 if (TRUE == gtk_tree_selection_get_selected (ctx->pseudonym_selection, NULL, &iter)) 292 if (gtk_tree_selection_get_selected (ctx->pseudonym_selection, NULL, &iter))
182 { 293 {
183 gtk_tree_model_get (ctx->pseudonym_treemodel, &iter, 2, &namespace_id, -1); 294 gtk_tree_model_get (ctx->pseudonym_treemodel, &iter, 2, &namespace_id, -1);
184 if (namespace_id == NULL) 295 if (namespace_id == NULL)
@@ -186,19 +297,26 @@ update_selectivity (struct MainPublishingDialogContext *ctx)
186 else 297 else
187 g_free (namespace_id); 298 g_free (namespace_id);
188 } 299 }
300
189 /* Don't let the user close the dialog until all scanners are finished and 301 /* Don't let the user close the dialog until all scanners are finished and
190 * their windows are closed 302 their windows are closed */
191 */ 303 /* FIXME: what about open-directory operations? */
192 if ((gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter)) 304 if ( (gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter)) &&
193 && (ns_ok == GNUNET_YES) && ctx->adddir_head == NULL) 305 (ns_ok == GNUNET_YES) &&
306 (ctx->adddir_head == NULL) )
194 gtk_widget_set_sensitive (ctx->execute_button, TRUE); 307 gtk_widget_set_sensitive (ctx->execute_button, TRUE);
195 else 308 else
196 gtk_widget_set_sensitive (ctx->execute_button, FALSE); 309 gtk_widget_set_sensitive (ctx->execute_button, FALSE);
310
311 /* if an 'edit' operation is open, don't even allow "cancel" */
312 /* FIXME: what about open-directory operations? */
197 if (ctx->adddir_head == NULL) 313 if (ctx->adddir_head == NULL)
198 gtk_widget_set_sensitive (ctx->cancel_button, TRUE); 314 gtk_widget_set_sensitive (ctx->cancel_button, TRUE);
199 else 315 else
200 gtk_widget_set_sensitive (ctx->cancel_button, FALSE); 316 gtk_widget_set_sensitive (ctx->cancel_button, FALSE);
201 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 317
318 /* now for the editing buttons... */
319 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
202 { 320 {
203 gtk_widget_set_sensitive (ctx->up_button, FALSE); 321 gtk_widget_set_sensitive (ctx->up_button, FALSE);
204 gtk_widget_set_sensitive (ctx->down_button, FALSE); 322 gtk_widget_set_sensitive (ctx->down_button, FALSE);
@@ -211,26 +329,22 @@ update_selectivity (struct MainPublishingDialogContext *ctx)
211 gtk_widget_set_sensitive (ctx->delete_button, TRUE); 329 gtk_widget_set_sensitive (ctx->delete_button, TRUE);
212 gtk_widget_set_sensitive (ctx->edit_button, TRUE); 330 gtk_widget_set_sensitive (ctx->edit_button, TRUE);
213 331
214 /* now figure out which move operations are currently legal */ 332 /* figure out which move operations are currently legal */
215 GNUNET_assert (TRUE == gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)); 333 GNUNET_assert (gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter));
216 if (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter)) 334 if (gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter))
217 { 335 gtk_widget_set_sensitive (ctx->down_button, TRUE);
218 gtk_widget_set_sensitive (ctx->down_button, TRUE); 336 else
219 }
220 else
221 {
222 gtk_widget_set_sensitive (ctx->down_button, FALSE); 337 gtk_widget_set_sensitive (ctx->down_button, FALSE);
223 } 338 GNUNET_assert (gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter));
224 GNUNET_assert (TRUE == gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)); 339 if (gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter))
225 if (TRUE == gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter))
226 { 340 {
227 gtk_widget_set_sensitive (ctx->left_button, TRUE); 341 gtk_widget_set_sensitive (ctx->left_button, TRUE);
228 GNUNET_assert (TRUE == gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent)); 342 GNUNET_assert (gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent));
229 } 343 }
230 else 344 else
231 { 345 {
232 gtk_widget_set_sensitive (ctx->left_button, FALSE); 346 gtk_widget_set_sensitive (ctx->left_button, FALSE);
233 GNUNET_assert (TRUE == gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred)); 347 GNUNET_assert (gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred));
234 } 348 }
235 /* iterate over 'next' of pred to find out if our 349 /* iterate over 'next' of pred to find out if our
236 * predecessor is a directory! */ 350 * predecessor is a directory! */
@@ -239,38 +353,49 @@ update_selectivity (struct MainPublishingDialogContext *ctx)
239 { 353 {
240 gtk_tree_model_get (ctx->file_info_treemodel, &pred, 5, &fip, -1); 354 gtk_tree_model_get (ctx->file_info_treemodel, &pred, 5, &fip, -1);
241 is_dir = GNUNET_FS_file_information_is_directory (fip); 355 is_dir = GNUNET_FS_file_information_is_directory (fip);
242 GNUNET_assert (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred)); 356 GNUNET_assert (gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred));
243 }
244 if (GNUNET_YES == is_dir)
245 {
246 gtk_widget_set_sensitive (ctx->right_button, TRUE);
247 }
248 else
249 {
250 gtk_widget_set_sensitive (ctx->right_button, FALSE);
251 }
252 if (GNUNET_SYSERR != is_dir)
253 {
254 gtk_widget_set_sensitive (ctx->up_button, TRUE);
255 }
256 else
257 {
258 gtk_widget_set_sensitive (ctx->up_button, FALSE);
259 } 357 }
358 if (GNUNET_YES == is_dir)
359 gtk_widget_set_sensitive (ctx->right_button, TRUE);
360 else
361 gtk_widget_set_sensitive (ctx->right_button, FALSE);
362 if (GNUNET_SYSERR != is_dir)
363 gtk_widget_set_sensitive (ctx->up_button, TRUE);
364 else
365 gtk_widget_set_sensitive (ctx->up_button, FALSE);
366}
367
368
369/**
370 * The selection in the file list tree view changed; update the button sensitivity.
371 *
372 * @param ts the changed selection
373 * @param user_data master publishing dialog context of our window
374 */
375static void
376selection_changed_cb (GtkTreeSelection * ts,
377 gpointer user_data)
378{
379 struct MainPublishingDialogContext *ctx = user_data;
380
381 update_selectivity (ctx);
260} 382}
261 383
262 384
263/** 385/**
264 * Add an empty directory to the tree model. 386 * Add an empty directory to the tree model.
265 * 387 *
388 * @param ctx master publishing dialog context of our window
266 * @param name name for the directory 389 * @param name name for the directory
267 * @param bo block options 390 * @param bo block options
268 * @param iter parent entry, or NULL for top-level addition 391 * @param iter parent entry, or NULL for top-level addition
269 * @param pos iterator to set to the location of the new element 392 * @param pos iterator to set to the location of the new element
270 */ 393 */
271static void 394static void
272create_dir_at_iter (struct MainPublishingDialogContext *ctx, const char *name, 395create_dir_at_iter (struct MainPublishingDialogContext *ctx,
273 const struct GNUNET_FS_BlockOptions *bo, GtkTreeIter * iter, 396 const char *name,
397 const struct GNUNET_FS_BlockOptions *bo,
398 GtkTreeIter * iter,
274 GtkTreeIter * pos) 399 GtkTreeIter * pos)
275{ 400{
276 struct GNUNET_FS_FileInformation *fi; 401 struct GNUNET_FS_FileInformation *fi;
@@ -291,62 +416,97 @@ create_dir_at_iter (struct MainPublishingDialogContext *ctx, const char *name,
291 fi = GNUNET_FS_file_information_create_empty_directory 416 fi = GNUNET_FS_file_information_create_empty_directory
292 (GNUNET_FS_GTK_get_fs_handle (), row_reference, NULL, meta, bo, name); 417 (GNUNET_FS_GTK_get_fs_handle (), row_reference, NULL, meta, bo, name);
293 GNUNET_CONTAINER_meta_data_destroy (meta); 418 GNUNET_CONTAINER_meta_data_destroy (meta);
294 gtk_tree_store_set (GTK_TREE_STORE (ctx->file_info_treemodel), pos, 0, MARKER_DIR_FILE_SIZE, 1, (gboolean) GNUNET_NO, 419 gtk_tree_store_set (GTK_TREE_STORE (ctx->file_info_treemodel), pos,
295 2, name, 3, (guint) bo->anonymity_level, 4, 420 0, MARKER_DIR_FILE_SIZE,
296 (guint) bo->content_priority, 5, fi, 421 1, (gboolean) GNUNET_NO,
422 2, name,
423 3, (guint) bo->anonymity_level,
424 4, (guint) bo->content_priority,
425 5, fi,
297 6, (guint64) bo->expiration_time.abs_value, 426 6, (guint64) bo->expiration_time.abs_value,
298 7, (guint) bo->replication_level, 427 7, (guint) bo->replication_level,
299 -1); 428 -1);
300 update_selectivity (ctx); 429 update_selectivity (ctx);
301} 430}
302 431
303static void
304selection_changed_cb (GtkTreeSelection * ts, struct MainPublishingDialogContext *ctx)
305{
306 update_selectivity (ctx);
307}
308 432
433/**
434 * Remove the given entry and all of its children from the tree store.
435 *
436 * @param ts tree store to edit
437 * @param root root of the subtree to remove
438 */
309static void 439static void
310remove_old_entry (GtkTreeStore * ts, GtkTreeIter * root) 440remove_old_entry (GtkTreeStore * ts,
441 GtkTreeIter * root)
311{ 442{
312 GtkTreeIter child; 443 GtkTreeIter child;
313 444
314 while (TRUE == 445 while (gtk_tree_model_iter_children (GTK_TREE_MODEL (ts), &child, root))
315 gtk_tree_model_iter_children (GTK_TREE_MODEL (ts), &child, root))
316 remove_old_entry (ts, &child); 446 remove_old_entry (ts, &child);
317 gtk_tree_store_remove (ts, root); 447 gtk_tree_store_remove (ts, root);
318} 448}
319 449
320 450
321/** 451/**
322 * Move an entry in the tree. 452 * Copy an entry in the tree from the 'old' position to the 'new'
453 * position. All of the fields are copied, plain pointers will be
454 * aliased (model will thus be inconsistent until 'remove_old_entry'
455 * is called on the 'old' entry).
456 *
457 * @param ctx main publishing context
458 * @param tm tree model for the move operation
459 * @param old old position (source of the copy operation)
460 * @param newpos destination of the copy operation
461 * @param dsel GNUNET_YES for the top-level operation,
462 * GNUNET_NO for the recursive calls; if GNUNET_YES,
463 * we ensure that the tree view is expanded to cover
464 * the element; the element is also then selected
323 */ 465 */
324static void 466static void
325move_entry (struct MainPublishingDialogContext *ctx, GtkTreeModel * tm, GtkTreeIter * old, 467copy_entry (struct MainPublishingDialogContext *ctx, GtkTreeModel * tm, GtkTreeIter * old,
326 GtkTreeIter * newpos, int dsel) 468 GtkTreeIter * newpos, int dsel)
327{ 469{
328 struct GNUNET_FS_FileInformation *fip;
329 gint do_index;
330 gchar *short_fn;
331 guint anonymity_level;
332 guint priority;
333 guint replication_level;
334 guint64 expiration_time_abs;
335 char *fsf;
336 GtkTreePath *path; 470 GtkTreePath *path;
337 GtkTreeIter child; 471 GtkTreeIter child;
338 GtkTreeIter cnewpos;
339 GtkTreeRowReference *rr; 472 GtkTreeRowReference *rr;
340 GtkTreeRowReference *rr2; 473
341 474 /* first, move the data */
342 gtk_tree_model_get (tm, old, 0, &fsf, 1, &do_index, 2, &short_fn, 3, 475 {
343 &anonymity_level, 4, &priority, 5, &fip, 476 struct GNUNET_FS_FileInformation *fip;
344 6, &expiration_time_abs, 7, &replication_level, -1); 477 gint do_index;
345 gtk_tree_store_set (GTK_TREE_STORE (tm), newpos, 0, fsf, 1, do_index, 2, 478 gchar *short_fn;
346 short_fn, 3, (guint) anonymity_level, 4, (guint) priority, 479 guint anonymity_level;
347 5, fip, 480 guint priority;
348 6, expiration_time_abs, 481 guint replication_level;
349 7, replication_level, -1); 482 guint64 expiration_time_abs;
483 char *fsf;
484
485 gtk_tree_model_get (tm, old,
486 0, &fsf,
487 1, &do_index,
488 2, &short_fn,
489 3, &anonymity_level,
490 4, &priority,
491 5, &fip,
492 6, &expiration_time_abs,
493 7, &replication_level,
494 -1);
495 gtk_tree_store_set (GTK_TREE_STORE (tm), newpos,
496 0, fsf,
497 1, do_index,
498 2, short_fn,
499 3, anonymity_level,
500 4, priority,
501 5, fip,
502 6, expiration_time_abs,
503 7, replication_level,
504 -1);
505 g_free (short_fn);
506 g_free (fsf);
507 }
508
509 /* remember our destination location if needed */
350 if (dsel == GNUNET_YES) 510 if (dsel == GNUNET_YES)
351 { 511 {
352 path = gtk_tree_model_get_path (tm, newpos); 512 path = gtk_tree_model_get_path (tm, newpos);
@@ -357,25 +517,30 @@ move_entry (struct MainPublishingDialogContext *ctx, GtkTreeModel * tm, GtkTreeI
357 { 517 {
358 rr = NULL; 518 rr = NULL;
359 } 519 }
360 if (TRUE == gtk_tree_model_iter_children (tm, &child, old)) 520
521 /* recursively move children */
522 if (gtk_tree_model_iter_children (tm, &child, old))
361 { 523 {
362 do 524 do
363 { 525 {
526 GtkTreeRowReference *crr;
527 GtkTreeIter cnewpos;
528
364 path = gtk_tree_model_get_path (tm, &child); 529 path = gtk_tree_model_get_path (tm, &child);
365 rr2 = gtk_tree_row_reference_new (tm, path); 530 crr = gtk_tree_row_reference_new (tm, path);
366 gtk_tree_path_free (path); 531 gtk_tree_path_free (path);
367 gtk_tree_store_insert_before (GTK_TREE_STORE (tm), &cnewpos, newpos, 532 gtk_tree_store_insert_before (GTK_TREE_STORE (tm), &cnewpos, newpos,
368 NULL); 533 NULL);
369 move_entry (ctx, tm, &child, &cnewpos, GNUNET_NO); 534 copy_entry (ctx, tm, &child, &cnewpos, GNUNET_NO);
370 path = gtk_tree_row_reference_get_path (rr2); 535 path = gtk_tree_row_reference_get_path (crr);
371 gtk_tree_row_reference_free (rr2); 536 gtk_tree_row_reference_free (crr);
372 GNUNET_assert (TRUE == gtk_tree_model_get_iter (tm, &child, path)); 537 GNUNET_assert (TRUE == gtk_tree_model_get_iter (tm, &child, path));
373 gtk_tree_path_free (path); 538 gtk_tree_path_free (path);
374 } 539 }
375 while (TRUE == gtk_tree_model_iter_next (tm, &child)); 540 while (gtk_tree_model_iter_next (tm, &child));
376 } 541 }
377 g_free (short_fn); 542
378 g_free (fsf); 543 /* update selection, etc. if applicable */
379 if (dsel == GNUNET_YES) 544 if (dsel == GNUNET_YES)
380 { 545 {
381 path = gtk_tree_row_reference_get_path (rr); 546 path = gtk_tree_row_reference_get_path (rr);
@@ -384,28 +549,37 @@ move_entry (struct MainPublishingDialogContext *ctx, GtkTreeModel * tm, GtkTreeI
384 GNUNET_assert (TRUE == gtk_tree_model_get_iter (tm, newpos, path)); 549 GNUNET_assert (TRUE == gtk_tree_model_get_iter (tm, newpos, path));
385 gtk_tree_path_free (path); 550 gtk_tree_path_free (path);
386 gtk_tree_selection_select_iter (ctx->file_info_selection, newpos); 551 gtk_tree_selection_select_iter (ctx->file_info_selection, newpos);
552 update_selectivity (ctx);
387 } 553 }
388 update_selectivity (ctx);
389} 554}
390 555
391 556
392/** 557/**
393 * User has changed the "current" identifier for the content in 558 * User has changed the "update" identifier for the content in
394 * the GtkTreeView. Update the model. 559 * the GtkTreeView. Update the model.
560 *
561 * @param renderer pseudonym renderer that notified us about the edit
562 * @param cpath where the edit happened
563 * @param new_text the new value
564 * @param user_data master publishing dialog context of our window
395 */ 565 */
396void GNUNET_GTK_master_publish_dialog_pseudonym_updates_renderer_edited_cb 566void
397 (GtkCellRendererText * renderer, gchar * cpath, gchar * new_text, 567GNUNET_GTK_master_publish_dialog_pseudonym_updates_renderer_edited_cb (GtkCellRendererText * renderer,
398 struct MainPublishingDialogContext *ctx) 568 gchar * cpath,
569 gchar * new_text,
570 gpointer user_data)
399{ 571{
572 struct MainPublishingDialogContext *ctx = user_data;
400 GtkTreeIter iter; 573 GtkTreeIter iter;
401 574
402 if (TRUE != 575 if (! gtk_tree_model_get_iter_from_string (ctx->pseudonym_treemodel, &iter, cpath))
403 gtk_tree_model_get_iter_from_string (ctx->pseudonym_treemodel, &iter, cpath))
404 { 576 {
405 GNUNET_break (0); 577 GNUNET_break (0);
406 return; 578 return;
407 } 579 }
408 gtk_tree_store_set (GTK_TREE_STORE (ctx->pseudonym_treemodel), &iter, 5, new_text, -1); 580 gtk_tree_store_set (GTK_TREE_STORE (ctx->pseudonym_treemodel), &iter,
581 5, new_text,
582 -1);
409 update_selectivity (ctx); 583 update_selectivity (ctx);
410} 584}
411 585
@@ -413,44 +587,59 @@ void GNUNET_GTK_master_publish_dialog_pseudonym_updates_renderer_edited_cb
413/** 587/**
414 * User has changed the "current" identifier for the content in 588 * User has changed the "current" identifier for the content in
415 * the GtkTreeView. Update the model. 589 * the GtkTreeView. Update the model.
590 *
591 * @param renderer pseudonym renderer that notified us about the edit
592 * @param cpath where the edit happened
593 * @param new_text the new value
594 * @param user_data master publishing dialog context of our window
416 */ 595 */
417void GNUNET_GTK_master_publish_dialog_pseudonym_identifier_renderer_edited_cb 596void
418 (GtkCellRendererText * renderer, gchar * cpath, gchar * new_text, 597GNUNET_GTK_master_publish_dialog_pseudonym_identifier_renderer_edited_cb (GtkCellRendererText * renderer,
419 struct MainPublishingDialogContext *ctx) 598 gchar * cpath,
599 gchar * new_text,
600 gpointer user_data)
420{ 601{
602 struct MainPublishingDialogContext *ctx = user_data;
421 GtkTreeIter iter; 603 GtkTreeIter iter;
422 604
423 if (TRUE != 605 if (! gtk_tree_model_get_iter_from_string (ctx->pseudonym_treemodel, &iter, cpath))
424 gtk_tree_model_get_iter_from_string (ctx->pseudonym_treemodel, &iter, cpath))
425 { 606 {
426 GNUNET_break (0); 607 GNUNET_break (0);
427 return; 608 return;
428 } 609 }
429 gtk_tree_store_set (GTK_TREE_STORE (ctx->pseudonym_treemodel), &iter, 2, new_text, -1); 610 gtk_tree_store_set (GTK_TREE_STORE (ctx->pseudonym_treemodel), &iter,
611 2, new_text,
612 -1);
430 update_selectivity (ctx); 613 update_selectivity (ctx);
431} 614}
432 615
433 616
617/**
618 * User has clicked on the 'right' button to move files in the master
619 * edit dialog tree view. Execute the move.
620 *
621 * @param dummy the button
622 * @param user_data master publishing dialog context of our window
623 */
434void 624void
435GNUNET_GTK_master_publish_dialog_right_button_clicked_cb (GtkWidget * dummy, 625GNUNET_GTK_master_publish_dialog_right_button_clicked_cb (GtkWidget * dummy,
436 struct MainPublishingDialogContext *ctx) 626 gpointer user_data)
437{ 627{
628 struct MainPublishingDialogContext *ctx = user_data;
438 GtkTreeIter iter; 629 GtkTreeIter iter;
439 GtkTreeIter parent; 630 GtkTreeIter parent;
440 GtkTreeIter pred; 631 GtkTreeIter pred;
441 GtkTreeIter prev; 632 GtkTreeIter prev;
442 GtkTreeIter pos; 633 GtkTreeIter pos;
443 634
444 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 635 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
445 { 636 {
446 GNUNET_break (0); 637 GNUNET_break (0);
447 return; 638 return;
448 } 639 }
449 if (TRUE == gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter)) 640 if (gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter))
450 { 641 GNUNET_assert (gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent));
451 GNUNET_assert (TRUE == gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent)); 642 else if (! gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred))
452 }
453 else if (TRUE != gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred))
454 { 643 {
455 GNUNET_break (0); 644 GNUNET_break (0);
456 return; 645 return;
@@ -460,53 +649,68 @@ GNUNET_GTK_master_publish_dialog_right_button_clicked_cb (GtkWidget * dummy,
460 while (GNUNET_YES != gtk_tree_iter_equals (ctx->file_info_treemodel, &pred, &iter)) 649 while (GNUNET_YES != gtk_tree_iter_equals (ctx->file_info_treemodel, &pred, &iter))
461 { 650 {
462 prev = pred; 651 prev = pred;
463 GNUNET_assert (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred)); 652 GNUNET_assert (gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred));
464 } 653 }
465 gtk_tree_store_insert_before (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, &prev, NULL); 654 gtk_tree_store_insert_before (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, &prev, NULL);
466 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 655 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
467 { 656 {
468 GNUNET_break (0); 657 GNUNET_break (0);
469 return; 658 return;
470 } 659 }
471 move_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES); 660 copy_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES);
472 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter); 661 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
473} 662}
474 663
475 664
665/**
666 * User has clicked on the 'left' button to move files in the master
667 * edit dialog tree view. Execute the move.
668 *
669 * @param dummy the button
670 * @param user_data master publishing dialog context of our window
671 */
476void 672void
477GNUNET_GTK_master_publish_dialog_left_button_clicked_cb (GtkWidget * dummy, 673GNUNET_GTK_master_publish_dialog_left_button_clicked_cb (GtkWidget * dummy,
478 struct MainPublishingDialogContext *ctx) 674 gpointer user_data)
479{ 675{
676 struct MainPublishingDialogContext *ctx = user_data;
480 GtkTreeIter iter; 677 GtkTreeIter iter;
481 GtkTreeIter parent; 678 GtkTreeIter parent;
482 GtkTreeIter pos; 679 GtkTreeIter pos;
483 680
484 681 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
485 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
486 { 682 {
487 GNUNET_break (0); 683 GNUNET_break (0);
488 return; 684 return;
489 } 685 }
490 if (TRUE != gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter)) 686 if (! gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter))
491 { 687 {
492 GNUNET_break (0); 688 GNUNET_break (0);
493 return; 689 return;
494 } 690 }
495 gtk_tree_store_insert_after (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, &parent); 691 gtk_tree_store_insert_after (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, &parent);
496 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 692 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
497 { 693 {
498 GNUNET_break (0); 694 GNUNET_break (0);
499 return; 695 return;
500 } 696 }
501 move_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES); 697 copy_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES);
502 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter); 698 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
503} 699}
504 700
505 701
702/**
703 * User has clicked on the 'up' button to move files in the master
704 * edit dialog tree view. Execute the move.
705 *
706 * @param dummy the button
707 * @param user_data master publishing dialog context of our window
708 */
506void 709void
507GNUNET_GTK_master_publish_dialog_up_button_clicked_cb (GtkWidget * dummy, 710GNUNET_GTK_master_publish_dialog_up_button_clicked_cb (GtkWidget * dummy,
508 struct MainPublishingDialogContext *ctx) 711 gpointer user_data)
509{ 712{
713 struct MainPublishingDialogContext *ctx = user_data;
510 GtkTreeIter iter; 714 GtkTreeIter iter;
511 GtkTreeIter parent; 715 GtkTreeIter parent;
512 GtkTreeIter pred; 716 GtkTreeIter pred;
@@ -514,101 +718,249 @@ GNUNET_GTK_master_publish_dialog_up_button_clicked_cb (GtkWidget * dummy,
514 GtkTreeIter *pprev; 718 GtkTreeIter *pprev;
515 GtkTreeIter pos; 719 GtkTreeIter pos;
516 720
517 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 721 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
518 { 722 {
519 GNUNET_break (0); 723 GNUNET_break (0);
520 return; 724 return;
521 } 725 }
522 if (TRUE == gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter)) 726 if (! gtk_tree_model_iter_parent (ctx->file_info_treemodel, &parent, &iter))
523 { 727 {
524 GNUNET_assert (TRUE == gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent)); 728 GNUNET_assert (TRUE == gtk_tree_model_iter_children (ctx->file_info_treemodel, &pred, &parent));
525 pprev = &parent; 729 pprev = &parent;
526 } 730 }
527 else if (TRUE == gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred)) 731 else if (! gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &pred))
528 {
529 pprev = NULL;
530 }
531 else
532 { 732 {
533 GNUNET_break (0); 733 GNUNET_break (0);
534 return; 734 return;
535 } 735 } else
736 pprev = NULL;
536 /* iterate over 'next' of pred to find out who our predecessor is! */ 737 /* iterate over 'next' of pred to find out who our predecessor is! */
537 while (GNUNET_YES != gtk_tree_iter_equals (ctx->file_info_treemodel, &pred, &iter)) 738 while (GNUNET_YES != gtk_tree_iter_equals (ctx->file_info_treemodel, &pred, &iter))
538 { 739 {
539 prev = pred; 740 prev = pred;
540 pprev = &prev; 741 pprev = &prev;
541 GNUNET_assert (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred)); 742 GNUNET_assert (gtk_tree_model_iter_next (ctx->file_info_treemodel, &pred));
542 } 743 }
543 gtk_tree_store_insert_before (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, pprev); 744 gtk_tree_store_insert_before (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, pprev);
544 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 745 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
545 { 746 {
546 GNUNET_break (0); 747 GNUNET_break (0);
547 return; 748 return;
548 } 749 }
549 move_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES); 750 copy_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES);
550 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter); 751 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
551} 752}
552 753
553 754
755/**
756 * User has clicked on the 'down' button to move files in the master
757 * edit dialog tree view. Execute the move.
758 *
759 * @param dummy the button
760 * @param user_data master publishing dialog context of our window
761 */
554void 762void
555GNUNET_GTK_master_publish_dialog_down_button_clicked_cb (GtkWidget * dummy, 763GNUNET_GTK_master_publish_dialog_down_button_clicked_cb (GtkWidget * dummy,
556 struct MainPublishingDialogContext *ctx) 764 gpointer user_data)
557{ 765{
766 struct MainPublishingDialogContext *ctx = user_data;
558 GtkTreeIter iter; 767 GtkTreeIter iter;
559 GtkTreeIter next; 768 GtkTreeIter next;
560 GtkTreeIter pos; 769 GtkTreeIter pos;
561 770
562 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 771 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
563 { 772 {
564 GNUNET_break (0); 773 GNUNET_break (0);
565 return; 774 return;
566 } 775 }
567 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &next)) 776 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &next))
568 { 777 {
569 GNUNET_break (0); 778 GNUNET_break (0);
570 return; 779 return;
571 } 780 }
572 GNUNET_assert (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &next)); 781 GNUNET_assert (gtk_tree_model_iter_next (ctx->file_info_treemodel, &next));
573 gtk_tree_store_insert_after (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, &next); 782 gtk_tree_store_insert_after (GTK_TREE_STORE (ctx->file_info_treemodel), &pos, NULL, &next);
574 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 783 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
575 { 784 {
576 GNUNET_break (0); 785 GNUNET_break (0);
577 return; 786 return;
578 } 787 }
579 move_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES); 788 copy_entry (ctx, ctx->file_info_treemodel, &iter, &pos, GNUNET_YES);
580 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter); 789 remove_old_entry (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
581} 790}
582 791
583 792
793/**
794 * User has clicked on the 'new' button to add an empty directory in the master
795 * edit dialog tree view. Add an empty directory.
796 *
797 * @param dummy the button
798 * @param user_data master publishing dialog context of our window
799 */
584void 800void
585GNUNET_GTK_master_publish_dialog_new_button_clicked_cb (GtkWidget * dummy, 801GNUNET_GTK_master_publish_dialog_new_button_clicked_cb (GtkWidget * dummy,
586 struct MainPublishingDialogContext *ctx) 802 gpointer user_data)
587{ 803{
804 struct MainPublishingDialogContext *ctx = user_data;
588 GtkTreeIter iter; 805 GtkTreeIter iter;
589 GtkTreeIter pos; 806 GtkTreeIter pos;
590 struct GNUNET_FS_BlockOptions bo; 807 struct GNUNET_FS_BlockOptions bo;
591 808
592 /* FIXME: consider opening a dialog to get 809 /* FIXME-FEATURE: consider opening a dialog to get anonymity,
593 * anonymity, priority and expiration prior 810 priority and expiration prior to calling this function (currently
594 * to calling this function (currently we 811 we use default values for those). Or getting these values from
595 * use default values for those). 812 the configuration. */
596 * Or getting these values from the configuration.
597 */
598 bo.anonymity_level = 1; 813 bo.anonymity_level = 1;
599 bo.content_priority = 1000; 814 bo.content_priority = 1000;
600 bo.expiration_time = 815 bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_YEARS);
601 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_YEARS);
602 bo.replication_level = 1; 816 bo.replication_level = 1;
603 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 817 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
604 {
605 create_dir_at_iter (ctx, "unnamed/", &bo, NULL, &pos); 818 create_dir_at_iter (ctx, "unnamed/", &bo, NULL, &pos);
819 else
820 create_dir_at_iter (ctx, "unnamed/", &bo, &iter, &pos);
821}
822
823
824/**
825 * Free row reference stored in the file information's
826 * client-info pointer.
827 *
828 * @param cls always NULL
829 * @param fi the file information that is being destroyed, unused
830 * @param length length of the file, unused
831 * @param meta meta data, unused
832 * @param uri keyword URI, unused
833 * @param bo publishing options, unused
834 * @param do_index indexing option, unused
835 * @param client_info pointer to the GtkTreeRowReference, freed
836 * @return GNUNET_OK to traverse entire subtree
837 */
838static int
839free_fi_row_reference (void *cls, struct GNUNET_FS_FileInformation *fi,
840 uint64_t length, struct GNUNET_CONTAINER_MetaData *meta,
841 struct GNUNET_FS_Uri **uri,
842 struct GNUNET_FS_BlockOptions *bo, int *do_index,
843 void **client_info)
844{
845 GtkTreeRowReference *row = *client_info;
846
847 if (row == NULL)
848 {
849 GNUNET_break (0);
850 return GNUNET_OK;
851 }
852 gtk_tree_row_reference_free (row);
853 *client_info = NULL;
854 return GNUNET_OK;
855}
856
857
858/**
859 * User has clicked on the 'delete' button to delete a file or directory in the master
860 * edit dialog tree view. Delete the selected entry.
861 *
862 * @param dummy the button
863 * @param user_data master publishing dialog context of our window
864 */
865void
866GNUNET_GTK_master_publish_dialog_delete_button_clicked_cb (GtkWidget * dummy,
867 gpointer user_data)
868{
869 struct MainPublishingDialogContext *ctx = user_data;
870 GtkTreeIter iter;
871 struct GNUNET_FS_FileInformation *fip;
872
873 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter))
874 {
875 GNUNET_break (0);
606 return; 876 return;
607 } 877 }
608 create_dir_at_iter (ctx, "unnamed/", &bo, &iter, &pos); 878 gtk_tree_model_get (ctx->file_info_treemodel, &iter, 5, &fip, -1);
879 GNUNET_FS_file_information_destroy (fip, &free_fi_row_reference, NULL);
880 /* FIXME-BUG: the call above frees the row references in the entire
881 subtree; however, with the 'remove' operation below we
882 ONLY delete the top-level entry; we probably want to delete
883 the entire directory subtree here... */
884 gtk_tree_store_remove (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
885 update_selectivity (ctx);
886}
887
888
889
890/* ******************** progress dialog / import of directories * ********************** */
891
892
893/**
894 * Close the progress dialog and free its handle.
895 *
896 * @param adcc context for the progress dialog to close
897 */
898static void
899destroy_progress_dialog (struct AddDirClientContext *adcc)
900{
901 GNUNET_assert (NULL == adcc->ds);
902 gtk_widget_destroy (adcc->progress_dialog);
903 g_object_unref (G_OBJECT (adcc->progress_dialog_builder));
904 GNUNET_CONTAINER_DLL_remove (adcc->ctx->adddir_head,
905 adcc->ctx->adddir_tail,
906 adcc);
907 update_selectivity (adcc->ctx);
908 GNUNET_free (adcc);
909}
910
911
912/**
913 * User clicked on the 'cancel' button of the progress dialog.
914 * Cancel the operation.
915 *
916 * @param button the cancel button
917 * @param user_data progress dialog context of our window
918 */
919void
920GNUNET_FS_GTK_progress_dialog_cancel_button_clicked_cb (GtkButton *button,
921 gpointer user_data)
922{
923 struct AddDirClientContext *adcc = user_data;
924
925 if (NULL == adcc->ds)
926 {
927 GNUNET_break (0);
928 }
929 else
930 {
931 /* signal the scanner to finish */
932 GNUNET_FS_directory_scan_abort (adcc->ds);
933 adcc->ds = NULL;
934 }
935 destroy_progress_dialog (adcc);
936}
937
938
939/**
940 * User attempted to close the progress dialog. Refuse.
941 *
942 * @param widget the widget emitting the event
943 * @param event the event
944 * @param user_data progress dialog context of our window
945 * @return FALSE to refuse to close
946 */
947gboolean
948GNUNET_FS_GTK_progress_dialog_delete_event_cb (GtkWidget *widget,
949 GdkEvent * event,
950 void *cls)
951{
952 /* Don't allow GTK to kill the window, until the scan is finished */
953 return FALSE;
609} 954}
610 955
611 956
957/**
958 * Display some additional information in the text area of the
959 * progress dialog.
960 *
961 * @param adcc progress dialog context of our window
962 * @param text text to add
963 */
612static void 964static void
613insert_progress_dialog_text (struct AddDirClientContext *adcc, 965insert_progress_dialog_text (struct AddDirClientContext *adcc,
614 const char *text) 966 const char *text)
@@ -616,13 +968,17 @@ insert_progress_dialog_text (struct AddDirClientContext *adcc,
616 gtk_text_buffer_insert_at_cursor (adcc->progress_dialog_textbuffer, 968 gtk_text_buffer_insert_at_cursor (adcc->progress_dialog_textbuffer,
617 text, -1); 969 text, -1);
618 gtk_text_view_place_cursor_onscreen (adcc->progress_dialog_textview); 970 gtk_text_view_place_cursor_onscreen (adcc->progress_dialog_textview);
619 gtk_adjustment_set_value (adcc->textview_vertial_adjustment, 971 gtk_adjustment_set_value (adcc->textview_vertical_adjustment,
620 gtk_adjustment_get_upper (adcc->textview_vertial_adjustment)); 972 gtk_adjustment_get_upper (adcc->textview_vertical_adjustment));
621} 973}
622 974
623 975
976/**
977 *
978 */
624static void 979static void
625add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts, 980add_item (struct AddDirClientContext *adcc,
981 GtkTreeStore *ts,
626 struct GNUNET_FS_ShareTreeItem *item, 982 struct GNUNET_FS_ShareTreeItem *item,
627 GtkTreeIter *parent, 983 GtkTreeIter *parent,
628 GtkTreeIter *sibling, 984 GtkTreeIter *sibling,
@@ -640,12 +996,10 @@ add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
640 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "stat", item->filename); 996 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "stat", item->filename);
641 return; 997 return;
642 } 998 }
643
644 gtk_tree_store_insert_after (ts, item_iter, parent, sibling); 999 gtk_tree_store_insert_after (ts, item_iter, parent, sibling);
645 path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), item_iter); 1000 path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), item_iter);
646 row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path); 1001 row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path);
647 gtk_tree_path_free (path); 1002 gtk_tree_path_free (path);
648
649 if (item->is_directory) 1003 if (item->is_directory)
650 { 1004 {
651 if (NULL != item->meta) 1005 if (NULL != item->meta)
@@ -675,14 +1029,15 @@ add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
675 else 1029 else
676 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (sbuf.st_size); 1030 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (sbuf.st_size);
677 1031
678 gtk_tree_store_set (ts, item_iter, 0, file_size_fancy, 1032 gtk_tree_store_set (ts, item_iter,
679 1, (gboolean) adcc->directory_scan_do_index, 1033 0, file_size_fancy,
680 2, item->short_filename, 1034 1, (gboolean) adcc->directory_scan_do_index,
681 3, (guint) adcc->directory_scan_bo.anonymity_level, 1035 2, item->short_filename,
682 4, (guint) adcc->directory_scan_bo.content_priority, 1036 3, (guint) adcc->directory_scan_bo.anonymity_level,
683 5, fi, 1037 4, (guint) adcc->directory_scan_bo.content_priority,
684 6, (guint64) adcc->directory_scan_bo.expiration_time.abs_value, 1038 5, fi,
685 7, (guint) adcc->directory_scan_bo.replication_level, -1); 1039 6, (guint64) adcc->directory_scan_bo.expiration_time.abs_value,
1040 7, (guint) adcc->directory_scan_bo.replication_level, -1);
686 GNUNET_free (file_size_fancy); 1041 GNUNET_free (file_size_fancy);
687} 1042}
688 1043
@@ -715,19 +1070,9 @@ add_share_items_to_treestore (struct AddDirClientContext *adcc,
715} 1070}
716 1071
717 1072
718static void 1073/**
719close_scan (struct AddDirClientContext *adcc) 1074 *
720{ 1075 */
721 gtk_widget_destroy (adcc->progress_dialog);
722 g_object_unref (G_OBJECT (adcc->progress_dialog_builder));
723 GNUNET_CONTAINER_DLL_remove (adcc->ctx->adddir_head,
724 adcc->ctx->adddir_tail,
725 adcc);
726 update_selectivity (adcc->ctx);
727 GNUNET_free (adcc);
728}
729
730
731static void 1076static void
732directory_scan_cb (void *cls, 1077directory_scan_cb (void *cls,
733 const char *filename, int is_directory, 1078 const char *filename, int is_directory,
@@ -810,17 +1155,20 @@ directory_scan_cb (void *cls,
810 adcc->ds = NULL; 1155 adcc->ds = NULL;
811 break; 1156 break;
812 case GNUNET_FS_DIRSCANNER_FINISHED: 1157 case GNUNET_FS_DIRSCANNER_FINISHED:
813 insert_progress_dialog_text (adcc, _("Scanner has finished.\n")); 1158 {
814 adcc->directory_scan_result = GNUNET_FS_directory_scan_get_result (adcc->ds); 1159 struct GNUNET_FS_ShareTreeItem *directory_scan_result;
815 adcc->ds = NULL; 1160
816 GNUNET_FS_share_tree_trim (adcc->directory_scan_result); 1161 insert_progress_dialog_text (adcc, _("Scanner has finished.\n"));
817 add_share_items_to_treestore (adcc, 1162 directory_scan_result = GNUNET_FS_directory_scan_get_result (adcc->ds);
818 adcc->directory_scan_result, 1163 adcc->ds = NULL;
819 NULL); 1164 GNUNET_FS_share_tree_trim (directory_scan_result);
820 GNUNET_FS_share_tree_free (adcc->directory_scan_result); 1165 add_share_items_to_treestore (adcc,
821 adcc->directory_scan_result = NULL; 1166 directory_scan_result,
822 update_selectivity (adcc->ctx); 1167 NULL);
823 close_scan (adcc); 1168 GNUNET_FS_share_tree_free (directory_scan_result);
1169 update_selectivity (adcc->ctx);
1170 destroy_progress_dialog (adcc);
1171 }
824 break; 1172 break;
825 default: 1173 default:
826 GNUNET_break (0); 1174 GNUNET_break (0);
@@ -829,6 +1177,9 @@ directory_scan_cb (void *cls,
829} 1177}
830 1178
831 1179
1180/**
1181 *
1182 */
832static void 1183static void
833scan_file_or_directory (struct MainPublishingDialogContext *ctx, 1184scan_file_or_directory (struct MainPublishingDialogContext *ctx,
834 gchar *filename, 1185 gchar *filename,
@@ -854,13 +1205,10 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx,
854 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object ( 1205 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (
855 adcc->progress_dialog_builder, 1206 adcc->progress_dialog_builder,
856 "GNUNET_FS_GTK_progress_dialog_progressbar")); 1207 "GNUNET_FS_GTK_progress_dialog_progressbar"));
857 adcc->progress_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (
858 adcc->progress_dialog_builder,
859 "GNUNET_FS_GTK_progress_dialog_cancel_button"));
860 adcc->progress_dialog_textview = GTK_TEXT_VIEW ( 1208 adcc->progress_dialog_textview = GTK_TEXT_VIEW (
861 gtk_builder_get_object (adcc->progress_dialog_builder, 1209 gtk_builder_get_object (adcc->progress_dialog_builder,
862 "GNUNET_FS_GTK_progress_dialog_textview")); 1210 "GNUNET_FS_GTK_progress_dialog_textview"));
863 adcc->textview_vertial_adjustment = GTK_ADJUSTMENT ( 1211 adcc->textview_vertical_adjustment = GTK_ADJUSTMENT (
864 gtk_builder_get_object (adcc->progress_dialog_builder, 1212 gtk_builder_get_object (adcc->progress_dialog_builder,
865 "GNUNET_FS_GTK_progress_dialog_textview_vertical_adjustment")); 1213 "GNUNET_FS_GTK_progress_dialog_textview_vertical_adjustment"));
866 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER ( 1214 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER (
@@ -868,9 +1216,6 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx,
868 "GNUNET_FS_GTK_progress_dialog_textbuffer")); 1216 "GNUNET_FS_GTK_progress_dialog_textbuffer"));
869 gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer, 1217 gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer,
870 &iter); 1218 &iter);
871 adcc->progress_dialog_textmark = gtk_text_buffer_create_mark (
872 adcc->progress_dialog_textbuffer, "scroll",
873 &iter, FALSE);
874#if VERBOSE_PROGRESS 1219#if VERBOSE_PROGRESS
875 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (adcc->progress_dialog_builder, 1220 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (adcc->progress_dialog_builder,
876 "GNUNET_FS_GTK_progress_dialog_scrolled_window"))); 1221 "GNUNET_FS_GTK_progress_dialog_scrolled_window")));
@@ -884,6 +1229,9 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx,
884} 1229}
885 1230
886 1231
1232/**
1233 * @param user_data master publishing dialog context of our window
1234 */
887static void 1235static void
888publish_directory_dialog_response_cb (GtkDialog * dialog, 1236publish_directory_dialog_response_cb (GtkDialog * dialog,
889 gint response_id, 1237 gint response_id,
@@ -936,6 +1284,9 @@ publish_directory_dialog_response_cb (GtkDialog * dialog,
936} 1284}
937 1285
938 1286
1287/**
1288 * @param user_data master publishing dialog context of our window
1289 */
939static void 1290static void
940publish_file_dialog_response_cb (GtkDialog * dialog, 1291publish_file_dialog_response_cb (GtkDialog * dialog,
941 gint response_id, 1292 gint response_id,
@@ -996,45 +1347,113 @@ publish_file_dialog_response_cb (GtkDialog * dialog,
996} 1347}
997 1348
998 1349
1350/**
1351 * User clicked on the 'add' button in the master publish dialog.
1352 * Create the dialog to allow the user to select a file to add.
1353 *
1354 * FIXME-UGLY: lots of code duplication between files & directories here...
1355 *
1356 * @param dummy the button that was pressed
1357 * @param user_data master publishing dialog context of our window
1358 */
999void 1359void
1000GNUNET_GTK_master_publish_dialog_add_button_clicked_cb (GtkWidget * dummy, 1360GNUNET_GTK_master_publish_dialog_add_button_clicked_cb (GtkWidget * dummy,
1001 struct MainPublishingDialogContext *ctx) 1361 gpointer user_data)
1002{ 1362{
1363 struct MainPublishingDialogContext *ctx = user_data;
1003 GtkWidget *ad; 1364 GtkWidget *ad;
1004
1005 GtkComboBox *combo; 1365 GtkComboBox *combo;
1006 GtkTreeModel *anon_treemodel; 1366 GtkTreeModel *anon_treemodel;
1007 1367
1368 /* FIXME-UGLY: should we use a fresh, specific context for this dialog?
1369 FIXME-BUG: how does this right now prevent two dialogs from being opened?
1370 (or the master dialog from being closed in the meantime?) */
1008 ctx->open_file_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_file_dialog.glade", ctx); 1371 ctx->open_file_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_file_dialog.glade", ctx);
1009 GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->open_file_builder); 1372 GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->open_file_builder);
1010 ad = GTK_WIDGET (gtk_builder_get_object 1373 ad = GTK_WIDGET (gtk_builder_get_object
1011 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog")); 1374 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog"));
1012 1375
1013 /* FIXME: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */ 1376 /* FIXME-FEATURE: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */
1014 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object ( 1377 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (ctx->open_file_builder,
1015 ctx->open_file_builder, 1378 "GNUNET_GTK_publish_file_dialog_priority_spin_button")), 1000);
1016 "GNUNET_GTK_publish_file_dialog_priority_spin_button")), 1000); 1379 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (ctx->open_file_builder,
1017 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object ( 1380 "GNUNET_GTK_publish_file_dialog_replication_spin_button")), 0);
1018 ctx->open_file_builder, 1381 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (ctx->open_file_builder,
1019 "GNUNET_GTK_publish_file_dialog_replication_spin_button")), 0); 1382 "GNUNET_GTK_publish_file_dialog_do_index_checkbutton")), TRUE);
1020 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object ( 1383
1021 ctx->open_file_builder, 1384 ctx->open_file_handler_id = g_signal_connect (G_OBJECT (ad), "response",
1022 "GNUNET_GTK_publish_file_dialog_do_index_checkbutton")), TRUE); 1385 G_CALLBACK (publish_file_dialog_response_cb), ctx);
1023
1024 ctx->open_file_handler_id = g_signal_connect (G_OBJECT (ad), "response", G_CALLBACK (publish_file_dialog_response_cb), ctx);
1025 1386
1387 /* FIXME-BUG-MAYBE: possibly bad sharing of the anonymity tree model */
1026 anon_treemodel = GTK_TREE_MODEL (gtk_builder_get_object (ctx->main_window_builder, 1388 anon_treemodel = GTK_TREE_MODEL (gtk_builder_get_object (ctx->main_window_builder,
1027 "main_window_search_anonymity_liststore")); 1389 "main_window_search_anonymity_liststore"));
1028 combo = GTK_COMBO_BOX (gtk_builder_get_object (ctx->open_file_builder, 1390 combo = GTK_COMBO_BOX (gtk_builder_get_object (ctx->open_file_builder,
1029 "GNUNET_GTK_publish_file_dialog_anonymity_combobox")); 1391 "GNUNET_GTK_publish_file_dialog_anonymity_combobox"));
1030 gtk_combo_box_set_model (combo, anon_treemodel); 1392 gtk_combo_box_set_model (combo, anon_treemodel);
1031 1393
1394 /* show dialog */
1032 gtk_window_set_transient_for (GTK_WINDOW (ad), ctx->master_pubdialog); 1395 gtk_window_set_transient_for (GTK_WINDOW (ad), ctx->master_pubdialog);
1396 gtk_window_present (GTK_WINDOW (ad));
1397}
1398
1399
1400/**
1401 * User clicked on the 'open' button in the master publish dialog.
1402 * Create the dialog to allow the user to select a directory.
1403 *
1404 * FIXME-UGLY: lots of code duplication between files & directories here...
1405 *
1406 * @param dummy the button that was pressed
1407 * @param user_data master publishing dialog context of our window
1408 */
1409void
1410GNUNET_GTK_master_publish_dialog_open_button_clicked_cb (GtkWidget * dummy,
1411 gpointer user_data)
1412{
1413 struct MainPublishingDialogContext *ctx = user_data;
1414 GtkWidget *ad;
1415 GtkComboBox *combo;
1416 GtkTreeModel *anon_treemodel;
1417
1418 /* FIXME-UGLY: should we use a fresh, specific context for this dialog?
1419 FIXME-BUG: how does this right now prevent two dialogs from being opened?
1420 (or the master dialog from being closed in the meantime?) */
1421
1422 ctx->open_directory_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_directory_dialog.glade", ctx);
1423 GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->open_directory_builder);
1424
1425 /* FIXME-FEATURE: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */
1426 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (ctx->open_directory_builder,
1427 "GNUNET_GTK_publish_directory_dialog_priority_spin_button")), 1000);
1428 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object (ctx->open_directory_builder,
1429 "GNUNET_GTK_publish_directory_dialog_replication_spin_button")), 0);
1430 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (ctx->open_directory_builder,
1431 "GNUNET_GTK_publish_directory_dialog_do_index_checkbutton")), TRUE);
1432
1433 ad = GTK_WIDGET (gtk_builder_get_object
1434 (ctx->open_directory_builder, "GNUNET_GTK_publish_directory_dialog"));
1435
1436 ctx->open_directory_handler_id = g_signal_connect (G_OBJECT (ad), "response",
1437 G_CALLBACK (publish_directory_dialog_response_cb), ctx);
1033 1438
1439 /* FIXME-BUG-MAYBE: possibly bad sharing of the anonymity tree model */
1440 anon_treemodel = GTK_TREE_MODEL (gtk_builder_get_object (ctx->main_window_builder,
1441 "main_window_search_anonymity_liststore"));
1442 combo = GTK_COMBO_BOX (gtk_builder_get_object (ctx->open_directory_builder,
1443 "GNUNET_GTK_publish_directory_dialog_anonymity_combobox"));
1444 gtk_combo_box_set_model (combo, anon_treemodel);
1445
1446 /* show dialog */
1447 gtk_window_set_transient_for (GTK_WINDOW (ad), ctx->master_pubdialog);
1034 gtk_window_present (GTK_WINDOW (ad)); 1448 gtk_window_present (GTK_WINDOW (ad));
1035} 1449}
1036 1450
1037 1451
1452
1453/* ********************************* editing sub-dialog ****************************************** */
1454
1455
1456
1038struct EditPublishContext 1457struct EditPublishContext
1039{ 1458{
1040 struct GNUNET_FS_FileInformation *fip; 1459 struct GNUNET_FS_FileInformation *fip;
@@ -1101,6 +1520,9 @@ master_publish_edit_publish_dialog_cb (gpointer cls,
1101} 1520}
1102 1521
1103 1522
1523/**
1524 * @param user_data master publishing dialog context of our window
1525*/
1104void 1526void
1105GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy, 1527GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy,
1106 struct MainPublishingDialogContext *ctx) 1528 struct MainPublishingDialogContext *ctx)
@@ -1132,147 +1554,208 @@ GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy,
1132} 1554}
1133 1555
1134 1556
1557
1558/* ******************** master edit dialog shutdown *********************** */
1559
1560
1561
1135/** 1562/**
1136 * Free row reference stored in the file information's 1563 * Get the file information struct corresponding to the
1137 * client-info pointer. 1564 * given iter in the publish dialog tree model. Recursively
1565 * builds the file information struct from the subtree.
1566 *
1567 * @param tm model to grab fi from
1568 * @param iter position to grab fi from
1569 * @return file information from the given position (never NULL)
1138 */ 1570 */
1139static int 1571static struct GNUNET_FS_FileInformation *
1140free_fi_row_reference (void *cls, struct GNUNET_FS_FileInformation *fi, 1572get_file_information (GtkTreeModel * tm, GtkTreeIter * iter)
1141 uint64_t length, struct GNUNET_CONTAINER_MetaData *meta,
1142 struct GNUNET_FS_Uri **uri,
1143 struct GNUNET_FS_BlockOptions *bo, int *do_index,
1144 void **client_info)
1145{ 1573{
1146 GtkTreeRowReference *row = *client_info; 1574 struct GNUNET_FS_FileInformation *fi;
1575 struct GNUNET_FS_FileInformation *fic;
1576 GtkTreeIter child;
1147 1577
1148 if (row == NULL) 1578 gtk_tree_model_get (tm, iter, 5, &fi, -1);
1579 gtk_tree_store_set (GTK_TREE_STORE (tm), iter, 5, NULL, -1);
1580 GNUNET_assert (fi != NULL);
1581 if (gtk_tree_model_iter_children (tm, &child, iter))
1149 { 1582 {
1150 GNUNET_break (0); 1583 GNUNET_break (GNUNET_YES == GNUNET_FS_file_information_is_directory (fi));
1151 return GNUNET_OK; 1584 do
1585 {
1586 fic = get_file_information (tm, &child);
1587 GNUNET_break (GNUNET_OK == GNUNET_FS_file_information_add (fi, fic));
1588 }
1589 while (gtk_tree_model_iter_next (tm, &child));
1152 } 1590 }
1153 gtk_tree_row_reference_free (row); 1591 return fi;
1154 return GNUNET_OK;
1155} 1592}
1156 1593
1157 1594
1158void 1595
1159GNUNET_GTK_master_publish_dialog_delete_button_clicked_cb (GtkWidget * dummy, 1596static void
1160 struct MainPublishingDialogContext *ctx) 1597free_pseudonym_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1161{ 1598{
1162 GtkTreeIter iter; 1599 struct GNUNET_CONTAINER_MetaData *meta;
1163 struct GNUNET_FS_FileInformation *fip; 1600 struct GNUNET_FS_Namespace *ns;
1601 GtkTreeIter child;
1164 1602
1165 if (TRUE != gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &iter)) 1603 gtk_tree_model_get (tm, iter, 1, &ns, 4, &meta, -1);
1604 if (meta != NULL)
1605 GNUNET_CONTAINER_meta_data_destroy (meta);
1606 if (ns != NULL)
1166 { 1607 {
1167 GNUNET_break (0); 1608 // FIXME: delete ns?
1168 return; 1609 // GNUNET_FS_namespace_delete (nso, GNUNET_NO);
1610 }
1611 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter))
1612 {
1613 do
1614 {
1615 free_pseudonym_tree_store (tm, &child);
1616 }
1617 while (TRUE == gtk_tree_model_iter_next (tm, &child));
1169 } 1618 }
1170 gtk_tree_model_get (ctx->file_info_treemodel, &iter, 5, &fip, -1);
1171 GNUNET_FS_file_information_destroy (fip, &free_fi_row_reference, NULL);
1172 gtk_tree_store_remove (GTK_TREE_STORE (ctx->file_info_treemodel), &iter);
1173 update_selectivity (ctx);
1174} 1619}
1175 1620
1176 1621
1177void 1622static void
1178GNUNET_FS_GTK_progress_dialog_cancel_button_clicked_cb (GtkButton *button, 1623free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1179 void *cls)
1180{ 1624{
1181 struct AddDirClientContext *adcc = cls; 1625 GtkTreeIter child;
1626 struct GNUNET_FS_FileInformation *fip;
1182 1627
1183 if (adcc->ds != NULL) 1628 gtk_tree_model_get (tm, iter, 5, &fip, -1);
1629 if (fip != NULL)
1630 GNUNET_FS_file_information_destroy (fip, NULL, NULL);
1631 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter))
1184 { 1632 {
1185 /* Still scanning - signal the scanner to finish */ 1633 do
1186 GNUNET_FS_directory_scan_abort (adcc->ds); 1634 {
1187 adcc->ds = NULL; 1635 free_file_information_tree_store (tm, &child);
1636 }
1637 while (TRUE == gtk_tree_model_iter_next (tm, &child));
1188 } 1638 }
1189 close_scan (adcc);
1190} 1639}
1191 1640
1192 1641
1193gboolean 1642/**
1194GNUNET_FS_GTK_progress_dialog_delete_event_cb (GtkWidget *widget, 1643 * FIXME: badly named!
1195 GdkEvent * event, 1644 *
1196 void *cls) 1645 * @param ctx master dialog context
1197{ 1646 * @param ret GTK_RESPONSE_OK if the dialog 'execute' button was pressed,
1198 /* Don't allow GTK to kill the window, until the scan is finished */ 1647 * GTK_RESPONSE_CANCEL if the dialog was aborted
1199 return GNUNET_NO; 1648 * @return WHAT?
1200} 1649 */
1201 1650static int
1202 1651hide_master_publish_dialog (struct MainPublishingDialogContext *ctx, gint ret)
1203void
1204GNUNET_GTK_master_publish_dialog_open_button_clicked_cb (GtkWidget * dummy,
1205 struct MainPublishingDialogContext *ctx)
1206{ 1652{
1207 GtkWidget *ad; 1653 GtkTreeIter iter;
1654 gpointer namespace;
1655 gchar *namespace_id;
1656 gchar *namespace_uid;
1657 struct GNUNET_FS_FileInformation *fi;
1208 1658
1209 GtkComboBox *combo; 1659 /* Don't close until all scanners are finished */
1210 GtkTreeModel *anon_treemodel; 1660 if (ctx->adddir_head != NULL)
1661 return GNUNET_NO;
1211 1662
1212 ctx->open_directory_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_directory_dialog.glade", ctx); 1663 if (ret == GTK_RESPONSE_OK)
1213 GNUNET_FS_GTK_setup_expiration_year_adjustment (ctx->open_directory_builder); 1664 {
1665 if (TRUE == gtk_tree_selection_get_selected (ctx->pseudonym_selection, NULL, &iter))
1666 {
1667 gtk_tree_model_get (ctx->pseudonym_treemodel, &iter, 1, &namespace, 2, &namespace_id, 5,
1668 &namespace_uid, -1);
1669 }
1670 else
1671 {
1672 namespace = NULL;
1673 namespace_id = NULL;
1674 namespace_uid = NULL;
1675 }
1676 if (gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter))
1677 do
1678 {
1679 fi = get_file_information (ctx->file_info_treemodel, &iter);
1680 /* FIXME: should we convert namespace id and uid from UTF8? */
1681 GNUNET_FS_publish_start (GNUNET_FS_GTK_get_fs_handle (), fi, namespace,
1682 namespace_id, namespace_uid,
1683 GNUNET_FS_PUBLISH_OPTION_NONE);
1684 }
1685 while (gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter));
1686 g_free (namespace_id);
1687 g_free (namespace_uid);
1688 }
1214 1689
1215 /* FIXME: Use some kind of adjustable defaults instead of 1000, 0 and TRUE */ 1690 /* free state from 'ptm' */
1216 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object ( 1691 if (TRUE == gtk_tree_model_get_iter_first (ctx->pseudonym_treemodel, &iter))
1217 ctx->open_directory_builder, 1692 do
1218 "GNUNET_GTK_publish_directory_dialog_priority_spin_button")), 1000); 1693 {
1219 gtk_spin_button_set_value (GTK_SPIN_BUTTON (gtk_builder_get_object ( 1694 free_pseudonym_tree_store (ctx->pseudonym_treemodel, &iter);
1220 ctx->open_directory_builder, 1695 }
1221 "GNUNET_GTK_publish_directory_dialog_replication_spin_button")), 0); 1696 while (TRUE == gtk_tree_model_iter_next (ctx->pseudonym_treemodel, &iter));
1222 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object ( 1697 gtk_tree_store_clear (GTK_TREE_STORE (ctx->pseudonym_treemodel));
1223 ctx->open_directory_builder,
1224 "GNUNET_GTK_publish_directory_dialog_do_index_checkbutton")), TRUE);
1225 1698
1226 ad = GTK_WIDGET (gtk_builder_get_object 1699 /* free state from 'tm' */
1227 (ctx->open_directory_builder, "GNUNET_GTK_publish_directory_dialog")); 1700 if (TRUE == gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter))
1701 do
1702 {
1703 free_file_information_tree_store (ctx->file_info_treemodel, &iter);
1704 }
1705 while (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter));
1706 gtk_tree_store_clear (GTK_TREE_STORE (ctx->file_info_treemodel));
1707 gtk_widget_destroy (GTK_WIDGET (ctx->master_pubdialog));
1708 g_object_unref (G_OBJECT (ctx->builder));
1709 GNUNET_free (ctx);
1710 return GNUNET_YES;
1711}
1228 1712
1229 ctx->open_directory_handler_id = g_signal_connect (G_OBJECT (ad), "response", G_CALLBACK (publish_directory_dialog_response_cb), ctx);
1230 1713
1231 anon_treemodel = GTK_TREE_MODEL (gtk_builder_get_object (ctx->main_window_builder, 1714/**
1232 "main_window_search_anonymity_liststore")); 1715 * @param user_data master publishing dialog context of our window
1233 combo = GTK_COMBO_BOX (gtk_builder_get_object (ctx->open_directory_builder, 1716*/
1234 "GNUNET_GTK_publish_directory_dialog_anonymity_combobox")); 1717void
1235 gtk_combo_box_set_model (combo, anon_treemodel); 1718GNUNET_GTK_master_publish_dialog_execute_button_clicked_cb (GtkButton * button,
1719 struct MainPublishingDialogContext *ctx)
1720{
1721 hide_master_publish_dialog (ctx, GTK_RESPONSE_OK);
1722}
1236 1723
1237 gtk_window_set_transient_for (GTK_WINDOW (ad), ctx->master_pubdialog);
1238 1724
1239 gtk_window_present (GTK_WINDOW (ad)); 1725/**
1726 * @param user_data master publishing dialog context of our window
1727*/
1728void
1729GNUNET_GTK_master_publish_dialog_cancel_button_clicked_cb (GtkButton * button,
1730 struct MainPublishingDialogContext *ctx)
1731{
1732 hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL);
1240} 1733}
1241 1734
1242 1735
1243/** 1736/**
1244 * Get the file information struct corresponding to the 1737 * @param user_data master publishing dialog context of our window
1245 * given iter in the publish dialog tree model. Recursively 1738*/
1246 * builds the file information struct from the subtree. 1739gboolean
1247 * 1740GNUNET_GTK_master_publish_dialog_delete_event_cb (GtkWidget * widget,
1248 * @param tm model to grab fi from 1741 GdkEvent * event,
1249 * @param iter position to grab fi from 1742 struct MainPublishingDialogContext *ctx)
1250 * @return file information from the given position (never NULL)
1251 */
1252static struct GNUNET_FS_FileInformation *
1253get_file_information (GtkTreeModel * tm, GtkTreeIter * iter)
1254{ 1743{
1255 struct GNUNET_FS_FileInformation *fi; 1744 /* Don't allow GTK to kill the window, until all edit dialogs are closed */
1256 struct GNUNET_FS_FileInformation *fic; 1745 if (NULL != ctx->adddir_head)
1257 GtkTreeIter child; 1746 return FALSE;
1747 /* FIXME: what about open-directory operations? */
1258 1748
1259 gtk_tree_model_get (tm, iter, 5, &fi, -1); 1749 if (GNUNET_NO == hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL))
1260 gtk_tree_store_set (GTK_TREE_STORE (tm), iter, 5, NULL, -1); 1750 return TRUE;
1261 GNUNET_assert (fi != NULL); 1751 return FALSE;
1262 if (gtk_tree_model_iter_children (tm, &child, iter))
1263 {
1264 GNUNET_break (GNUNET_YES == GNUNET_FS_file_information_is_directory (fi));
1265 do
1266 {
1267 fic = get_file_information (tm, &child);
1268 GNUNET_break (GNUNET_OK == GNUNET_FS_file_information_add (fi, fic));
1269 }
1270 while (gtk_tree_model_iter_next (tm, &child));
1271 }
1272 return fi;
1273} 1752}
1274 1753
1275 1754
1755
1756/* ******************** master edit dialog initialization *********************** */
1757
1758
1276/** 1759/**
1277 * Closure for 'add_updateable_to_ts'. 1760 * Closure for 'add_updateable_to_ts'.
1278 */ 1761 */
@@ -1433,164 +1916,75 @@ add_namespace_to_ts (void *cls, const char *name, const GNUNET_HashCode * id)
1433} 1916}
1434 1917
1435 1918
1436static void
1437free_pseudonym_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1438{
1439 struct GNUNET_CONTAINER_MetaData *meta;
1440 struct GNUNET_FS_Namespace *ns;
1441 GtkTreeIter child;
1442
1443 gtk_tree_model_get (tm, iter, 1, &ns, 4, &meta, -1);
1444 if (meta != NULL)
1445 GNUNET_CONTAINER_meta_data_destroy (meta);
1446 if (ns != NULL)
1447 {
1448 // FIXME: delete ns?
1449 // GNUNET_FS_namespace_delete (nso, GNUNET_NO);
1450 }
1451 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter))
1452 {
1453 do
1454 {
1455 free_pseudonym_tree_store (tm, &child);
1456 }
1457 while (TRUE == gtk_tree_model_iter_next (tm, &child));
1458 }
1459}
1460
1461
1462static void
1463free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1464{
1465 GtkTreeIter child;
1466 struct GNUNET_FS_FileInformation *fip;
1467
1468 gtk_tree_model_get (tm, iter, 5, &fip, -1);
1469 if (fip != NULL)
1470 GNUNET_FS_file_information_destroy (fip, NULL, NULL);
1471 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter))
1472 {
1473 do
1474 {
1475 free_file_information_tree_store (tm, &child);
1476 }
1477 while (TRUE == gtk_tree_model_iter_next (tm, &child));
1478 }
1479}
1480
1481static int
1482hide_master_publish_dialog (struct MainPublishingDialogContext *ctx, gint ret)
1483{
1484 GtkTreeIter iter;
1485 gpointer namespace;
1486 gchar *namespace_id;
1487 gchar *namespace_uid;
1488 struct GNUNET_FS_FileInformation *fi;
1489
1490 /* Don't close until all scanners are finished */
1491 if (ctx->adddir_head != NULL)
1492 return GNUNET_NO;
1493
1494 if (ret == GTK_RESPONSE_OK)
1495 {
1496 if (TRUE == gtk_tree_selection_get_selected (ctx->pseudonym_selection, NULL, &iter))
1497 {
1498 gtk_tree_model_get (ctx->pseudonym_treemodel, &iter, 1, &namespace, 2, &namespace_id, 5,
1499 &namespace_uid, -1);
1500 }
1501 else
1502 {
1503 namespace = NULL;
1504 namespace_id = NULL;
1505 namespace_uid = NULL;
1506 }
1507 if (gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter))
1508 do
1509 {
1510 fi = get_file_information (ctx->file_info_treemodel, &iter);
1511 /* FIXME: should we convert namespace id and uid from UTF8? */
1512 GNUNET_FS_publish_start (GNUNET_FS_GTK_get_fs_handle (), fi, namespace,
1513 namespace_id, namespace_uid,
1514 GNUNET_FS_PUBLISH_OPTION_NONE);
1515 }
1516 while (gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter));
1517 g_free (namespace_id);
1518 g_free (namespace_uid);
1519 }
1520
1521 /* free state from 'ptm' */
1522 if (TRUE == gtk_tree_model_get_iter_first (ctx->pseudonym_treemodel, &iter))
1523 do
1524 {
1525 free_pseudonym_tree_store (ctx->pseudonym_treemodel, &iter);
1526 }
1527 while (TRUE == gtk_tree_model_iter_next (ctx->pseudonym_treemodel, &iter));
1528 gtk_tree_store_clear (GTK_TREE_STORE (ctx->pseudonym_treemodel));
1529
1530 /* free state from 'tm' */
1531 if (TRUE == gtk_tree_model_get_iter_first (ctx->file_info_treemodel, &iter))
1532 do
1533 {
1534 free_file_information_tree_store (ctx->file_info_treemodel, &iter);
1535 }
1536 while (TRUE == gtk_tree_model_iter_next (ctx->file_info_treemodel, &iter));
1537 gtk_tree_store_clear (GTK_TREE_STORE (ctx->file_info_treemodel));
1538 gtk_widget_destroy (GTK_WIDGET (ctx->master_pubdialog));
1539 g_object_unref (G_OBJECT (ctx->builder));
1540 GNUNET_free (ctx);
1541 return GNUNET_YES;
1542}
1543
1544
1545void
1546GNUNET_GTK_master_publish_dialog_execute_button_clicked_cb (GtkButton * button,
1547 struct MainPublishingDialogContext *ctx)
1548{
1549 hide_master_publish_dialog (ctx, GTK_RESPONSE_OK);
1550}
1551
1552
1553void
1554GNUNET_GTK_master_publish_dialog_cancel_button_clicked_cb (GtkButton * button,
1555 struct MainPublishingDialogContext *ctx)
1556{
1557 hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL);
1558}
1559
1560
1561gboolean
1562GNUNET_GTK_master_publish_dialog_delete_event_cb (GtkWidget * widget,
1563 GdkEvent * event,
1564 struct MainPublishingDialogContext *ctx)
1565{
1566 if (GNUNET_NO == hide_master_publish_dialog (ctx, GTK_RESPONSE_CANCEL))
1567 return TRUE;
1568 return FALSE;
1569}
1570
1571 1919
1572/** 1920/**
1921 * Run the file-publishing operation (by opening the master publishing dialog).
1922 *
1923 * @param dummy widget that triggered the action
1924 * @param user_data builder of the main window
1573 */ 1925 */
1574void 1926void
1575GNUNET_GTK_main_menu_file_publish_activate_cb (GtkWidget * dummy, gpointer user_data) 1927GNUNET_GTK_main_menu_file_publish_activate_cb (GtkWidget * dummy, gpointer user_data)
1576{ 1928{
1577 struct MainPublishingDialogContext *ctx; 1929 struct MainPublishingDialogContext *ctx;
1930 GtkTreeView *pseudonym_treeview;
1578 1931
1579 ctx = GNUNET_malloc (sizeof (struct MainPublishingDialogContext)); 1932 ctx = GNUNET_malloc (sizeof (struct MainPublishingDialogContext));
1580 ctx->builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_dialog.glade", ctx); 1933 /* FIXME-UNCLEAN: why bother keeping this one? */
1934 ctx->main_window_builder = GTK_BUILDER (user_data);
1581 1935
1936 ctx->builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_publish_dialog.glade", ctx);
1582 if (ctx->builder == NULL) 1937 if (ctx->builder == NULL)
1583 { 1938 {
1939 GNUNET_break (0);
1584 GNUNET_free (ctx); 1940 GNUNET_free (ctx);
1585 return; 1941 return;
1586 } 1942 }
1587 1943
1588 init_ctx (ctx); 1944 /* initialize widget references */
1589 ctx->main_window_builder = GTK_BUILDER (user_data); 1945 ctx->up_button = GTK_WIDGET (gtk_builder_get_object
1946 (ctx->builder, "GNUNET_GTK_master_publish_dialog_up_button"));
1947 ctx->down_button = GTK_WIDGET (gtk_builder_get_object
1948 (ctx->builder, "GNUNET_GTK_master_publish_dialog_down_button"));
1949 ctx->left_button = GTK_WIDGET (gtk_builder_get_object
1950 (ctx->builder, "GNUNET_GTK_master_publish_dialog_left_button"));
1951 ctx->right_button = GTK_WIDGET (gtk_builder_get_object
1952 (ctx->builder, "GNUNET_GTK_master_publish_dialog_right_button"));
1953 ctx->delete_button = GTK_WIDGET (gtk_builder_get_object
1954 (ctx->builder, "GNUNET_GTK_master_publish_dialog_delete_button"));
1955 ctx->edit_button = GTK_WIDGET (gtk_builder_get_object
1956 (ctx->builder, "GNUNET_GTK_master_publish_dialog_edit_button"));
1957 ctx->execute_button = GTK_WIDGET (gtk_builder_get_object
1958 (ctx->builder, "GNUNET_GTK_master_publish_dialog_execute_button"));
1959 ctx->cancel_button = GTK_WIDGET (gtk_builder_get_object
1960 (ctx->builder , "GNUNET_GTK_master_publish_dialog_cancel_button"));
1961 ctx->file_info_treeview = GTK_TREE_VIEW (gtk_builder_get_object
1962 (ctx->builder, "GNUNET_GTK_master_publish_dialog_file_information_tree_view"));
1963 ctx->file_info_selection = gtk_tree_view_get_selection (ctx->file_info_treeview);
1964 ctx->file_info_treemodel = gtk_tree_view_get_model (ctx->file_info_treeview);
1965 ctx->master_pubdialog =
1966 GTK_WINDOW (gtk_builder_get_object
1967 (ctx->builder, "GNUNET_GTK_master_publish_dialog"));
1968 pseudonym_treeview = GTK_TREE_VIEW (gtk_builder_get_object
1969 (ctx->builder,
1970 "GNUNET_GTK_master_publish_dialog_pseudonym_tree_view"));
1971 ctx->pseudonym_selection = gtk_tree_view_get_selection (pseudonym_treeview);
1972 ctx->pseudonym_treemodel = gtk_tree_view_get_model (pseudonym_treeview);
1973
1974 /* connect signals; FIXME-UNCLEAN: these could be connected with (modern) Glade */
1975 g_signal_connect (G_OBJECT (ctx->file_info_selection), "changed",
1976 G_CALLBACK (selection_changed_cb), ctx);
1977 g_signal_connect (G_OBJECT (ctx->pseudonym_selection), "changed",
1978 G_CALLBACK (selection_changed_cb), ctx);
1979
1980 /* populate namespace model */
1590 GNUNET_FS_namespace_list (GNUNET_FS_GTK_get_fs_handle (), 1981 GNUNET_FS_namespace_list (GNUNET_FS_GTK_get_fs_handle (),
1591 &add_namespace_to_ts, GTK_TREE_STORE (ctx->pseudonym_treemodel)); 1982 &add_namespace_to_ts,
1983 GTK_TREE_STORE (ctx->pseudonym_treemodel));
1984
1985 /* show dialog */
1592 gtk_window_present (GTK_WINDOW (ctx->master_pubdialog)); 1986 gtk_window_present (GTK_WINDOW (ctx->master_pubdialog));
1593} 1987}
1594 1988
1595 1989
1596/* end of gnunet-fs-gtk-main_window_file_publish.c */ 1990/* end of gnunet-fs-gtk_publish-dialog.c */