aboutsummaryrefslogtreecommitdiff
path: root/src/fs/gnunet-fs-gtk-event_handler.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/gnunet-fs-gtk-event_handler.c')
-rw-r--r--src/fs/gnunet-fs-gtk-event_handler.c218
1 files changed, 201 insertions, 17 deletions
diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c
index aa870b0c..32852aef 100644
--- a/src/fs/gnunet-fs-gtk-event_handler.c
+++ b/src/fs/gnunet-fs-gtk-event_handler.c
@@ -596,6 +596,8 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
596 guint applicability_rank; 596 guint applicability_rank;
597 guint availability_certainty; 597 guint availability_certainty;
598 gint availability_rank; 598 gint availability_rank;
599 gchar *downloaded_filename;
600 gint downloaded_anonymity;
599 601
600 if (TRUE == gtk_tree_model_iter_children (src_model, &src_child, src_iter)) 602 if (TRUE == gtk_tree_model_iter_children (src_model, &src_child, src_iter))
601 { 603 {
@@ -607,7 +609,8 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
607 &uri_as_string, 8, &status_colour, 9, &search_result, 609 &uri_as_string, 8, &status_colour, 9, &search_result,
608 10, &mimetype, 11, &applicability_rank, 12, 610 10, &mimetype, 11, &applicability_rank, 12,
609 &availability_certainty, 13, &availability_rank, 14, 611 &availability_certainty, 13, &availability_rank, 14,
610 &completed, -1); 612 &completed, 15, &downloaded_filename, 16,
613 &downloaded_anonymity, -1);
611 gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child, 614 gtk_tree_store_insert_with_values (GTK_TREE_STORE (dst_model), &dst_child,
612 dst_iter, G_MAXINT, 0, meta, 1, uri, 2, 615 dst_iter, G_MAXINT, 0, meta, 1, uri, 2,
613 filesize, 3, preview, 4, 616 filesize, 3, preview, 4,
@@ -617,8 +620,11 @@ move_children (GtkTreeModel * src_model, GtkTreeIter * src_iter,
617 search_result, 10, mimetype, 11, 620 search_result, 10, mimetype, 11,
618 applicability_rank, 12, 621 applicability_rank, 12,
619 availability_certainty, 13, 622 availability_certainty, 13,
620 availability_rank, 14, completed, -1); 623 availability_rank, 14, completed, 15,
624 downloaded_filename, 16,
625 downloaded_anonymity, -1);
621 g_free (filename); 626 g_free (filename);
627 g_free (downloaded_filename);
622 g_free (uri_as_string); 628 g_free (uri_as_string);
623 g_free (status_colour); 629 g_free (status_colour);
624 g_free (mimetype); 630 g_free (mimetype);
@@ -807,6 +813,164 @@ setup_download (struct DownloadEntry *de, struct DownloadEntry *pde,
807 return de; 813 return de;
808} 814}
809 815
816/**
817 * This should get the default download directory
818 * (so that GNUnet won't offer the user to download files
819 * to the 'bin' subdirectory, or whatever is the cwd).
820 * Returns NULL on failure (such as non-existend directory).
821 * Should also preserve the last setting (so if the user
822 * saves files somewhere else, next time we default to
823 * somewhere else, at least until application restart, or maybe even
824 * between application restarts).
825 * Fills the @buffer up to @size bytes, returns a pointer to it.
826 */
827static char *
828get_default_download_directory (char *buffer, size_t size)
829{
830 return NULL;
831}
832
833/**
834 * Called recursively to build a suggested filename by
835 * prepending suggested names for its parent directories (if any).
836 * Might return NULL. Returned name might be absolute.
837 * local_parents is set to GNUNET_YES if all parents are directories,
838 * and are downloaded.
839 */
840static char *
841get_suggested_filename_anonymity (GtkTreeModel *tm, GtkTreeIter *iter, int top,
842 int *local_parents, int *anonymity, int *filename_is_absolute)
843{
844 char *result;
845 char *dirname;
846 char *local_filename, *filename;
847 int downloaded_anonymity;
848 int have_a_parent;
849 struct GNUNET_CONTAINER_MetaData *meta;
850 GtkTreeIter parent;
851 gtk_tree_model_get (tm, iter, 0, &meta, 15, &local_filename, 16, &downloaded_anonymity, -1);
852 if (local_filename == NULL && !top)
853 *local_parents = GNUNET_NO;
854 if (downloaded_anonymity != -1 && *anonymity == -1 && !top)
855 *anonymity = downloaded_anonymity;
856 if (gtk_tree_model_iter_parent (tm, &parent, iter))
857 {
858 have_a_parent = GNUNET_YES;
859 dirname = get_suggested_filename_anonymity (tm, &parent, GNUNET_NO, local_parents, anonymity, filename_is_absolute);
860 }
861 else
862 {
863 have_a_parent = GNUNET_NO;
864 dirname = NULL;
865 if (top)
866 *local_parents = GNUNET_NO;
867 }
868 if (local_filename == NULL)
869 filename = GNUNET_FS_meta_data_suggest_filename (meta);
870 else
871 {
872 /* This directory was downloaded as /foo/bar/baz/somedirname
873 * Hopefully, "somedirname" is actually "somedir.gnd"
874 * We need to strip the ".gnd" part to get "somedir", which is
875 * what we're going to use instead of suggested original filename
876 * Without the .gnd extension we're going to just use a copy
877 * of the directory file name - and that would fail. Sad.
878 */
879 const char *basename;
880 if (dirname == NULL && !have_a_parent)
881 {
882 /* This is the ealderlest parent directory. Use absolute path. */
883 basename = (const char *) local_filename;
884 *filename_is_absolute = GNUNET_YES;
885 }
886 else
887 basename = GNUNET_STRINGS_get_short_name (local_filename);
888 if (basename != NULL && strlen (basename) > 0)
889 {
890 char *dot;
891 filename = GNUNET_strdup (basename);
892 dot = strrchr (filename, '.');
893 if (dot)
894 *dot = '\0';
895 }
896 else
897 filename = GNUNET_FS_meta_data_suggest_filename (meta);
898 }
899 if (dirname && filename)
900 {
901 GNUNET_asprintf (&result, "%s%s%s", dirname, DIR_SEPARATOR_STR, filename);
902 GNUNET_free (filename);
903 GNUNET_free (dirname);
904 return result;
905 }
906 else if (filename)
907 return filename;
908 else
909 return NULL;
910}
911
912static void
913open_download_as_callback (struct DownloadContext *dc)
914{
915 enum GNUNET_FS_DownloadOptions opt;
916 struct GNUNET_FS_Handle *fs;
917 struct DownloadEntry *de;
918 uint64_t len;
919
920 GtkTreeIter iter;
921 GtkTreePath *path;
922
923 fs = GNUNET_FS_GTK_get_fs_handle ();
924 opt = GNUNET_FS_DOWNLOAD_OPTION_NONE;
925 if (dc->is_recursive)
926 opt |= GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE;
927 len = GNUNET_FS_uri_chk_get_file_size (dc->uri);
928
929 de = GNUNET_malloc (sizeof (struct DownloadEntry));
930 de->uri = dc->uri;
931 dc->uri = NULL;
932 de->meta = dc->meta;
933 dc->meta = NULL;
934 if (dc->rr != NULL)
935 {
936 /* We're going to free "dc" very soon */
937 de->rr = gtk_tree_row_reference_copy (dc->rr);
938 de->ts = GTK_TREE_STORE (gtk_tree_row_reference_get_model (dc->rr));
939
940 path = gtk_tree_row_reference_get_path (de->rr);
941 GNUNET_assert (NULL != path);
942 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (de->ts), &iter, path))
943 {
944 /* Store filename and anonymity as specified by the user.
945 * These will be re-used when this is a directory, and the user
946 * downloads its children.
947 */
948 gtk_tree_store_set (de->ts, &iter, 15, dc->filename, 16, dc->anonymity, -1);
949 }
950 gtk_tree_path_free (path);
951
952 }
953 if (dc->sr != NULL)
954 {
955 GNUNET_break (NULL !=
956 GNUNET_FS_download_start_from_search (fs, dc->sr,
957 dc->filename,
958 NULL /* tempname */ ,
959 0 /* offset */ ,
960 len, dc->anonymity, opt,
961 de));
962 }
963 else
964 {
965 GNUNET_break (NULL !=
966 GNUNET_FS_download_start (fs, de->uri, NULL /* meta */ ,
967 dc->filename, NULL /* tempname */ ,
968 0 /* offset */ ,
969 len, dc->anonymity, opt, de,
970 NULL /* parent download ctx */ ));
971 }
972 GNUNET_GTK_save_as_dialog_free_download_context (dc);
973}
810 974
811/** 975/**
812 * Tell FS to start a download. Begins by opening the 976 * Tell FS to start a download. Begins by opening the
@@ -825,11 +989,16 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
825 struct SearchResult *sr; 989 struct SearchResult *sr;
826 gchar *mime; 990 gchar *mime;
827 struct DownloadContext *dc; 991 struct DownloadContext *dc;
828 char *buf; 992 char *buf = NULL;
829 char *tmp; 993 char *tmp;
830 size_t tmplen; 994 size_t tmplen;
831 char cwd[FILENAME_MAX]; 995 char cwd[FILENAME_MAX];
996 char *download_directory;
832 char *filename; 997 char *filename;
998 int local_parents;
999 int have_a_suggestion;
1000 int anonymity;
1001 int filename_is_absolute;
833 1002
834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1003 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
835 "Starting a %sdownload\n", sdc->recursive ? "recursive " : ""); 1004 "Starting a %sdownload\n", sdc->recursive ? "recursive " : "");
@@ -858,24 +1027,32 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
858 return; 1027 return;
859 } 1028 }
860 1029
861 1030 download_directory = get_default_download_directory (cwd, sizeof (cwd));
862 /* FIXME: we should check if this download is a file in some directory 1031 /* If no download directory is known, try working directory */
863 (gtk_tree_model_iter_get_parent) and if so obtain the name under which 1032 if (download_directory == NULL)
864 the directory was stored! */ 1033 download_directory = getcwd (cwd, sizeof (cwd));
865 /* Calculate suggested filename; first, pre-pend current working directory */ 1034 /* Calculate suggested filename */
866 filename = GNUNET_FS_meta_data_suggest_filename (meta); 1035 local_parents = GNUNET_YES;
867 if (NULL != getcwd (cwd, sizeof (cwd))) 1036 anonymity = -1;
1037 filename_is_absolute = GNUNET_NO;
1038 filename = get_suggested_filename_anonymity (tm, &iter, GNUNET_YES, &local_parents, &anonymity, &filename_is_absolute);
1039 have_a_suggestion = GNUNET_NO;
1040 if (NULL != download_directory)
868 { 1041 {
869 if (NULL == filename) 1042 if (NULL == filename)
870 { 1043 {
871 buf = GNUNET_strdup (cwd); 1044 buf = GNUNET_strdup (download_directory);
872 } 1045 }
873 else 1046 else
874 { 1047 {
875 GNUNET_asprintf (&tmp, "%s%s%s", 1048 have_a_suggestion = GNUNET_YES;
876 cwd, 1049 if (filename_is_absolute)
877 DIR_SEPARATOR_STR, 1050 GNUNET_asprintf (&tmp, "%s", filename);
878 filename); 1051 else
1052 GNUNET_asprintf (&tmp, "%s%s%s",
1053 download_directory,
1054 DIR_SEPARATOR_STR,
1055 filename);
879 tmplen = strlen (tmp); 1056 tmplen = strlen (tmp);
880 /* now, if we have a directory, replace trailing '/' with ".gnd" */ 1057 /* now, if we have a directory, replace trailing '/' with ".gnd" */
881 if (GNUNET_YES == 1058 if (GNUNET_YES ==
@@ -906,10 +1083,15 @@ start_download (GtkTreeView * tree_view, GtkTreePath * path,
906 dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); 1083 dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
907 dc->rr = gtk_tree_row_reference_new (tm, path); 1084 dc->rr = gtk_tree_row_reference_new (tm, path);
908 dc->sr = sr->result; 1085 dc->sr = sr->result;
909 dc->anonymity = -1; 1086 dc->anonymity = anonymity;
910 dc->is_recursive = sdc->recursive; 1087 dc->is_recursive = sdc->recursive;
911 dc->tab = tab; 1088 dc->tab = tab;
912 GNUNET_FS_GTK_open_download_as_dialog (dc); 1089 dc->cb = &open_download_as_callback;
1090 if (local_parents && have_a_suggestion)
1091 /* Skip the dialog, call directly */
1092 open_download_as_callback (dc);
1093 else
1094 GNUNET_FS_GTK_open_download_as_dialog (dc);
913} 1095}
914 1096
915 1097
@@ -1608,6 +1790,8 @@ GNUNET_GTK_add_search_result (struct SearchTab *tab, GtkTreeIter * iter,
1608 0 /* avail-cert */ , 1790 0 /* avail-cert */ ,
1609 13, 0, /* avail-rank */ 1791 13, 0, /* avail-rank */
1610 14, (guint64) 0, /* completed */ 1792 14, (guint64) 0, /* completed */
1793 15, NULL, /* downloaded_filename */
1794 16, -1, /* downloaded_anonymity */
1611 -1); 1795 -1);
1612 if (tab != NULL) 1796 if (tab != NULL)
1613 { 1797 {