00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00025 #include <errno.h>
00026 #include <fcntl.h>
00027 #include <gtk/gtk.h>
00028 #include <libtar.h>
00029
00030 #include "application-data.h"
00031 #include "frame-open-panel.h"
00032 #include "frame-saving.h"
00033 #include "notebook.h"
00034
00035
00036
00037 gboolean frame_open_try_load_frame (GFile *file)
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
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
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
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
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 }
00092
00093
00094
00095 gboolean frame_open_try_load_tab (gchar *filename)
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
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
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
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:
00164 tmpname = g_strdup (g_file_info_get_name (current));
00165 break;
00166
00167 case 1:
00168 notebook_remove_all ();
00169
00170
00171 default:
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
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
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
00224 recursive_remove (destpath);
00225 g_free (destpath);
00226
00227 return TRUE;
00228 }
00229
00230
00231
00232 void frame_open_file (GFile *file)
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
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
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
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
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
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 }
00304
00305
00306
00307 static void frame_open_from_filebutton (GtkFileChooserButton *button, gpointer user_data)
00308 {
00309
00310 gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (button));
00311 GFile *file = g_file_new_for_path (filename);
00312 gchar *fileuri = g_file_get_uri (file);
00313 GtkRecentManager *manager = gtk_recent_manager_get_default ();
00314
00315
00316 gtk_recent_manager_add_item (manager, fileuri);
00317 g_free (filename);
00318 g_free (fileuri);
00319
00320
00321 frame_open_file (file);
00322 g_object_unref (file);
00323 }
00324
00325
00326
00327 static void frame_open_from_recent (GtkRecentChooser *chooser, gpointer user_data)
00328 {
00329 gchar *uri = NULL;
00330 GFile *file = NULL;
00331
00332 uri = gtk_recent_chooser_get_current_uri (chooser);
00333 file = g_file_new_for_uri (uri);
00334 g_free (uri);
00335
00336 frame_open_file (file);
00337 g_object_unref (file);
00338 }
00339
00340
00341
00342 void frame_open_setup_widgets ()
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
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
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 }