anastasis-gtk_io.c (6781B)
1 /* 2 This file is part of anastasis-gtk. 3 Copyright (C) 2020 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 Anastasis is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with Anastasis; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file src/anastasis/anastasis-gtk_io.c 22 * @brief 23 * @author Christian Grothoff 24 */ 25 #include <gnunet/gnunet_util_lib.h> 26 #include "anastasis_gtk_util.h" 27 #include "anastasis-gtk_attributes.h" 28 #include "anastasis-gtk_dispatch.h" 29 #include "anastasis-gtk_helper.h" 30 #include <jansson.h> 31 32 33 /** 34 * Function called from the open-directory dialog upon completion. 35 * 36 * @param dialog the pseudonym selection dialog 37 * @param response_id response code from the dialog 38 * @param user_data the builder of the dialog 39 */ 40 void 41 open_directory_dialog_response_cb (GtkDialog *dialog, 42 gint response_id, 43 gpointer user_data) 44 { 45 GtkBuilder *builder = GTK_BUILDER (user_data); 46 char *filename; 47 48 if (GTK_RESPONSE_OK != response_id) 49 { 50 gtk_widget_destroy (GTK_WIDGET (dialog)); 51 g_object_unref (G_OBJECT (builder)); 52 return; 53 } 54 filename = 55 ANASTASIS_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (dialog)); 56 gtk_widget_destroy (GTK_WIDGET (dialog)); 57 g_object_unref (G_OBJECT (builder)); 58 AG_load (filename); 59 GNUNET_free (filename); 60 } 61 62 63 /** 64 * User clicked the "open" button. 65 * 66 * @param button the button 67 * @param user_data unused 68 */ 69 void 70 anastasis_gtk_open_state_clicked_cb (GtkButton *button, 71 gpointer user_data) 72 { 73 GtkWidget *ad; 74 GtkBuilder *builder; 75 76 builder = ANASTASIS_GTK_get_new_builder ( 77 ANASTASIS_GTK_project_data (), 78 "anastasis_gtk_open_file_dialog.glade", 79 NULL); 80 if (NULL == builder) 81 { 82 GNUNET_break (0); 83 return; 84 } 85 ad = GTK_WIDGET (gtk_builder_get_object (builder, 86 "open_file_dialog")); 87 { 88 GtkWidget *toplevel; 89 90 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button)); 91 gtk_window_set_transient_for (GTK_WINDOW (ad), 92 GTK_WINDOW (toplevel)); 93 gtk_window_present (GTK_WINDOW (ad)); 94 } 95 } 96 97 98 /** 99 * Serialize state of currently shown use attribute editing frame to JSON. 100 */ 101 static void 102 save_user_attributes_collecting (void) 103 { 104 json_t *ia; 105 106 ia = AG_collect_attributes (true); 107 if (NULL == ia) 108 { 109 GNUNET_break (0); 110 return; 111 } 112 GNUNET_break (0 == 113 json_object_set (AG_redux_state, 114 "identity_attributes", 115 json_object_get (ia, 116 "identity_attributes"))); 117 json_decref (ia); 118 } 119 120 121 /** 122 * Function called from the open-directory dialog upon completion. 123 * 124 * @param dialog the pseudonym selection dialog 125 * @param response_id response code from the dialog 126 * @param user_data the builder of the dialog 127 */ 128 void 129 save_directory_dialog_response_cb (GtkDialog *dialog, 130 gint response_id, 131 gpointer user_data) 132 { 133 static const struct DispatchItem save_state[] = { 134 { .state = "USER_ATTRIBUTES_COLLECTING", 135 .action = &save_user_attributes_collecting }, 136 { .state = NULL, 137 .action = NULL } 138 }; 139 GtkBuilder *builder = GTK_BUILDER (user_data); 140 char *filename; 141 142 if (GTK_RESPONSE_ACCEPT != response_id) 143 { 144 gtk_widget_destroy (GTK_WIDGET (dialog)); 145 g_object_unref (G_OBJECT (builder)); 146 return; 147 } 148 (void) AG_dispatch (save_state); 149 filename = 150 ANASTASIS_GTK_filechooser_get_filename_utf8 (GTK_FILE_CHOOSER (dialog)); 151 gtk_widget_destroy (GTK_WIDGET (dialog)); 152 g_object_unref (G_OBJECT (builder)); 153 154 /* check if we should warn the user about writing 'core_secret' to disk */ 155 { 156 json_t *cs; 157 158 cs = json_object_get (AG_redux_state, 159 "core_secret"); 160 if ( (NULL != cs) && 161 (! json_is_null (cs)) ) 162 { 163 GtkWidget *diag; 164 gint ret; 165 GtkWidget *toplevel; 166 167 toplevel = gtk_widget_get_toplevel ( 168 GTK_WIDGET (GCG_get_main_window_object ( 169 "anastasis_gtk_main_window"))); 170 diag = gtk_message_dialog_new ( 171 GTK_WINDOW (toplevel), 172 GTK_DIALOG_MODAL, 173 GTK_MESSAGE_QUESTION, 174 GTK_BUTTONS_OK_CANCEL, 175 _ ("This will write your secret to disk in cleartext!")); 176 ret = gtk_dialog_run (GTK_DIALOG (diag)); 177 gtk_widget_destroy (diag); 178 switch (ret) 179 { 180 case GTK_RESPONSE_OK: 181 break; 182 default: 183 /* user aborted */ 184 return; 185 } 186 } 187 } 188 189 /* all good, do writing! */ 190 { 191 const char *ana; 192 193 ana = strstr (filename, 194 ".ana"); 195 if ( (NULL == ana) || 196 (4 != strlen (ana)) ) 197 { 198 char *tmp; 199 200 GNUNET_asprintf (&tmp, 201 "%s.ana", 202 filename); 203 GNUNET_free (filename); 204 filename = tmp; 205 } 206 } 207 if (0 != 208 json_dump_file (AG_redux_state, 209 filename, 210 JSON_COMPACT)) 211 { 212 AG_error ("Failed to write state to `%s'\n", 213 filename); 214 } 215 GNUNET_free (filename); 216 } 217 218 219 /** 220 * User clicked the "save as" button. 221 * 222 * @param button the button 223 * @param user_data unused 224 */ 225 void 226 anastasis_gtk_main_window_save_as_button_clicked_cb (GtkButton *button, 227 gpointer user_data) 228 { 229 GtkWidget *ad; 230 GtkBuilder *builder; 231 GtkWidget *toplevel; 232 233 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button)); 234 builder = ANASTASIS_GTK_get_new_builder ( 235 ANASTASIS_GTK_project_data (), 236 "anastasis_gtk_save_file_dialog.glade", 237 NULL); 238 if (NULL == builder) 239 { 240 GNUNET_break (0); 241 return; 242 } 243 ad = GTK_WIDGET (gtk_builder_get_object (builder, 244 "save_file_dialog")); 245 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (ad), 246 "untitled.ana"); 247 { 248 gtk_window_set_transient_for (GTK_WINDOW (ad), 249 GTK_WINDOW (toplevel)); 250 gtk_window_present (GTK_WINDOW (ad)); 251 } 252 }