#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"
gchar **argv;
GPid rsync_pid;
gchar **groups = NULL;
gint session_last = -1;
// gint height_expander;
gsize session_number = 0;
gboolean had_error, paused, channel_closed, first_load_groups = TRUE;
gchar *argv_session, *error_list;
gboolean cmdline_session = FALSE, cmdline_execute = FALSE, dryrunning = FALSE;
GtkWidget *main_window, *rsync = NULL;
gchar config_command[MAXPATH];
gboolean config_output = FALSE, config_remember = TRUE, config_errorlist = TRUE, config_log = FALSE;
GTimeVal startime, pausedtime;
gchar *grsync_dir, *rsync_help = NULL, *rsync_man = NULL;
FILE *log_file = NULL;
gboolean get_checkbox(void* main, gchar* name) {
return gtk_toggle_button_get_active((GtkToggleButton*) lookup_widget((GtkWidget*) main, name));
}
void set_checkbox(void* main, gchar* name, gboolean val) {
gtk_toggle_button_set_active((GtkToggleButton*) lookup_widget((GtkWidget*) main, name), val);
}
void set_main_title(gchar* session, gchar* extra) {
gchar *stmp;
stmp = g_strconcat("Grsync: ", session, " ", extra, NULL);
gtk_window_set_title((GtkWindow*) main_window, stmp);
g_free(stmp);
}
void load_settings(GtkWidget* main, gchar* session, gchar *filename) {
gchar settings_file_path[MAXPATH];
GError *error_handler = NULL;
GKeyFile *settings_file;
gchar *stmp;
gboolean btmp;
gint root_x, root_y, width, height;
if (filename == NULL) g_sprintf(settings_file_path, "%s/%s", grsync_dir, "grsync.ini");
else strncpy(settings_file_path, filename, MAXPATH-1);
// initializes config_command before other functions which may use it
if (filename == NULL) strcpy(config_command, "rsync");
if (!g_file_test(settings_file_path, G_FILE_TEST_EXISTS)) {
g_printf (_("(ERROR) Can't open config file! Maybe this is the first run?\n"));
if (session != NULL) {
save_settings(main, session, NULL);
load_groups(main, session);
}
}
settings_file = g_key_file_new();
g_key_file_load_from_file(settings_file, settings_file_path, G_KEY_FILE_NONE, NULL);
if (session == NULL) {
session = g_key_file_get_start_group(settings_file);
save_settings(main, session, NULL);
load_groups(main, session);
}
set_main_title(session, NULL);
if (filename == NULL) {
// load configuration (preferences)
stmp = g_key_file_get_string(settings_file, CONFIG_GROUP, "command", NULL);
if (stmp != NULL) strncpy(config_command, stmp, MAXPATH - 1);
btmp = g_key_file_get_boolean(settings_file, CONFIG_GROUP, "output", &error_handler);
if (error_handler != NULL) g_clear_error (&error_handler);
else config_output = btmp;
btmp = g_key_file_get_boolean(settings_file, CONFIG_GROUP, "remember", &error_handler);
if (error_handler != NULL) g_clear_error (&error_handler);
else config_remember = btmp;
btmp = g_key_file_get_boolean(settings_file, CONFIG_GROUP, "errorlist", &error_handler);
if (error_handler != NULL) g_clear_error (&error_handler);
else config_errorlist = btmp;
btmp = g_key_file_get_boolean(settings_file, CONFIG_GROUP, "logging", &error_handler);
if (error_handler != NULL) g_clear_error (&error_handler);
else config_log = btmp;
// load window position and size
root_x = g_key_file_get_integer(settings_file, CONFIG_GROUP, "root_x", NULL);
root_y = g_key_file_get_integer(settings_file, CONFIG_GROUP, "root_y", NULL);
width = g_key_file_get_integer(settings_file, CONFIG_GROUP, "width", NULL);
height = g_key_file_get_integer(settings_file, CONFIG_GROUP, "height", NULL);
gtk_window_move((GtkWindow*) main_window, root_x, root_y);
if (width > 0 && height > 0) gtk_window_resize((GtkWindow*) main_window, width, height);
}
// load specific session
stmp = g_key_file_get_string(settings_file, session, "text_source", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) main, "text_source"), stmp);
g_free(stmp);
stmp = g_key_file_get_string(settings_file, session, "text_dest", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) main, "text_dest"), stmp);
g_free(stmp);
stmp = g_key_file_get_string(settings_file, session, "text_addit", NULL);
if (stmp == NULL) stmp = g_strconcat("", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_additional"), stmp);
g_free(stmp);
stmp = g_key_file_get_string(settings_file, session, "text_com_before", NULL);
if (stmp == NULL) stmp = g_strconcat("", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_com_before"), stmp);
g_free(stmp);
stmp = g_key_file_get_string(settings_file, session, "text_com_after", NULL);
if (stmp == NULL) stmp = g_strconcat("", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_com_after"), stmp);
g_free(stmp);
set_checkbox(main, "check_time", g_key_file_get_boolean(settings_file, session, "check_time", NULL));
set_checkbox(main, "check_perm", g_key_file_get_boolean(settings_file, session, "check_perm", NULL));
set_checkbox(main, "check_owner", g_key_file_get_boolean(settings_file, session, "check_owner", NULL));
set_checkbox(main, "check_group", g_key_file_get_boolean(settings_file, session, "check_group", NULL));
set_checkbox(main, "check_onefs", g_key_file_get_boolean(settings_file, session, "check_onefs", NULL));
set_checkbox(main, "check_verbose", g_key_file_get_boolean(settings_file, session, "check_verbose", NULL));
set_checkbox(main, "check_progr", g_key_file_get_boolean(settings_file, session, "check_progr", NULL));
set_checkbox(main, "check_delete", g_key_file_get_boolean(settings_file, session, "check_delete", NULL));
set_checkbox(main, "check_exist", g_key_file_get_boolean(settings_file, session, "check_exist", NULL));
set_checkbox(main, "check_size", g_key_file_get_boolean(settings_file, session, "check_size", NULL));
set_checkbox(main, "check_skipnew", g_key_file_get_boolean(settings_file, session, "check_skipnew", NULL));
set_checkbox(main, "check_windows", g_key_file_get_boolean(settings_file, session, "check_windows", NULL));
set_checkbox(main, "check_sum", g_key_file_get_boolean(settings_file, session, "check_sum", NULL));
set_checkbox(main, "check_symlink", g_key_file_get_boolean(settings_file, session, "check_symlink", NULL));
set_checkbox(main, "check_dev", g_key_file_get_boolean(settings_file, session, "check_dev", NULL));
set_checkbox(main, "check_update", g_key_file_get_boolean(settings_file, session, "check_update", NULL));
set_checkbox(main, "check_keepart", g_key_file_get_boolean(settings_file, session, "check_keepart", NULL));
set_checkbox(main, "check_mapuser", g_key_file_get_boolean(settings_file, session, "check_mapuser", NULL));
set_checkbox(main, "check_compr", g_key_file_get_boolean(settings_file, session, "check_compr", NULL));
set_checkbox(main, "check_backup", g_key_file_get_boolean(settings_file, session, "check_backup", NULL));
set_checkbox(main, "check_com_before", g_key_file_get_boolean(settings_file, session, "check_com_before", NULL));
set_checkbox(main, "check_com_after", g_key_file_get_boolean(settings_file, session, "check_com_after", NULL));
set_checkbox(main, "check_browse_files", g_key_file_get_boolean(settings_file, session, "check_browse_files", NULL));
g_key_file_free (settings_file);
}
void save_settings(GtkWidget* main, gchar *session, gchar *filename) {
gchar settings_file_name[MAXPATH];
gchar *key_data;
FILE *key_file;
GError *error_handler = NULL;
GKeyFile *settings_file;
const gchar *stmp;
gint root_x, root_y, width, height;
if (filename == NULL) g_sprintf(settings_file_name, "%s/%s", grsync_dir, "grsync.ini");
else strncpy(settings_file_name, filename, MAXPATH-1);
// g_printf(_("Saving settings to %s...\n"), settings_file_name);
g_mkdir(grsync_dir, 0700);
settings_file = g_key_file_new();
if (filename == NULL) {
g_key_file_load_from_file(settings_file, settings_file_name, G_KEY_FILE_NONE, NULL);
// save configuration (preferences)
g_key_file_set_string(settings_file, CONFIG_GROUP, "command", config_command);
g_key_file_set_boolean(settings_file, CONFIG_GROUP, "output", config_output);
g_key_file_set_boolean(settings_file, CONFIG_GROUP, "remember", config_remember);
g_key_file_set_boolean(settings_file, CONFIG_GROUP, "errorlist", config_errorlist);
g_key_file_set_boolean(settings_file, CONFIG_GROUP, "logging", config_log);
if (session_last != -1) g_key_file_set_string(settings_file, CONFIG_GROUP, "last_session", groups[session_last]);
// window position and size
gtk_window_get_position((GtkWindow*) main_window, &root_x, &root_y);
gtk_window_get_size((GtkWindow*) main_window, &width, &height);
g_key_file_set_integer(settings_file, CONFIG_GROUP, "root_x", root_x);
g_key_file_set_integer(settings_file, CONFIG_GROUP, "root_y", root_y);
g_key_file_set_integer(settings_file, CONFIG_GROUP, "width", width);
g_key_file_set_integer(settings_file, CONFIG_GROUP, "height", height);
}
// save specific session
stmp = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main, "text_source"));
g_key_file_set_string(settings_file, session, "text_source", stmp);
stmp = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main, "text_dest"));
g_key_file_set_string(settings_file, session, "text_dest", stmp);
stmp = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_additional"));
g_key_file_set_string(settings_file, session, "text_addit", stmp);
stmp = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_com_before"));
g_key_file_set_string(settings_file, session, "text_com_before", stmp);
stmp = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main, "entry_com_after"));
g_key_file_set_string(settings_file, session, "text_com_after", stmp);
g_key_file_set_boolean(settings_file, session, "check_time", get_checkbox(main, "check_time"));
g_key_file_set_boolean(settings_file, session, "check_perm", get_checkbox(main, "check_perm"));
g_key_file_set_boolean(settings_file, session, "check_owner", get_checkbox(main, "check_owner"));
g_key_file_set_boolean(settings_file, session, "check_group", get_checkbox(main, "check_group"));
g_key_file_set_boolean(settings_file, session, "check_onefs", get_checkbox(main, "check_onefs"));
g_key_file_set_boolean(settings_file, session, "check_verbose", get_checkbox(main, "check_verbose"));
g_key_file_set_boolean(settings_file, session, "check_progr", get_checkbox(main, "check_progr"));
g_key_file_set_boolean(settings_file, session, "check_delete", get_checkbox(main, "check_delete"));
g_key_file_set_boolean(settings_file, session, "check_exist", get_checkbox(main, "check_exist"));
g_key_file_set_boolean(settings_file, session, "check_size", get_checkbox(main, "check_size"));
g_key_file_set_boolean(settings_file, session, "check_skipnew", get_checkbox(main, "check_skipnew"));
g_key_file_set_boolean(settings_file, session, "check_windows", get_checkbox(main, "check_windows"));
g_key_file_set_boolean(settings_file, session, "check_sum", get_checkbox(main, "check_sum"));
g_key_file_set_boolean(settings_file, session, "check_symlink", get_checkbox(main, "check_symlink"));
g_key_file_set_boolean(settings_file, session, "check_dev", get_checkbox(main, "check_dev"));
g_key_file_set_boolean(settings_file, session, "check_update", get_checkbox(main, "check_update"));
g_key_file_set_boolean(settings_file, session, "check_keepart", get_checkbox(main, "check_keepart"));
g_key_file_set_boolean(settings_file, session, "check_mapuser", get_checkbox(main, "check_mapuser"));
g_key_file_set_boolean(settings_file, session, "check_compr", get_checkbox(main, "check_compr"));
g_key_file_set_boolean(settings_file, session, "check_backup", get_checkbox(main, "check_backup"));
g_key_file_set_boolean(settings_file, session, "check_com_before", get_checkbox(main, "check_com_before"));
g_key_file_set_boolean(settings_file, session, "check_com_after", get_checkbox(main, "check_com_after"));
g_key_file_set_boolean(settings_file, session, "check_browse_files", get_checkbox(main, "check_browse_files"));
key_data = g_key_file_to_data(settings_file, NULL, &error_handler);
key_file = fopen(settings_file_name, "w");
if (key_file != NULL) {
fputs(key_data, key_file);
fclose(key_file);
} else {
g_printf(_("\tUnable to save settings!\n"));
}
g_key_file_free(settings_file);
g_clear_error(&error_handler);
}
int compare_strings (char **p1, char **p2) {
return strcoll (*p1, *p2);
}
gboolean load_groups(GtkWidget* main, gchar *session) {
gchar settings_file_path[MAXPATH], *stmp;
g_sprintf(settings_file_path, "%s/%s", grsync_dir, "grsync.ini");
if (g_file_test(settings_file_path, G_FILE_TEST_EXISTS)) {
GError *error_handler = NULL;
GKeyFile *settings_file;
GtkComboBox *combo;
gint i;
gboolean flag = FALSE;
combo = (GtkComboBox*) lookup_widget(main, "combo_session");
// while (i = gtk_combo_box_get_active(combo) != -1) gtk_combo_box_remove_text(combo, i);
for (i = 0; i < session_number; i++) gtk_combo_box_remove_text(combo, 0);
settings_file = g_key_file_new();
g_key_file_load_from_file(settings_file, settings_file_path, G_KEY_FILE_NONE, &error_handler);
groups = g_key_file_get_groups(settings_file, &session_number);
if (!cmdline_session && first_load_groups && g_key_file_get_boolean(settings_file, CONFIG_GROUP, "remember", NULL)) {
stmp = g_key_file_get_string(settings_file, CONFIG_GROUP, "last_session", NULL);
if (stmp != NULL) {
session = stmp;
g_free(argv_session);
argv_session = g_strconcat(session, NULL);
}
first_load_groups = FALSE;
}
i = 0;
while (groups[i] != NULL) {
if (strcmp(groups[i], CONFIG_GROUP) == 0) {
session_number--;
g_free(groups[i]);
flag = TRUE;
} else {
if (i > 0 && flag) groups[i - 1] = groups[i];
}
i++;
}
groups[session_number] = NULL;
qsort(groups, session_number, sizeof(gchar*), compare_strings);
i = 0;
while (groups[i] != NULL) {
gtk_combo_box_insert_text(combo, i, groups[i]);
if (strcmp(groups[i], session) == 0) {
gtk_combo_box_set_active(combo, i);
session_last = i;
}
i++;
}
g_key_file_free (settings_file);
g_clear_error (&error_handler);
if (session_last == -1) return FALSE;
}
/*
else {
g_printf (_("(ERROR) Can't open config file! Maybe this is the first run?\n"));
// return FALSE;
}
*/
return TRUE;
}
void show_browse_source(GtkButton *button, gpointer user_data) {
GtkWidget *dialog;
gint retval;
gboolean browse_files = get_checkbox((GtkWidget*) main_window, "check_browse_files");
GtkFileChooserAction action = browse_files ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
gchar *curr_path = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_source"));
gchar *curr_folder = g_path_get_dirname(curr_path);
dialog = gtk_file_chooser_dialog_new (_("Browse"), (GtkWindow*) main_window, action,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), curr_folder);
if (browse_files) gtk_file_chooser_select_filename(GTK_FILE_CHOOSER (dialog), curr_path);
retval = gtk_dialog_run (GTK_DIALOG (dialog));
if (retval == GTK_RESPONSE_ACCEPT || retval == GTK_RESPONSE_OK) {
gchar *filename, *tmp;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
tmp = g_strconcat(filename, browse_files ? "" : "/", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_source"), tmp);
g_free(filename);
g_free(tmp);
}
gtk_widget_destroy (dialog);
g_free(curr_folder);
}
void show_browse_dest(GtkButton *button, gpointer user_data) {
GtkWidget *dialog;
gint retval;
gboolean browse_files = get_checkbox((GtkWidget*) main_window, "check_browse_files");
GtkFileChooserAction action = browse_files ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
gchar *curr_path = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_dest"));
gchar *curr_folder = g_path_get_dirname(curr_path);
dialog = gtk_file_chooser_dialog_new (_("Browse"), (GtkWindow*) main_window, action,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), curr_folder);
if (browse_files) gtk_file_chooser_select_filename(GTK_FILE_CHOOSER (dialog), curr_path);
retval = gtk_dialog_run (GTK_DIALOG (dialog));
if (retval == GTK_RESPONSE_ACCEPT || retval == GTK_RESPONSE_OK) {
gchar *filename, *tmp;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
tmp = g_strconcat(filename, browse_files ? "" : "/", NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_dest"), tmp);
g_free (filename);
g_free(tmp);
}
gtk_widget_destroy (dialog);
g_free(curr_folder);
}
void on_play_clicked(GtkButton *button, gpointer user_data) {
gint i = 0, j, argc_tmp;
gchar **argv_tmp, *gtmp;
argv = g_new(gchar *, MAXOPT);
argv_tmp = g_new(gchar *, MAXOPT);
argv[i++] = config_command;
argv[i++] = "-r";
if (dryrunning) argv[i++] = "-n";
if (get_checkbox(button, "check_time")) argv[i++] = "-t";
if (get_checkbox(button, "check_perm")) argv[i++] = "-p";
if (get_checkbox(button, "check_owner")) argv[i++] = "-o";
if (get_checkbox(button, "check_group")) argv[i++] = "-g";
if (get_checkbox(button, "check_onefs")) argv[i++] = "-x";
if (get_checkbox(button, "check_verbose")) argv[i++] = "-v";
if (get_checkbox(button, "check_progr")) argv[i++] = "--progress";
if (get_checkbox(button, "check_delete")) argv[i++] = "--delete";
if (get_checkbox(button, "check_exist")) argv[i++] = "--ignore-existing";
if (get_checkbox(button, "check_size")) argv[i++] = "--size-only";
if (get_checkbox(button, "check_skipnew")) argv[i++] = "-u";
if (get_checkbox(button, "check_windows")) argv[i++] = "--modify-window=1";
if (get_checkbox(button, "check_sum")) argv[i++] = "-c";
if (get_checkbox(button, "check_symlink")) argv[i++] = "-l";
if (get_checkbox(button, "check_dev")) argv[i++] = "-D";
if (get_checkbox(button, "check_update")) argv[i++] = "--existing";
if (get_checkbox(button, "check_keepart")) argv[i++] = "--partial";
if (get_checkbox(button, "check_mapuser")) argv[i++] = "--numeric-ids";
if (get_checkbox(button, "check_compr")) argv[i++] = "-z";
if (get_checkbox(button, "check_backup")) argv[i++] = "-b";
gtmp = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "entry_additional"));
if (gtmp[0]) {
g_shell_parse_argv(gtmp, &argc_tmp, &argv_tmp, NULL);
for (j = 0; j < argc_tmp && i + 3 < MAXOPT; j++) argv[i++] = g_strconcat(argv_tmp[j], NULL);
g_strfreev(argv_tmp);
}
// source, dest and NULL must follow only, or change the previous for cicle ending condition.
argv[i++] = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_source"));
argv[i++] = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_dest"));
argv[i++] = NULL;
paused = FALSE;
rsync = create_dialog_rsync();
gtk_window_set_transient_for((GtkWindow*) rsync, (GtkWindow*) main_window);
if (config_output || dryrunning) {
gtk_expander_set_expanded((GtkExpander*) lookup_widget((GtkWidget*) rsync, "expander_rsync"), TRUE);
}
if (config_errorlist) error_list = g_strconcat("", NULL);
if (config_log) {
gtmp = g_strconcat(grsync_dir, "/", groups[session_last], ".log", NULL);
log_file = fopen(gtmp, "w");
g_free(gtmp);
}
gtk_widget_show(rsync);
gtk_window_set_title((GtkWindow*)rsync, "rsync: running");
if (dryrunning) gtk_label_set_text((GtkLabel*)lookup_widget((GtkWidget*) rsync, "label_file"), _("Simulation in progress"));
}
void on_dryrun_clicked (GtkButton *button, gpointer user_data) {
dryrunning = TRUE;
on_play_clicked(button, NULL);
}
void set_tooltip(GtkTooltips *tooltips, gchar *long_opt, gchar *widget_str) {
gchar *tmpc, *tmpc2, *out, *opt;
GtkWidget *widget;
GtkTooltipsData *oldtip;
opt = rsync_man != NULL ? g_strconcat(long_opt, "\n", NULL) : g_strconcat(long_opt, " ", NULL);
out = rsync_man != NULL ? g_strconcat(rsync_man, NULL) : g_strconcat(rsync_help, NULL);
tmpc = g_strrstr(out, opt);
// tmpc = g_strstr_len(out, strlen(out), opt);
if (tmpc != NULL && *tmpc) {
while (*tmpc != '\n') tmpc--;
tmpc++;
tmpc2 = rsync_man != NULL ? strstr(tmpc, "\n\n\n") : strchr(tmpc, '\n');
*tmpc2 = '\0';
g_strstrip(tmpc);
widget = (GtkWidget*) lookup_widget((GtkWidget*) main_window, widget_str);
oldtip = gtk_tooltips_data_get(widget);
if (oldtip != NULL) tmpc2 = g_strconcat(tmpc, "\n\n", oldtip->tip_text, NULL);
else tmpc2 = g_strconcat(tmpc, NULL);
gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltips), widget, tmpc2, "");
g_free(tmpc2);
}
g_free(opt);
g_free(out);
}
void on_main_create(GtkWindow *window, gpointer user_data) {
GtkWidget *error;
gchar *stmp, *tmpc;
GtkTooltips *rsync_tips;
grsync_dir = g_strconcat(g_get_home_dir(), "/.grsync", NULL);
if (!load_groups((GtkWidget*) window, argv_session)) {
error = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CANCEL,
_("The session you specified on the command line doesn't exists"));
gtk_dialog_run(GTK_DIALOG(error));
gtk_widget_destroy(error);
g_free(argv_session);
argv_session = g_strconcat("default", NULL);
load_groups((GtkWidget*) window, argv_session);
}
load_settings((GtkWidget*) window, argv_session, NULL);
stmp = g_strconcat(config_command, " --help", NULL);
if (!g_spawn_command_line_sync(stmp, &rsync_help, NULL, NULL, NULL)) {
error = gtk_message_dialog_new(window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CANCEL,
_("Unable to execute the rsync command line tool. It is needed by this program. You may need to install the rsync package or make it available in the default executable search PATH. See file/preferences to change the default rsync executable command."));
gtk_dialog_run(GTK_DIALOG(error));
gtk_widget_destroy(error);
} else {
// g_spawn_command_line_sync("man rsync", &rsync_man, NULL, NULL, NULL);
rsync_tips = gtk_tooltips_new();
set_tooltip(rsync_tips, "--times", "check_time");
set_tooltip(rsync_tips, "--perms", "check_perm");
set_tooltip(rsync_tips, "--owner", "check_owner");
set_tooltip(rsync_tips, "--group", "check_group");
set_tooltip(rsync_tips, "--one-file-system", "check_onefs");
set_tooltip(rsync_tips, "--verbose", "check_verbose");
set_tooltip(rsync_tips, "--progress", "check_progr");
set_tooltip(rsync_tips, "--delete", "check_delete");
set_tooltip(rsync_tips, "--ignore-existing", "check_exist");
set_tooltip(rsync_tips, "--size-only", "check_size");
set_tooltip(rsync_tips, "--update", "check_skipnew");
set_tooltip(rsync_tips, "--modify-window=NUM", "check_windows");
set_tooltip(rsync_tips, "--checksum", "check_sum");
set_tooltip(rsync_tips, "--links", "check_symlink");
set_tooltip(rsync_tips, "-D", "check_dev");
set_tooltip(rsync_tips, "--existing", "check_update");
set_tooltip(rsync_tips, "--partial", "check_keepart");
set_tooltip(rsync_tips, "--numeric-ids", "check_mapuser");
set_tooltip(rsync_tips, "--compress", "check_compr");
set_tooltip(rsync_tips, "--backup", "check_backup");
}
g_free(stmp);
if (cmdline_execute) on_play_clicked((GtkButton*) window, NULL);
}
void on_main_destroy(GtkObject *object, gpointer user_data) {
gint sel = gtk_combo_box_get_active((GtkComboBox*) lookup_widget((GtkWidget*) object, "combo_session"));
save_settings((GtkWidget*) object, groups[sel], NULL);
g_strfreev(groups);
if (rsync_help != NULL) g_free(rsync_help);
if (rsync_man != NULL) g_free(rsync_man);
gtk_main_quit();
}
void on_close_clicked(GtkButton *button, gpointer user_data) {
if (rsync_pid) {
if (paused) kill(rsync_pid, SIGCONT);
kill(rsync_pid, SIGTERM);
gtk_widget_set_sensitive(lookup_widget((GtkWidget*) button, "button_pause"), FALSE);
} else {
gtk_widget_destroy(rsync);
set_main_title(groups[session_last], NULL);
rsync = NULL;
}
if (cmdline_execute) on_main_destroy((GtkObject*) main_window, NULL);
}
void set_global_progress(GtkProgressBar* progr, gdouble fraction) {
GTimeVal curtime;
glong elapsed, remaining;
gchar tmps[50];
gtk_progress_bar_set_fraction(progr, fraction);
g_get_current_time(&curtime);
elapsed = curtime.tv_sec - startime.tv_sec;
remaining = elapsed / fraction - elapsed;
snprintf(tmps, 49, _("%.f%% (%li:%02li elapsed, %li:%02li remaining)"), round(fraction * 100), elapsed / 60, elapsed % 60,
remaining / 60, remaining % 60);
gtk_progress_bar_set_text(progr, tmps);
set_main_title(groups[session_last], tmps);
}
void scroll_to_end(GtkTextView* view) {
GtkTextBuffer *buffer;
GtkTextIter iter;
GtkTextMark *mark;
buffer = gtk_text_view_get_buffer(view);
gtk_text_buffer_get_end_iter(buffer, &iter);
mark = gtk_text_buffer_create_mark(buffer, "end_mark", &iter, TRUE);
gtk_text_view_scroll_mark_onscreen(view, mark);
gtk_text_buffer_delete_mark(buffer, mark);
}
void rsync_cleanup(gpointer data) {
gchar tmps[50];
GTimeVal curtime;
glong elapsed;
GtkWidget *errors;
GtkTextBuffer *buffer;
GtkTextView *view;
GtkTextIter iter;
GtkTextTag *tag;
gchar *comm_str, *comm_out, *comm_err, *comm_after;
if (channel_closed) {
view = (GtkTextView*) lookup_widget((GtkWidget*) data, "textview_output");
if (get_checkbox((GtkWidget*) main_window, "check_com_after")) {
comm_str = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main_window, "entry_com_after"));
if (!g_spawn_command_line_sync(comm_str, &comm_out, &comm_err, NULL, NULL)) {
comm_out = g_strconcat("", NULL);
comm_err = g_strconcat("Error launching command!\n", NULL);
}
comm_after = g_strconcat("\n", _("*** Launching AFTER command:\n"), comm_str, "\n", comm_out, comm_err, NULL);
g_free(comm_out);
g_free(comm_err);
buffer = gtk_text_view_get_buffer(view);
gtk_text_buffer_insert_at_cursor(buffer, comm_after, -1);
scroll_to_end(view);
if (config_log) fputs(comm_after, log_file);
g_free(comm_after);
}
gtk_button_set_label((GtkButton*) lookup_widget((GtkWidget*) data, "close"), "gtk-close");
GtkLabel *tmpl = (GtkLabel*) lookup_widget((GtkWidget*) data, "label_file");
if (had_error) {
gtk_label_set_markup(tmpl, _("<span foreground=\"red\" weight=\"bold\">Completed with errors!</span>"));
} else {
gtk_label_set_markup(tmpl, _("<span foreground=\"darkgreen\" weight=\"bold\">Completed successfully!</span>"));
set_global_progress((GtkProgressBar*) lookup_widget((GtkWidget*) data, "progress_global"), 1);
}
gtk_widget_set_sensitive(lookup_widget((GtkWidget*) data, "button_pause"), FALSE);
gtk_widget_set_sensitive((GtkWidget*) view, TRUE);
gtk_window_set_title((GtkWindow*) rsync, "rsync: stopped");
g_spawn_close_pid(rsync_pid);
rsync_pid = 0;
g_free(argv);
if (config_errorlist && had_error) {
errors = create_dialog_errors();
gtk_window_set_transient_for((GtkWindow*) errors, (GtkWindow*) rsync);
buffer = gtk_text_view_get_buffer((GtkTextView*) lookup_widget(errors, "textview_errors"));
tag = gtk_text_buffer_create_tag(buffer, "fore-red", "foreground", "red", NULL);
gtk_text_buffer_get_start_iter(buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, error_list, -1, "fore-red", NULL);
gtk_widget_show(errors);
g_free(error_list);
}
dryrunning = FALSE;
if (cmdline_execute) on_close_clicked((GtkButton*) data, NULL);
} else {
channel_closed = TRUE;
}
}
gboolean out_watch(GIOChannel *source, GIOCondition condition, gpointer data) {
GtkTextBuffer *buffer;
GtkTextIter iter, iter2;
GString *str;
GtkProgressBar *tmpp;
static gchar *carriage = NULL, *oldfile = NULL;
gchar *file, tmps[50];
gdouble fraction, done, total;
if (condition & G_IO_IN) {
buffer = gtk_text_view_get_buffer((GtkTextView*)data);
if (carriage != NULL) {
gtk_text_buffer_get_iter_at_line(buffer, &iter, gtk_text_buffer_get_line_count(buffer) - 2);
gtk_text_buffer_get_end_iter(buffer, &iter2);
gtk_text_buffer_delete(buffer, &iter, &iter2);
}
str = g_string_new("");
g_io_channel_read_line_string(source, str, NULL, NULL);
carriage = strchr(str->str, '\r');
gtk_text_buffer_insert_at_cursor(buffer, (gchar*)str->str, -1);
scroll_to_end((GtkTextView*)data);
if (config_log) fputs((gchar*)str->str, log_file);
if (!dryrunning) {
if (strchr(str->str, '%') && str->str[0] == ' ') {
if (oldfile != NULL) file = g_strconcat(oldfile, NULL);
else file = g_strconcat(str->str, NULL);
fraction = g_ascii_strtod(strchr(strchr(str->str, '%') - 4, ' '), NULL) / 100;
tmpp = (GtkProgressBar*)lookup_widget((GtkWidget*) data, "progress_file");
gtk_progress_bar_set_fraction(tmpp, fraction);
snprintf(tmps, 5, "%.f%%", round(fraction * 100));
gtk_progress_bar_set_text(tmpp, tmps);
fraction = 0;
if (strchr(str->str, '%') != strrchr(str->str, '%')) fraction = g_ascii_strtod(strchr(strrchr(str->str, '%') - 6, ' '), NULL) / 100;
else if (strchr(str->str, '=')) {
total = g_ascii_strtod(strrchr(str->str, '/') + 1, NULL);
done = total - g_ascii_strtod(strrchr(str->str, '=') + 1, NULL);
fraction = done / total;
}
if (fraction) set_global_progress((GtkProgressBar*)lookup_widget((GtkWidget*) data, "progress_global"), fraction);
} else {
file = g_strconcat(str->str, NULL);
if (oldfile != NULL) g_free(oldfile);
oldfile = g_strconcat(str->str, NULL);
}
g_strchomp(file);
if (file[0] != 0) gtk_label_set_text((GtkLabel*)lookup_widget((GtkWidget*) data, "label_file"), file);
g_free(file);
}
g_string_free(str, TRUE);
} else {
// if (condition & G_IO_HUP || condition & G_IO_ERR) {
g_io_channel_shutdown (source, FALSE, NULL);
g_io_channel_unref (source);
rsync_cleanup(data);
if (oldfile != NULL) g_free(oldfile);
oldfile = NULL;
return FALSE;
}
return TRUE;
}
gboolean err_watch(GIOChannel *source, GIOCondition condition, gpointer data) {
GtkTextBuffer *buffer;
GtkTextIter iter;
// GIOStatus status;
GString *str;
gchar *tmpc;
if (condition & G_IO_IN) {
buffer = gtk_text_view_get_buffer((GtkTextView*)data);
str = g_string_new("");
g_io_channel_read_line_string(source, str, NULL, NULL);
if (str->len > 2) had_error = TRUE;
// if (status == G_IO_STATUS_NORMAL) {
gtk_text_buffer_get_end_iter(buffer, &iter);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, (gchar*)str->str, -1, "fore-red", NULL);
scroll_to_end((GtkTextView*)data);
// }
if (config_log) {
// fputs("*ERROR* ", log_file);
fputs((gchar*)str->str, log_file);
}
tmpc = g_strconcat(error_list, str->str, NULL);
g_free(error_list);
error_list = tmpc;
g_string_free(str, TRUE);
} else {
// if (condition & G_IO_HUP || condition & G_IO_ERR) {
g_io_channel_shutdown (source, FALSE, NULL);
g_io_channel_unref (source);
rsync_cleanup(data);
return FALSE;
}
return TRUE;
}
void on_rsync_show(GtkWidget *widget, gpointer user_data) {
gint out, err, i;
// gint bogus;
GtkTextBuffer *buffer;
GtkTextView *view;
GIOChannel *chout, *cherr;
GtkTextTag *tag;
GtkWidget *error;
gchar *comm_str, *comm_text, *comm_out, *comm_err, *comm_before, *tmpc;
rsync_pid = 0;
had_error = FALSE;
gtk_label_set_ellipsize((GtkLabel*)lookup_widget(widget, "label_file"), PANGO_ELLIPSIZE_MIDDLE);
if (get_checkbox((GtkWidget*) main_window, "check_com_before")) {
comm_str = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) main_window, "entry_com_before"));
if (!g_spawn_command_line_sync(comm_str, &comm_out, &comm_err, NULL, NULL)) {
comm_out = g_strconcat("", NULL);
comm_err = g_strconcat("Error launching command!\n", NULL);
}
comm_before = g_strconcat(_("*** Launching BEFORE command:\n"), comm_str, "\n", comm_out, comm_err, "\n", NULL);
g_free(comm_out);
g_free(comm_err);
} else {
comm_before = g_strconcat("", NULL);
}
comm_str = g_strjoinv(" ", argv);
if (dryrunning) tmpc =_("*** Launching RSYNC command (simulation mode):\n");
else tmpc = _("*** Launching RSYNC command:\n");
comm_text = g_strconcat(comm_before, tmpc, comm_str, "\n\n", NULL);
g_free(comm_before);
g_free(comm_str);
view = (GtkTextView*)lookup_widget(widget, "textview_output");
buffer = gtk_text_view_get_buffer(view);
gtk_text_buffer_insert_at_cursor(buffer, comm_text, -1);
if (config_log) fputs(comm_text, log_file);
g_free(comm_text);
// gtk_widget_get_size_request((GtkWidget*) lookup_widget(widget, "scrolled1"), &bogus, &height_expander);
g_get_current_time(&startime);
if (g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &rsync_pid, NULL, &out, &err, NULL)) {
chout = g_io_channel_unix_new (out);
cherr = g_io_channel_unix_new (err);
g_io_channel_set_flags(chout, G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_set_flags(cherr, G_IO_FLAG_NONBLOCK, NULL);
// g_io_channel_set_buffer_size(chout, 32);
// g_io_channel_set_encoding(chout, NULL, NULL); g_io_channel_set_buffered(chout, FALSE);
tag = gtk_text_buffer_create_tag(buffer, "fore-red", "foreground", "red", NULL);
channel_closed = FALSE;
g_io_add_watch_full(chout, G_PRIORITY_DEFAULT_IDLE, G_IO_IN | G_IO_HUP | G_IO_ERR, out_watch, view, NULL);
g_io_add_watch_full(cherr, G_PRIORITY_DEFAULT_IDLE, G_IO_IN | G_IO_HUP | G_IO_ERR, err_watch, view, NULL);
} else {
gtk_button_set_label((GtkButton*)lookup_widget(widget, "close"), "gtk-close");
gtk_widget_set_sensitive(lookup_widget(widget, "button_pause"), FALSE);
error = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CANCEL,
_("Cannot execute rsync"));
gtk_dialog_run(GTK_DIALOG(error));
gtk_widget_destroy(error);
}
}
void on_rsync_destroy(GtkObject *object, gpointer user_data) {
if (rsync_pid) {
if (paused) kill(rsync_pid, SIGCONT);
kill(rsync_pid, SIGTERM);
}
if (log_file != NULL) {
fclose(log_file);
log_file = NULL;
}
}
void on_combo_session_changed (GtkComboBox *combobox, gpointer user_data) {
gint sel = gtk_combo_box_get_active((GtkComboBox*) lookup_widget((GtkWidget*) combobox, "combo_session"));
if (session_last != -1 && sel != session_last) {
save_settings((GtkWidget*) combobox, groups[session_last], NULL);
session_last = sel;
load_settings((GtkWidget*) combobox, groups[session_last], NULL);
}
}
void on_session_add_clicked(GtkButton *button, gpointer user_data) {
GtkWidget *add, *confirm;
gint result, i = 0;
add = create_dialog_new_session();
gtk_window_set_transient_for((GtkWindow*) add, (GtkWindow*) main_window);
result = gtk_dialog_run ((GtkDialog*) add);
if (result == GTK_RESPONSE_OK) {
gchar *newses;
newses = (gchar*) gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) add, "entry_session_name"));
if (strcmp(CONFIG_GROUP, newses) == 0) {
confirm = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CANCEL, _("This session name is reserved, you cannot call it like this"));
gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(confirm);
gtk_widget_destroy(add);
return;
}
while (groups[i] != NULL && strcmp(groups[i], newses)) i++;
if (groups[i] != NULL) {
confirm = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CANCEL, _("A session named like this already exists"));
gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(confirm);
gtk_widget_destroy(add);
return;
}
save_settings((GtkWidget*) button, newses, NULL);
session_number++;
load_groups((GtkWidget*) button, newses);
}
gtk_widget_destroy(add);
}
void on_session_del_clicked(GtkButton *button, gpointer user_data) {
gchar settings_file_name[MAXPATH];
gchar *key_data;
FILE *key_file;
GError *error_handler = NULL;
GKeyFile *settings_file;
gint i, result;
GtkWidget *confirm;
i = gtk_combo_box_get_active((GtkComboBox*) lookup_widget((GtkWidget*) button, "combo_session"));
if (strcmp(groups[i], "default") == 0) {
confirm = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CANCEL, _("You cannot delete the default session"));
gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(confirm);
return;
}
confirm = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
GTK_BUTTONS_OK_CANCEL, _("Are you sure you want to delete the '%s' session?"), groups[i]);
result = gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(confirm);
if (result == GTK_RESPONSE_OK) {
g_sprintf(settings_file_name, "%s/%s", grsync_dir, "grsync.ini");
settings_file = g_key_file_new();
g_key_file_load_from_file(settings_file, settings_file_name, G_KEY_FILE_NONE, NULL);
g_key_file_remove_group(settings_file, groups[i], &error_handler);
key_data = g_key_file_to_data(settings_file, NULL, &error_handler);
key_file = fopen(settings_file_name, "w");
if (key_file != NULL) {
fputs(key_data, key_file);
fclose(key_file);
} else {
g_printf(_("\tUnable to save settings!\n"));
}
g_key_file_free(settings_file);
g_clear_error(&error_handler);
session_last = -1;
load_groups((GtkWidget*) button, "default");
load_settings((GtkWidget*) button, "default", NULL);
}
}
void on_button_about_clicked(GtkButton *button, gpointer user_data) {
// GtkWidget *about = gtk_about_dialog_new();
GdkPixbuf *pixbuf;
pixbuf = create_pixbuf("grsync.png");
gtk_show_about_dialog((GtkWindow*) main_window, "name", PACKAGE, "version", VERSION, "logo", pixbuf, "comments", _("A GTK GUI for rsync"),
"copyright", _("(C) Piero Orsoni and others. Released under the GPL.\nSee AUTHORS and COPYING for details"),
"website", "http://www.opbyte.it/grsync/", NULL);
gdk_pixbuf_unref(pixbuf);
}
void on_button_switch_clicked (GtkButton *button, gpointer user_data) {
const gchar *tmps, *tmpd;
gchar *tmp;
tmps = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_source"));
tmpd = gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_dest"));
tmp = g_strconcat(tmps, NULL);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_source"), tmpd);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) button, "text_dest"), tmp);
g_free(tmp);
}
void on_button_pause_clicked(GtkButton *button, gpointer user_data) {
GtkButton *tmpbutt = (GtkButton*)lookup_widget((GtkWidget*) button, "button_pause");
GTimeVal tmptime;
if (paused) {
if (rsync_pid) kill(rsync_pid, SIGCONT);
gtk_button_set_label(tmpbutt, "gtk-media-pause");
gtk_window_set_title((GtkWindow*)rsync, "rsync: running");
g_get_current_time(&tmptime);
startime.tv_sec += tmptime.tv_sec - pausedtime.tv_sec;
startime.tv_usec += tmptime.tv_usec - pausedtime.tv_usec;
} else {
if (rsync_pid) kill(rsync_pid, SIGSTOP);
gtk_button_set_label(tmpbutt, "gtk-media-play");
gtk_window_set_title((GtkWindow*)rsync, "rsync: paused");
g_get_current_time(&pausedtime);
}
paused = !paused;
}
void on_preferences1_activate(GtkMenuItem *menuitem, gpointer user_data) {
GtkWidget *config;
gint result;
config = create_dialog_config();
gtk_window_set_transient_for((GtkWindow*) config, (GtkWindow*) main_window);
gtk_entry_set_text((GtkEntry*) lookup_widget((GtkWidget*) config, "entry_command"), config_command);
set_checkbox(config, "check_output", config_output);
set_checkbox(config, "check_remember", config_remember);
set_checkbox(config, "check_errorlist", config_errorlist);
set_checkbox(config, "check_log", config_log);
result = gtk_dialog_run((GtkDialog*) config);
if (result == GTK_RESPONSE_OK) {
strncpy(config_command, gtk_entry_get_text((GtkEntry*) lookup_widget((GtkWidget*) config, "entry_command")), MAXPATH - 1);
config_output = get_checkbox(config, "check_output");
config_remember = get_checkbox(config, "check_remember");
config_errorlist = get_checkbox(config, "check_errorlist");
config_log = get_checkbox(config, "check_log");
}
gtk_widget_destroy(config);
}
void on_rsync_info_activate(GtkMenuItem *menuitem, gpointer user_data) {
GtkWidget *dialog;
gchar *tmps, *result;
tmps = g_strconcat(config_command, " --version", NULL);
g_spawn_command_line_sync(tmps, &result, NULL, NULL, NULL);
dialog = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, result);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_free(tmps);
g_free(result);
}
void on_import1_activate(GtkMenuItem *menuitem, gpointer user_data) {
GtkWidget *dialog, *dialog2;
gint retval, i;
dialog = gtk_file_chooser_dialog_new (_("Browse"), (GtkWindow*) main_window, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
retval = gtk_dialog_run (GTK_DIALOG (dialog));
if (retval == GTK_RESPONSE_ACCEPT || retval == GTK_RESPONSE_OK) {
gchar *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
load_settings((GtkWidget*) menuitem, NULL, filename);
dialog2 = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
_("Session imported"));
gtk_dialog_run(GTK_DIALOG(dialog2));
gtk_widget_destroy(dialog2);
g_free(filename);
}
gtk_widget_destroy (dialog);
}
void on_export1_activate (GtkMenuItem *menuitem, gpointer user_data) {
GtkWidget *dialog, *dialog2;
gchar *filename;
gint retval, i;
i = gtk_combo_box_get_active((GtkComboBox*) lookup_widget((GtkWidget*) menuitem, "combo_session"));
dialog = gtk_file_chooser_dialog_new (_("Browse"), (GtkWindow*) main_window, GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
filename = g_strconcat(groups[i], ".grsync", NULL);
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
g_free(filename);
retval = gtk_dialog_run (GTK_DIALOG (dialog));
if (retval == GTK_RESPONSE_ACCEPT || retval == GTK_RESPONSE_OK) {
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
save_settings((GtkWidget*) menuitem, groups[i], filename);
dialog2 = gtk_message_dialog_new((GtkWindow*) main_window, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
_("Session exported"));
gtk_dialog_run(GTK_DIALOG(dialog2));
gtk_widget_destroy(dialog2);
g_free(filename);
}
gtk_widget_destroy (dialog);
}
syntax highlighted by Code2HTML, v. 0.9.1