Mercurial > gftp.yaz
diff src/gtk/misc-gtk.c @ 1:8b1883341c6f
Initial revision
author | masneyb |
---|---|
date | Mon, 05 Aug 2002 19:46:57 +0000 |
parents | |
children | 5551ab2301fe |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gtk/misc-gtk.c Mon Aug 05 19:46:57 2002 +0000 @@ -0,0 +1,1106 @@ +/*****************************************************************************/ +/* misc-gtk.c - misc stuff for the gtk+ 1.2 port of gftp */ +/* Copyright (C) 1998-2002 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/*****************************************************************************/ + +#include <gftp-gtk.h> + +static void set_menu_sensitive ( gftp_window_data * wdata, + char *path, + int sensitive ); +static void destroy_dialog_data ( gftp_dialog_data * data ); +static gint delete_event ( GtkWidget * widget, + GdkEvent * event, + gpointer data ); +static void trans_stop_button ( GtkWidget * widget, + gpointer data ); + +static GtkWidget * statuswid; + + +void +fix_display (void) +{ + while (g_main_iteration (FALSE)); +} + + +void +remove_files_window (gftp_window_data * wdata) +{ + wdata->show_selected = 0; + gtk_clist_freeze (GTK_CLIST (wdata->listbox)); + gtk_clist_clear (GTK_CLIST (wdata->listbox)); + free_file_list (wdata->files); + wdata->files = NULL; + gtk_clist_thaw (GTK_CLIST (wdata->listbox)); +} + + +void +ftp_log (gftp_logging_level level, void *ptr, const char *string, ...) +{ + char tempstr[512]; + gftp_log * newlog; + gint delsize; + va_list argp; + guint len; + int upd; +#if GTK_MAJOR_VERSION == 1 && GTK_MINOR_VERSION == 2 + gftp_color * color; + GdkColor fore; +#else + GtkTextBuffer * textbuf; + GtkTextIter iter, iter2; + const char *descr; + guint inslen; +#endif + + if (ptr == (void *) 0x1) + { + newlog = g_malloc0 (sizeof (*newlog)); + newlog->type = level; + va_start (argp, string); + newlog->msg = g_strdup_vprintf (string, argp); + va_end (argp); + + pthread_mutex_lock (&log_mutex); + file_transfer_logs = g_list_append (file_transfer_logs, newlog); + pthread_mutex_unlock (&log_mutex); + return; + } + + va_start (argp, string); + g_vsnprintf (tempstr, sizeof (tempstr), string, argp); + va_end (argp); + + if (logfd != NULL) + { + if (fwrite (tempstr, strlen (tempstr), 1, logfd) != 1) + { + fclose (logfd); + logfd = NULL; + } + else + fflush (logfd); + } + + upd = logwdw_vadj->upper - logwdw_vadj->page_size == logwdw_vadj->value; + +#if GTK_MAJOR_VERSION == 1 && GTK_MINOR_VERSION == 2 + switch (level) + { + case gftp_logging_send: + color = &send_color; + break; + case gftp_logging_recv: + color = &recv_color; + break; + case gftp_logging_error: + color = &error_color; + break; + default: + color = &misc_color; + break; + } + + memset (&fore, 0, sizeof (fore)); + fore.red = color->red; + fore.green = color->green; + fore.blue = color->blue; + + gtk_text_freeze (GTK_TEXT (logwdw)); + gtk_text_insert (GTK_TEXT (logwdw), NULL, &fore, NULL, tempstr, -1); + + len = gtk_text_get_length (GTK_TEXT (logwdw)); + if (max_log_window_size > 0 && len > max_log_window_size) + { + delsize = len - max_log_window_size; + gtk_text_set_point (GTK_TEXT (logwdw), delsize); + gtk_text_backward_delete (GTK_TEXT (logwdw), delsize); + len = max_log_window_size; + } + gtk_text_set_point (GTK_TEXT (logwdw), len); + + gtk_text_thaw (GTK_TEXT (logwdw)); + + if (upd) + gtk_adjustment_set_value (logwdw_vadj, logwdw_vadj->upper); +#else + switch (level) + { + case gftp_logging_send: + descr = "send"; + break; + case gftp_logging_recv: + descr = "recv"; + break; + case gftp_logging_error: + descr = "error"; + break; + default: + descr = "misc"; + break; + } + + textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logwdw)); + len = gtk_text_buffer_get_char_count (textbuf); + inslen = strlen (tempstr); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, len); + gtk_text_buffer_insert_with_tags_by_name (textbuf, &iter, tempstr, inslen, + descr, NULL); + + if (upd) + { + gtk_text_buffer_move_mark (textbuf, logwdw_textmark, &iter); + gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (logwdw), logwdw_textmark, + 0, 1, 1, 1); + } + + delsize = len + inslen - max_log_window_size; + if (max_log_window_size > 0 && delsize > 0) + { + gtk_text_buffer_get_iter_at_offset (textbuf, &iter, 0); + gtk_text_buffer_get_iter_at_offset (textbuf, &iter2, delsize); + gtk_text_buffer_delete (textbuf, &iter, &iter2); + } +#endif + + if (ptr == NULL) + fix_display (); +} + + +void +refresh (gftp_window_data * wdata) +{ + if (!check_status (_("Refresh"), wdata, 0, 0, 0, 1)) + return; + gtk_clist_freeze (GTK_CLIST (wdata->listbox)); + remove_files_window (wdata); + gftp_delete_cache_entry (wdata->request); + ftp_list_files (wdata, 0); + gtk_clist_thaw (GTK_CLIST (wdata->listbox)); + fix_display (); +} + + +void +update_window_info (void) +{ + char *tempstr, empty[] = ""; + GtkWidget * tempwid; + int i; + + if (current_wdata->request != NULL) + { + if ((tempstr = GFTP_GET_HOSTNAME (current_wdata->request)) == NULL) + tempstr = empty; + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (hostedit)->entry), tempstr); + + if ((tempstr = GFTP_GET_USERNAME (current_wdata->request)) == NULL) + tempstr = empty; + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (useredit)->entry), tempstr); + + if ((tempstr = GFTP_GET_PASSWORD (current_wdata->request)) == NULL) + tempstr = empty; + gtk_entry_set_text (GTK_ENTRY (passedit), tempstr); + + if (GFTP_GET_PORT (current_wdata->request) != 0) + { + tempstr = g_strdup_printf ("%d", GFTP_GET_PORT (current_wdata->request)); + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (portedit)->entry), tempstr); + g_free (tempstr); + } + + for (i=0; gftp_protocols[i].init != NULL; i++) + { + if (current_wdata->request->init == gftp_protocols[i].init) + { + gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), i); + break; + } + } + } + + update_window (&window1); + update_window (&window2); + + tempwid = gtk_item_factory_get_widget (factory, _(menus[tools_start+2].path)); + gtk_widget_set_sensitive (tempwid, GFTP_IS_CONNECTED (window1.request) + && GFTP_IS_CONNECTED (window2.request)); +} + + +void +update_window (gftp_window_data * wdata) +{ + char *dir, *tempstr, *temp1str, *fspec; + int connected, start; + + connected = GFTP_IS_CONNECTED (wdata->request); + if (connected) + { + fspec = wdata->show_selected ? "Selected" : strcmp (wdata->filespec, "*") == 0 ? _("All Files") : wdata->filespec; + + if ((temp1str = GFTP_GET_HOSTNAME (wdata->request)) == NULL) + temp1str = ""; + tempstr = g_strconcat (temp1str, *temp1str == '\0' ? "[" : " [", + GFTP_GET_PROTOCOL_NAME (wdata->request), + wdata->request->cached ? _("] (Cached) [") : "] [", + fspec, "]", current_wdata == wdata ? "*" : "", NULL); + gtk_label_set (GTK_LABEL (wdata->hoststxt), tempstr); + g_free (tempstr); + + if ((dir = GFTP_GET_DIRECTORY (wdata->request)) == NULL) + temp1str = ""; + else + temp1str = dir; + + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry),temp1str); + } + else if (wdata->hoststxt != NULL) + { + tempstr = g_strconcat (_("Not connected"), + current_wdata == wdata ? "*" : "", NULL); + gtk_label_set (GTK_LABEL (wdata->hoststxt), tempstr); + g_free (tempstr); + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (wdata->combo)->entry), ""); + } + + if (wdata == &window1) + start = local_start; + else + start = remote_start; + + set_menu_sensitive (wdata, menus[start + 3].path, connected && + strcmp (wdata->request->url_prefix, "file") != 0); + set_menu_sensitive (wdata, menus[start + 5].path, connected); + set_menu_sensitive (wdata, menus[start + 6].path, connected); + set_menu_sensitive (wdata, menus[start + 7].path, connected); + set_menu_sensitive (wdata, menus[start + 8].path, connected); + set_menu_sensitive (wdata, menus[start + 9].path, connected); + set_menu_sensitive (wdata, menus[start + 11].path, connected && + wdata->request->site != NULL); + set_menu_sensitive (wdata, menus[start + 12].path, connected && + wdata->request->chdir!= NULL); + set_menu_sensitive (wdata, menus[start + 13].path, connected && + wdata->request->chmod != NULL); + set_menu_sensitive (wdata, menus[start + 14].path, connected && + wdata->request->mkdir != NULL); + set_menu_sensitive (wdata, menus[start + 15].path, connected && + wdata->request->rename != NULL); + set_menu_sensitive (wdata, menus[start + 16].path, connected && + wdata->request->rmdir != NULL && + wdata->request->rmfile != NULL); + set_menu_sensitive (wdata, menus[start + 17].path, connected && + wdata->request->get_file != NULL); + set_menu_sensitive (wdata, menus[start + 18].path, connected && + wdata->request->get_file != NULL); + set_menu_sensitive (wdata, menus[start + 19].path, connected); + fix_display (); +} + + +static void +set_menu_sensitive (gftp_window_data * wdata, char *path, int sensitive) +{ + GtkWidget * tempwid; + char * pos; + + tempwid = NULL; + + if (factory != NULL) + tempwid = gtk_item_factory_get_widget (factory, _(path)); + if (tempwid) + gtk_widget_set_sensitive (tempwid, sensitive); + + if ((pos = strchr (path + 1, '/')) == NULL) + pos = path; + + if (wdata->ifactory) + tempwid = gtk_item_factory_get_widget (wdata->ifactory, _(pos)); + if (tempwid) + gtk_widget_set_sensitive (tempwid, sensitive); +} + + +GtkWidget * +toolbar_pixmap (GtkWidget * widget, char *filename) +{ + gftp_graphic * graphic; + GtkWidget *pix; + + if (filename == NULL || *filename == '\0') + return (NULL); + + graphic = open_xpm (widget, filename); + + if (graphic == NULL) + return (NULL); + + if ((pix = gtk_pixmap_new (graphic->pixmap, graphic->bitmap)) == NULL) + return (NULL); + + gtk_widget_show (pix); + return (pix); +} + + +gftp_graphic * +open_xpm (GtkWidget * widget, char *filename) +{ + gftp_graphic * graphic; + GtkStyle *style; + char *exfile; + + if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) != NULL) + return (graphic); + + style = gtk_widget_get_style (widget); + + if ((exfile = get_xpm_path (filename, 0)) == NULL) + return (NULL); + + graphic = g_malloc0 (sizeof (*graphic)); + graphic->pixmap = gdk_pixmap_create_from_xpm (widget->window, + &graphic->bitmap, &style->bg[GTK_STATE_NORMAL], exfile); + g_free (exfile); + + if (graphic->pixmap == NULL) + { + g_free (graphic); + ftp_log (gftp_logging_error, NULL, _("Error opening file %s: %s\n"), + exfile, g_strerror (errno)); + return (NULL); + } + + graphic->filename = g_malloc (strlen (filename) + 1); + strcpy (graphic->filename, filename); + g_hash_table_insert (graphic_hash_table, graphic->filename, graphic); + + return (graphic); +} + + +void +gftp_free_pixmap (char *filename) +{ + gftp_graphic * graphic; + + if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) == NULL) + return; + +#if GTK_MAJOR_VERSION == 1 && GTK_MINOR_VERSION == 2 + gdk_pixmap_unref (graphic->pixmap); + gdk_bitmap_unref (graphic->bitmap); +#else + gdk_drawable_unref (graphic->pixmap); + gdk_drawable_unref (graphic->bitmap); +#endif + + g_hash_table_remove (graphic_hash_table, filename); + g_free (graphic->filename); + g_free (graphic); +} + + +void +gftp_get_pixmap (GtkWidget * widget, char *filename, GdkPixmap ** pix, + GdkBitmap ** bitmap) +{ + gftp_graphic * graphic; + + if (filename == NULL || *filename == '\0') + { + *pix = NULL; + *bitmap = NULL; + return; + } + + if ((graphic = g_hash_table_lookup (graphic_hash_table, filename)) == NULL) + graphic = open_xpm (widget, filename); + + if (graphic == NULL) + { + *pix = NULL; + *bitmap = NULL; + return; + } + + *pix = graphic->pixmap; + *bitmap = graphic->bitmap; +} + + +int +check_status (char *name, gftp_window_data *wdata, int check_other_stop, + int only_one, int at_least_one, int func) +{ + gftp_window_data * owdata; + + owdata = wdata == &window1 ? &window2 : &window1; + + if (wdata->request->stopable) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: Please hit the stop button first to do anything else\n"), + name); + return (0); + } + + if (check_other_stop && owdata->request->stopable) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: Please hit the stop button first to do anything else\n"), + name); + return (0); + } + + if (!GFTP_IS_CONNECTED (wdata->request)) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: Not connected to a remote site\n"), name); + return (0); + } + + if (!func) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: This feature is not available using this protocol\n"), + name); + return (0); + } + + if (only_one && !IS_ONE_SELECTED (wdata)) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: You must only have one item selected\n"), name); + return (0); + } + + if (at_least_one && !only_one && IS_NONE_SELECTED (wdata)) + { + ftp_log (gftp_logging_misc, NULL, + _("%s: You must have at least one item selected\n"), name); + return (0); + } + return (1); +} + + +void +create_item_factory (GtkItemFactory * ifactory, guint n_entries, + GtkItemFactoryEntry * entries, gpointer callback_data) +{ + GtkItemFactoryEntry dummy_item; + int i; + + for (i = 0; i < n_entries; i++) + { + memcpy (&dummy_item, entries + i, sizeof (dummy_item)); + if (dummy_item.item_type) + dummy_item.item_type = _(entries[i].item_type); + dummy_item.path = _(entries[i].path); + gtk_item_factory_create_item (ifactory, &dummy_item, callback_data, 1); + } +} + + +GList * +get_next_selection (GList * selection, GList ** list, int *curnum) +{ + gftp_file * tempfle; + int i, newpos; + + newpos = (int) selection->data; + i = *curnum - newpos; + + if (i < 0) + { + while (i != 0) + { + tempfle = (*list)->data; + if (tempfle->shown) + { + ++*curnum; + i++; + } + *list = (*list)->next; + } + } + else if (i > 0) + { + while (i != 0) + { + tempfle = (*list)->data; + if (tempfle->shown) + { + --*curnum; + i--; + } + *list = (*list)->prev; + } + } + + tempfle = (*list)->data; + while ((*list)->next && !tempfle->shown) + { + *list = (*list)->next; + tempfle = (*list)->data; + } + return (selection->next); +} + + +void +add_history (GtkWidget * widget, GList ** history, unsigned int *histlen, + const char *str) +{ + GList *node, *delnode; + char *tempstr; + int i; + + if (str == NULL || *str == '\0') + return; + + for (node = *history; node != NULL; node = node->next) + { + if (strcmp ((char *) node->data, str) == 0) + break; + } + + if (node == NULL) + { + if (*histlen >= MAX_HIST_LEN) + { + node = *history; + for (i = 1; i < MAX_HIST_LEN; i++) + node = node->next; + node->prev->next = NULL; + node->prev = NULL; + delnode = node; + while (delnode != NULL) + { + if (delnode->data) + g_free (delnode->data); + delnode = delnode->next; + } + g_list_free (node); + } + tempstr = g_malloc (strlen (str) + 1); + strcpy (tempstr, str); + *history = g_list_prepend (*history, tempstr); + ++*histlen; + } + else if (node->prev != NULL) + { + node->prev->next = node->next; + if (node->next != NULL) + node->next->prev = node->prev; + node->prev = NULL; + node->next = *history; + if (node->next != NULL) + node->next->prev = node; + *history = node; + } + gtk_combo_set_popdown_strings (GTK_COMBO (widget), *history); +} + + +int +check_reconnect (gftp_window_data *wdata) +{ + return (wdata->request->cached && wdata->request->sockfd == NULL && + !ftp_connect (wdata, wdata->request, 0) ? -1 : 0); +} + + +void +add_file_listbox (gftp_window_data * wdata, gftp_file * fle) +{ + char *add_data[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, *pos; + gftp_file_extensions * tempext; + char *tempstr, *str; + GdkBitmap * bitmap; + GList * templist; + GdkPixmap * pix; + int clist_num; + size_t stlen; + + if (wdata->show_selected) + { + fle->shown = fle->was_sel; + if (!fle->shown) + return; + } + else if ((!show_hidden_files && *fle->file == '.' && + strcmp (fle->file, "..") != 0) || + !gftp_match_filespec (fle->file, wdata->filespec)) + { + fle->shown = 0; + fle->was_sel = 0; + return; + } + else + fle->shown = 1; + + clist_num = gtk_clist_append (GTK_CLIST (wdata->listbox), add_data); + + if (fle->was_sel) + { + fle->was_sel = 0; + gtk_clist_select_row (GTK_CLIST (wdata->listbox), clist_num, 0); + } + + pix = NULL; + bitmap = NULL; + if (strcmp (fle->file, "..") == 0) + gftp_get_pixmap (wdata->listbox, "dotdot.xpm", &pix, &bitmap); + else if (fle->islink && fle->isdir) + gftp_get_pixmap (wdata->listbox, "linkdir.xpm", &pix, &bitmap); + else if (fle->islink) + gftp_get_pixmap (wdata->listbox, "linkfile.xpm", &pix, &bitmap); + else if (fle->isdir) + gftp_get_pixmap (wdata->listbox, "dir.xpm", &pix, &bitmap); + else if (fle->isexe) + gftp_get_pixmap (wdata->listbox, "exe.xpm", &pix, &bitmap); + else + { + stlen = strlen (fle->file); + templist = registered_exts; + while (templist != NULL) + { + tempext = templist->data; + if (stlen >= tempext->stlen && + strcmp (&fle->file[stlen - tempext->stlen], tempext->ext) == 0) + { + if (toupper (*tempext->ascii_binary) == 'A') + fle->ascii = 1; + + gftp_get_pixmap (wdata->listbox, tempext->filename, &pix, + &bitmap); + break; + } + templist = templist->next; + } + } + + if (pix == NULL && bitmap == NULL) + gftp_get_pixmap (wdata->listbox, "doc.xpm", &pix, &bitmap); + + gtk_clist_set_pixmap (GTK_CLIST (wdata->listbox), clist_num, 0, pix, bitmap); + + if (fle->file) + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 1, fle->file); + + if (fle->attribs && (*fle->attribs == 'b' || *fle->attribs == 'c')) + tempstr = g_strdup_printf ("%d, %d", (int) fle->size >> 16, + (int) fle->size & 0xFF); + else + tempstr = insert_commas (fle->size, NULL, 0); + + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 2, tempstr); + g_free (tempstr); + + if (fle->user) + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 3, fle->user); + if (fle->group) + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 4, fle->group); + if ((str = ctime (&fle->datetime))) + { + if ((pos = strchr (str, '\n')) != NULL) + *pos = '\0'; + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 5, str); + } + if (fle->attribs) + gtk_clist_set_text (GTK_CLIST (wdata->listbox), clist_num, 6, fle->attribs); + +} + + +void +MakeEditDialog (char *diagtxt, char *infotxt, char *deftext, int edit_shown, + int erase, char *checktext, + char *oktxt, void (*okfunc) (), void *okptr, + char *canceltxt, void (*cancelfunc) (), void *cancelptr) +{ + gftp_dialog_data * d, * cancel_d; + GtkWidget * tempwid; + + d = g_malloc0 (sizeof (*d)); + cancel_d = g_malloc0 (sizeof (*cancel_d)); + cancel_d->data = cancelptr; + d->data = okptr; + cancel_d->all_buttons = d->all_buttons = NULL; + d->dialog = cancel_d->dialog = gtk_dialog_new (); + gtk_grab_add (d->dialog); + gtk_window_set_title (GTK_WINDOW (d->dialog), diagtxt); + gtk_window_set_wmclass (GTK_WINDOW(d->dialog), "edit", "gFTP"); + gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (d->dialog)->vbox), 10); + gtk_container_border_width (GTK_CONTAINER + (GTK_DIALOG (d->dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d->dialog)->vbox), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d->dialog)->action_area), 15); + gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (d->dialog)->action_area), TRUE); + gtk_window_set_position (GTK_WINDOW (d->dialog), GTK_WIN_POS_MOUSE); + + if (cancelfunc) + gtk_signal_connect (GTK_OBJECT (d->dialog), "delete_event", + GTK_SIGNAL_FUNC (cancelfunc), (gpointer) cancel_d); + + gtk_signal_connect_object (GTK_OBJECT (d->dialog), "delete_event", + GTK_SIGNAL_FUNC (destroy_dialog_data), + (gpointer) cancel_d); + tempwid = gtk_label_new (infotxt); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d->dialog)->vbox), tempwid, TRUE, + TRUE, 0); + gtk_widget_show (tempwid); + + d->edit = cancel_d->edit = gtk_entry_new (); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d->dialog)->vbox), d->edit, TRUE, + TRUE, 0); + if (okfunc) + gtk_signal_connect (GTK_OBJECT (d->edit), "activate", + GTK_SIGNAL_FUNC (okfunc), (gpointer) d); + if (erase || !okfunc) + gtk_signal_connect_object (GTK_OBJECT (d->edit), "activate", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + (gpointer) d->dialog); + + gtk_widget_grab_focus (d->edit); + gtk_entry_set_visibility (GTK_ENTRY (d->edit), edit_shown); + if (deftext != NULL) + { + gtk_entry_set_text (GTK_ENTRY (d->edit), deftext); + gtk_entry_select_region (GTK_ENTRY (d->edit), 0, strlen (deftext)); + } + gtk_widget_show (d->edit); + + if (checktext) + { + d->checkbox = cancel_d->checkbox = + gtk_check_button_new_with_label (checktext); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d->dialog)->vbox), d->checkbox, + TRUE, TRUE, 0); + gtk_widget_show (d->checkbox); + } + + tempwid = gtk_button_new_with_label (oktxt); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d->dialog)->action_area), tempwid, + TRUE, TRUE, 0); + if (okfunc) + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (okfunc), (gpointer) d); + if (erase || !okfunc) + gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + (gpointer) d->dialog); + gtk_widget_grab_default (tempwid); + gtk_widget_show (tempwid); + + tempwid = gtk_button_new_with_label (canceltxt); + GTK_WIDGET_SET_FLAGS (tempwid, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d->dialog)->action_area), tempwid, + TRUE, TRUE, 0); + if (cancelfunc) + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (cancelfunc), (gpointer) cancel_d); + if (erase || !cancelfunc) + gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + (gpointer) d->dialog); + gtk_widget_show (tempwid); + + d->all_buttons = g_list_append (d->all_buttons, d); + d->all_buttons = g_list_append (d->all_buttons, cancel_d); + cancel_d->all_buttons = d->all_buttons; + gtk_widget_show (d->dialog); +} + + +void +MakeYesNoDialog (char *diagtxt, char *infotxt, int erase, int num, ...) +{ + GtkWidget * text, * tempwid, * dialog; + typedef void (*func) (); + gftp_dialog_data * d; + char *tempstr; + va_list argp; + func myfunc; + GList * list; + void *ptr; + int i; + + dialog = gtk_dialog_new (); + gtk_grab_add (dialog); + gtk_window_set_title (GTK_WINDOW (dialog), diagtxt); + gtk_window_set_wmclass (GTK_WINDOW(dialog), "yndiag", "gFTP"); + gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 10); + gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), + 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 15); + gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dialog)->action_area), TRUE); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + + text = gtk_label_new (infotxt); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), text, TRUE, TRUE, 0); + gtk_widget_show (text); + + list = NULL; + ptr = g_malloc0 (sizeof (gftp_dialog_data)); + list = g_list_append (list, ptr); + va_start (argp, num); + for (i = 0; i < num; i++) + { + tempstr = va_arg (argp, char *); + myfunc = va_arg (argp, func); + ptr = va_arg (argp, void *); + d = g_malloc (sizeof (gftp_dialog_data)); + list = g_list_append (list, d); + d->dialog = dialog; + d->data = ptr; + d->all_buttons = list; + + tempwid = gtk_button_new_with_label (tempstr); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), tempwid, + TRUE, TRUE, 0); + if (myfunc) + gtk_signal_connect (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (myfunc), (gpointer) d); + if (erase || !myfunc) + gtk_signal_connect_object (GTK_OBJECT (tempwid), "clicked", + GTK_SIGNAL_FUNC (gtk_widget_destroy), + (gpointer) d->dialog); + gtk_widget_show (tempwid); + } + + gtk_widget_show (dialog); +} + + +static void +destroy_dialog_data (gftp_dialog_data * data) +{ + GList * list; + + list = data->all_buttons; + while (list != NULL) + { + if (list->data != data && list->data) + g_free (list->data); + list = list->next; + } + g_list_free (data->all_buttons); + g_free (data); +} + + +void +update_directory_download_progress (gftp_transfer * transfer) +{ + static GtkWidget * dialog = NULL, * textwid, * stopwid; + char tempstr[255]; + GtkWidget * vbox; + + if (transfer->numfiles < 0 || transfer->numdirs < 0) + { + if (dialog != NULL) + gtk_widget_destroy (dialog); + dialog = NULL; + return; + } + + if (dialog == NULL) + { + dialog = gtk_window_new (GTK_WINDOW_POPUP); + gtk_grab_add (dialog); + gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", + GTK_SIGNAL_FUNC (delete_event), NULL); + gtk_window_set_title (GTK_WINDOW (dialog), + _("Getting directory listings")); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + gtk_window_set_wmclass (GTK_WINDOW(dialog), "dirlist", "gFTP"); + + vbox = gtk_vbox_new (FALSE, 5); + gtk_container_border_width (GTK_CONTAINER (vbox), 10); + gtk_container_add (GTK_CONTAINER (dialog), vbox); + gtk_widget_show (vbox); + + textwid = gtk_label_new (NULL); + gtk_box_pack_start (GTK_BOX (vbox), textwid, TRUE, TRUE, 0); + gtk_widget_show (textwid); + + statuswid = gtk_progress_bar_new (); + gtk_progress_set_activity_mode (GTK_PROGRESS (statuswid), 1); + gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (statuswid), 3); + gtk_progress_bar_set_activity_blocks (GTK_PROGRESS_BAR (statuswid), 5); + gtk_box_pack_start (GTK_BOX (vbox), statuswid, TRUE, TRUE, 0); + gtk_widget_show (statuswid); + + stopwid = gtk_button_new_with_label (_(" Stop ")); + gtk_signal_connect (GTK_OBJECT (stopwid), "clicked", + GTK_SIGNAL_FUNC (trans_stop_button), transfer); + gtk_box_pack_start (GTK_BOX (vbox), stopwid, TRUE, TRUE, 0); + gtk_widget_show (stopwid); + + gtk_widget_show (dialog); + } + + g_snprintf (tempstr, sizeof (tempstr), + _("Received %ld directories\nand %ld files"), + transfer->numdirs, transfer->numfiles); + gtk_label_set_text (GTK_LABEL (textwid), tempstr); +} + + +void * +generic_thread (void * (*func) (void *), gftp_window_data * wdata) +{ + void * ret; + + if (wdata->request->use_threads) + { + wdata->request->stopable = 1; + gtk_widget_set_sensitive (stop_btn, 1); + pthread_create (&wdata->tid, NULL, func, wdata); + + while (wdata->request->stopable) + g_main_iteration (TRUE); + + pthread_join (wdata->tid, &ret); + gtk_widget_set_sensitive (stop_btn, 0); + } + else + ret = func (wdata); + + if (!GFTP_IS_CONNECTED (wdata->request)) + disconnect (wdata); + + return (ret); +} + + +int +progress_timeout (gpointer data) +{ + gftp_transfer * tdata; + double val; + + tdata = data; + + update_directory_download_progress (tdata); + + val = gtk_progress_get_value (GTK_PROGRESS (statuswid)); + if (val >= 1.0) + val = 0; + else + val += 0.10; + gtk_progress_bar_update (GTK_PROGRESS_BAR (statuswid), val); + + return (1); +} + + +static gint +delete_event (GtkWidget * widget, GdkEvent * event, gpointer data) +{ + return (TRUE); +} + + +static void +trans_stop_button (GtkWidget * widget, gpointer data) +{ + gftp_transfer * transfer; + + transfer = data; + pthread_kill (((gftp_window_data *) transfer->fromwdata)->tid, SIGINT); +} + +void +display_cached_logs (void) +{ + gftp_log * templog; + GList * templist; + + pthread_mutex_lock (&log_mutex); + templist = file_transfer_logs; + while (templist != NULL) + { + templog = (gftp_log *) templist->data; + ftp_log (templog->type, (void *) 0x2, "%s", templog->msg); + g_free (templog->msg); + g_free (templog); + templist->data = NULL; + templist = templist->next; + } + g_list_free (file_transfer_logs); + file_transfer_logs = NULL; + pthread_mutex_unlock (&log_mutex); +} + +#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR) + +static pthread_mutex_t netfunclock = PTHREAD_MUTEX_INITIALIZER; + +struct hostent * +r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop) +{ + struct hostent *hent; + + pthread_mutex_lock (&netfunclock); + if ((hent = gethostbyname (name)) == NULL) + { + if (h_errnop) + *h_errnop = h_errno; + } + else + { + *result_buf = *hent; + hent = result_buf; + } + pthread_mutex_unlock (&netfunclock); + return (hent); +} + + +struct servent * +r_getservbyname (const char *name, const char *proto, + struct servent *result_buf, int *h_errnop) +{ + struct servent *sent; + + pthread_mutex_lock (&netfunclock); + if ((sent = getservbyname (name, proto)) == NULL) + { + if (h_errnop) + *h_errnop = h_errno; + } + else + { + *result_buf = *sent; + sent = result_buf; + } + pthread_mutex_unlock (&netfunclock); + return (sent); +} + +#endif /* !HAVE_GETADDRINFO */ +