aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk-main_window_file_publish.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk-main_window_file_publish.c')
-rw-r--r--src/fs/gnunet-fs-gtk-main_window_file_publish.c286
1 files changed, 103 insertions, 183 deletions
diff --git a/src/fs/gnunet-fs-gtk-main_window_file_publish.c b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
index ca9a1500..d44d2c63 100644
--- a/src/fs/gnunet-fs-gtk-main_window_file_publish.c
+++ b/src/fs/gnunet-fs-gtk-main_window_file_publish.c
@@ -69,26 +69,12 @@ struct AddDirClientContext
69 struct AddDirClientContext *prev; 69 struct AddDirClientContext *prev;
70 struct AddDirClientContext *next; 70 struct AddDirClientContext *next;
71 71
72 /**
73 * GNUNET_YES if the user asked to cancel the processing.
74 * If so, wrap up as fast as possible and close the progress dialog.
75 */
76 int cancelling;
77
78 /**
79 * GNUNET_YES if there was something during the scan that might
80 * need user's attention. Prevents the dialog from closing, unless
81 * the process was cancelled.
82 */
83 int keep;
84
85 struct GNUNET_FS_ProcessMetadataContext *pmc; 72 struct GNUNET_FS_ProcessMetadataContext *pmc;
86 73
87 struct MainPublishingDialogContext *ctx; 74 struct MainPublishingDialogContext *ctx;
88 struct GNUNET_FS_DirScanner *ds; 75 struct GNUNET_FS_DirScanner *ds;
89 76
90 struct GNUNET_FS_ShareTreeItem *directory_scan_result; 77 struct GNUNET_FS_ShareTreeItem *directory_scan_result;
91 struct GNUNET_FS_ShareTreeItem *directory_scan_intermediary_result;
92 78
93 struct GNUNET_FS_BlockOptions directory_scan_bo; 79 struct GNUNET_FS_BlockOptions directory_scan_bo;
94 int directory_scan_do_index; 80 int directory_scan_do_index;
@@ -96,7 +82,6 @@ struct AddDirClientContext
96 GtkBuilder *progress_dialog_builder; 82 GtkBuilder *progress_dialog_builder;
97 GtkWidget *progress_dialog; 83 GtkWidget *progress_dialog;
98 GtkProgressBar *progress_dialog_bar; 84 GtkProgressBar *progress_dialog_bar;
99 GtkButton *progress_dialog_ok;
100 GtkButton *progress_dialog_cancel; 85 GtkButton *progress_dialog_cancel;
101 GtkTextView *progress_dialog_textview; 86 GtkTextView *progress_dialog_textview;
102 GtkTextBuffer *progress_dialog_textbuffer; 87 GtkTextBuffer *progress_dialog_textbuffer;
@@ -817,18 +802,28 @@ discard_item (struct GNUNET_FS_ShareTreeItem *item)
817 GNUNET_free (item->filename); 802 GNUNET_free (item->filename);
818} 803}
819 804
820void 805
806static void
821add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts, 807add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
822 struct GNUNET_FS_ShareTreeItem *item, GtkTreeIter *parent, GtkTreeIter *sibling, 808 struct GNUNET_FS_ShareTreeItem *item,
823 GtkTreeIter *item_iter) 809 GtkTreeIter *parent,
810 GtkTreeIter *sibling,
811 GtkTreeIter *item_iter)
824{ 812{
825 char *file_size_fancy; 813 char *file_size_fancy;
826 struct GNUNET_FS_FileInformation *fi; 814 struct GNUNET_FS_FileInformation *fi;
827 GtkTreeRowReference *row_reference; 815 GtkTreeRowReference *row_reference;
828 GtkTreePath *path; 816 GtkTreePath *path;
817 struct stat sbuf;
818
819 if (0 != stat (item->filename,
820 &sbuf))
821 {
822 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "stat", item->filename);
823 return;
824 }
829 825
830 gtk_tree_store_insert_after (ts, item_iter, parent, sibling); 826 gtk_tree_store_insert_after (ts, item_iter, parent, sibling);
831
832 path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), item_iter); 827 path = gtk_tree_model_get_path (GTK_TREE_MODEL (ts), item_iter);
833 row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path); 828 row_reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (ts), path);
834 gtk_tree_path_free (path); 829 gtk_tree_path_free (path);
@@ -836,7 +831,7 @@ add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
836 if (item->is_directory) 831 if (item->is_directory)
837 { 832 {
838 GNUNET_CONTAINER_meta_data_delete (item->meta, 833 GNUNET_CONTAINER_meta_data_delete (item->meta,
839 EXTRACTOR_METATYPE_MIMETYPE, NULL, 0); 834 EXTRACTOR_METATYPE_MIMETYPE, NULL, 0);
840 GNUNET_FS_meta_data_make_directory (item->meta); 835 GNUNET_FS_meta_data_make_directory (item->meta);
841 GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri, GNUNET_FS_DIRECTORY_MIME, 836 GNUNET_FS_uri_ksk_add_keyword (item->ksk_uri, GNUNET_FS_DIRECTORY_MIME,
842 GNUNET_NO); 837 GNUNET_NO);
@@ -856,7 +851,8 @@ add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
856 if (item->is_directory) 851 if (item->is_directory)
857 file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE); 852 file_size_fancy = GNUNET_strdup (MARKER_DIR_FILE_SIZE);
858 else 853 else
859 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (item->file_size); 854 file_size_fancy = GNUNET_STRINGS_byte_size_fancy (sbuf.st_size);
855
860 gtk_tree_store_set (ts, item_iter, 0, file_size_fancy, 856 gtk_tree_store_set (ts, item_iter, 0, file_size_fancy,
861 1, (gboolean) adcc->directory_scan_do_index, 857 1, (gboolean) adcc->directory_scan_do_index,
862 2, item->short_filename, 858 2, item->short_filename,
@@ -870,21 +866,23 @@ add_item (struct AddDirClientContext *adcc, GtkTreeStore *ts,
870 GNUNET_free (item->filename); 866 GNUNET_free (item->filename);
871} 867}
872 868
869
873/* Used to avoid recursion */ 870/* Used to avoid recursion */
871// FIXME: we should probably use recursion instead ;-).
874struct AddShareItemsStack 872struct AddShareItemsStack
875{ 873{
876 struct AddShareItemsStack *parent; 874 struct AddShareItemsStack *parent;
877 GtkTreeIter last_added; 875 GtkTreeIter last_added;
878}; 876};
879 877
878
880/** 879/**
881 * Traverse the share tree and add it to the tree store 880 * Traverse the share tree and add it to the tree store
882 * Set "discard" to GNUNET_YES to force the tree to be destroyed 881 *
883 * without processing (it is destroyed either way).
884 */ 882 */
885void 883static void
886add_share_items_to_treestore (struct AddDirClientContext *adcc, 884add_share_items_to_treestore (struct AddDirClientContext *adcc,
887 struct GNUNET_FS_ShareTreeItem *toplevel, int discard) 885 struct GNUNET_FS_ShareTreeItem *toplevel)
888{ 886{
889 struct MainPublishingDialogContext *ctx = adcc->ctx; 887 struct MainPublishingDialogContext *ctx = adcc->ctx;
890 GtkTreeStore *ts = GTK_TREE_STORE (ctx->file_info_treemodel); 888 GtkTreeStore *ts = GTK_TREE_STORE (ctx->file_info_treemodel);
@@ -893,33 +891,22 @@ add_share_items_to_treestore (struct AddDirClientContext *adcc,
893 struct GNUNET_FS_ShareTreeItem *item, *next; 891 struct GNUNET_FS_ShareTreeItem *item, *next;
894 struct AddShareItemsStack *stack; 892 struct AddShareItemsStack *stack;
895 893
896 if (!discard) 894 stack = GNUNET_malloc (sizeof (struct AddShareItemsStack));
897 { 895 parent_iter = NULL;
898 stack = GNUNET_malloc (sizeof (struct AddShareItemsStack)); 896 sibling_iter = NULL;
899 parent_iter = NULL;
900 sibling_iter = NULL;
901 }
902 for (item = toplevel; item != NULL; item = next) 897 for (item = toplevel; item != NULL; item = next)
903 { 898 {
904 if (!discard) 899 add_item (adcc, ts, item, parent_iter, sibling_iter, &stack->last_added);
905 { 900 sibling_iter = &stack->last_added;
906 add_item (adcc, ts, item, parent_iter, sibling_iter, &stack->last_added);
907 sibling_iter = &stack->last_added;
908 }
909 else
910 discard_item (item);
911 if (item->is_directory) 901 if (item->is_directory)
912 { 902 {
913 if (item->children_head != NULL) 903 if (item->children_head != NULL)
914 { 904 {
915 if (!discard) 905 struct AddShareItemsStack *child = GNUNET_malloc (sizeof (struct AddShareItemsStack));
916 { 906 child->parent = stack;
917 struct AddShareItemsStack *child = GNUNET_malloc (sizeof (struct AddShareItemsStack)); 907 sibling_iter = NULL;
918 child->parent = stack; 908 parent_iter = &stack->last_added;
919 sibling_iter = NULL; 909 stack = child;
920 parent_iter = &stack->last_added;
921 stack = child;
922 }
923 next = item->children_head; 910 next = item->children_head;
924 continue; 911 continue;
925 } 912 }
@@ -929,118 +916,62 @@ add_share_items_to_treestore (struct AddDirClientContext *adcc,
929 if (item->parent != NULL) 916 if (item->parent != NULL)
930 { 917 {
931 next = item->parent; 918 next = item->parent;
932 if (!discard) 919 struct AddShareItemsStack *child;
933 { 920 sibling_iter = &stack->parent->last_added;
934 struct AddShareItemsStack *child; 921 parent_iter = stack->parent->parent != NULL ? &stack->parent->parent->last_added : NULL;
935 sibling_iter = &stack->parent->last_added; 922 child = stack;
936 parent_iter = stack->parent->parent != NULL ? &stack->parent->parent->last_added : NULL; 923 stack = stack->parent;
937 child = stack;
938 stack = stack->parent;
939 GNUNET_free (child);
940 }
941 GNUNET_free (item);
942 item = next; 924 item = next;
943 } 925 }
944 else 926 else
945 break; 927 break;
946 } 928 }
947 GNUNET_free (item);
948 } 929 }
949 if (!discard) 930 GNUNET_free (stack);
950 GNUNET_free (stack);
951} 931}
952 932
933
953static void 934static void
954close_scan (struct AddDirClientContext *adcc) 935close_scan (struct AddDirClientContext *adcc)
955{ 936{
956 gtk_widget_destroy (adcc->progress_dialog); 937 gtk_widget_destroy (adcc->progress_dialog);
957 g_object_unref (G_OBJECT (adcc->progress_dialog_builder)); 938 g_object_unref (G_OBJECT (adcc->progress_dialog_builder));
958 GNUNET_CONTAINER_DLL_remove (adcc->ctx->adddir_head, 939 GNUNET_CONTAINER_DLL_remove (adcc->ctx->adddir_head,
959 adcc->ctx->adddir_tail, adcc); 940 adcc->ctx->adddir_tail,
941 adcc);
960 update_selectivity (adcc->ctx); 942 update_selectivity (adcc->ctx);
961 GNUNET_free (adcc); 943 GNUNET_free (adcc);
962} 944}
963 945
964static void
965complete_scan (struct AddDirClientContext *adcc)
966{
967 /* Pressing OK shouldn't work until we have the results */
968 if (adcc->directory_scan_result != NULL)
969 {
970 add_share_items_to_treestore (adcc, adcc->directory_scan_result,
971 adcc->cancelling ? GNUNET_YES : GNUNET_NO);
972 adcc->directory_scan_result = NULL;
973 update_selectivity (adcc->ctx);
974 close_scan (adcc);
975 }
976}
977 946
978static int 947void
979cancel_scan (struct AddDirClientContext *adcc) 948GNUNET_FS_GTK_progress_dialog_cancel_button_clicked_cb (GtkButton *button,
949 void *cls)
980{ 950{
981 int result = GNUNET_YES; 951 struct AddDirClientContext *adcc = cls;
982 /* User wants to cancel */ 952
983 adcc->cancelling = GNUNET_YES;
984 if (adcc->ds != NULL) 953 if (adcc->ds != NULL)
985 { 954 {
986 /* Still scanning - signal the scanner to finish */ 955 /* Still scanning - signal the scanner to finish */
987 GNUNET_FS_directory_scan_abort (adcc->ds); 956 GNUNET_FS_directory_scan_abort (adcc->ds);
988 result = GNUNET_NO; 957 adcc->ds = NULL;
989 }
990 if (adcc->directory_scan_result != NULL)
991 {
992 /* Not scanning anymore - discard the results of the scan and close */
993 add_share_items_to_treestore (adcc, adcc->directory_scan_result, GNUNET_YES);
994 adcc->directory_scan_result = NULL;
995 close_scan (adcc);
996 result = GNUNET_YES;
997 } 958 }
998 return result; 959 close_scan (adcc);
999} 960}
1000 961
1001void
1002GNUNET_FS_GTK_progress_dialog_ok_button_clicked_cb (GtkButton *button,
1003 struct AddDirClientContext *adcc)
1004{
1005 complete_scan (adcc);
1006}
1007
1008void
1009GNUNET_FS_GTK_progress_dialog_cancel_button_clicked_cb (GtkButton *button,
1010 struct AddDirClientContext *adcc)
1011{
1012 cancel_scan (adcc);
1013}
1014 962
1015gboolean 963gboolean
1016GNUNET_FS_GTK_progress_dialog_delete_event_cb (GtkWidget *widget, 964GNUNET_FS_GTK_progress_dialog_delete_event_cb (GtkWidget *widget,
1017 GdkEvent * event, struct AddDirClientContext *adcc) 965 GdkEvent * event,
966 void *cls)
1018{ 967{
1019 /* Don't allow GTK to kill the window, until the scan is finished */ 968 /* Don't allow GTK to kill the window, until the scan is finished */
1020 return cancel_scan (adcc) == GNUNET_NO; 969 return GNUNET_NO;
1021} 970}
1022 971
1023static void
1024directory_trim_complete (void *cls,
1025 const struct GNUNET_SCHEDULER_TaskContext *tc)
1026{
1027 struct AddDirClientContext *adcc = cls;
1028 adcc->directory_scan_result = adcc->directory_scan_intermediary_result;
1029 if (adcc->cancelling)
1030 {
1031 cancel_scan (adcc);
1032 }
1033 else
1034 {
1035 gtk_widget_set_sensitive (GTK_WIDGET (adcc->progress_dialog_ok), TRUE);
1036 gtk_widget_set_visible (GTK_WIDGET (adcc->progress_dialog_bar), FALSE);
1037 if (!adcc->keep)
1038 complete_scan (adcc);
1039 }
1040}
1041 972
1042static void 973static void
1043directory_scan_cb (void *cls, struct GNUNET_FS_DirScanner *ds, 974directory_scan_cb (void *cls,
1044 const char *filename, int is_directory, 975 const char *filename, int is_directory,
1045 enum GNUNET_FS_DirScannerProgressUpdateReason reason) 976 enum GNUNET_FS_DirScannerProgressUpdateReason reason)
1046{ 977{
@@ -1050,69 +981,62 @@ directory_scan_cb (void *cls, struct GNUNET_FS_DirScanner *ds,
1050 gtk_progress_bar_pulse (adcc->progress_dialog_bar); 981 gtk_progress_bar_pulse (adcc->progress_dialog_bar);
1051 switch (reason) 982 switch (reason)
1052 { 983 {
1053 case GNUNET_FS_DIRSCANNER_FILE_START: 984 case GNUNET_FS_DIRSCANNER_FILE_START:
1054 if (filename != NULL) 985 if (filename != NULL)
1055 { 986 {
1056 if (is_directory) 987 if (is_directory)
1057 GNUNET_asprintf (&s, _("Scanning directory `%s'.\n"), filename); 988 GNUNET_asprintf (&s, _("Scanning directory `%s'.\n"), filename);
1058 else
1059 GNUNET_asprintf (&s, _("Scanning file `%s'.\n"), filename);
1060 insert_progress_dialog_text (adcc, s);
1061 GNUNET_free (s);
1062 }
1063 break;
1064 case GNUNET_FS_DIRSCANNER_DOES_NOT_EXIST:
1065 if (filename != NULL)
1066 {
1067 GNUNET_asprintf (&s,
1068 _("Failed to scan `%s', because it does not exist.\n"),
1069 filename);
1070 adcc->keep = 1;
1071 insert_progress_dialog_text (adcc, s);
1072 GNUNET_free (s);
1073 }
1074 break;
1075 case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR:
1076 if (filename != NULL)
1077 {
1078 GNUNET_asprintf (&s,
1079 _("Scanner was about to scan `%s', but is now stopping.\n"),
1080 filename);
1081 insert_progress_dialog_text (adcc, s);
1082 GNUNET_free (s);
1083 }
1084 else 989 else
1085 insert_progress_dialog_text (adcc, _("Scanner is stopping.\n")); 990 GNUNET_asprintf (&s, _("Scanning file `%s'.\n"), filename);
1086 break;
1087 case GNUNET_FS_DIRSCANNER_FINISHED:
1088 insert_progress_dialog_text (adcc, _("Scanner has finished.\n"));
1089 break;
1090 case GNUNET_FS_DIRSCANNER_ALL_COUNTED:
1091 // FIXME...
1092 break;
1093 case GNUNET_FS_DIRSCANNER_SUBTREE_COUNTED:
1094 // FIXME...
1095 break;
1096 case GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED:
1097 // FIXME...
1098 GNUNET_asprintf (&s,_("Got unknown scanner update with filename `%s'.\n"),
1099 filename);
1100 insert_progress_dialog_text (adcc, s); 991 insert_progress_dialog_text (adcc, s);
1101 GNUNET_free (s); 992 GNUNET_free (s);
1102 adcc->directory_scan_intermediary_result = GNUNET_FS_directory_scan_get_result (ds); 993 }
1103 GNUNET_FS_share_tree_trim (adcc->directory_scan_intermediary_result); 994 break;
1104 // FIXME... 995 case GNUNET_FS_DIRSCANNER_FILE_IGNORED:
1105 directory_trim_complete (adcc, NULL); 996 if (filename != NULL)
1106 adcc->ds = NULL; 997 {
1107 adcc->keep = 1; 998 GNUNET_asprintf (&s,
1108 break; 999 _("Failed to scan `%s', because it does not exist.\n"),
1000 filename);
1001 insert_progress_dialog_text (adcc, s);
1002 GNUNET_free (s);
1003 }
1004 break;
1005 case GNUNET_FS_DIRSCANNER_ALL_COUNTED:
1006 // FIXME...
1007 break;
1008 case GNUNET_FS_DIRSCANNER_EXTRACT_FINISHED:
1009 // FIXME...
1010 break;
1011 case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR:
1012 insert_progress_dialog_text (adcc, _("Operation failed (press cancel)\n"));
1013 GNUNET_FS_directory_scan_abort (adcc->ds);
1014 adcc->ds = NULL;
1015 break;
1016 case GNUNET_FS_DIRSCANNER_FINISHED:
1017 insert_progress_dialog_text (adcc, _("Scanner has finished.\n"));
1018 adcc->directory_scan_result = GNUNET_FS_directory_scan_get_result (adcc->ds);
1019 adcc->ds = NULL;
1020 GNUNET_FS_share_tree_trim (adcc->directory_scan_result);
1021 add_share_items_to_treestore (adcc,
1022 adcc->directory_scan_result);
1023 GNUNET_FS_share_tree_free (adcc->directory_scan_result);
1024 adcc->directory_scan_result = NULL;
1025 update_selectivity (adcc->ctx);
1026 close_scan (adcc);
1027 break;
1028 default:
1029 GNUNET_break (0);
1030 break;
1109 } 1031 }
1110} 1032}
1111 1033
1112 1034
1113void 1035static void
1114scan_file_or_directory (struct MainPublishingDialogContext *ctx, gchar *filename, 1036scan_file_or_directory (struct MainPublishingDialogContext *ctx,
1115 struct GNUNET_FS_BlockOptions *bo, int do_index) 1037 gchar *filename,
1038 struct GNUNET_FS_BlockOptions *bo,
1039 int do_index)
1116{ 1040{
1117 struct AddDirClientContext *adcc; 1041 struct AddDirClientContext *adcc;
1118 GtkTextIter iter; 1042 GtkTextIter iter;
@@ -1133,9 +1057,6 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx, gchar *filename
1133 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object ( 1057 adcc->progress_dialog_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (
1134 adcc->progress_dialog_builder, 1058 adcc->progress_dialog_builder,
1135 "GNUNET_FS_GTK_progress_dialog_progressbar")); 1059 "GNUNET_FS_GTK_progress_dialog_progressbar"));
1136 adcc->progress_dialog_ok = GTK_BUTTON (gtk_builder_get_object (
1137 adcc->progress_dialog_builder,
1138 "GNUNET_FS_GTK_progress_dialog_ok_button"));
1139 adcc->progress_dialog_cancel = GTK_BUTTON (gtk_builder_get_object ( 1060 adcc->progress_dialog_cancel = GTK_BUTTON (gtk_builder_get_object (
1140 adcc->progress_dialog_builder, 1061 adcc->progress_dialog_builder,
1141 "GNUNET_FS_GTK_progress_dialog_cancel_button")); 1062 "GNUNET_FS_GTK_progress_dialog_cancel_button"));
@@ -1145,8 +1066,6 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx, gchar *filename
1145 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER ( 1066 adcc->progress_dialog_textbuffer = GTK_TEXT_BUFFER (
1146 gtk_builder_get_object (adcc->progress_dialog_builder, 1067 gtk_builder_get_object (adcc->progress_dialog_builder,
1147 "GNUNET_FS_GTK_progress_dialog_textbuffer")); 1068 "GNUNET_FS_GTK_progress_dialog_textbuffer"));
1148 gtk_widget_set_sensitive (GTK_WIDGET (adcc->progress_dialog_ok), FALSE);
1149
1150 gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer, 1069 gtk_text_buffer_get_end_iter (adcc->progress_dialog_textbuffer,
1151 &iter); 1070 &iter);
1152 adcc->progress_dialog_textmark = gtk_text_buffer_create_mark ( 1071 adcc->progress_dialog_textmark = gtk_text_buffer_create_mark (
@@ -1159,6 +1078,7 @@ scan_file_or_directory (struct MainPublishingDialogContext *ctx, gchar *filename
1159 update_selectivity (ctx); 1078 update_selectivity (ctx);
1160} 1079}
1161 1080
1081
1162void 1082void
1163GNUNET_GTK_publish_directory_dialog_response_cb (GtkDialog * dialog, 1083GNUNET_GTK_publish_directory_dialog_response_cb (GtkDialog * dialog,
1164 gint response_id, 1084 gint response_id,