diff options
Diffstat (limited to 'src/fs/gnunet-fs-gtk_publish-dialog.c')
-rw-r--r-- | src/fs/gnunet-fs-gtk_publish-dialog.c | 298 |
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 | */ |
979 | static void | 986 | static void |
980 | add_item (struct AddDirClientContext *adcc, | 987 | add_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 | */ |
1049 | static void | 1059 | static void |
1050 | add_share_items_to_treestore (struct AddDirClientContext *adcc, | 1060 | add_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 | */ |
1076 | static void | 1092 | static void |
1077 | directory_scan_cb (void *cls, | 1093 | directory_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 | */ |
1183 | static void | 1207 | static void |
1184 | scan_file_or_directory (struct MainPublishingDialogContext *ctx, | 1208 | scan_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 | */ |
1235 | static void | 1256 | static void |
1236 | publish_directory_dialog_response_cb (GtkDialog * dialog, | 1257 | publish_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 | */ |
1290 | static void | 1328 | static void |
1291 | publish_file_dialog_response_cb (GtkDialog * dialog, | 1329 | publish_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 | */ | ||
1457 | struct EditPublishContext | 1507 | struct 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 | */ |
1526 | void | 1595 | void |
1527 | GNUNET_GTK_master_publish_dialog_edit_button_clicked_cb (GtkWidget * dummy, | 1596 | GNUNET_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 | */ | ||
1596 | static void | 1672 | static void |
1597 | free_pseudonym_tree_store (GtkTreeModel * tm, GtkTreeIter * iter) | 1673 | free_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 | */ | ||
1622 | static void | 1705 | static void |
1623 | free_file_information_tree_store (GtkTreeModel * tm, GtkTreeIter * iter) | 1706 | free_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 | ||