/* SciGraphica - Scientific graphics and data manipulation * Copyright (C) 2001 Adrian E. Feiguin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "sg_project_autosave.h" #include "sg_dialogs.h" #include "sg.h" #include "sg_project.h" gboolean project_changed_since_last_autosave = FALSE; static gchar autosave_filename[250] = ""; static gboolean autosave_locked = FALSE; static gint autosave(gpointer data); /* set new autosave timeout when interval (in minutes) > 0 * otherwise disable timeout */ void sg_project_autosave_set( gint autosave_interval ) { static gint *timeout_tag = NULL; if ( autosave_interval > 0 ) {if ( timeout_tag ) gtk_timeout_remove( *timeout_tag ); /* remove previous timeout */ else timeout_tag = g_new(gint, 1); /* set new timeout; gtk_timeout_add wants milliseconds */ *timeout_tag = gtk_timeout_add(autosave_interval * 60 * 1000, (GtkFunction)autosave, NULL ); } else { /* remove autosave timeout */ if ( timeout_tag ) {gtk_timeout_remove(*timeout_tag); g_free(timeout_tag); timeout_tag = NULL; } /* if locked, then wait till autosave() is done */ while ( autosave_locked ) sleep(1); /* remove autosave file */ if ( *autosave_filename ) remove(autosave_filename); } } /* autosave the current project if necessary * return TRUE/FALSE: continues/terminates subsequent autosave timeouts */ static gint autosave( gpointer data ) { /* locked avoids simultaneous autosave invokations */ if ( autosave_locked ) return TRUE; autosave_locked = TRUE; if ( project_changed == FALSE ) { /* only remove previous autosave file; no save needed, nothing has changed */ if (*autosave_filename) remove(autosave_filename); *autosave_filename = '\0'; } else if ( project_changed_since_last_autosave ) { /* autosave the current project */ if ( *autosave_filename ) remove(autosave_filename); g_snprintf(autosave_filename, 250, "%s/" AUTOSAVE_PREFIX "%s", last_project_path, last_project_filename); if ( sg_project_file_export_xml(autosave_filename) ) project_changed_since_last_autosave = FALSE; } /* unlock */ autosave_locked = FALSE; return TRUE; } /* Check for a newer rescued or autosaved version of the file. Pop up a dialog that asks * whether to open the newer rescued/autosaved file instead. This situation can occur when * SciGraphica is forcefully terminated, leaving rescue and/or autosave files behind. */ gchar* sg_project_autosave_check(gchar *file) { gchar autosave_fn[250], rescue_fn[250]; gboolean autosave_exist, rescue_exist; struct stat file_sb, autosave_sb, rescue_sb; time_t file_mtime, autosave_mtime, rescue_mtime, mtime; /* quit when stat on file fails */ if ( stat(file, &file_sb) == -1 ) return file; g_snprintf(autosave_fn, 250, "%s/" AUTOSAVE_PREFIX "%s", g_dirname(file), g_basename(file)); autosave_exist = ( stat(autosave_fn, &autosave_sb) != -1 ); g_snprintf(rescue_fn, 250, "%s/" RESCUE_PREFIX "%s", g_dirname(file), g_basename(file)); rescue_exist = ( stat(rescue_fn, &rescue_sb) != -1 ); #ifndef _POSIX_SOURCE file_mtime = file_sb.st_mtimespec.tv_sec; if ( autosave_exist ) autosave_mtime = autosave_sb.st_mtimespec.tv_sec; if ( rescue_exist ) rescue_mtime = rescue_sb.st_mtimespec.tv_sec; #else file_mtime = file_sb.st_mtime; if ( autosave_exist ) autosave_mtime = autosave_sb.st_mtime; if ( rescue_exist ) rescue_mtime = rescue_sb.st_mtime; #endif /* mtime will contain the time of the most recent autosave/rescue file */ mtime = file_mtime; if ( autosave_exist && rescue_exist ) mtime = (rescue_mtime > autosave_mtime ? rescue_mtime : autosave_mtime); else if ( autosave_exist ) mtime = autosave_mtime; else if ( rescue_exist ) mtime = rescue_mtime; if ( rescue_exist && mtime == rescue_mtime && mtime > file_mtime ) {gchar message[]= "Found rescued file that is newer.\nOpen that instead?"; if ( sg_accept_dialog(message, 1) == YES_CLICKED ) g_snprintf(file, 1+strlen(rescue_fn), "%s", rescue_fn); } else if ( autosave_exist && mtime == autosave_mtime && mtime > file_mtime ) {gchar message[]= "Found autosaved file that is newer.\nOpen that instead?"; if ( sg_accept_dialog(message, 1) == YES_CLICKED ) g_snprintf(file, 1+strlen(autosave_fn), "%s", autosave_fn); } return file; }