src/frame-open-panel.c File Reference

Source code for functions related to the frame opening panel. More...

#include <errno.h>
#include <fcntl.h>
#include <gtk/gtk.h>
#include <libtar.h>
#include "application-data.h"
#include "frame-open-panel.h"
#include "frame-saving.h"
#include "notebook.h"
Include dependency graph for frame-open-panel.c:

Go to the source code of this file.

Functions

gboolean frame_open_try_load_frame (GFile *file)
gboolean frame_open_try_load_tab (gchar *filename)
void frame_open_file (GFile *file)
void frame_open_setup_widgets ()

Detailed Description

Source code for functions related to the frame opening panel.

Author:
Steve Dodier <sidnioulz@gmail.com>

This source file contains the definition of functions related to the frame opening panel.

Definition in file frame-open-panel.c.


Function Documentation

void frame_open_file ( GFile *  file  ) 

Definition at line 232 of file frame-open-panel.c.

00233 {
00234     synema_instance_t   *inst       = synema_instance ();
00235     gboolean            opened      = FALSE;
00236     gboolean            tested[LAST_FILETYPE_T];
00237     gchar               *filename   = g_file_get_path (file);
00238     gint                i;
00239 
00240 
00241     // Make the GUI insensitive while the function is in use
00242     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_filebutton_file"), FALSE);
00243     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_recentchooser"), FALSE);
00244     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_label_file"), FALSE);
00245     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_label_recent"), FALSE);
00246 
00247 
00248     for (i=0; i<LAST_FILETYPE_T; i++) {
00249         tested[i] = FALSE;
00250     }
00251 
00252 
00253     // If file is likely to be a frame  
00254     if (g_str_has_suffix (filename, FRAME_SAVE_SUFFIX)) {
00255         if (frame_open_try_load_frame (file)) {
00256             g_debug ("frame_open_file: File of type "FRAME_SAVE_SUFFIX" successfully opened");
00257             opened = TRUE;
00258         }
00259         tested[FILE_FRAME] = TRUE;
00260     }
00261     // If file is likely to be a frame tab (or several tabs) archive
00262     else if (g_str_has_suffix (filename, TAB_SAVE_SUFFIX)) {
00263         if (frame_open_try_load_tab (filename)) {
00264             g_debug ("frame_open_file: File of type "TAB_SAVE_SUFFIX" successfully opened");
00265             opened = TRUE;
00266         }
00267         tested[FILE_TAB] = TRUE;
00268     }
00269 
00270 
00271     // If the file type assertions were wrong, try every filetype.
00272     if (!opened && !tested[FILE_FRAME]) {
00273         if (frame_open_try_load_frame (file)) {
00274             g_debug ("frame_open_file: File of type "FRAME_SAVE_SUFFIX" successfully opened");
00275             opened = TRUE;
00276         }
00277         tested[FILE_FRAME] = TRUE;
00278     }
00279     
00280     if (!opened && !tested[FILE_TAB]) {
00281         if (frame_open_try_load_tab (filename)) {
00282             g_debug ("frame_open_file: File of type "TAB_SAVE_SUFFIX" successfully opened");
00283             opened = TRUE;
00284         }
00285         tested[FILE_TAB] = TRUE;
00286     }
00287 
00288     if (!opened) {
00289         g_warning ("frame_open_file: Failed to open file %s", filename);
00290         error_dialog ("Failed to open file ā€˜%s’", filename);
00291     }
00292     g_free (filename);
00293 
00294 
00295     // Make the GUI insensitive while the function is in use
00296     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_filebutton_file"), TRUE);
00297     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_recentchooser"), TRUE);
00298     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_label_file"), TRUE);
00299     gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "open_label_recent"), TRUE);
00300 
00301 
00302     return;
00303 }

void frame_open_setup_widgets (  ) 

Definition at line 342 of file frame-open-panel.c.

00343 {
00344     synema_instance_t       *inst           = synema_instance ();
00345     GtkFileFilter           *filter         = NULL;
00346     GtkRecentFilter         *recfilter      = NULL;
00347     GtkWidget               *filebutton     = (GtkWidget *) gtk_builder_get_object (inst->builder, "open_filebutton_file");
00348     GtkRecentChooser        *chooser        = GTK_RECENT_CHOOSER (gtk_builder_get_object (inst->builder, "open_recentchooser"));
00349 
00350 
00351     // Set the file filter for the Open from File dialog
00352     filter = gtk_file_filter_new ();
00353     gtk_file_filter_add_mime_type (filter, "application/x-tar");
00354     gtk_file_filter_add_pattern (filter, "*"FRAME_SAVE_SUFFIX);
00355     gtk_file_filter_set_name (filter, APP_NAME" files (*"FRAME_SAVE_SUFFIX", *."TAB_SAVE_SUFFIX")");
00356     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filebutton), filter);
00357     gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (filebutton), filter);
00358 
00359     filter = gtk_file_filter_new ();
00360     gtk_file_filter_add_pattern (filter, "*");
00361     gtk_file_filter_set_name (filter, "All files");
00362     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filebutton), filter);
00363 
00364     filter = gtk_file_filter_new ();
00365     gtk_file_filter_add_mime_type (filter, "application/x-tar");
00366     gtk_file_filter_set_name (filter, "Frame tab archives (*"TAB_SAVE_SUFFIX")");
00367     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filebutton), filter);
00368 
00369     filter = gtk_file_filter_new ();
00370     gtk_file_filter_add_pattern (filter, "*"FRAME_SAVE_SUFFIX);
00371     gtk_file_filter_set_name (filter, "Standalone frames (*"FRAME_SAVE_SUFFIX")");
00372     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (filebutton), filter);
00373     g_signal_connect (GTK_FILE_CHOOSER (filebutton), "file-set", G_CALLBACK (frame_open_from_filebutton), NULL);
00374 
00375 
00376     // Set up the recently saved frame tabs tree view
00377     recfilter = gtk_recent_filter_new ();
00378     gtk_recent_filter_set_name (recfilter, APP_NAME" files");
00379     gtk_recent_filter_add_application (recfilter, APP_NAME);
00380     gtk_recent_chooser_set_filter (chooser, recfilter);
00381     g_signal_connect (GTK_RECENT_CHOOSER (chooser), "item-activated", G_CALLBACK (frame_open_from_recent), NULL);
00382 }

gboolean frame_open_try_load_frame ( GFile *  file  ) 

Definition at line 37 of file frame-open-panel.c.

00038 {
00039     synema_instance_t   *inst       = synema_instance ();
00040     frame_t             *frame      = NULL;
00041     gchar               *buffer     = NULL;
00042     GError              *err        = NULL;
00043     GFileInputStream    *stream     = NULL;
00044     guint               len         = g_utf8_strlen (FRAME_HEADER, -1) + 1;
00045 
00046 
00047     // Getting a read stream for the file
00048     stream = g_file_read (file, NULL, &err);
00049     if (err) {
00050         g_debug ("frame_open_try_load_frame: Could not open the file for reading (%s)", err->message);
00051         g_clear_error (&err);
00052         return FALSE;
00053     }
00054 
00055 
00056     // Getting the first bits of the frame file to compare against a frame header
00057     buffer = g_malloc (len);
00058     g_input_stream_read (G_INPUT_STREAM (stream), buffer, len, NULL, &err);
00059     if (err) {
00060         g_debug ("frame_open_try_load_frame: Could not read the file (%s)", err->message);
00061         g_clear_error (&err);
00062         return FALSE;
00063     }
00064 
00065 
00066     // Checking the buffer begins with the frame header
00067     if (!g_str_has_prefix (buffer, FRAME_HEADER)) {
00068         g_free (buffer);
00069         g_debug ("frame_open_try_load_frame: File is not a frame");
00070         return FALSE;
00071     }
00072     g_free (buffer);
00073 
00074 
00075     // Reading the file for real
00076     buffer = g_file_get_path (file);
00077     frame = file_to_frame (buffer, NULL, NULL);
00078     g_free (buffer);
00079     if (frame == NULL) {
00080         g_warning ("frame_open_try_load_frame: File is a frame but is corrupted");
00081         return FALSE;
00082     } else {
00083         if (frame_table_add (inst->current_table, frame) != 0) {
00084             g_warning ("frame_open_try_load_frame: Frame could not be added to the current table");
00085             return FALSE;
00086         } else {
00087             g_debug ("frame_open_try_load_frame: Frame loaded");
00088             return TRUE;
00089         }
00090     }
00091 }

gboolean frame_open_try_load_tab ( gchar *  filename  ) 

Definition at line 95 of file frame-open-panel.c.

00096 {
00097     synema_instance_t   *inst       = synema_instance ();
00098     frame_table_t       *tmptab     = NULL;
00099     gchar               *destpath   = NULL;
00100     gchar               *framesdir  = NULL;
00101     gchar               *ptr        = NULL;
00102     gchar               *subdirpath = NULL;
00103     gchar               *tmpname    = NULL;
00104     GError              *err        = NULL;
00105     GFile               *file       = NULL;
00106     GFileEnumerator     *fileenum   = NULL;
00107     GFileInfo           *current    = NULL;
00108     GList               *iter       = NULL;
00109     GtkWidget           *frame_box  = NULL;
00110     guint               tabcount;
00111     TAR                 *tarhandle  = NULL;
00112 
00113 
00114 
00115     // Getting a TAR handle for the file
00116     if (tar_open (&tarhandle, filename, NULL, O_RDONLY, 0, 0)) {
00117         g_debug ("frame_open_try_load_tab: Could not get a TAR handle for the file (%s)", g_strerror (errno));
00118         return FALSE;
00119     }
00120 
00121 
00122     // Extracting the TAR file's data to a temporary folder
00123     destpath = g_strdup_printf ("%s/"FRAME_OPENING_DIR, inst->tmp_dir);
00124     if (tar_extract_all (tarhandle, destpath) != 0) {
00125         g_debug ("frame_open_try_load_tab: Could not extract the contents of the file (%s)", g_strerror (errno));
00126         g_free (destpath);
00127         tar_close (tarhandle);
00128         return FALSE;
00129     }
00130     tar_close (tarhandle);
00131     framesdir = g_strdup_printf ("%s/"SAVED_FRAMES_DIR, destpath);
00132     file = g_file_new_for_path (framesdir);
00133     current = g_file_query_info (file, "standard::type", G_FILE_QUERY_INFO_NONE, NULL, &err);
00134     if (err) {
00135         g_debug ("frame_open_try_load_tab: Archive does not contain a "SAVED_FRAMES_DIR" directory (%s)", err->message);
00136         g_clear_error (&err);
00137         return FALSE;
00138     }
00139 
00140     if (!g_file_info_get_file_type (current) == G_FILE_TYPE_DIRECTORY) {
00141         g_debug ("frame_open_try_load_tab: File "SAVED_FRAMES_DIR" in the archive is not a directory (%s)", err->message);
00142         g_clear_error (&err);
00143         return FALSE;
00144     }
00145 
00146 
00147     // Reading the data in the destination folder
00148     fileenum = g_file_enumerate_children (file, "standard::name", G_FILE_QUERY_INFO_NONE, NULL, &err);
00149     if (err) {
00150         g_warning ("frame_open_try_load_tab: Error while reading the temp directory containing the tabs (%s)", err->message);
00151         g_clear_error (&err);
00152         return FALSE;
00153     }
00154     
00155     tabcount = 0;
00156     frame_box = (GtkWidget *) gtk_builder_get_object (inst->builder, "notebook");
00157     while ((current = g_file_enumerator_next_file (fileenum, NULL, &err)) != NULL) {
00158         if (err) {
00159             g_warning ("frame_open_try_load_tab: Apparently corrupted file in Tar archive (%s)", err->message);
00160             g_clear_error (&err);
00161         } else {
00162             switch (tabcount) {
00163                 case 0: // Save the current tab and wait before it's added
00164                     tmpname = g_strdup (g_file_info_get_name (current));
00165                     break;
00166 
00167                 case 1: // There are several tabs, empty current notebook
00168                     notebook_remove_all ();
00169                     // There is no break as we still want to add the current tab to the notebook
00170                     
00171                 default: // Add the current file to the notebook
00172                     subdirpath = g_strdup_printf ("%s/%s", framesdir, g_file_info_get_name (current));
00173                     ptr = g_strstr_len (g_strrstr (subdirpath, "/"), -1, "__");
00174                     if (!ptr) {
00175                         g_warning ("frame_open_try_load_tab: Malformed directory name %s", subdirpath);
00176                         notebook_add_page (NULL, (GtkWidget *) gtk_builder_get_object (inst->builder, "notebook"));
00177                         return FALSE;
00178                     } else {
00179                         tmptab = _notebook_add_page (frame_box, ptr + 2);
00180                         if (frame_table_load_from_files (subdirpath, tmptab) != 0) {
00181                             notebook_remove_page (NULL, tmptab);
00182                         }
00183                     }
00184                     g_free (subdirpath);
00185                     break;
00186             }
00187 
00188             tabcount++;
00189             g_object_unref (current);
00190         }
00191     }
00192     g_object_unref (fileenum);
00193 
00194 
00195     // If tmpname is set then we can now add the tab to the notebook
00196     if (tmpname) {
00197         subdirpath = g_strdup_printf ("%s/%s", framesdir, tmpname);
00198         g_free (tmpname);
00199         ptr = g_strstr_len (g_strrstr (subdirpath, "/"), -1, "__");
00200         if (!ptr) {
00201             g_warning ("frame_open_try_load_tab: Malformed directory name %s", subdirpath);
00202         } else {
00203             tmptab = _notebook_add_page (frame_box, ptr + 2);
00204             if (frame_table_load_from_files (subdirpath, tmptab) != 0) {
00205                 notebook_remove_page (NULL, tmptab);
00206             }
00207         }
00208         g_free (subdirpath);
00209     }
00210 
00211 
00212     // As in post_init_restore_frames, we need to sort the tabs as they were when saved
00213     inst->tables_list = g_list_sort (inst->tables_list, frame_table_list_cmp_by_position);
00214     if (inst->tables_list) {
00215         iter = inst->tables_list;
00216         do {
00217             tmptab = iter->data;
00218             gtk_notebook_reorder_child (GTK_NOTEBOOK (frame_box), tmptab->table_box, tmptab->position);
00219         } while ((iter = g_list_next (iter)) != NULL);
00220     }
00221 
00222 
00223     // Removing the temporary files created 
00224     recursive_remove (destpath);
00225     g_free (destpath);
00226 
00227     return TRUE;
00228 }

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

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