/* SciGraphica - Scientific graphics and data manipulation
* Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
*
* 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 <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <gtkextra/gtkextra.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1