/* giFTui * Copyright (C) 2003 the giFTui team * * 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-1307, USA. */ #include "main.h" #include #include #include "io.h" #include "event.h" #include "configure.h" #include "util.h" #include "ui.h" #include "ui_connect.h" #include "ui_icon.h" #define ABOUT_REMOTE_TIMEOUT (10000) #define ABOUT_LOCAL_TIMEOUT (5000) /**/ typedef enum { ABOUT_PROTO = 0, ABOUT_USERS, ABOUT_FILES, ABOUT_SIZE, ABOUT_VERSION, ABOUT_ICON, ABOUT_STATUS, ABOUT_NUMBER } GiftuiAboutColumn_t; static gpointer parent_class = NULL; static void giftui_about_init (GiftuiAbout *about); static void giftui_about_class_init (GiftuiAboutClass *class); static void giftui_about_dispose (GObject *object); /**/ GType giftui_about_get_type (void) { static GType about_type = 0; if (!about_type) { static const GTypeInfo about_type_info = { sizeof (GiftuiAboutClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) giftui_about_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GiftuiAbout), 0, /* n_preallocs */ (GInstanceInitFunc) giftui_about_init, NULL }; about_type = g_type_register_static (GIFTUI_TYPE_CHILD, "GiftuiAbout", &about_type_info, 0); } return about_type; } static void giftui_about_class_init (GiftuiAboutClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); parent_class = g_type_class_peek_parent (class); object_class->dispose = giftui_about_dispose; return; } static void giftui_about_init (GiftuiAbout *about) { gint i; gchar *text; gchar *column_headers[] = { _("Protocol"), _("Users"), _("Files"), _("Size"),}; GtkWidget *vbox; GtkWidget *label; GtkWidget *frame, *scrolled; GtkTreeSelection *select; GtkTreeStore *store; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GiftuiChild *child; child = GIFTUI_CHILD (about); vbox = GTK_WIDGET (about); about->timeout = 0; child->type = GIFTUI_CHILD_ABOUT; g_object_set (G_OBJECT (about), "label", _("Status"), "stock", GTK_STOCK_HOME, NULL); text = g_strdup_printf ("%s version %s", PACKAGE, VERSION); label = gtk_label_new (text); g_free (text); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 5); /**/ frame = gtk_frame_new (_("Stats")); gtk_container_set_border_width (GTK_CONTAINER (frame), 5); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 5); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (frame), scrolled); store = gtk_tree_store_new (ABOUT_NUMBER, G_TYPE_STRING, /* proto */ G_TYPE_ULONG, /* users */ G_TYPE_ULONG, /* files */ G_TYPE_STRING, /* size */ G_TYPE_STRING, /* icon */ G_TYPE_STRING, /* version */ G_TYPE_UINT ); about->list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); /* refcount is 2 (1 for store variable, and 1 into the * gtktreeview widget). */ g_object_unref (store); gtk_container_add (GTK_CONTAINER (scrolled), about->list); /* create columns */ for (i = 0; i < ABOUT_ICON ; i++) { column = gtk_tree_view_column_new (); gtk_tree_view_column_set_title (column, column_headers[i]); switch (i) { case ABOUT_USERS: case ABOUT_SIZE: case ABOUT_FILES: renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "text", i, NULL); gtk_tree_view_column_set_sort_column_id (column, i); break; case ABOUT_PROTO: renderer = gtk_cell_renderer_pixbuf_new (); g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "stock-id", ABOUT_ICON, NULL); renderer = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_set_attributes (column, renderer, "text", i, NULL); break; } gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable (column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW (about->list), column); } select = gtk_tree_view_get_selection (GTK_TREE_VIEW (about->list)); gtk_tree_selection_set_mode (select, GTK_SELECTION_MULTIPLE); /**/ frame = gtk_frame_new (_("Messages")); gtk_container_set_border_width (GTK_CONTAINER (frame), 5); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 5); scrolled = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolled), GTK_CORNER_BOTTOM_RIGHT); gtk_container_add (GTK_CONTAINER (frame), scrolled); about->messages = gtk_text_view_new (); gtk_container_add (GTK_CONTAINER (scrolled), about->messages); gtk_text_view_set_editable (GTK_TEXT_VIEW (about->messages), FALSE); gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (about->messages), GTK_WRAP_WORD); return; } /**/ static gboolean _search_proto (GtkTreeModel *model, GtkTreeIter *iter, const gchar *proto) { gboolean ret; gchar *text; ret = gtk_tree_model_get_iter_first (model, iter); while (ret) { gtk_tree_model_get (model, iter, ABOUT_PROTO, &text, -1); if (text) { if (!strcasecmp (text, proto)) { g_free (text); return TRUE; } g_free (text); } ret = gtk_tree_model_iter_next (model, iter); } return FALSE; } static void giftui_about_update_proto_ (Interface *iface, InterfaceNode *inode, GiftuiAbout *ab) { GtkTreeStore *store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (ab->list))); if (!inode->value) return; if (!strcasecmp (inode->key, "users")) gtk_tree_store_set (store, &ab->iter, ABOUT_USERS, atol (inode->value), -1); else if (!strcasecmp (inode->key, "files")) gtk_tree_store_set (store, &ab->iter, ABOUT_FILES, atol (inode->value), -1); else if (!strcasecmp (inode->key, "size")) { gchar *hsize; if ((hsize = size_str_human_extra (inode->value))) { gtk_tree_store_set (store, &ab->iter, ABOUT_SIZE, hsize, -1); g_free (hsize); } } return; } static void giftui_about_update_proto (Interface *iface, InterfaceNode *inode, GiftuiAbout *ab) { gchar *local; GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (ab->list)); if (!inode->key) return; if (strcasecmp (inode->key, "giFT")) { GArray *array; local = inode->key; array = (GArray *) giftui_data_get (PREFS_SEARCH_NETWORKS); if (network_list_update (&array, local)) giftui_data_set_full (PREFS_SEARCH_NETWORKS, array, (GDestroyNotify) network_list_free); } else local = _("local files"); if (!_search_proto (model, &ab->iter, local)) { gtk_tree_store_append (GTK_TREE_STORE (model), &ab->iter, NULL); if (local == inode->key) { gchar *tmp; tmp = giftui_icon_case_stock (ICON_NETWORK, local); gtk_tree_store_set (GTK_TREE_STORE (model), &ab->iter, ABOUT_PROTO, local, ABOUT_ICON, tmp, -1); g_free (tmp); } else gtk_tree_store_set (GTK_TREE_STORE (model), &ab->iter, ABOUT_PROTO, local, ABOUT_ICON, GTK_STOCK_HOME, -1); } interface_foreach_ex (iface, inode, (InterfaceForeach) giftui_about_update_proto_, ab); return; } static void giftui_about_update (GiftuiAbout *ab, GiftuiEvent_t *in) { g_return_if_fail (ab != NULL); g_return_if_fail (in != NULL); interface_foreach (in->iface, NULL, (InterfaceForeach) giftui_about_update_proto, ab); return; } /**/ static gboolean giftui_about_stat_timeout (GiftuiAbout *ab) { if (gift_connected ()) gift_send_str ("STATS;"); return TRUE; } static void giftui_about_stat_timeout_stop (GiftuiAbout *ab) { if (!ab->timeout) return; g_source_remove (ab->timeout); giftui_event_unregister (ab, EVENT_STATS, 0); ab->timeout = 0; return; } static void giftui_about_stat_timeout_start (GiftuiAbout *ab) { if (ab->timeout) giftui_about_stat_timeout_stop (ab); giftui_event_register (EVENT_STATS, 0, ab, GIFTUI_REGISTRED_CB (giftui_about_update)); giftui_about_stat_timeout (ab); ab->timeout = g_timeout_add (ABOUT_REMOTE_TIMEOUT, (GSourceFunc) giftui_about_stat_timeout, ab); return; } static void giftui_about_message (GiftuiAbout *ab, GiftuiEvent_t *in) { GtkTextBuffer *buf; GtkTextIter iter; gchar *text; text = str_convert_to_utf8 (in->iface->value); buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ab->messages)); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buf), &iter); gtk_text_buffer_insert (GTK_TEXT_BUFFER (buf), &iter, text, -1); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buf), &iter); gtk_text_buffer_insert (GTK_TEXT_BUFFER (buf), &iter, "\n", -1); g_free (text); /*if (gtk_text_view_forward_display_line_end (GTK_TEXT_VIEW (ab->messages), &iter)) gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (ab->messages), &iter, 0, FALSE, 0, 0);*/ return; } /**/ static void giftui_about_attach (GiftuiAbout *ab, GiftuiEvent_t *in) { GtkTextBuffer *buf; GtkTextIter iter; gchar *tmp; /* This display a little message showing giFtui is connected. */ tmp = g_strdup_printf (_("Connected on %s:%i running %s version %s"), giftui_config_get_str (PREFS_DAEMON_HOST), giftui_config_get_int (PREFS_DAEMON_PORT), interface_get (in->iface, "server"), interface_get (in->iface, "version")); /*text = str_convert_to_utf8 (tmp);*/ buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (ab->messages)); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buf), &iter); gtk_text_buffer_insert (GTK_TEXT_BUFFER (buf), &iter, tmp, -1); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buf), &iter); gtk_text_buffer_insert (GTK_TEXT_BUFFER (buf), &iter, "\n", -1); g_free (tmp); /*g_free (text);*/ /* Start timeout for STATS. */ giftui_about_stat_timeout_start (ab); return; } static void giftui_about_disconnect (GiftuiAbout *ab, GiftuiEvent_t *in) { GtkTreeStore *st; g_return_if_fail (ab != NULL); /* Stop timeout first. */ giftui_about_stat_timeout_stop (ab); /* Remove stats. */ st = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (ab->list))); gtk_tree_store_clear (st); /* Display disconnection error. */ giftui_about_message (ab, in); /* Run the reconnect window. */ if (in->type == EVENT_DISCONNECT) giftui_connect_create (GTK_STOCK_STOP, _("Disconnected from the giFT daemon. Would you like to try to reconnect ?"), giftui_config_get_str (PREFS_DAEMON_HOST), giftui_config_get_int (PREFS_DAEMON_PORT), giftui_config_get_bool (PREFS_DAEMON_LAUNCH)); return; } GtkWidget * giftui_about_new (void) { GiftuiAbout *about; about = g_object_new (GIFTUI_TYPE_ABOUT, "close", FALSE, NULL); giftui_event_register (EVENT_ATTACH, 0, about, GIFTUI_REGISTRED_CB (giftui_about_attach)); giftui_event_register (EVENT_MESSAGE, 0, about, GIFTUI_REGISTRED_CB (giftui_about_message)); giftui_event_register (EVENT_DISCONNECT, 0, about, GIFTUI_REGISTRED_CB (giftui_about_disconnect)); giftui_event_register (EVENT_CLOSE, 0, about, GIFTUI_REGISTRED_CB (giftui_about_disconnect)); gtk_widget_show_all (GTK_WIDGET (about)); return GTK_WIDGET (about); } static void giftui_about_dispose (GObject *object) { GiftuiAbout *ab = GIFTUI_ABOUT (object); giftui_about_stat_timeout_stop (ab); giftui_event_unregister_all (ab); G_OBJECT_CLASS (parent_class)->dispose (object); return; }