Logo Search packages:      
Sourcecode: xchat version File versions

dccgui.c

/* X-Chat
 * Copyright (C) 1998 Peter Zelezny.
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

#define WANTSOCKET
#define WANTARPA
#include "../common/inet.h"
#include "fe-gtk.h"

#include <gtk/gtkclist.h>
#include <gtk/gtkhbbox.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtkstock.h>

#include "../common/xchat.h"
#include "../common/xchatc.h"
#include "../common/fe.h"
#include "../common/util.h"
#include "../common/network.h"
#include "gtkutil.h"
#include "palette.h"
#include "maingui.h"

#ifdef USE_GNOME
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#endif

/*** UNIT PATCH ***/

#define KILOBYTE 1024
#define MEGABYTE (KILOBYTE * 1024)
#define GIGABYTE (MEGABYTE * 1024)

static void proper_unit (unsigned int size, char *buf, int buf_len)
{
      if (size <= KILOBYTE)
      {
            snprintf (buf, buf_len, "%uB", size);
      }
      else if (size > KILOBYTE && size <= MEGABYTE)
      {
            snprintf (buf, buf_len, "%ukB", size / KILOBYTE);
      }
      else
      {
            snprintf (buf, buf_len, "%.2fMB", (float)size / MEGABYTE);
      }
}

/*** UNIT PATCH ***/

struct dccwindow
{
      GtkWidget *window;
      GtkWidget *list;
};

struct my_dcc_send
{
      struct session *sess;
      char *nick;
      int maxcps;
};

static struct dccwindow dccrwin;    /* recv */
static struct dccwindow dccswin;    /* send */
static struct dccwindow dcccwin;    /* chat */


static void
dcc_send_filereq_file (struct my_dcc_send *mdc, char *file)
{
      if (file)
            dcc_send (mdc->sess, mdc->nick, file, mdc->maxcps, 0);
      else
      {
            free (mdc->nick);
            free (mdc);
      }
}

static void
dcc_psend_filereq_file (struct my_dcc_send *mdc, char *file)
{
      if (file)
            dcc_send (mdc->sess, mdc->nick, file, mdc->maxcps, 1);
      else
      {
            free (mdc->nick);
            free (mdc);
      }
}

void
fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive)
{
      char tbuf[128];
      struct my_dcc_send *mdc;
      
      mdc = malloc (sizeof (*mdc));
      mdc->sess = sess;
      mdc->nick = strdup (nick);
      mdc->maxcps = maxcps;

      snprintf (tbuf, sizeof tbuf, _("Send file to %s"), nick);
      if (passive)
            gtkutil_file_req (tbuf, dcc_psend_filereq_file, mdc, NULL, FRF_MULTIPLE);
      else
            gtkutil_file_req (tbuf, dcc_send_filereq_file, mdc, NULL, FRF_MULTIPLE);
}

static void
dcc_prepare_row_chat (struct DCC *dcc, char *col[])
{
      static char pos[16], siz[16];

      col[0] = _(dccstat[dcc->dccstat].name);
      col[1] = dcc->nick;
      col[2] = pos;
      col[3] = siz;
      col[4] = ctime (&dcc->starttime);
      col[4][strlen (col[4]) - 1] = 0;    /* remove the \n */

      proper_unit (dcc->pos, pos, sizeof (pos));
      proper_unit (dcc->size, siz, sizeof (siz));
}

static void
dcc_prepare_row_send (struct DCC *dcc, char *col[])
{
      static char pos[16], size[16], kbs[14], ack[16], perc[14], eta[14];
      int to_go;
      float per;

      col[0] = _(dccstat[dcc->dccstat].name);
      col[1] = file_part (dcc->file);
      col[2] = size;
      col[3] = pos;
      col[4] = ack;
      col[5] = perc;
      col[6] = kbs;
      col[7] = eta;
      col[8] = dcc->nick;

      /* percentage ack'ed */
      per = (float) ((dcc->ack * 100.00) / dcc->size);
      proper_unit (dcc->size, size, sizeof (size));
      proper_unit (dcc->pos, pos, sizeof (pos));
      snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
      proper_unit (dcc->ack, ack, sizeof (ack));
      snprintf (perc, sizeof (perc), "%.0f%%", per);
      if (dcc->cps != 0)
      {
            to_go = (dcc->size - dcc->ack) / dcc->cps;
            snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
                               to_go / 3600, (to_go / 60) % 60, to_go % 60);
      } else
            strcpy (eta, "--:--:--");
}

static void
dcc_prepare_row_recv (struct DCC *dcc, char *col[])
{
      static char size[16], pos[16], kbs[16], perc[14], eta[16];
      float per;
      int to_go;

      col[0] = _(dccstat[dcc->dccstat].name);
      col[1] = dcc->file;
      col[2] = size;
      col[3] = pos;
      col[4] = perc;
      col[5] = kbs;
      col[6] = eta;
      col[7] = dcc->nick;
#ifdef USE_GNOME
      if (dcc->dccstat == STAT_DONE)
            col[8] = (char *) gnome_vfs_get_mime_type (dcc->destfile);
      else
            col[8] = "";
#endif
      proper_unit (dcc->size, size, sizeof (size));
      if (dcc->dccstat == STAT_QUEUED)
            proper_unit (dcc->resumable, pos, sizeof (pos));
      else
            proper_unit (dcc->pos, pos, sizeof (pos));
      snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
      /* percentage recv'ed */
      per = (float) ((dcc->pos * 100.00) / dcc->size);
      snprintf (perc, sizeof (perc), "%.0f%%", per);
      if (dcc->cps != 0)
      {
            to_go = (dcc->size - dcc->pos) / dcc->cps;
            snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
                               to_go / 3600, (to_go / 60) % 60, to_go % 60);
      } else
            strcpy (eta, "--:--:--");
}

static void
dcc_update_recv (struct DCC *dcc)
{
      gint row;
      char *col[9];

      if (!dccrwin.window)
            return;

      row = gtk_clist_find_row_from_data (GTK_CLIST (dccrwin.list), dcc);

      dcc_prepare_row_recv (dcc, col);

      gtk_clist_freeze (GTK_CLIST (dccrwin.list));
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 0, col[0]);
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 3, col[3]);
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 4, col[4]);
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 5, col[5]);
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 6, col[6]);
#ifdef USE_GNOME
      gtk_clist_set_text (GTK_CLIST (dccrwin.list), row, 8, col[8]);
#endif

      if (dccstat[dcc->dccstat].color != 1)
            gtk_clist_set_foreground (GTK_CLIST (dccrwin.list), row,
                                                              colors + dccstat[dcc->dccstat].color);

      gtk_clist_thaw (GTK_CLIST (dccrwin.list));
}

static void
dcc_update_chat (struct DCC *dcc)
{
      gint row;
      char *col[5];

      if (!dcccwin.window)
            return;

      row = gtk_clist_find_row_from_data (GTK_CLIST (dcccwin.list), dcc);

      dcc_prepare_row_chat (dcc, col);

      gtk_clist_freeze (GTK_CLIST (dcccwin.list));
      gtk_clist_set_text (GTK_CLIST (dcccwin.list), row, 0, col[0]);
      gtk_clist_set_text (GTK_CLIST (dcccwin.list), row, 2, col[2]);
      gtk_clist_set_text (GTK_CLIST (dcccwin.list), row, 3, col[3]);
      gtk_clist_thaw (GTK_CLIST (dcccwin.list));
}

static void
dcc_update_send (struct DCC *dcc)
{
      gint row;
      char *col[9];

      if (!dccswin.window)
            return;

      row = gtk_clist_find_row_from_data (GTK_CLIST (dccswin.list), dcc);

      dcc_prepare_row_send (dcc, col);

      gtk_clist_freeze (GTK_CLIST (dccswin.list));
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 0,
                                            _(dccstat[dcc->dccstat].name));
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 3, col[3]);
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 4, col[4]);
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 5, col[5]);
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 6, col[6]);
      gtk_clist_set_text (GTK_CLIST (dccswin.list), row, 7, col[7]);

      if (dccstat[dcc->dccstat].color != 1)
            gtk_clist_set_foreground (GTK_CLIST (dccswin.list), row,
                               colors + dccstat[dcc->dccstat].color);

      gtk_clist_thaw (GTK_CLIST (dccswin.list));
}

static void
close_dcc_recv_window (void)
{
      dccrwin.window = 0;
}

static void
dcc_update_recv_win (void)
{
      struct DCC *dcc;
      GSList *list = dcc_list;
      gchar *nnew[9];
      gint row;
      int i = 0;

      gtk_clist_freeze (GTK_CLIST (dccrwin.list));
      gtk_clist_clear (GTK_CLIST (dccrwin.list));
      while (list)
      {
            dcc = list->data;
            if (dcc->type == TYPE_RECV)
            {
                  dcc_prepare_row_recv (dcc, nnew);

                  row = gtk_clist_append (GTK_CLIST (dccrwin.list), nnew);
                  gtk_clist_set_row_data (GTK_CLIST (dccrwin.list), row, dcc);
                  if (dccstat[dcc->dccstat].color != 1)
                        gtk_clist_set_foreground (GTK_CLIST (dccrwin.list), row,
                                                                          colors +
                                                                          dccstat[dcc->dccstat].color);
                  i++;
            }
            list = list->next;
      }

      /* if only one entry, select it (so Accept button can work) */
      if (i == 1)
            gtk_clist_select_row (GTK_CLIST (dccrwin.list), 0, 0);

      gtk_clist_thaw (GTK_CLIST (dccrwin.list));
}

static void
dcc_info (struct DCC *dcc)
{
      char tbuf[256];
      snprintf (tbuf, 255, _("      File: %s\n"
                         "   To/From: %s\n"
                         "      Size: %u\n"
                         "      Port: %d\n"
                         " IP Number: %s\n"
                         "Start Time: %s"
                         "   Max CPS: %d\n"),
                         dcc->file,
                         dcc->nick,
                         dcc->size,
                         dcc->port,
                         net_ip (dcc->addr), ctime (&dcc->starttime),
                         dcc->maxcps);
      gtkutil_simpledialog (tbuf);
}

static void
resume_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;
      char buf[512];

      row = gtkutil_clist_selection (dccrwin.list);
      if (row != -1)
      {
            gtk_clist_unselect_row (GTK_CLIST (dccrwin.list), row, 0);
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccrwin.list), row);
            if (!dcc_resume (dcc))
            {
                  switch (dcc->resume_error)
                  {
                  case 0:     /* unknown error */
                        gtkutil_simpledialog (_("That file is not resumable."));
                        break;
                  case 1:
                        snprintf (buf, sizeof (buf),
                                          _(    "Cannot access file: %s\n"
                                                "%s.\n"
                                                "Resuming not possible."), dcc->destfile, 
                                                errorstring (dcc->resume_errno));
                        gtkutil_simpledialog (buf);
                        break;
                  case 2:
                        gtkutil_simpledialog (_("File in download directory is larger "
                                                                  "than file offered. Resuming not possible."));
                        break;
                  case 3:
                        gtkutil_simpledialog (_("Cannot resume the same file from two people."));
                  }
            }
      }
}

static void
abort_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccrwin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccrwin.list), row);
            dcc_abort (dcc->serv->front_session, dcc);
      }
}

static void
accept_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccrwin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccrwin.list), row);
            gtk_clist_unselect_row (GTK_CLIST (dccrwin.list), row, 0);
            dcc_get (dcc);
      }
}

static void
info_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccrwin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccrwin.list), row);
            if (dcc)
                  dcc_info (dcc);
      }
}

#ifdef USE_GNOME

static void
open_clicked (void)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccrwin.list);
      if (row == -1)
            return;

      dcc = gtk_clist_get_row_data (GTK_CLIST (dccrwin.list), row);
      if (dcc || dcc->dccstat == STAT_DONE)
            return;

      /* do something with dcc->destfile */
}

#endif

static void
recv_row_selected (GtkWidget * clist, gint row, gint column,
                                     GdkEventButton * even)
{
      if (even && even->type == GDK_2BUTTON_PRESS)
            accept_clicked (0, 0);
}

int
fe_dcc_open_recv_win (int passive)
{
      GtkWidget *vbox, *bbox;
#ifdef USE_GNOME
      gchar *titles[] =
            { NULL, NULL, NULL, NULL, "%", "KB/s", NULL, NULL, NULL };

      titles[8] = _("MIME Type");
#else
      gchar *titles[] =
            { NULL, NULL, NULL, NULL, "%", "KB/s", NULL, NULL };
#endif

      titles[0] = _("Status");
      titles[1] = _("File");
      titles[2] = _("Size");
      titles[3] = _("Position");
      titles[6] = _("ETA");
      titles[7] = _("From");

      if (dccrwin.window)
      {
            if (!passive)
                  mg_bring_tofront (dccrwin.window);
            return TRUE;
      }
      dccrwin.window =
                    mg_create_generic_tab ("dccrecv", _("X-Chat: File Receive List"),
                                    FALSE, TRUE, close_dcc_recv_window, NULL, 601, 200, &vbox, 0);

#ifdef USE_GNOME
      dccrwin.list = gtkutil_clist_new (9, titles, vbox, GTK_POLICY_ALWAYS,
                                                                         recv_row_selected, 0,
                                                                         0, 0, GTK_SELECTION_SINGLE);
#else
      dccrwin.list = gtkutil_clist_new (8, titles, vbox, GTK_POLICY_ALWAYS,
                                                                         recv_row_selected, 0,
                                                                         0, 0, GTK_SELECTION_SINGLE);
#endif
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 0, 65);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 1, 100);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 2, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 3, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 4, 30);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 5, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 6, 60);
      gtk_clist_set_column_width (GTK_CLIST (dccrwin.list), 7, 60);
      gtk_clist_set_column_justification (GTK_CLIST (dccrwin.list), 4,
                                                                              GTK_JUSTIFY_CENTER);

      bbox = gtk_hbutton_box_new ();
      gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
      gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
      gtk_widget_show (bbox);

      gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_clicked, 0, _("Abort"));

      gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_clicked, 0, _("Accept"));

      gtkutil_button (bbox, GTK_STOCK_REFRESH, 0, resume_clicked, 0, _("Resume"));

      gtkutil_button (bbox, GTK_STOCK_DIALOG_INFO, 0, info_clicked, 0, _("Info"));
#ifdef USE_GNOME
      gtkutil_button (bbox, GTK_STOCK_OPEN, 0, open_clicked, 0, _("Open"));
#endif
      gtk_widget_show (dccrwin.window);
      dcc_update_recv_win ();

      return FALSE;
}

static void
close_dcc_send_window (void)
{
      dccswin.window = 0;
}

static void
dcc_update_send_win (void)
{
      struct DCC *dcc;
      GSList *list = dcc_list;
      gchar *nnew[9];
      gint row;
      int i = 0;

      gtk_clist_freeze (GTK_CLIST (dccswin.list));
      gtk_clist_clear ((GtkCList *) dccswin.list);
      while (list)
      {
            dcc = list->data;
            if (dcc->type == TYPE_SEND)
            {
                  dcc_prepare_row_send (dcc, nnew);
                  row = gtk_clist_append (GTK_CLIST (dccswin.list), nnew);
                  gtk_clist_set_row_data (GTK_CLIST (dccswin.list), row, dcc);
                  if (dccstat[dcc->dccstat].color != 1)
                        gtk_clist_set_foreground
                              (GTK_CLIST (dccswin.list), row,
                               colors + dccstat[dcc->dccstat].color);
                  i++;
            }
            list = list->next;
      }

      /* if only one entry, select it (so Abort button can work) */
      if (i == 1)
            gtk_clist_select_row (GTK_CLIST (dccswin.list), 0, 0);

      gtk_clist_thaw (GTK_CLIST (dccswin.list));
}

static void
send_row_selected (GtkWidget * clist, gint row, gint column,
                                     GdkEventButton * even)
{
      struct DCC *dcc;

      if (even && even->type == GDK_2BUTTON_PRESS)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (clist), row);
            if (dcc)
            {
                  switch (dcc->dccstat)
                  {
                  case STAT_FAILED:
                  case STAT_ABORTED:
                  case STAT_DONE:
                        dcc_abort (dcc->serv->front_session, dcc);
                  }
            }
      }
}

static void
info_send_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccswin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccswin.list), row);
            if (dcc)
                  dcc_info (dcc);
      }
}

static void
abort_send_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dccswin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dccswin.list), row);
            dcc_abort (dcc->serv->front_session, dcc);
      }
}

int
fe_dcc_open_send_win (int passive)
{
      GtkWidget *vbox, *bbox;
      gchar *titles[] =
            { NULL, NULL, NULL, NULL, NULL, "%", "KB/s", NULL, NULL };

      titles[0] = _("Status");
      titles[1] = _("File");
      titles[2] = _("Size");
      titles[3] = _("Position");
      titles[4] = _("Ack");
      titles[7] = _("ETA");
      titles[8] = _("To");

      if (dccswin.window)
      {
            if (!passive)
                  mg_bring_tofront (dccswin.window);
            return TRUE;
      }

      dccswin.window =
                    mg_create_generic_tab ("dccsend", _("X-Chat: File Send List"),
                                    FALSE, TRUE, close_dcc_send_window, NULL, 595, 200, &vbox, 0);

      dccswin.list = gtkutil_clist_new (9, titles, vbox, GTK_POLICY_ALWAYS,
                                                                         send_row_selected, 0,
                                                                         0, 0, GTK_SELECTION_SINGLE);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 0, 65);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 1, 100);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 2, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 3, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 4, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 5, 30);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 6, 50);
      gtk_clist_set_column_width (GTK_CLIST (dccswin.list), 7, 50);
      gtk_clist_set_column_justification (GTK_CLIST (dccswin.list), 5,
                                                                              GTK_JUSTIFY_CENTER);

      bbox = gtk_hbutton_box_new ();
      gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
      gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
      gtk_widget_show (bbox);

      gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_send_clicked, 0, _("Abort"));
      gtkutil_button (bbox, GTK_STOCK_DIALOG_INFO, 0, info_send_clicked, 0, _("Info"));

      gtk_widget_show (dccswin.window);
      dcc_update_send_win ();

      return FALSE;
}


/* DCC CHAT GUIs BELOW */

static void
accept_chat_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dcccwin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dcccwin.list), row);
            gtk_clist_unselect_row (GTK_CLIST (dcccwin.list), row, 0);
            dcc_get (dcc);
      }
}

static void
abort_chat_clicked (GtkWidget * wid, gpointer none)
{
      int row;
      struct DCC *dcc;

      row = gtkutil_clist_selection (dcccwin.list);
      if (row != -1)
      {
            dcc = gtk_clist_get_row_data (GTK_CLIST (dcccwin.list), row);
            dcc_abort (dcc->serv->front_session, dcc);
      }
}

static void
chat_row_selected (GtkWidget * clist, gint row, gint column,
                                     GdkEventButton * even)
{
      if (even && even->type == GDK_2BUTTON_PRESS)
            accept_chat_clicked (0, 0);
}

static void
close_dcc_chat_window (void)
{
      dcccwin.window = 0;
}

static void
dcc_update_chat_win (void)
{
      struct DCC *dcc;
      GSList *list = dcc_list;
      gchar *col[5];
      gint row;

      gtk_clist_freeze (GTK_CLIST (dcccwin.list));
      gtk_clist_clear ((GtkCList *) dcccwin.list);
      while (list)
      {
            dcc = list->data;
            if ((dcc->type == TYPE_CHATSEND || dcc->type == TYPE_CHATRECV))
            {
                  dcc_prepare_row_chat (dcc, col);
                  row = gtk_clist_append (GTK_CLIST (dcccwin.list), col);
                  gtk_clist_set_row_data (GTK_CLIST (dcccwin.list), row, dcc);
            }
            list = list->next;
      }
      gtk_clist_thaw (GTK_CLIST (dcccwin.list));
}

int
fe_dcc_open_chat_win (int passive)
{
      GtkWidget *vbox, *bbox;
      gchar *titles[5];

      titles[0] = _("Status");
      titles[1] = _("To/From");
      titles[2] = _("Recv");
      titles[3] = _("Sent");
      titles[4] = _("StartTime");

      if (dcccwin.window)
      {
            if (!passive)
                  mg_bring_tofront (dcccwin.window);
            return TRUE;
      }

      dcccwin.window =
                    mg_create_generic_tab ("dccchat", _("X-Chat: DCC Chat List"),
                                    FALSE, TRUE, close_dcc_chat_window, NULL, 550, 180, &vbox, 0);

      dcccwin.list = gtkutil_clist_new (5, titles, vbox, GTK_POLICY_ALWAYS,
                                                                         chat_row_selected, 0,
                                                                         0, 0, GTK_SELECTION_BROWSE);
      gtk_clist_set_column_width (GTK_CLIST (dcccwin.list), 0, 65);
      gtk_clist_set_column_width (GTK_CLIST (dcccwin.list), 1, 100);
      gtk_clist_set_column_width (GTK_CLIST (dcccwin.list), 2, 65);
      gtk_clist_set_column_width (GTK_CLIST (dcccwin.list), 3, 65);

      bbox = gtk_hbutton_box_new ();
      gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
      gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
      gtk_widget_show (bbox);

      gtkutil_button (bbox, GTK_STOCK_CANCEL, 0, abort_chat_clicked, 0, _("Abort"));
      gtkutil_button (bbox, GTK_STOCK_APPLY, 0, accept_chat_clicked, 0, _("Accept"));

      gtk_widget_show (dcccwin.window);
      dcc_update_chat_win ();

      return FALSE;
}

void
fe_dcc_add (struct DCC *dcc)
{
      int row;
      char *col[9];

      switch (dcc->type)
      {
      case TYPE_RECV:
            if (!dccrwin.window)
                  return;
            dcc_prepare_row_recv (dcc, col);
            row = gtk_clist_prepend (GTK_CLIST (dccrwin.list), col);
            gtk_clist_set_row_data (GTK_CLIST (dccrwin.list), row, dcc);
            if (dccstat[dcc->dccstat].color != 1)
                  gtk_clist_set_foreground (GTK_CLIST (dccrwin.list), row,
                                                                    colors + dccstat[dcc->dccstat].color);
            break;

      case TYPE_SEND:
            if (!dccswin.window)
                  return;
            dcc_prepare_row_send (dcc, col);
            row = gtk_clist_prepend (GTK_CLIST (dccswin.list), col);
            gtk_clist_set_row_data (GTK_CLIST (dccswin.list), row, dcc);
            if (dccstat[dcc->dccstat].color != 1)
                  gtk_clist_set_foreground (GTK_CLIST (dccswin.list), row,
                                                                    colors + dccstat[dcc->dccstat].color);
            break;

      default: /* chat */
            if (!dcccwin.window)
                  return;
            dcc_prepare_row_chat (dcc, col);
            row = gtk_clist_prepend (GTK_CLIST (dcccwin.list), col);
            gtk_clist_set_row_data (GTK_CLIST (dcccwin.list), row, dcc);
      }
}

void
fe_dcc_update (struct DCC *dcc)
{
      switch (dcc->type)
      {
      case TYPE_SEND:
            dcc_update_send (dcc);
            break;

      case TYPE_RECV:
            dcc_update_recv (dcc);
            break;

      default:
            dcc_update_chat (dcc);
      }
}

void
fe_dcc_remove (struct DCC *dcc)
{
      GtkCList *list = NULL;
      int row;

      switch (dcc->type)
      {
      case TYPE_SEND:
            if (dccswin.window)
                  list = GTK_CLIST (dccswin.list);
            break;

      case TYPE_RECV:
            if (dccrwin.window)
                  list = GTK_CLIST (dccrwin.list);
            break;

      default:    /* chat */
            if (dcccwin.window)
                  list = GTK_CLIST (dcccwin.list);
            break;
      }

      if (list)
      {
            row = gtk_clist_find_row_from_data (list, dcc);
            if (row != -1)
                  gtk_clist_remove (list, row);
      }
}

Generated by  Doxygen 1.6.0   Back to index