src/frame-saving.h File Reference

Header for saving and restoring Synema frames. More...

#include <glib.h>
#include "frame-common.h"
Include dependency graph for frame-saving.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

GKeyFile * frame_to_key_file (frame_t *, guint, guint)
 Saves the frame's data into a GKeyFile.
int frame_table_save_to_files (const char *, frame_table_t *)
 Takes a list of frames from a table and saves them all in files.
frame_tfile_to_frame (const char *, guint *, guint *)
 Creates an uninitialised frame from a .frame file.
int frame_table_load_from_files (const char *, frame_table_t *)
 Loads frames from a save and puts them into a frames table.
void save_frames_dialog_show (GtkToolButton *, gpointer)

Detailed Description

Header for saving and restoring Synema frames.

Author:
Steve Dodier <sidnioulz@gmail.com>

This header file contains functions for saving and loading Synema frames.

Definition in file frame-saving.h.


Function Documentation

frame_t* file_to_frame ( const char *  path,
guint *  left,
guint *  top 
)

Creates an uninitialised frame from a .frame file.

This function turns a saved frame (with the GKeyFile syntax) into an actual frame. The returned frame is uninitialised and must be initialised by the calling function. The left and top parameters can be NULL, but if one of them is set, then the other one must be set too.

Parameters:
[in] path the path to the file containing the saved frame
[out] left a place to store the left position of the frame in it's table, or NULL.
[out] top a place to store the top position of the frame in it's table, or NULL.
Returns:
the frame that has been restored from the file, uninitialised

Definition at line 188 of file frame-saving.c.

00189 {
00190     synema_instance_t   *inst           = synema_instance ();
00191     frame_t             *frame          = NULL;
00192     gchar               *plugin_type    = NULL;
00193     gchar               *buffer         = NULL;
00194     GError              *err            = NULL;
00195     gint                *list_buffer    = NULL;
00196     GKeyFile            *keyfile        = g_key_file_new ();
00197     gsize               list_len        = 0;
00198     machine_t           *machine        = NULL;
00199     size_ratio_t        size;
00200     time_period_t       period          = {0,0};
00201 
00202 
00203     // Loading the file
00204     g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, &err);
00205     if (err) {
00206         g_warning ("file_to_frame: Opening file %s failed (%s)", path, err->message);
00207         g_clear_error (&err);
00208         return NULL;
00209     }
00210 
00211 
00212     // Plugin type (get the value and check its validity)
00213     plugin_type = g_key_file_get_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_TYPE, &err);
00214     if (err) {
00215         g_warning ("file_to_frame: Could not read plugin type (%s)", err->message);
00216         g_clear_error (&err);
00217         g_key_file_free (keyfile);
00218         return NULL;
00219     }
00220     if ((frame = frame_new (plugin_type)) == NULL) {
00221         g_warning ("file_to_frame: Unsupported plugin type %s", plugin_type);
00222         g_key_file_free (keyfile);
00223         g_free (plugin_type);
00224         return NULL;
00225     }
00226     g_free (plugin_type);
00227 
00228     
00229     // Size ratio
00230     buffer = g_key_file_get_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_SIZE, &err);
00231     if (err) {
00232         g_warning ("file_to_frame: Could not read size ratio (%s)", err->message);
00233         g_clear_error (&err);
00234         g_key_file_free (keyfile);
00235         frame_free_uninitialised (frame);
00236         return NULL;
00237     }
00238 
00239     if (g_strcmp0 (buffer, "LARGE") == 0)
00240         size = LARGE;
00241     else if (g_strcmp0 (buffer, "NORMAL") == 0)
00242         size = NORMAL;
00243     else if (g_strcmp0 (buffer, "FULL") == 0)
00244         size = FULL;
00245     else {
00246         g_warning ("file_to_frame: Unsupported size ratio %s", buffer);
00247         g_key_file_free (keyfile);
00248         frame_free_uninitialised (frame);
00249         g_free (buffer);
00250         return NULL;
00251     }
00252     g_free (buffer);
00253 
00254     
00255     // Machine name
00256     buffer = g_key_file_get_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_MACHINE, &err);
00257     if (err) {
00258         g_warning ("file_to_frame: Could not read machine name (%s)", err->message);
00259         g_clear_error (&err);
00260         g_key_file_free (keyfile);
00261         frame_free_uninitialised (frame);
00262         return NULL;
00263     }
00264     if ((machine = machine_list_find_by_name (inst->machines_list, buffer)) == NULL) {
00265         g_warning ("file_to_frame: Could not find machine %s", buffer); 
00266         g_key_file_free (keyfile);
00267         frame_free_uninitialised (frame);
00268         g_free (buffer);
00269         return NULL;
00270     }
00271     g_free (buffer);
00272 
00273 
00274     // Plugin type
00275     list_buffer = g_key_file_get_integer_list (keyfile, FTGKF_GROUP_FRAME, FTGKF_PERIOD, &list_len, &err);
00276     if (err) {
00277         g_warning ("file_to_frame: Could not read time period (%s)", err->message);
00278         g_clear_error (&err);
00279         g_key_file_free (keyfile);
00280         frame_free_uninitialised (frame);
00281         return NULL;
00282     }
00283     if (list_len == 2) {
00284         period.type = list_buffer[0];
00285         period.value = list_buffer[1];
00286     } else {
00287         g_warning ("file_to_frame: Invalid time period setting");
00288         g_key_file_free (keyfile);
00289         frame_free_uninitialised (frame);
00290         g_free (list_buffer);
00291         return NULL;
00292     }
00293     g_free (list_buffer);
00294 
00295 
00296     // Coordinates
00297     if (left || top) {
00298         list_buffer = g_key_file_get_integer_list (keyfile, FTGKF_GROUP_POSITION, FTGKF_POSITION, &list_len, &err);
00299         if (err) {
00300             g_warning ("file_to_frame: Could not read table coordinates (%s)", err->message);
00301             g_clear_error (&err);
00302             g_key_file_free (keyfile);
00303             frame_free_uninitialised (frame);
00304             return NULL;
00305         }
00306         
00307         if (list_len == 2) {
00308             *left = list_buffer[0];
00309             *top = list_buffer[1];
00310         } else {
00311             g_warning ("file_to_frame: Invalid table coordinate setting");
00312             g_key_file_free (keyfile);
00313             frame_free_uninitialised (frame);
00314             g_free (list_buffer);
00315             return NULL;
00316         }
00317         g_free (list_buffer);
00318     }
00319 
00320 
00321     // Create the frame
00322     if (frame_initialise (frame, size, machine, &period) != 0) {
00323         frame_free (frame);
00324         g_key_file_free (keyfile);
00325         g_warning ("file_to_frame: Frame could not be initialised");
00326         return NULL;
00327     }
00328 
00329 
00330     // Private data
00331     frame_restore_private (frame, keyfile);
00332 
00333     g_key_file_free (keyfile);
00334     return frame;
00335 }

int frame_table_load_from_files ( const char *  subdirpath,
frame_table_t tab 
)

Loads frames from a save and puts them into a frames table.

This function loads frames from .frame files that have been previously saved in a directory given as a parameter, and puts them in the frames table passed as a parameter as well.

Parameters:
[in] subdirpath the path to the subdirectory where saved files are
[out] tab the frames table in which frames should be added
Returns:
0 if loading succeeds, -1 on error

Definition at line 339 of file frame-saving.c.

00340 {
00341     gchar           *framepath  = NULL;
00342     GError          *err        = NULL;
00343     GFile           *dirfile    = NULL;
00344     GFileEnumerator *direnum    = NULL;
00345     GFileInfo       *dirinfo    = NULL;
00346     GFileInfo       *current    = NULL;
00347     guint           left = 0, top = 0;
00348     
00349     dirfile = g_file_new_for_path (subdirpath);
00350     
00351     tab->position = g_ascii_strtod (g_strrstr (subdirpath, "/") + 1, NULL);
00352 
00353     dirinfo = g_file_query_info (dirfile, "standard::type", G_FILE_QUERY_INFO_NONE, NULL, &err);
00354     if (err) {
00355         //g_warning ("frame_table_load_from_files: Error while querying the "SAVED_FRAMES_DIR" file (%s)", err->message);
00356         // This may happen if the file doesn't exist, in which case we just don't restore any frame
00357         g_clear_error (&err);
00358         g_object_unref (dirfile);
00359         return -1;
00360     }
00361     if (g_file_info_get_file_type (dirinfo) != G_FILE_TYPE_DIRECTORY) {
00362         // This is not an error, we just can't restore frames since there is no saved frames directory
00363         return -1;
00364     }
00365     g_object_unref (dirinfo);
00366 
00367     direnum = g_file_enumerate_children (dirfile, "standard::name", G_FILE_QUERY_INFO_NONE, NULL, &err);
00368     if (err) {
00369         g_warning ("frame_table_load_from_files: Error while reading the saved frames directory (%s)", err->message);
00370         g_clear_error (&err);
00371         g_object_unref (dirfile);
00372         return -1;
00373     }
00374 
00375 
00376     while ((current = g_file_enumerator_next_file (direnum, NULL, &err)) != NULL) {
00377         if (err) {
00378             g_warning ("frame_table_load_from_files: Error while reading a file of the saved frames (%s)", err->message);
00379             g_clear_error (&err);
00380         } else {
00381             if (g_str_has_suffix (g_file_info_get_name (current), FRAME_SAVE_SUFFIX)) {
00382                 framepath = g_strdup_printf ("%s/%s", subdirpath, g_file_info_get_name (current));
00383                 frame_t *frame = file_to_frame (framepath, &left, &top);
00384                 g_free (framepath);
00385                 if (frame) {
00386                     frame_table_add_with_coords (tab, frame, left, top);
00387                 }
00388             }
00389             g_object_unref (current);
00390         }
00391     }
00392 
00393     g_object_unref (direnum);
00394     g_object_unref (dirfile);
00395     return 0;
00396 }

int frame_table_save_to_files ( const char *  savedirpath,
frame_table_t tab 
)

Takes a list of frames from a table and saves them all in files.

This function grabs all the frames associated to a table from the Synema instance's frames list, and saves all of them into different files, which are written in a directory whose path is given as a parameter.

Parameters:
[in] savedirpath the directory in which the saved files should be put
[in] tab the frame_table_t containing the frames list to save
Returns:
0 if no error occurred, -1 otherwise

Definition at line 117 of file frame-saving.c.

00118 {
00119     synema_instance_t   *inst       = synema_instance ();
00120     const gchar         *tablabel   = notebook_get_tab_label (GTK_NOTEBOOK (gtk_builder_get_object (inst->builder, "notebook")), tab->table_box);
00121     gchar               *buffer     = NULL;
00122     gchar               *framepath  = NULL;
00123     gchar               *path       = NULL;
00124     GError              *err        = NULL;
00125     gint                nbindex     = gtk_notebook_page_num (GTK_NOTEBOOK (gtk_builder_get_object (inst->builder, "notebook")), tab->table_box);
00126     GFile               *file       = NULL;
00127     GFileOutputStream   *stream     = NULL;
00128     GKeyFile            *keyfile    = NULL;
00129     guint               left, top, index = 0;
00130     gsize               len         = 0;
00131     GList               *iter       = tab->frames_list;
00132 
00133     path = g_strdup_printf ("%s/%i__%s", savedirpath, nbindex, tablabel);
00134 
00135     if (g_mkdir_with_parents (path, 0777)) {
00136         g_warning ("frame_table_save_to_file: Could not make the saved frames directory (%s)", g_strerror (errno));
00137         g_free (path);
00138         return -1;
00139     }
00140 
00141     if (iter) {
00142         do {
00143             if (!frame_get_coordinates (iter->data, tab->table, &left, &top)) {
00144                 g_warning ("frame_table_save_to_file: A frame could not be saved (not in the table) (err0)");
00145             } else {
00146                 keyfile = frame_to_key_file (iter->data, left, top);
00147                 buffer = g_key_file_to_data (keyfile, &len, &err);
00148                 if (err) {
00149                     g_warning ("frame_table_save_to_file: A frame could not be saved (%s) (err1)", err->message);
00150                     g_clear_error (&err);
00151                 } else {
00152                     framepath = g_strdup_printf ("%s/%03d"FRAME_SAVE_SUFFIX, path, index);
00153                     index++;
00154                     file = g_file_new_for_path (framepath);
00155                     g_free (framepath);
00156 
00157                     stream = g_file_replace (file, NULL, TRUE, G_FILE_CREATE_NONE, NULL, &err);
00158                     if (err) {
00159                         g_warning ("frame_table_save_to_file: A frame could not be saved (%s) (err2)", err->message);
00160                         g_clear_error (&err);
00161                     } else {
00162                         if (g_output_stream_write (G_OUTPUT_STREAM (stream), FRAME_HEADER, g_utf8_strlen (FRAME_HEADER, -1), NULL, &err) == -1) {
00163                             g_warning ("frame_table_save_to_file: A frame could not be saved (%s) (err3)", err->message);
00164                             g_clear_error (&err);
00165                         }
00166                         if (g_output_stream_write (G_OUTPUT_STREAM (stream), buffer, len, NULL, &err) == -1) {
00167                             g_warning ("frame_table_save_to_file: A frame could not be saved (%s) (err4)", err->message);
00168                             g_clear_error (&err);
00169                         }
00170                         g_object_unref (stream);
00171                     }
00172 
00173                     g_object_unref (file);
00174                 }
00175                 
00176                 g_key_file_free (keyfile);
00177                 g_free (buffer);
00178             }
00179         } while ((iter = g_list_next (iter)) != NULL);
00180     }
00181 
00182     g_free (path);
00183     return 0;
00184 }

GKeyFile* frame_to_key_file ( frame_t frame,
guint  left,
guint  top 
)

Saves the frame's data into a GKeyFile.

This function saves all the members of a frame_t into a GKeyFile so that it can be restored from the file. The GKeyFile must be freed by calling functions, with g_key_file_free

Parameters:
[in] frame the frame to turn into a GKeyFile
[in] left the columns index of the frame in the table containing it
[in] top the rows index of the frame in the table containing it
Returns:
the GKeyFile containing the frame's data. You must free it with g_key_file_free

Definition at line 68 of file frame-saving.c.

00069 {
00070     gchar       *size_label     = NULL;
00071     GKeyFile    *keyfile        = g_key_file_new ();
00072     gint        *list_buffer    = g_malloc (sizeof (gint) * 2);
00073 
00074     // Save frame settings
00075     g_key_file_set_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_TYPE, frame->type);
00076 
00077     switch (frame->size) {
00078         case LARGE:
00079             size_label = g_strdup ("LARGE");
00080             break;
00081         case NORMAL:
00082             size_label = g_strdup ("NORMAL");
00083             break;
00084         case FULL:
00085             size_label = g_strdup ("FULL");
00086             break;
00087         default:
00088             size_label = g_strdup ("INVALID");
00089             break;
00090     }
00091     g_key_file_set_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_SIZE, size_label);
00092     g_free (size_label);
00093 
00094     g_key_file_set_string (keyfile, FTGKF_GROUP_FRAME, FTGKF_MACHINE,
00095                             machine_get_folder_name (frame->display_machine));
00096 
00097     list_buffer[0] = frame->display_period.type;
00098     list_buffer[1] = frame->display_period.value;
00099     g_key_file_set_integer_list (keyfile, FTGKF_GROUP_FRAME, FTGKF_PERIOD, list_buffer, 2);
00100 
00101 
00102     // Save positioning
00103     list_buffer[0] = left;
00104     list_buffer[1] = top;
00105     g_key_file_set_integer_list (keyfile, FTGKF_GROUP_POSITION, FTGKF_POSITION, list_buffer, 2);
00106 
00107 
00108     // Private data saving
00109     frame_save_private (frame, keyfile);
00110     
00111     g_free (list_buffer);
00112     return keyfile;
00113 }

void save_frames_dialog_show ( GtkToolButton *  ,
gpointer   
)

Definition at line 400 of file frame-saving.c.

00401 {
00402     synema_instance_t   *inst           = synema_instance ();
00403     gchar               *path           = NULL;
00404     gchar               *tarpath        = NULL;
00405     gchar               *taruri         = NULL;
00406     gchar               *dlg_objects[]  = {"save_frames_dialog", NULL};
00407     GError              *err            = NULL;
00408     GFile               *tmp            = NULL;
00409     GList               *iter           = NULL;
00410     GtkRecentManager    *manager        = NULL;
00411     GtkWidget           *dialog         = NULL;
00412     TAR                 *tarhandle      = NULL;
00413 
00414 
00415     // Add a new dialog to the builder
00416     path = g_strdup_printf ("%s/window.ui", inst->data_dir);
00417     gtk_builder_add_objects_from_file (inst->builder, path, dlg_objects, &err);
00418     g_free (path);
00419     if (err) {
00420         g_warning ("frame_on_new: %s", err->message);
00421         g_clear_error (&err);
00422         return;
00423     }
00424 
00425 
00426     // Now running the dialog
00427     dialog = (GtkWidget *) gtk_builder_get_object (inst->builder, "save_frames_dialog");
00428     gint result = gtk_dialog_run (GTK_DIALOG (dialog));
00429 
00430 
00431     // Exploiting the result here
00432     switch (result) {
00433         case GTK_RESPONSE_OK:
00434             gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
00435             path = g_strdup_printf ("%s/"FRAME_SAVING_DIR, inst->tmp_dir);
00436             if (g_mkdir_with_parents (path, 0777)) {
00437                 g_warning ("save_frames_dialog_show: Could not create a temporary directory in which frames could be written (%s)", g_strerror (errno));
00438                 error_dialog ("<b>Failed to save file</b>\n\nCould not create a temporary  directory in which frames could be written (%s)", g_strerror (errno));
00439                 recursive_remove (path);
00440                 g_free (path);
00441                 break;
00442             }
00443             
00444             // If all tabs should be saved
00445             if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object (inst->builder, "save_frames_all_tabs")))) {
00446                 iter = inst->tables_list;
00447                 if (iter) {
00448                     do {
00449                         frame_table_save_to_files (path, iter->data);
00450                     } while ((iter = g_list_next (iter)) != NULL);
00451                 }
00452             }
00453             // If only the current tab should be saved
00454             else {
00455                 frame_table_save_to_files (path, inst->current_table);
00456             }
00457 
00458             tarpath = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
00459             if (!g_str_has_suffix (tarpath, TAB_SAVE_SUFFIX)) {
00460                 char *tmp = g_strdup_printf ("%s"TAB_SAVE_SUFFIX, tarpath);
00461                 g_free (tarpath);
00462                 tarpath = tmp;
00463             }
00464             
00465             if (tar_open (&tarhandle, tarpath, NULL, O_CREAT | O_TRUNC | O_WRONLY, 0666, 0)) {
00466                 g_warning ("save_frames_dialog_show: Could not create a tar archive to save the frames (%s)", g_strerror (errno));
00467                 error_dialog ("<b>Failed to save file</b>\n\nCould not create a tar archive to save the frames (%s)", g_strerror (errno));
00468                 g_free (tarpath);
00469                 recursive_remove (path);
00470                 g_free (path);
00471                 break;
00472             }
00473             
00474             if (tar_append_tree (tarhandle, path, SAVED_FRAMES_DIR)) {
00475                 g_warning ("save_frames_dialog_show: Could not put frames into the tar archive (%s)", g_strerror (errno));
00476                 error_dialog ("<b>Failed to save file</b>\n\nCould not put frames into the tar archive (%s)", g_strerror (errno));
00477                 tar_close (tarhandle);
00478                 g_free (tarpath);
00479                 g_free (path);
00480                 break;
00481             }
00482             recursive_remove (path);
00483             g_free (path);
00484 
00485             if (tar_append_eof (tarhandle)) {
00486                 g_warning ("save_frames_dialog_show: Could not set the EOF of the tar archive (%s)", g_strerror (errno));
00487                 error_dialog ("<b>Failed to save file</b>\n\nCould not set the EOF of the tar archive (%s)\nThis is most likely a libtar bug", g_strerror (errno));
00488                 tar_close (tarhandle);
00489                 g_free (tarpath);
00490                 break;
00491             }
00492 
00493             if (tar_close (tarhandle)) {
00494                 g_warning ("save_frames_dialog_show: Error on closing the tar archive (%s)", g_strerror (errno));
00495                 error_dialog ("<b>Failed to save file</b>\n\nError on closing the tar archive (%s)\nThis is most likely a libtar bug", g_strerror (errno));
00496                 g_free (tarpath);
00497                 break;
00498             }
00499             manager = gtk_recent_manager_get_default ();
00500             tmp = g_file_new_for_path (tarpath);
00501             taruri = g_file_get_uri (tmp);
00502             gtk_recent_manager_add_item (manager, taruri);
00503             g_free (tarpath);
00504             g_free (taruri);
00505             g_object_unref (tmp);
00506         default:
00507             break;
00508     }
00509 
00510     gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
00511     gtk_widget_destroy (dialog);
00512 }

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Tue Jan 12 00:48:45 2010 for ENSIBSynema by  doxygen 1.6.1