Header for saving and restoring Synema frames. More...
#include <glib.h>
#include "frame-common.h"
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_t * | file_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) |
Header for saving and restoring Synema frames.
This header file contains functions for saving and loading Synema frames.
Definition in file frame-saving.h.
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.
[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. |
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.
[in] | subdirpath | the path to the subdirectory where saved files are |
[out] | tab | the frames table in which frames should be added |
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.
[in] | savedirpath | the directory in which the saved files should be put |
[in] | tab | the frame_table_t containing the frames list to save |
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
[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 |
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 }