/*****************************************************************************/
/* gtkui.c - GTK+ UI related functions for gFTP */
/* Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org> */
/* */
/* 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., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
/*****************************************************************************/
#include "gftp-gtk.h"
static const char cvsid[] = "$Id: gtkui.c,v 1.23 2005/01/26 03:22:05 masneyb Exp $";
void
gftpui_lookup_file_colors (gftp_file * fle, char **start_color,
char ** end_color)
{
*start_color = GFTPUI_COMMON_COLOR_NONE;
*end_color = GFTPUI_COMMON_COLOR_NONE;
}
void
gftpui_run_command (GtkWidget * widget, gpointer data)
{
const char *txt;
txt = gtk_entry_get_text (GTK_ENTRY (gftpui_command_widget));
gftpui_common_process_command (&window1, window1.request,
&window2, window2.request, txt);
gtk_entry_set_text (GTK_ENTRY (gftpui_command_widget), "");
}
void
gftpui_refresh (void *uidata, int clear_cache_entry)
{
gftp_window_data * wdata;
wdata = uidata;
if (!check_status (_("Refresh"), wdata, 0, 0, 0, 1))
return;
if (check_reconnect (wdata) < 0)
return;
gtk_clist_freeze (GTK_CLIST (wdata->listbox));
remove_files_window (wdata);
if (clear_cache_entry)
gftp_delete_cache_entry (wdata->request, NULL, 0);
ftp_list_files (wdata);
gtk_clist_thaw (GTK_CLIST (wdata->listbox));
}
#define _GFTPUI_GTK_USER_PW_SIZE 256
static void
_gftpui_gtk_set_username (gftp_request * request, gftp_dialog_data * ddata)
{
gftp_set_username (request, gtk_entry_get_text (GTK_ENTRY (ddata->edit)));
request->stopable = 0;
}
static void
_gftpui_gtk_set_password (gftp_request * request, gftp_dialog_data * ddata)
{
gftp_set_password (request, gtk_entry_get_text (GTK_ENTRY (ddata->edit)));
request->stopable = 0;
}
static void
_gftpui_gtk_abort (gftp_request * request, gftp_dialog_data * ddata)
{
request->stopable = 0;
}
void
gftpui_prompt_username (void *uidata, gftp_request * request)
{
MakeEditDialog (_("Enter Username"),
_("Please enter your username for this site"), NULL,
0, NULL, gftp_dialog_button_connect,
_gftpui_gtk_set_username, request,
_gftpui_gtk_abort, request);
request->stopable = 1;
while (request->stopable)
{
GDK_THREADS_LEAVE ();
#if GTK_MAJOR_VERSION == 1
g_main_iteration (TRUE);
#else
g_main_context_iteration (NULL, TRUE);
#endif
}
}
void
gftpui_prompt_password (void *uidata, gftp_request * request)
{
MakeEditDialog (_("Enter Password"),
_("Please enter your password for this site"), NULL,
0, NULL, gftp_dialog_button_connect,
_gftpui_gtk_set_password, request,
_gftpui_gtk_abort, request);
request->stopable = 1;
while (request->stopable)
{
GDK_THREADS_LEAVE ();
#if GTK_MAJOR_VERSION == 1
g_main_iteration (TRUE);
#else
g_main_context_iteration (NULL, TRUE);
#endif
}
}
/* The wakeup main thread functions are so that after the thread terminates
there won't be a delay in updating the GUI */
static void
_gftpui_wakeup_main_thread (gpointer data, gint source,
GdkInputCondition condition)
{
gftp_request * request;
char c;
request = data;
if (request->wakeup_main_thread[0] > 0)
read (request->wakeup_main_thread[0], &c, 1);
}
static gint
_gftpui_setup_wakeup_main_thread (gftp_request * request)
{
gint handler;
if (socketpair (AF_UNIX, SOCK_STREAM, 0, request->wakeup_main_thread) == 0)
{
handler = gdk_input_add (request->wakeup_main_thread[0],
GDK_INPUT_READ, _gftpui_wakeup_main_thread,
request);
}
else
{
request->wakeup_main_thread[0] = 0;
request->wakeup_main_thread[1] = 0;
handler = 0;
}
return (handler);
}
static void
_gftpui_teardown_wakeup_main_thread (gftp_request * request, gint handler)
{
if (request->wakeup_main_thread[0] > 0 && request->wakeup_main_thread[1] > 0)
{
gdk_input_remove (handler);
close (request->wakeup_main_thread[0]);
close (request->wakeup_main_thread[1]);
request->wakeup_main_thread[0] = 0;
request->wakeup_main_thread[1] = 0;
}
}
static void *
_gftpui_gtk_thread_func (void *data)
{
gftpui_gtk_thread_data * thread_data;
void *ret;
thread_data = data;
ret = thread_data->func (thread_data->cdata);
if (thread_data->cdata->request->wakeup_main_thread[1] > 0)
write (thread_data->cdata->request->wakeup_main_thread[1], " ", 1);
return (ret);
}
void *
gftpui_generic_thread (void * (*func) (void *), void *data)
{
gftpui_gtk_thread_data * thread_data;
gftpui_callback_data * cdata;
gftp_window_data * wdata;
gint handler;
void * ret;
cdata = data;
wdata = cdata->uidata;
wdata->request->stopable = 1;
gtk_widget_set_sensitive (stop_btn, 1);
thread_data = g_malloc0 (sizeof (*thread_data));
thread_data->func = func;
thread_data->cdata = cdata;
handler = _gftpui_setup_wakeup_main_thread (cdata->request);
pthread_create (&wdata->tid, NULL, _gftpui_gtk_thread_func, thread_data);
while (wdata->request->stopable)
{
GDK_THREADS_LEAVE ();
#if GTK_MAJOR_VERSION == 1
g_main_iteration (TRUE);
#else
g_main_context_iteration (NULL, TRUE);
#endif
}
_gftpui_teardown_wakeup_main_thread (cdata->request, handler);
g_free (thread_data);
pthread_join (wdata->tid, &ret);
gtk_widget_set_sensitive (stop_btn, 0);
if (!GFTP_IS_CONNECTED (wdata->request))
gftpui_disconnect (wdata);
return (ret);
}
int
gftpui_check_reconnect (gftpui_callback_data * cdata)
{
gftp_window_data * wdata;
wdata = cdata->uidata;
return (wdata->request->cached && wdata->request->datafd < 0 &&
!wdata->request->always_connected &&
!ftp_connect (wdata, wdata->request, 0) ? -1 : 0);
}
void
gftpui_run_function_callback (gftp_window_data * wdata,
gftp_dialog_data * ddata)
{
gftpui_callback_data * cdata;
const char *edttext;
cdata = ddata->yespointer;
if (ddata->edit != NULL)
{
edttext = gtk_entry_get_text (GTK_ENTRY (ddata->edit));
if (*edttext == '\0')
{
ftp_log (gftp_logging_error, NULL,
_("Operation canceled...you must enter a string\n"));
return;
}
cdata->input_string = g_strdup (edttext);
}
if (ddata->checkbox != NULL)
cdata->toggled = GTK_TOGGLE_BUTTON (ddata->checkbox)->active;
else
cdata->toggled = 0;
gtk_widget_destroy (ddata->dialog);
ddata->dialog = NULL;
gftpui_common_run_callback_function (cdata);
}
void
gftpui_run_function_cancel_callback (gftp_window_data * wdata,
gftp_dialog_data * ddata)
{
gftpui_callback_data * cdata;
cdata = ddata->yespointer;
if (cdata->input_string != NULL)
g_free (cdata->input_string);
if (cdata->source_string != NULL)
g_free (cdata->source_string);
g_free (cdata);
}
void
gftpui_mkdir_dialog (gpointer data)
{
gftpui_callback_data * cdata;
gftp_window_data * wdata;
wdata = data;
cdata = g_malloc0 (sizeof (*cdata));
cdata->request = wdata->request;
cdata->uidata = wdata;
cdata->run_function = gftpui_common_run_mkdir;
if (!check_status (_("Mkdir"), wdata, gftpui_common_use_threads (wdata->request), 0, 0, wdata->request->mkdir != NULL))
return;
MakeEditDialog (_("Make Directory"), _("Enter name of directory to create"),
NULL, 1, NULL, gftp_dialog_button_create,
gftpui_run_function_callback, cdata,
gftpui_run_function_cancel_callback, cdata);
}
void
gftpui_rename_dialog (gpointer data)
{
gftpui_callback_data * cdata;
GList *templist, *filelist;
gftp_window_data * wdata;
gftp_file * curfle;
char *tempstr;
int num;
wdata = data;
cdata = g_malloc0 (sizeof (*cdata));
cdata->request = wdata->request;
cdata->uidata = wdata;
cdata->run_function = gftpui_common_run_rename;
if (!check_status (_("Rename"), wdata, gftpui_common_use_threads (wdata->request), 1, 1, wdata->request->rename != NULL))
return;
templist = gftp_gtk_get_list_selection (wdata);
num = 0;
filelist = wdata->files;
templist = get_next_selection (templist, &filelist, &num);
curfle = filelist->data;
cdata->source_string = g_strdup (curfle->file);
tempstr = g_strdup_printf (_("What would you like to rename %s to?"),
cdata->source_string);
MakeEditDialog (_("Rename"), tempstr, cdata->source_string, 1, NULL,
gftp_dialog_button_rename,
gftpui_run_function_callback, cdata,
gftpui_run_function_cancel_callback, cdata);
g_free (tempstr);
}
void
gftpui_site_dialog (gpointer data)
{
gftpui_callback_data * cdata;
gftp_window_data * wdata;
wdata = data;
cdata = g_malloc0 (sizeof (*cdata));
cdata->request = wdata->request;
cdata->uidata = wdata;
cdata->run_function = gftpui_common_run_site;
if (!check_status (_("Site"), wdata, 0, 0, 0, wdata->request->site != NULL))
return;
MakeEditDialog (_("Site"), _("Enter site-specific command"), NULL, 1,
_("Prepend with SITE"), gftp_dialog_button_ok,
gftpui_run_function_callback, cdata,
gftpui_run_function_cancel_callback, cdata);
}
int
gftpui_run_chdir (gpointer uidata, char *directory)
{
gftpui_callback_data * cdata;
gftp_window_data * wdata;
char *tempstr;
int ret;
wdata = uidata;
if ((tempstr = gftp_expand_path (wdata->request, directory)) == NULL)
return (FALSE);
cdata = g_malloc0 (sizeof (*cdata));
cdata->request = wdata->request;
cdata->uidata = wdata;
cdata->run_function = gftpui_common_run_chdir;
cdata->input_string = tempstr;
cdata->dont_clear_cache = 1;
ret = gftpui_common_run_callback_function (cdata);
g_free(tempstr);
g_free (cdata);
return (ret);
}
void
gftpui_chdir_dialog (gpointer data)
{
GList *templist, *filelist;
gftp_window_data * wdata;
gftp_file * curfle;
char *tempstr;
int num;
wdata = data;
if (!check_status (_("Chdir"), wdata, gftpui_common_use_threads (wdata->request), 1, 0,
wdata->request->chdir != NULL))
return;
templist = gftp_gtk_get_list_selection (wdata);
num = 0;
filelist = wdata->files;
templist = get_next_selection (templist, &filelist, &num);
curfle = filelist->data;
tempstr = gftp_build_path (wdata->request, wdata->request->directory,
curfle->file, NULL);
gftpui_run_chdir (wdata, tempstr);
g_free (tempstr);
}
void
gftpui_disconnect (void *uidata)
{
gftp_window_data * wdata;
wdata = uidata;
gftp_delete_cache_entry (wdata->request, NULL, 1);
gftp_disconnect (wdata->request);
remove_files_window (wdata);
update_window_info ();
}
char *
gftpui_gtk_get_utf8_file_pos (gftp_file * fle)
{
char *disp_item, *pos;
if (fle->utf8_file != NULL)
disp_item = fle->utf8_file;
else
disp_item = fle->file;
if ((pos = strrchr (disp_item, '/')) != NULL)
pos++;
else
pos = disp_item;
return (pos);
}
static void
_protocol_yes_answer (gpointer answer, gftp_dialog_data * ddata)
{
*(int *) answer = 1;
}
static void
_protocol_no_answer (gpointer answer, gftp_dialog_data * ddata)
{
*(int *) answer = 0;
}
int
gftpui_protocol_ask_yes_no (gftp_request * request, char *title,
char *question)
{
int answer = -1;
GDK_THREADS_ENTER ();
MakeYesNoDialog (title, question, _protocol_yes_answer, &answer,
_protocol_no_answer, &answer);
if (gftp_protocols[request->protonum].use_threads)
{
/* Let the main loop in the main thread run the events */
GDK_THREADS_LEAVE ();
while (answer == -1)
{
sleep (1);
}
}
else
{
while (answer == -1)
{
GDK_THREADS_LEAVE ();
#if GTK_MAJOR_VERSION == 1
g_main_iteration (TRUE);
#else
g_main_context_iteration (NULL, TRUE);
#endif
}
}
return (answer);
}
static void
_protocol_ok_answer (char *buf, gftp_dialog_data * ddata)
{
buf[1] = ' '; /* In case this is an empty string entered */
strncpy (buf, gtk_entry_get_text (GTK_ENTRY (ddata->edit)), BUFSIZ);
}
static void
_protocol_cancel_answer (char *buf, gftp_dialog_data * ddata)
{
buf[0] = '\0';
buf[1] = '\0';
}
char *
gftpui_protocol_ask_user_input (gftp_request * request, char *title,
char *question, int shown)
{
char buf[BUFSIZ];
GDK_THREADS_ENTER ();
*buf = '\0';
*(buf + 1) = ' ';
MakeEditDialog (title, question, NULL, shown, NULL, gftp_dialog_button_ok,
_protocol_ok_answer, &buf, _protocol_cancel_answer, &buf);
if (gftp_protocols[request->protonum].use_threads)
{
/* Let the main loop in the main thread run the events */
GDK_THREADS_LEAVE ();
while (*buf == '\0' && *(buf + 1) == ' ')
{
sleep (1);
}
}
else
{
while (*buf == '\0' && *(buf + 1) == ' ')
{
GDK_THREADS_LEAVE ();
#if GTK_MAJOR_VERSION == 1
g_main_iteration (TRUE);
#else
g_main_context_iteration (NULL, TRUE);
#endif
}
}
if (*buf != '\0')
return (g_strdup (buf));
else
return (NULL);
}
syntax highlighted by Code2HTML, v. 0.9.1