Save and load grid state functionality implemented
authorHarishankar <v.harishankar@gmail.com>
Sat, 9 May 2020 09:30:06 +0000 (15:00 +0530)
committerHarishankar <v.harishankar@gmail.com>
Sat, 9 May 2020 09:30:06 +0000 (15:00 +0530)
Implemented the functionality for saving and loading the grid
state in the player application, so that the player can save a
puzzle solving session and continue working on it later.

constantstrings.h
wordblox.h
wordblox_player.c
wordblox_player.glade

index d80bc1a..b2a270a 100644 (file)
@@ -45,6 +45,7 @@ columns (warning: existing file name may be overwritten)\n"
 #define ERROR_ICON "Unable to load icon!"
 #define ERROR_WINDOW "Error loading Window Resource!"
 #define OPEN_FILE "Open File"
+#define SAVE_FILE "Save File"
 #define UNFROZEN_GRID_PLAYER "Puzzle is not finalized/frozen and hence cannot\
  be played"
 
index a355a09..7519ff4 100644 (file)
@@ -506,7 +506,8 @@ void init_puzzle (Puzzle *p, int grid_size)
 }
 
 /* save the puzzle to a file */
-void save_puzzle (Puzzle *puzzle, const char* file) {
+void save_puzzle (Puzzle *puzzle, const char* file) 
+{
        FILE *outfile;
        /* First output the uncompressed contents to a temp file */
        outfile = tmpfile ();
@@ -605,7 +606,8 @@ void save_puzzle (Puzzle *puzzle, const char* file) {
 }
 
 /* read the puzzle from a file */
-Puzzle load_puzzle (const char* file) {
+Puzzle load_puzzle (const char* file) 
+{
        /* First open the GZip file */
        gzFile insourcefile = gzopen (file, "rb");
        if (insourcefile == NULL)
@@ -914,6 +916,53 @@ void reset_player_data (MainPlayerData *app_data, const char *filename)
        
 }
 
+/* save the user grid to a file */
+void save_user_data (MainPlayerData *app_data, const char *filename) 
+{
+       FILE *outfile;
+       outfile = fopen (filename, "wb");
+       if (outfile == NULL) 
+       {
+               fprintf (stderr, ERROR_WRITING_FILE);
+               return;
+       }
+       fprintf (outfile, "%s\n", app_data->filename);
+       for (int i = 0; i < app_data->puzzle.grid_size; i ++)
+       {
+               for (int j = 0; j < app_data->puzzle.grid_size; j ++)
+                       fprintf (outfile, "%c", app_data->char_ans[i][j]);
+               fprintf (outfile, "\n");
+       }
+       
+       fclose (outfile);
+}
+
+/* load the user grid from a file */
+void load_user_data (MainPlayerData *app_data, const char *filename)
+{
+       FILE *infile;
+       infile = fopen (filename, "rb");
+       if (infile == NULL)
+       {
+               fprintf (stderr, "%s\n", ERROR_READING_FILE);
+               return;
+       }
+
+       char puzzle_file_name[65535];
+       fgets (puzzle_file_name, 65535, infile);        
+       reset_player_data (app_data, strtok (puzzle_file_name, "\n"));
+
+       char line[MAX_PUZZLE_SIZE+10];
+       for (int i = 0; i < app_data->puzzle.grid_size; i ++)
+       {
+               fgets (line, MAX_PUZZLE_SIZE+10, infile);
+               for (int j = 0; j < app_data->puzzle.grid_size; j ++)
+                       app_data->char_ans[i][j] = line[j];
+
+       }
+       fclose (infile);
+}
+
 /* in the player app, move the current selection index left or right */
 void move_current_col (MainPlayerData *app_data, enum DIRECTION dir)
 {
index d1f0929..9560ac8 100644 (file)
@@ -535,15 +535,64 @@ void on_menu_reveal_solution_activate (GtkMenuItem *item, GtkDrawingArea *area)
 }
 
 /* slot for load grid state menu */
-void on_menu_load_grid_state_activate (GtkMenuItem *item, gpointer *data)
+void on_menu_load_grid_state_activate (GtkMenuItem *item, GtkDrawingArea *area)
 {
-       /* TODO */
+       GtkWidget *dialog;
+       GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
+       gint res;
+       dialog = gtk_file_chooser_dialog_new (OPEN_FILE, GTK_WINDOW (main_window),
+                                                                               action,
+                                                                               "_Cancel",
+                                                                               GTK_RESPONSE_CANCEL,
+                                                                               "_Open",
+                                                                               GTK_RESPONSE_ACCEPT,
+                                                                               NULL
+                                                                               );
+                                                                               
+       res = gtk_dialog_run (GTK_DIALOG (dialog));
+       if (res == GTK_RESPONSE_ACCEPT)
+       {
+               char *filename;
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+               load_user_data (&app_data, filename);
+               g_free (filename);
+       }
+       
+       gtk_widget_destroy (dialog);
+       
+       gtk_widget_queue_draw_area (GTK_WIDGET(area), 0, 0,  
+                               app_data.puzzle.grid_size*GRID_PIXELS+10, 
+                               app_data.puzzle.grid_size*GRID_PIXELS+10);
+                               
+       update_clue_items ();
 }
 
 /* slot for save grid state menu */
 void on_menu_save_grid_state_activate (GtkMenuItem *item, gpointer *data)
 {
-       /* TODO */
+       if (app_data.is_loaded == false)
+               return;
+               
+       GtkWidget *dialog;
+       GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
+       gint res;
+       dialog = gtk_file_chooser_dialog_new (SAVE_FILE, GTK_WINDOW(main_window),
+                                                                               action,
+                                                                               "_Cancel",
+                                                                               GTK_RESPONSE_CANCEL,
+                                                                               "_Save",
+                                                                               GTK_RESPONSE_ACCEPT,
+                                                                               NULL);
+       res = gtk_dialog_run (GTK_DIALOG (dialog));
+       if (res == GTK_RESPONSE_ACCEPT)
+       {
+               char *filename;
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+               save_user_data (&app_data, filename);
+               g_free (filename);
+       }
+       
+       gtk_widget_destroy (dialog);
 }
 
 /* slot for exit menu */
index 19d8fdd..dc20b5b 100644 (file)
@@ -99,7 +99,7 @@
                         <property name="can_focus">False</property>
                         <property name="label" translatable="yes">_Load Grid State...</property>
                         <property name="use_underline">True</property>
-                        <signal name="activate" handler="on_menu_load_grid_state_activate" swapped="no"/>
+                        <signal name="activate" handler="on_menu_load_grid_state_activate" object="puzzle_area" swapped="no"/>
                       </object>
                     </child>
                   </object>