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.c298
1 files changed, 191 insertions, 107 deletions
diff --git a/src/fs/gnunet-fs-gtk_publish-dialog.c b/src/fs/gnunet-fs-gtk_publish-dialog.c
index def302cf..8167a116 100644
--- a/src/fs/gnunet-fs-gtk_publish-dialog.c
+++ b/src/fs/gnunet-fs-gtk_publish-dialog.c
@@ -974,7 +974,14 @@ insert_progress_dialog_text (struct AddDirClientContext *adcc,
974 974
975 975
976/** 976/**
977 * Convert a single item from the scan to an entry in the tree view.
977 * 978 *
979 * @param adcc progress dialog context of our window
980 * @param ts tree store to add an item to
981 * @param item scanned item to add
982 * @param parent of the item, can be NULL (for root)
983 * @param sibling predecessor of the item, can be NULL (for first)
984 * @param item_iter entry to set to the added item (OUT)
978 */ 985 */
979static void 986static void
980add_item (struct AddDirClientContext *adcc, 987add_item (struct AddDirClientContext *adcc,
@@ -1002,33 +1009,33 @@ add_item (struct AddDirClientContext *adcc,
1002 gtk_tree_path_free (path); 1009 gtk_tree_path_free (path);
1003 if (item->is_directory) 1010 if (item->is_directory)
1004 { 1011 {
1012 /* update meta data mime type (force to be GNUnet-directory) */
1005 if (NULL != item->meta) 1013 if (NULL != item->meta)
1006 GNUNET_CONTAINER_meta_data_delete (item->meta, 1014 GNUNET_CONTAINER_meta_data_delete (item->meta,
1007 EXTRACTOR_METATYPE_MIMETYPE, NULL, 0); 1015 EXTRACTOR_METATYPE_MIMETYPE, NULL, 0);
1008 else 1016 else
1009 item->meta = GNUNET_CONTAINER_meta_data_create (); 1017 item->meta = GNUNET_CONTAINER_meta_data_create ();
1010 GNUNET_FS_meta_data_make_directory (item->meta); 1018 GNUNET_FS_meta_data_make_directory (item->meta);
1011 if (NULL == item->ksk_uri) 1019
1012 item->ksk_uri = GNUNET_FS_uri_ksk_create (GNUNET_FS_DIRECTORY_MIME, NULL); 1020 fi = GNUNET_FS_file_information_create_empty_directory (GNUNET_FS_GTK_get_fs_handle (),
1013 else 1021 row_reference,
1014 GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri, GNUNET_FS_DIRECTORY_MIME, 1022 item->ksk_uri,
1015 GNUNET_NO); 1023 item->meta,
1016 fi = GNUNET_FS_file_information_create_empty_directory ( 1024 &adcc->directory_scan_bo,
1017 GNUNET_FS_GTK_get_fs_handle (), row_reference, item->ksk_uri, 1025 item->filename);
1018 item->meta, &adcc->directory_scan_bo, item->filename); 1026 file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE);
1019 } 1027 }
1020 else 1028 else
1021 { 1029 {
1022 fi = GNUNET_FS_file_information_create_from_file ( 1030 fi = GNUNET_FS_file_information_create_from_file (GNUNET_FS_GTK_get_fs_handle (),
1023 GNUNET_FS_GTK_get_fs_handle (), row_reference, item->filename, 1031 row_reference,
1024 item->ksk_uri, item->meta, adcc->directory_scan_do_index, 1032 item->filename,
1025 &adcc->directory_scan_bo); 1033 item->ksk_uri,
1026 } 1034 item->meta,
1027 if (item->is_directory) 1035 adcc->directory_scan_do_index,
1028 file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE); 1036 &adcc->directory_scan_bo);
1029 else
1030 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (sbuf.st_size); 1037 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (sbuf.st_size);
1031 1038 }
1032 gtk_tree_store_set (ts, item_iter, 1039 gtk_tree_store_set (ts, item_iter,
1033 0, file_size_fancy, 1040 0, file_size_fancy,
1034 1, (gboolean) adcc->directory_scan_do_index, 1041 1, (gboolean) adcc->directory_scan_do_index,
@@ -1043,8 +1050,11 @@ add_item (struct AddDirClientContext *adcc,
1043 1050
1044 1051
1045/** 1052/**
1046 * Traverse the share tree and add it to the tree store 1053 * Recursively traverse the share tree and add it to the tree store
1047 * 1054 *
1055 * @param adcc progress dialog context of our window
1056 * @param toplevel root of the tree to add
1057 * @param parent_iter parent of the current entry to add
1048 */ 1058 */
1049static void 1059static void
1050add_share_items_to_treestore (struct AddDirClientContext *adcc, 1060add_share_items_to_treestore (struct AddDirClientContext *adcc,
@@ -1058,7 +1068,7 @@ add_share_items_to_treestore (struct AddDirClientContext *adcc,
1058 struct GNUNET_FS_ShareTreeItem *item; 1068 struct GNUNET_FS_ShareTreeItem *item;
1059 1069
1060 sibling_iter = NULL; 1070 sibling_iter = NULL;
1061 for (item = toplevel; item != NULL; item = item->next) 1071 for (item = toplevel; NULL != item; item = item->next)
1062 { 1072 {
1063 add_item (adcc, ts, item, parent_iter, sibling_iter, &last_added); 1073 add_item (adcc, ts, item, parent_iter, sibling_iter, &last_added);
1064 sibling_iter = &last_added; 1074 sibling_iter = &last_added;
@@ -1071,22 +1081,28 @@ add_share_items_to_treestore (struct AddDirClientContext *adcc,
1071 1081
1072 1082
1073/** 1083/**
1084 * Progress callback called from the directory scanner with
1085 * information about our progress scanning the hierarchy.
1074 * 1086 *
1087 * @param cls progress dialog context of our window
1088 * @param filename filename this update is about, can be NULL
1089 * @param is_directory is this file a directory, SYSERR if not applicable
1090 * @param reason kind of progress that was made
1075 */ 1091 */
1076static void 1092static void
1077directory_scan_cb (void *cls, 1093directory_scan_cb (void *cls,
1078 const char *filename, int is_directory, 1094 const char *filename, int is_directory,
1079 enum GNUNET_FS_DirScannerProgressUpdateReason reason) 1095 enum GNUNET_FS_DirScannerProgressUpdateReason reason)
1080{ 1096{
1081 static struct GNUNET_TIME_Absolute last_pulse;
1082 struct AddDirClientContext *adcc = cls; 1097 struct AddDirClientContext *adcc = cls;
1098 static struct GNUNET_TIME_Absolute last_pulse;
1083 char *s; 1099 char *s;
1084 gdouble fraction; 1100 gdouble fraction;
1085 1101
1086 switch (reason) 1102 switch (reason)
1087 { 1103 {
1088 case GNUNET_FS_DIRSCANNER_FILE_START: 1104 case GNUNET_FS_DIRSCANNER_FILE_START:
1089 GNUNET_assert (filename != NULL); 1105 GNUNET_assert (NULL != filename);
1090 if (GNUNET_TIME_absolute_get_duration (last_pulse).rel_value > 100) 1106 if (GNUNET_TIME_absolute_get_duration (last_pulse).rel_value > 100)
1091 { 1107 {
1092 gtk_progress_bar_pulse (adcc->progress_dialog_bar); 1108 gtk_progress_bar_pulse (adcc->progress_dialog_bar);
@@ -1107,7 +1123,7 @@ directory_scan_cb (void *cls,
1107#endif 1123#endif
1108 break; 1124 break;
1109 case GNUNET_FS_DIRSCANNER_FILE_IGNORED: 1125 case GNUNET_FS_DIRSCANNER_FILE_IGNORED:
1110 GNUNET_assert (filename != NULL); 1126 GNUNET_assert (NULL != filename);
1111 GNUNET_asprintf (&s, 1127 GNUNET_asprintf (&s,
1112 _("Failed to scan `%s' (access error). Skipping.\n"), 1128 _("Failed to scan `%s' (access error). Skipping.\n"),
1113 filename); 1129 filename);
@@ -1131,6 +1147,7 @@ directory_scan_cb (void *cls,
1131 fraction); 1147 fraction);
1132 break; 1148 break;
1133 case GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED: 1149 case GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED:
1150 GNUNET_assert (NULL != filename);
1134#if VERBOSE_PROGRESS 1151#if VERBOSE_PROGRESS
1135 GNUNET_asprintf (&s, _("Processed file `%s'.\n"), filename); 1152 GNUNET_asprintf (&s, _("Processed file `%s'.\n"), filename);
1136 insert_progress_dialog_text (adcc, s); 1153 insert_progress_dialog_text (adcc, s);
@@ -1178,7 +1195,14 @@ directory_scan_cb (void *cls,
1178 1195
1179 1196
1180/** 1197/**
1198 * Setup the context and progress dialog for scanning a file or
1199 * directory structure (for meta data) and importing it into
1200 * the tree view.
1181 * 1201 *
1202 * @param ctx publishing context for the main publishing window
1203 * @param filename name of the file or directory to scan
1204 * @param bo options for the operation
1205 * @param do_index should we index or insert files (by default)
1182 */ 1206 */
1183static void 1207static void
1184scan_file_or_directory (struct MainPublishingDialogContext *ctx, 1208scan_file_or_directory (struct MainPublishingDialogContext *ctx,
@@ -1187,78 +1211,80 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx,
1187 int do_index) 1211 int do_index)
1188{ 1212{
1189 struct AddDirClientContext *adcc; 1213 struct AddDirClientContext *adcc;
1190 GtkTextIter iter;
1191 1214
1192 adcc = GNUNET_malloc (sizeof (struct AddDirClientContext)); 1215 adcc = GNUNET_malloc (sizeof (struct AddDirClientContext));
1193 adcc->ctx = ctx; 1216 adcc->ctx = ctx;
1194 GNUNET_CONTAINER_DLL_insert_tail (ctx->adddir_head, ctx->adddir_tail, adcc); 1217 GNUNET_CONTAINER_DLL_insert_tail (ctx->adddir_head, ctx->adddir_tail, adcc);
1195 adcc->ds = GNUNET_FS_directory_scan_start (filename,
1196 GNUNET_NO, NULL, &directory_scan_cb, adcc);
1197 adcc->directory_scan_bo = *bo; 1218 adcc->directory_scan_bo = *bo;
1198 adcc->directory_scan_do_index = do_index; 1219 adcc->directory_scan_do_index = do_index;
1199 1220
1200 adcc->progress_dialog_builder = GNUNET_GTK_get_new_builder ( 1221 /* setup the dialog and get the widgets we need most */
1201 "gnunet_fs_gtk_progress_dialog.glade", adcc); 1222 adcc->progress_dialog_builder = GNUNET_GTK_get_new_builder ("gnunet_fs_gtk_progress_dialog.glade", adcc);
1202 adcc->progress_dialog = GTK_WIDGET (gtk_builder_get_object ( 1223 adcc->progress_dialog = GTK_WIDGET (gtk_builder_get_object (adcc->progress_dialog_builder,
1203 adcc->progress_dialog_builder, 1224 "GNUNET_FS_GTK_progress_dialog"));
1204 "GNUNET_FS_GTK_progress_dialog")); 1225 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (adcc->progress_dialog_builder,
1205 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object ( 1226 "GNUNET_FS_GTK_progress_dialog_progressbar"));
1206 adcc->progress_dialog_builder, 1227 adcc->progress_dialog_textview = GTK_TEXT_VIEW (gtk_builder_get_object (adcc->progress_dialog_builder,
1207 "GNUNET_FS_GTK_progress_dialog_progressbar")); 1228 "GNUNET_FS_GTK_progress_dialog_textview"));
1208 adcc->progress_dialog_textview = GTK_TEXT_VIEW ( 1229 adcc->textview_vertical_adjustment = GTK_ADJUSTMENT (gtk_builder_get_object (adcc->progress_dialog_builder,
1209 gtk_builder_get_object (adcc->progress_dialog_builder, 1230 "GNUNET_FS_GTK_progress_dialog_textview_vertical_adjustment"));
1210 "GNUNET_FS_GTK_progress_dialog_textview")); 1231 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER (gtk_builder_get_object (adcc->progress_dialog_builder,
1211 adcc->textview_vertical_adjustment = GTK_ADJUSTMENT ( 1232 "GNUNET_FS_GTK_progress_dialog_textbuffer"));
1212 gtk_builder_get_object (adcc->progress_dialog_builder, 1233
1213 "GNUNET_FS_GTK_progress_dialog_textview_vertical_adjustment")); 1234 /* show the window */
1214 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER (
1215 gtk_builder_get_object (adcc->progress_dialog_builder,
1216 "GNUNET_FS_GTK_progress_dialog_textbuffer"));
1217 gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer,
1218 &iter);
1219#if VERBOSE_PROGRESS
1220 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (adcc->progress_dialog_builder,
1221 "GNUNET_FS_GTK_progress_dialog_scrolled_window")));
1222#endif
1223
1224 gtk_window_set_transient_for (GTK_WINDOW (adcc->progress_dialog), adcc->ctx->master_pubdialog); 1235 gtk_window_set_transient_for (GTK_WINDOW (adcc->progress_dialog), adcc->ctx->master_pubdialog);
1225 gtk_window_set_title (GTK_WINDOW (adcc->progress_dialog), filename); 1236 gtk_window_set_title (GTK_WINDOW (adcc->progress_dialog), filename);
1226 gtk_window_present (GTK_WINDOW (adcc->progress_dialog)); 1237 gtk_window_present (GTK_WINDOW (adcc->progress_dialog));
1227 1238
1239 /* actually start the scan */
1240 adcc->ds = GNUNET_FS_directory_scan_start (filename,
1241 GNUNET_NO, NULL,
1242 &directory_scan_cb, adcc);
1243
1244 /* disables 'cancel' button of the master dialog */
1228 update_selectivity (ctx); 1245 update_selectivity (ctx);
1229} 1246}
1230 1247
1231 1248
1232/** 1249/**
1250 * Function called when the "open" (directory) dialog was closed.
1251 *
1252 * @param dialog the open dialog
1253 * @param response_id result of the dialog ("-5" means to "run")
1233 * @param user_data master publishing dialog context of our window 1254 * @param user_data master publishing dialog context of our window
1234 */ 1255 */
1235static void 1256static void
1236publish_directory_dialog_response_cb (GtkDialog * dialog, 1257publish_directory_dialog_response_cb (GtkDialog * dialog,
1237 gint response_id, 1258 gint response_id,
1238 struct MainPublishingDialogContext *ctx) 1259 gpointer user_data)
1239{ 1260{
1240 char *filename; 1261 struct MainPublishingDialogContext *ctx = user_data;
1241 int do_index;
1242 GtkSpinButton *sb;
1243 struct GNUNET_FS_BlockOptions bo;
1244 GtkWidget *ad; 1262 GtkWidget *ad;
1245 1263
1264 /* FIXME-UGLY: how about using a separate closure and not needing this mess?
1265 In fact, even without it I don't see why we need to disconnect the handler... */
1246 if (g_signal_handler_is_connected (G_OBJECT (dialog), ctx->open_directory_handler_id)) 1266 if (g_signal_handler_is_connected (G_OBJECT (dialog), ctx->open_directory_handler_id))
1247 g_signal_handler_disconnect (G_OBJECT (dialog), ctx->open_directory_handler_id); 1267 g_signal_handler_disconnect (G_OBJECT (dialog), ctx->open_directory_handler_id);
1248 ctx->open_directory_handler_id = 0; 1268 ctx->open_directory_handler_id = 0;
1249 1269
1250 ad = GTK_WIDGET (gtk_builder_get_object 1270 ad = GTK_WIDGET (gtk_builder_get_object
1251 (ctx->open_directory_builder, "GNUNET_GTK_publish_directory_dialog")); 1271 (ctx->open_directory_builder,
1252 if (response_id == -5) 1272 "GNUNET_GTK_publish_directory_dialog"));
1273 if (response_id == -5 /* OK */)
1253 { 1274 {
1275 char *filename;
1276 int do_index;
1277 struct GNUNET_FS_BlockOptions bo;
1278
1254 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (ad)); 1279 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (ad));
1255 sb = GTK_SPIN_BUTTON (gtk_builder_get_object 1280 if (! GNUNET_GTK_get_selected_anonymity_level
1256 (ctx->open_directory_builder, 1281 (ctx->open_directory_builder,
1257 "GNUNET_GTK_publish_directory_dialog_expiration_year_spin_button")); 1282 "GNUNET_GTK_publish_directory_dialog_anonymity_combobox",
1258 if (!GNUNET_GTK_get_selected_anonymity_level
1259 (ctx->open_directory_builder, "GNUNET_GTK_publish_directory_dialog_anonymity_combobox",
1260 &bo.anonymity_level)) 1283 &bo.anonymity_level))
1284 {
1285 GNUNET_break (0);
1261 bo.anonymity_level = 1; 1286 bo.anonymity_level = 1;
1287 }
1262 bo.content_priority = 1288 bo.content_priority =
1263 gtk_spin_button_get_value (GTK_SPIN_BUTTON 1289 gtk_spin_button_get_value (GTK_SPIN_BUTTON
1264 (gtk_builder_get_object 1290 (gtk_builder_get_object
@@ -1269,59 +1295,79 @@ publish_directory_dialog_response_cb (GtkDialog * dialog,
1269 (gtk_builder_get_object 1295 (gtk_builder_get_object
1270 (ctx->open_directory_builder, 1296 (ctx->open_directory_builder,
1271 "GNUNET_GTK_publish_directory_dialog_replication_spin_button"))); 1297 "GNUNET_GTK_publish_directory_dialog_replication_spin_button")));
1272 bo.expiration_time = GNUNET_FS_GTK_get_expiration_time (sb); 1298 {
1299 GtkSpinButton *sb;
1300
1301 sb = GTK_SPIN_BUTTON (gtk_builder_get_object
1302 (ctx->open_directory_builder,
1303 "GNUNET_GTK_publish_directory_dialog_expiration_year_spin_button"));
1304 bo.expiration_time = GNUNET_FS_GTK_get_expiration_time (sb);
1305 }
1273 do_index = 1306 do_index =
1274 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 1307 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
1275 (gtk_builder_get_object 1308 (gtk_builder_get_object
1276 (ctx->open_directory_builder, 1309 (ctx->open_directory_builder,
1277 "GNUNET_GTK_publish_directory_dialog_do_index_checkbutton"))); 1310 "GNUNET_GTK_publish_directory_dialog_do_index_checkbutton")));
1278
1279 scan_file_or_directory (ctx, filename, &bo, do_index); 1311 scan_file_or_directory (ctx, filename, &bo, do_index);
1280 g_free (filename); 1312 g_free (filename);
1281 } 1313 }
1314 /* FIXME: do we need to do widget-destroy + builder destroy? */
1282 gtk_widget_destroy (ad); 1315 gtk_widget_destroy (ad);
1283 g_object_unref (G_OBJECT (ctx->open_directory_builder)); 1316 g_object_unref (G_OBJECT (ctx->open_directory_builder));
1317 ctx->open_directory_builder = NULL;
1284} 1318}
1285 1319
1286 1320
1287/** 1321/**
1322 * Function called when the "open" (file) dialog was closed.
1323 *
1324 * @param dialog the open dialog
1325 * @param response_id result of the dialog ("-5" means to "run")
1288 * @param user_data master publishing dialog context of our window 1326 * @param user_data master publishing dialog context of our window
1289 */ 1327 */
1290static void 1328static void
1291publish_file_dialog_response_cb (GtkDialog * dialog, 1329publish_file_dialog_response_cb (GtkDialog * dialog,
1292 gint response_id, 1330 gint response_id,
1293 struct MainPublishingDialogContext *ctx) 1331 gpointer user_data)
1294{ 1332{
1295 char *filename; 1333 struct MainPublishingDialogContext *ctx = user_data;
1296 struct GNUNET_FS_BlockOptions bo;
1297 int do_index;
1298 GtkSpinButton *sb;
1299 GtkWidget *ad; 1334 GtkWidget *ad;
1300 1335
1336 /* FIXME-UGLY: how about using a separate closure and not needing this mess?
1337 In fact, even without it I don't see why we need to disconnect the handler... */
1301 if (g_signal_handler_is_connected (G_OBJECT (dialog), ctx->open_file_handler_id)) 1338 if (g_signal_handler_is_connected (G_OBJECT (dialog), ctx->open_file_handler_id))
1302 g_signal_handler_disconnect (G_OBJECT (dialog), ctx->open_file_handler_id); 1339 g_signal_handler_disconnect (G_OBJECT (dialog), ctx->open_file_handler_id);
1303 ctx->open_file_handler_id = 0; 1340 ctx->open_file_handler_id = 0;
1304 1341
1305 ad = GTK_WIDGET (gtk_builder_get_object 1342 ad = GTK_WIDGET (gtk_builder_get_object
1306 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog")); 1343 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog"));
1307 1344 if (response_id == -5 /* OK */)
1308 if (response_id == -5)
1309 { 1345 {
1310 /* OK */ 1346 char *filename;
1311 sb = GTK_SPIN_BUTTON (gtk_builder_get_object 1347 struct GNUNET_FS_BlockOptions bo;
1312 (ctx->open_file_builder, 1348 int do_index;
1313 "GNUNET_GTK_publish_file_dialog_expiration_year_spin_button"));
1314 1349
1350 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (ad));
1315 if (!GNUNET_GTK_get_selected_anonymity_level 1351 if (!GNUNET_GTK_get_selected_anonymity_level
1316 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog_anonymity_combobox", 1352 (ctx->open_file_builder, "GNUNET_GTK_publish_file_dialog_anonymity_combobox",
1317 &bo.anonymity_level)) 1353 &bo.anonymity_level))
1354 {
1355 GNUNET_break (0);
1318 bo.anonymity_level = 1; 1356 bo.anonymity_level = 1;
1357 }
1319 bo.content_priority = 1358 bo.content_priority =
1320 gtk_spin_button_get_value (GTK_SPIN_BUTTON 1359 gtk_spin_button_get_value (GTK_SPIN_BUTTON
1321 (gtk_builder_get_object 1360 (gtk_builder_get_object
1322 (ctx->open_file_builder, 1361 (ctx->open_file_builder,
1323 "GNUNET_GTK_publish_file_dialog_priority_spin_button"))); 1362 "GNUNET_GTK_publish_file_dialog_priority_spin_button")));
1324 bo.expiration_time = GNUNET_FS_GTK_get_expiration_time (sb); 1363 {
1364 GtkSpinButton *sb;
1365
1366 sb = GTK_SPIN_BUTTON (gtk_builder_get_object
1367 (ctx->open_file_builder,
1368 "GNUNET_GTK_publish_file_dialog_expiration_year_spin_button"));
1369 bo.expiration_time = GNUNET_FS_GTK_get_expiration_time (sb);
1370 }
1325 bo.replication_level = 1371 bo.replication_level =
1326 gtk_spin_button_get_value (GTK_SPIN_BUTTON 1372 gtk_spin_button_get_value (GTK_SPIN_BUTTON
1327 (gtk_builder_get_object 1373 (gtk_builder_get_object
@@ -1333,17 +1379,13 @@ publish_file_dialog_response_cb (GtkDialog * dialog,
1333 (ctx->open_file_builder, 1379 (ctx->open_file_builder,
1334 "GNUNET_GTK_publish_file_dialog_do_index_checkbutton"))); 1380 "GNUNET_GTK_publish_file_dialog_do_index_checkbutton")));
1335 1381
1336 filename = GNUNET_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (ad));
1337
1338 scan_file_or_directory (ctx, filename, &bo, do_index); 1382 scan_file_or_directory (ctx, filename, &bo, do_index);
1339
1340 g_free (filename); 1383 g_free (filename);
1341 } 1384 }
1342 else 1385 /* FIXME: do we need to do widget-destroy + builder destroy? */
1343 {
1344 /* Cancel/Escape/close/etc */
1345 }
1346 gtk_widget_destroy (ad); 1386 gtk_widget_destroy (ad);
1387 g_object_unref (G_OBJECT (ctx->open_file_builder));
1388 ctx->open_file_builder = NULL;
1347} 1389}
1348 1390
1349 1391
@@ -1454,12 +1496,35 @@ GNUNET_GTK_master_publish_dialog_open_button_clicked_cb (GtkWidget * dummy,
1454 1496
1455 1497
1456 1498
1499/**
1500 * Context we keep while an "edit" sub-dialog is open.
1501 *
1502 * FIXME-MAYBE: we should probably keep these also in a DLL with the
1503 * master dialog to prevent the master dialog from closing while the
1504 * edit dialog is running? Or are we otherwise already preventing
1505 * this?
1506 */
1457struct EditPublishContext 1507struct EditPublishContext
1458{ 1508{
1509 /**
1510 * File information that is being edited
1511 */
1459 struct GNUNET_FS_FileInformation *fip; 1512 struct GNUNET_FS_FileInformation *fip;
1460 1513
1514 /**
1515 * Tree model that is being edited (where to store the results afterwards).
1516 */
1461 GtkTreeModel *tm; 1517 GtkTreeModel *tm;
1462 1518
1519 /**
1520 * Position in the tree that is being edited.
1521 *
1522 * FIXME-MAYBE: using a TreeIter here is not great, as the row may be
1523 * moved (or even deleted) while the edit dialog is running. Should
1524 * use a RowReference instead. Also, how do we guard against two
1525 * edit dialogs being opened for the same file? (Shouldn't we store
1526 * the EditPublishContext with, say, the tree model?)
1527 */
1463 GtkTreeIter iter; 1528 GtkTreeIter iter;
1464}; 1529};
1465 1530
@@ -1512,45 +1577,51 @@ master_publish_edit_publish_dialog_cb (gpointer cls,
1512 gint ret, 1577 gint ret,
1513 const char *root) 1578 const char *root)
1514{ 1579{
1515 struct EditPublishContext *cbargs = cls; 1580 struct EditPublishContext *epc = cls;
1516 1581
1517 if (ret == GTK_RESPONSE_OK) 1582 if (ret == GTK_RESPONSE_OK)
1518 GNUNET_FS_file_information_inspect (cbargs->fip, &update_treeview_after_edit, cbargs); 1583 GNUNET_FS_file_information_inspect (epc->fip, &update_treeview_after_edit, epc);
1519 GNUNET_free (cbargs); 1584 GNUNET_free (epc);
1520} 1585}
1521 1586
1522 1587
1523/** 1588/**
1589 * The user clicked on the "edit" button in the master dialog. Edit
1590 * the selected tree item.
1591 *
1592 * @param dummy the 'edit' button
1524 * @param user_data master publishing dialog context of our window 1593 * @param user_data master publishing dialog context of our window
1525*/ 1594 */
1526void 1595void
1527GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy, 1596GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy,
1528 struct MainPublishingDialogContext *ctx) 1597 gpointer user_data)
1529{ 1598{
1530 struct EditPublishContext *cbargs; 1599 struct MainPublishingDialogContext *ctx = user_data;
1600 struct EditPublishContext *epc;
1531 GtkListStore *anon_liststore; 1601 GtkListStore *anon_liststore;
1532 1602
1533 anon_liststore = GTK_LIST_STORE (gtk_builder_get_object (ctx->main_window_builder, 1603 anon_liststore = GTK_LIST_STORE (gtk_builder_get_object (ctx->main_window_builder,
1534 "main_window_search_anonymity_liststore")); 1604 "main_window_search_anonymity_liststore"));
1535 cbargs = GNUNET_malloc (sizeof (struct EditPublishContext)); 1605 epc = GNUNET_malloc (sizeof (struct EditPublishContext));
1536 cbargs->tm = ctx->file_info_treemodel; 1606 epc->tm = ctx->file_info_treemodel;
1537 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &cbargs->iter)) 1607 if (! gtk_tree_selection_get_selected (ctx->file_info_selection, NULL, &epc->iter))
1538 { 1608 {
1539 GNUNET_break (0); 1609 GNUNET_break (0);
1540 GNUNET_free (cbargs); 1610 GNUNET_free (epc);
1541 return; 1611 return;
1542 } 1612 }
1543 gtk_tree_model_get (ctx->file_info_treemodel, &cbargs->iter, 1613 gtk_tree_model_get (ctx->file_info_treemodel,
1544 5, &cbargs->fip, 1614 &epc->iter,
1615 5, &epc->fip,
1545 -1); 1616 -1);
1546 /* FIXME: can we just give our anon_liststore out like this? What about 1617 /* FIXME-UGLY: can we just give our anon_liststore out like this? What about
1547 (unintended) sharing of state? */ 1618 (unintended) sharing of state? */
1548 GNUNET_FS_GTK_edit_publish_dialog (ctx->master_pubdialog, 1619 GNUNET_FS_GTK_edit_publish_dialog (ctx->master_pubdialog,
1549 cbargs->fip, 1620 epc->fip,
1550 GNUNET_YES, 1621 GNUNET_YES,
1551 anon_liststore, 1622 anon_liststore,
1552 &master_publish_edit_publish_dialog_cb, 1623 &master_publish_edit_publish_dialog_cb,
1553 cbargs); 1624 epc);
1554} 1625}
1555 1626
1556 1627
@@ -1592,33 +1663,45 @@ get_file_information (GtkTreeModel * tm, GtkTreeIter * iter)
1592} 1663}
1593 1664
1594 1665
1595 1666/**
1667 * (Recursively) clean up the tree store with the pseudonyms.
1668 *
1669 * @param tm tree model we are cleaning up
1670 * @param iter current position to clean up
1671 */
1596static void 1672static void
1597free_pseudonym_tree_store (GtkTreeModel * tm, GtkTreeIter * iter) 1673free_pseudonym_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1598{ 1674{
1675 GtkTreeIter child;
1599 struct GNUNET_CONTAINER_MetaData *meta; 1676 struct GNUNET_CONTAINER_MetaData *meta;
1600 struct GNUNET_FS_Namespace *ns; 1677 struct GNUNET_FS_Namespace *ns;
1601 GtkTreeIter child;
1602 1678
1603 gtk_tree_model_get (tm, iter, 1, &ns, 4, &meta, -1); 1679 gtk_tree_model_get (tm, iter, 1, &ns, 4, &meta, -1);
1604 if (meta != NULL) 1680 if (NULL != meta)
1605 GNUNET_CONTAINER_meta_data_destroy (meta); 1681 GNUNET_CONTAINER_meta_data_destroy (meta);
1606 if (ns != NULL) 1682 if (NULL != ns)
1607 { 1683 {
1608 // FIXME: delete ns? 1684 /* FIXME-BUG-MAYBE: should we not delete ns here? (resource leak?) */
1609 // GNUNET_FS_namespace_delete (nso, GNUNET_NO); 1685 // GNUNET_FS_namespace_delete (nso, GNUNET_NO);
1610 } 1686 }
1611 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter)) 1687 /* recursively clean up children */
1688 if (gtk_tree_model_iter_children (tm, &child, iter))
1612 { 1689 {
1613 do 1690 do
1614 { 1691 {
1615 free_pseudonym_tree_store (tm, &child); 1692 free_pseudonym_tree_store (tm, &child);
1616 } 1693 }
1617 while (TRUE == gtk_tree_model_iter_next (tm, &child)); 1694 while (gtk_tree_model_iter_next (tm, &child));
1618 } 1695 }
1619} 1696}
1620 1697
1621 1698
1699/**
1700 * Recursively clean up the tree store with the file information in it.
1701 *
1702 * @param tm tree model we are cleaning up
1703 * @param iter current position to clean up
1704 */
1622static void 1705static void
1623free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter) 1706free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1624{ 1707{
@@ -1626,15 +1709,16 @@ free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter)
1626 struct GNUNET_FS_FileInformation *fip; 1709 struct GNUNET_FS_FileInformation *fip;
1627 1710
1628 gtk_tree_model_get (tm, iter, 5, &fip, -1); 1711 gtk_tree_model_get (tm, iter, 5, &fip, -1);
1629 if (fip != NULL) 1712 if (NULL != fip)
1630 GNUNET_FS_file_information_destroy (fip, NULL, NULL); 1713 GNUNET_FS_file_information_destroy (fip, NULL, NULL);
1631 if (TRUE == gtk_tree_model_iter_children (tm, &child, iter)) 1714 /* recursively clean up children */
1715 if (gtk_tree_model_iter_children (tm, &child, iter))
1632 { 1716 {
1633 do 1717 do
1634 { 1718 {
1635 free_file_information_tree_store (tm, &child); 1719 free_file_information_tree_store (tm, &child);
1636 } 1720 }
1637 while (TRUE == gtk_tree_model_iter_next (tm, &child)); 1721 while (gtk_tree_model_iter_next (tm, &child));
1638 } 1722 }
1639} 1723}
1640 1724