2011-02-24 04:14:30 +01:00
|
|
|
/* X-Chat
|
|
|
|
|
* Copyright (C) 1998-2006 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
|
2012-12-23 11:36:54 -08:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2011-02-24 04:14:30 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#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"
|
|
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
#include "../common/zoitechat.h"
|
|
|
|
|
#include "../common/zoitechatc.h"
|
2011-02-24 04:14:30 +01:00
|
|
|
#include "../common/fe.h"
|
|
|
|
|
#include "../common/util.h"
|
|
|
|
|
#include "../common/network.h"
|
|
|
|
|
#include "gtkutil.h"
|
|
|
|
|
#include "palette.h"
|
|
|
|
|
#include "maingui.h"
|
|
|
|
|
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
#define ICON_DCC_CANCEL "dialog-cancel"
|
|
|
|
|
#define ICON_DCC_ACCEPT "dialog-apply"
|
|
|
|
|
#define ICON_DCC_RESUME "view-refresh"
|
|
|
|
|
#define ICON_DCC_CLEAR "edit-clear"
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
enum /* DCC SEND/RECV */
|
|
|
|
|
{
|
|
|
|
|
COL_TYPE,
|
|
|
|
|
COL_STATUS,
|
|
|
|
|
COL_FILE,
|
|
|
|
|
COL_SIZE,
|
|
|
|
|
COL_POS,
|
|
|
|
|
COL_PERC,
|
|
|
|
|
COL_SPEED,
|
|
|
|
|
COL_ETA,
|
|
|
|
|
COL_NICK,
|
|
|
|
|
COL_DCC, /* struct DCC * */
|
2026-01-19 22:50:17 -07:00
|
|
|
COL_COLOR, /* PaletteColor */
|
2011-02-24 04:14:30 +01:00
|
|
|
N_COLUMNS
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
enum /* DCC CHAT */
|
|
|
|
|
{
|
|
|
|
|
CCOL_STATUS,
|
|
|
|
|
CCOL_NICK,
|
|
|
|
|
CCOL_RECV,
|
|
|
|
|
CCOL_SENT,
|
|
|
|
|
CCOL_START,
|
|
|
|
|
CCOL_DCC, /* struct DCC * */
|
2026-01-19 22:50:17 -07:00
|
|
|
CCOL_COLOR, /* PaletteColor * */
|
2011-02-24 04:14:30 +01:00
|
|
|
CN_COLUMNS
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct dccwindow
|
|
|
|
|
{
|
|
|
|
|
GtkWidget *window;
|
|
|
|
|
|
|
|
|
|
GtkWidget *list;
|
|
|
|
|
GtkListStore *store;
|
|
|
|
|
GtkTreeSelection *sel;
|
|
|
|
|
|
|
|
|
|
GtkWidget *abort_button;
|
|
|
|
|
GtkWidget *accept_button;
|
|
|
|
|
GtkWidget *resume_button;
|
|
|
|
|
GtkWidget *open_button;
|
2013-07-10 18:29:10 +01:00
|
|
|
GtkWidget *clear_button; /* clears aborted and completed requests */
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
GtkWidget *file_label;
|
|
|
|
|
GtkWidget *address_label;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct my_dcc_send
|
|
|
|
|
{
|
|
|
|
|
struct session *sess;
|
|
|
|
|
char *nick;
|
2014-12-06 14:02:45 -08:00
|
|
|
gint64 maxcps;
|
2011-02-24 04:14:30 +01:00
|
|
|
int passive;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct dccwindow dccfwin = {NULL, }; /* file */
|
|
|
|
|
static struct dccwindow dcccwin = {NULL, }; /* chat */
|
|
|
|
|
static GdkPixbuf *pix_up = NULL; /* down arrow */
|
|
|
|
|
static GdkPixbuf *pix_dn = NULL; /* up arrow */
|
|
|
|
|
static int win_width = 600;
|
|
|
|
|
static int win_height = 256;
|
|
|
|
|
static short view_mode; /* 1=download 2=upload 3=both */
|
|
|
|
|
#define VIEW_DOWNLOAD 1
|
|
|
|
|
#define VIEW_UPLOAD 2
|
|
|
|
|
#define VIEW_BOTH 3
|
|
|
|
|
|
2026-01-30 18:09:31 -07:00
|
|
|
static GdkPixbuf *
|
|
|
|
|
dcc_load_icon (const char *stock_name)
|
|
|
|
|
{
|
|
|
|
|
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
|
|
|
|
const char *icon_name = gtkutil_icon_name_from_stock (stock_name);
|
|
|
|
|
int width = 16;
|
|
|
|
|
int height = 16;
|
|
|
|
|
|
|
|
|
|
if (g_strcmp0 (stock_name, "gtk-go-up") == 0)
|
|
|
|
|
icon_name = "go-up";
|
|
|
|
|
else if (g_strcmp0 (stock_name, "gtk-go-down") == 0)
|
|
|
|
|
icon_name = "go-down";
|
|
|
|
|
|
|
|
|
|
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
|
|
|
|
|
|
|
|
|
|
return gtk_icon_theme_load_icon (theme, icon_name, width, 0, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
static void
|
2014-12-06 14:02:45 -08:00
|
|
|
proper_unit (guint64 size, char *buf, size_t buf_len)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2014-05-03 23:57:45 -04:00
|
|
|
gchar *formatted_str;
|
|
|
|
|
GFormatSizeFlags format_flags = G_FORMAT_SIZE_DEFAULT;
|
2014-04-15 04:05:18 -04:00
|
|
|
|
2014-05-03 23:57:45 -04:00
|
|
|
#ifndef __APPLE__ /* OS X uses SI */
|
|
|
|
|
#ifndef WIN32 /* Windows uses IEC size (with SI format) */
|
|
|
|
|
if (prefs.hex_gui_filesize_iec) /* Linux can't decide... */
|
|
|
|
|
#endif
|
|
|
|
|
format_flags = G_FORMAT_SIZE_IEC_UNITS;
|
|
|
|
|
#endif
|
2014-04-15 04:05:18 -04:00
|
|
|
|
2014-12-06 14:02:45 -08:00
|
|
|
formatted_str = g_format_size_full (size, format_flags);
|
2014-05-03 23:57:45 -04:00
|
|
|
g_strlcpy (buf, formatted_str, buf_len);
|
|
|
|
|
|
|
|
|
|
g_free (formatted_str);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_send_filereq_file (struct my_dcc_send *mdc, char *file)
|
|
|
|
|
{
|
|
|
|
|
if (file)
|
|
|
|
|
dcc_send (mdc->sess, mdc->nick, file, mdc->maxcps, mdc->passive);
|
|
|
|
|
else
|
|
|
|
|
{
|
2014-12-28 06:37:25 -05:00
|
|
|
g_free (mdc->nick);
|
|
|
|
|
g_free (mdc);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive)
|
|
|
|
|
{
|
2014-12-28 06:37:25 -05:00
|
|
|
char* tbuf = g_strdup_printf (_("Send file to %s"), nick);
|
|
|
|
|
|
|
|
|
|
struct my_dcc_send *mdc = g_new (struct my_dcc_send, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
mdc->sess = sess;
|
2014-12-28 06:37:25 -05:00
|
|
|
mdc->nick = g_strdup (nick);
|
2011-02-24 04:14:30 +01:00
|
|
|
mdc->maxcps = maxcps;
|
|
|
|
|
mdc->passive = passive;
|
|
|
|
|
|
2022-04-16 18:41:34 -05:00
|
|
|
gtkutil_file_req (NULL, tbuf, dcc_send_filereq_file, mdc, prefs.hex_dcc_dir, NULL, FRF_MULTIPLE|FRF_FILTERISINITIAL);
|
2014-12-28 06:37:25 -05:00
|
|
|
|
|
|
|
|
g_free (tbuf);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-20 12:26:01 -07:00
|
|
|
static void
|
|
|
|
|
dcc_store_color (GtkListStore *store, GtkTreeIter *iter, int column, int color_index)
|
|
|
|
|
{
|
|
|
|
|
const PaletteColor *color = NULL;
|
|
|
|
|
|
|
|
|
|
if (color_index != 1)
|
|
|
|
|
color = &colors[color_index];
|
|
|
|
|
|
2026-01-22 22:03:31 -07:00
|
|
|
if (color)
|
|
|
|
|
{
|
|
|
|
|
GdkRGBA rgba = *color;
|
|
|
|
|
gtk_list_store_set (store, iter, column, &rgba, -1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_list_store_set (store, iter, column, NULL, -1);
|
|
|
|
|
}
|
2026-01-20 12:26:01 -07:00
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
|
|
|
|
|
gboolean update_only)
|
|
|
|
|
{
|
2014-12-06 14:02:45 -08:00
|
|
|
static char pos[16], size[16];
|
2011-02-24 04:14:30 +01:00
|
|
|
char *date;
|
|
|
|
|
|
|
|
|
|
date = ctime (&dcc->starttime);
|
|
|
|
|
date[strlen (date) - 1] = 0; /* remove the \n */
|
|
|
|
|
|
|
|
|
|
proper_unit (dcc->pos, pos, sizeof (pos));
|
2014-12-06 14:02:45 -08:00
|
|
|
proper_unit (dcc->size, size, sizeof (size));
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
gtk_list_store_set (store, iter,
|
|
|
|
|
CCOL_STATUS, _(dccstat[dcc->dccstat].name),
|
|
|
|
|
CCOL_NICK, dcc->nick,
|
|
|
|
|
CCOL_RECV, pos,
|
2014-12-06 14:02:45 -08:00
|
|
|
CCOL_SENT, size,
|
2011-02-24 04:14:30 +01:00
|
|
|
CCOL_START, date,
|
|
|
|
|
CCOL_DCC, dcc,
|
|
|
|
|
-1);
|
2026-01-20 12:26:01 -07:00
|
|
|
dcc_store_color (store, iter, CCOL_COLOR, dccstat[dcc->dccstat].color);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
|
|
|
|
|
gboolean update_only)
|
|
|
|
|
{
|
|
|
|
|
static char pos[16], size[16], kbs[14], perc[14], eta[14];
|
|
|
|
|
int to_go;
|
|
|
|
|
float per;
|
|
|
|
|
|
|
|
|
|
if (!pix_up)
|
2026-01-30 18:09:31 -07:00
|
|
|
pix_up = dcc_load_icon ("gtk-go-up");
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
/* 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));
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
|
|
|
|
|
g_snprintf (perc, sizeof (perc), "%.0f%%", per);
|
2011-02-24 04:14:30 +01:00
|
|
|
if (dcc->cps != 0)
|
|
|
|
|
{
|
|
|
|
|
to_go = (dcc->size - dcc->ack) / dcc->cps;
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
|
2011-02-24 04:14:30 +01:00
|
|
|
to_go / 3600, (to_go / 60) % 60, to_go % 60);
|
|
|
|
|
} else
|
|
|
|
|
strcpy (eta, "--:--:--");
|
|
|
|
|
|
|
|
|
|
if (update_only)
|
|
|
|
|
gtk_list_store_set (store, iter,
|
|
|
|
|
COL_STATUS, _(dccstat[dcc->dccstat].name),
|
|
|
|
|
COL_POS, pos,
|
|
|
|
|
COL_PERC, perc,
|
|
|
|
|
COL_SPEED, kbs,
|
|
|
|
|
COL_ETA, eta,
|
|
|
|
|
-1);
|
|
|
|
|
else
|
|
|
|
|
gtk_list_store_set (store, iter,
|
|
|
|
|
COL_TYPE, pix_up,
|
|
|
|
|
COL_STATUS, _(dccstat[dcc->dccstat].name),
|
|
|
|
|
COL_FILE, file_part (dcc->file),
|
|
|
|
|
COL_SIZE, size,
|
|
|
|
|
COL_POS, pos,
|
|
|
|
|
COL_PERC, perc,
|
|
|
|
|
COL_SPEED, kbs,
|
|
|
|
|
COL_ETA, eta,
|
|
|
|
|
COL_NICK, dcc->nick,
|
|
|
|
|
COL_DCC, dcc,
|
|
|
|
|
-1);
|
2026-01-20 12:26:01 -07:00
|
|
|
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter,
|
|
|
|
|
gboolean update_only)
|
|
|
|
|
{
|
|
|
|
|
static char size[16], pos[16], kbs[16], perc[14], eta[16];
|
|
|
|
|
float per;
|
|
|
|
|
int to_go;
|
|
|
|
|
|
|
|
|
|
if (!pix_dn)
|
2026-01-30 18:09:31 -07:00
|
|
|
pix_dn = dcc_load_icon ("gtk-go-down");
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
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));
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024);
|
2011-02-24 04:14:30 +01:00
|
|
|
/* percentage recv'ed */
|
|
|
|
|
per = (float) ((dcc->pos * 100.00) / dcc->size);
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (perc, sizeof (perc), "%.0f%%", per);
|
2011-02-24 04:14:30 +01:00
|
|
|
if (dcc->cps != 0)
|
|
|
|
|
{
|
|
|
|
|
to_go = (dcc->size - dcc->pos) / dcc->cps;
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d",
|
2011-02-24 04:14:30 +01:00
|
|
|
to_go / 3600, (to_go / 60) % 60, to_go % 60);
|
|
|
|
|
} else
|
|
|
|
|
strcpy (eta, "--:--:--");
|
|
|
|
|
|
|
|
|
|
if (update_only)
|
|
|
|
|
gtk_list_store_set (store, iter,
|
|
|
|
|
COL_STATUS, _(dccstat[dcc->dccstat].name),
|
|
|
|
|
COL_POS, pos,
|
|
|
|
|
COL_PERC, perc,
|
|
|
|
|
COL_SPEED, kbs,
|
|
|
|
|
COL_ETA, eta,
|
|
|
|
|
-1);
|
|
|
|
|
else
|
|
|
|
|
gtk_list_store_set (store, iter,
|
|
|
|
|
COL_TYPE, pix_dn,
|
|
|
|
|
COL_STATUS, _(dccstat[dcc->dccstat].name),
|
|
|
|
|
COL_FILE, file_part (dcc->file),
|
|
|
|
|
COL_SIZE, size,
|
|
|
|
|
COL_POS, pos,
|
|
|
|
|
COL_PERC, perc,
|
|
|
|
|
COL_SPEED, kbs,
|
|
|
|
|
COL_ETA, eta,
|
|
|
|
|
COL_NICK, dcc->nick,
|
|
|
|
|
COL_DCC, dcc,
|
|
|
|
|
-1);
|
2026-01-20 12:26:01 -07:00
|
|
|
dcc_store_color (store, iter, COL_COLOR, dccstat[dcc->dccstat].color);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
dcc_find_row (struct DCC *find_dcc, GtkTreeModel *model, GtkTreeIter *iter, int col)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
|
|
|
|
|
if (gtk_tree_model_get_iter_first (model, iter))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
gtk_tree_model_get (model, iter, col, &dcc, -1);
|
|
|
|
|
if (dcc == find_dcc)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
while (gtk_tree_model_iter_next (model, iter));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_update_recv (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
if (!dccfwin.window)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!dcc_find_row (dcc, GTK_TREE_MODEL (dccfwin.store), &iter, COL_DCC))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dcc_prepare_row_recv (dcc, dccfwin.store, &iter, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_update_chat (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
if (!dcccwin.window)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!dcc_find_row (dcc, GTK_TREE_MODEL (dcccwin.store), &iter, CCOL_DCC))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dcc_prepare_row_chat (dcc, dcccwin.store, &iter, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_update_send (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
if (!dccfwin.window)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!dcc_find_row (dcc, GTK_TREE_MODEL (dccfwin.store), &iter, COL_DCC))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dcc_prepare_row_send (dcc, dccfwin.store, &iter, TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
close_dcc_file_window (GtkWindow *win, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
dccfwin.window = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_append (struct DCC *dcc, GtkListStore *store, gboolean prepend)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
if (prepend)
|
|
|
|
|
gtk_list_store_prepend (store, &iter);
|
|
|
|
|
else
|
|
|
|
|
gtk_list_store_append (store, &iter);
|
|
|
|
|
|
|
|
|
|
if (dcc->type == TYPE_RECV)
|
|
|
|
|
dcc_prepare_row_recv (dcc, store, &iter, FALSE);
|
|
|
|
|
else
|
|
|
|
|
dcc_prepare_row_send (dcc, store, &iter, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-17 09:20:54 +01:00
|
|
|
/* Returns aborted and completed transfers. */
|
2013-07-10 18:29:10 +01:00
|
|
|
static GSList *
|
|
|
|
|
dcc_get_completed (void)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
GtkTreeModel *model;
|
|
|
|
|
GSList *completed = NULL;
|
|
|
|
|
|
|
|
|
|
model = GTK_TREE_MODEL (dccfwin.store);
|
|
|
|
|
if (gtk_tree_model_get_iter_first (model, &iter))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
gtk_tree_model_get (model, &iter, COL_DCC, &dcc, -1);
|
2013-07-17 09:20:54 +01:00
|
|
|
if (is_dcc_completed (dcc))
|
2013-07-10 18:29:10 +01:00
|
|
|
completed = g_slist_prepend (completed, dcc);
|
|
|
|
|
|
|
|
|
|
} while (gtk_tree_model_iter_next (model, &iter));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return completed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2013-07-17 09:20:54 +01:00
|
|
|
dcc_completed_transfer_exists (void)
|
2013-07-10 18:29:10 +01:00
|
|
|
{
|
|
|
|
|
gboolean exist;
|
|
|
|
|
GSList *comp_list;
|
|
|
|
|
|
|
|
|
|
comp_list = dcc_get_completed ();
|
|
|
|
|
exist = comp_list != NULL;
|
|
|
|
|
|
|
|
|
|
g_slist_free (comp_list);
|
|
|
|
|
return exist;
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-23 23:55:20 +01:00
|
|
|
static void
|
|
|
|
|
update_clear_button_sensitivity (void)
|
|
|
|
|
{
|
|
|
|
|
gboolean sensitive = dcc_completed_transfer_exists ();
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.clear_button, sensitive);
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
dcc_fill_window (int flags)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *list;
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
gtk_list_store_clear (GTK_LIST_STORE (dccfwin.store));
|
|
|
|
|
|
|
|
|
|
if (flags & VIEW_UPLOAD)
|
|
|
|
|
{
|
|
|
|
|
list = dcc_list;
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->type == TYPE_SEND)
|
|
|
|
|
{
|
|
|
|
|
dcc_append (dcc, dccfwin.store, FALSE);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
list = list->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags & VIEW_DOWNLOAD)
|
|
|
|
|
{
|
|
|
|
|
list = dcc_list;
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->type == TYPE_RECV)
|
|
|
|
|
{
|
|
|
|
|
dcc_append (dcc, dccfwin.store, FALSE);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
list = list->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if only one entry, select it (so Accept button can work) */
|
|
|
|
|
if (i == 1)
|
|
|
|
|
{
|
|
|
|
|
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dccfwin.store), &iter);
|
|
|
|
|
gtk_tree_selection_select_iter (dccfwin.sel, &iter);
|
|
|
|
|
}
|
2013-07-23 23:55:20 +01:00
|
|
|
|
|
|
|
|
update_clear_button_sensitivity ();
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return list of selected DCCs */
|
|
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
|
treeview_get_selected (GtkTreeModel *model, GtkTreeSelection *sel, int column)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
GSList *list = NULL;
|
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
|
|
if (gtk_tree_model_get_iter_first (model, &iter))
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
if (gtk_tree_selection_iter_is_selected (sel, &iter))
|
|
|
|
|
{
|
|
|
|
|
gtk_tree_model_get (model, &iter, column, &ptr, -1);
|
|
|
|
|
list = g_slist_prepend (list, ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (gtk_tree_model_iter_next (model, &iter));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
|
dcc_get_selected (void)
|
|
|
|
|
{
|
|
|
|
|
return treeview_get_selected (GTK_TREE_MODEL (dccfwin.store),
|
|
|
|
|
dccfwin.sel, COL_DCC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
resume_clicked (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
char buf[512];
|
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
|
|
list = dcc_get_selected ();
|
|
|
|
|
if (!list)
|
|
|
|
|
return;
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
g_slist_free (list);
|
|
|
|
|
|
|
|
|
|
if (dcc->type == TYPE_RECV && !dcc_resume (dcc))
|
|
|
|
|
{
|
|
|
|
|
switch (dcc->resume_error)
|
|
|
|
|
{
|
|
|
|
|
case 0: /* unknown error */
|
|
|
|
|
fe_message (_("That file is not resumable."), FE_MSG_ERROR);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (buf, sizeof (buf),
|
2011-02-24 04:14:30 +01:00
|
|
|
_( "Cannot access file: %s\n"
|
|
|
|
|
"%s.\n"
|
|
|
|
|
"Resuming not possible."), dcc->destfile,
|
|
|
|
|
errorstring (dcc->resume_errno));
|
|
|
|
|
fe_message (buf, FE_MSG_ERROR);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
fe_message (_("File in download directory is larger "
|
|
|
|
|
"than file offered. Resuming not possible."), FE_MSG_ERROR);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
fe_message (_("Cannot resume the same file from two people."), FE_MSG_ERROR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
abort_clicked (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *start, *list;
|
|
|
|
|
|
|
|
|
|
start = list = dcc_get_selected ();
|
|
|
|
|
for (; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
dcc_abort (dcc->serv->front_session, dcc);
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (start);
|
2013-07-10 18:29:10 +01:00
|
|
|
|
2013-07-17 09:20:54 +01:00
|
|
|
/* Enable the clear button if it wasn't already enabled */
|
|
|
|
|
update_clear_button_sensitivity ();
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
accept_clicked (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *start, *list;
|
|
|
|
|
|
|
|
|
|
start = list = dcc_get_selected ();
|
|
|
|
|
for (; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->type != TYPE_SEND)
|
|
|
|
|
dcc_get (dcc);
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (start);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-10 18:29:10 +01:00
|
|
|
static void
|
|
|
|
|
clear_completed (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
2013-07-17 09:20:54 +01:00
|
|
|
GSList *completed;
|
|
|
|
|
|
|
|
|
|
/* Make a new list of only the completed items and abort each item.
|
|
|
|
|
* A new list is made because calling dcc_abort removes items from the original list,
|
|
|
|
|
* making it impossible to iterate over that list directly.
|
|
|
|
|
*/
|
|
|
|
|
for (completed = dcc_get_completed (); completed; completed = completed->next)
|
2013-07-10 18:29:10 +01:00
|
|
|
{
|
|
|
|
|
dcc = completed->data;
|
|
|
|
|
dcc_abort (dcc->serv->front_session, dcc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The data was freed by dcc_close */
|
|
|
|
|
g_slist_free (completed);
|
2013-07-17 09:20:54 +01:00
|
|
|
update_clear_button_sensitivity ();
|
2013-07-10 18:29:10 +01:00
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
browse_folder (char *dir)
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
/* no need for file:// in ShellExecute() */
|
|
|
|
|
fe_open_url (dir);
|
|
|
|
|
#else
|
|
|
|
|
char buf[512];
|
|
|
|
|
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (buf, sizeof (buf), "file://%s", dir);
|
2011-02-24 04:14:30 +01:00
|
|
|
fe_open_url (buf);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
browse_dcc_folder (void)
|
|
|
|
|
{
|
2012-10-22 12:10:55 +02:00
|
|
|
if (prefs.hex_dcc_completed_dir[0])
|
|
|
|
|
browse_folder (prefs.hex_dcc_completed_dir);
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2012-10-22 12:10:55 +02:00
|
|
|
browse_folder (prefs.hex_dcc_dir);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_details_populate (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
char buf[128];
|
|
|
|
|
|
|
|
|
|
if (!dcc)
|
|
|
|
|
{
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (dccfwin.file_label), NULL);
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (dccfwin.address_label), NULL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* full path */
|
|
|
|
|
if (dcc->type == TYPE_RECV)
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (dccfwin.file_label), dcc->destfile);
|
|
|
|
|
else
|
|
|
|
|
gtk_label_set_text (GTK_LABEL (dccfwin.file_label), dcc->file);
|
|
|
|
|
|
|
|
|
|
/* address and port */
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (buf, sizeof (buf), "%s : %d", net_ip (dcc->addr), dcc->port);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_label_set_text (GTK_LABEL (dccfwin.address_label), buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_row_cb (GtkTreeSelection *sel, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
|
|
list = dcc_get_selected ();
|
|
|
|
|
if (!list)
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.accept_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.resume_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.abort_button, FALSE);
|
|
|
|
|
dcc_details_populate (NULL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2013-07-23 23:55:20 +01:00
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_set_sensitive (dccfwin.abort_button, TRUE);
|
|
|
|
|
|
|
|
|
|
if (list->next) /* multi selection */
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.accept_button, TRUE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.resume_button, TRUE);
|
|
|
|
|
dcc_details_populate (list->data);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* turn OFF/ON appropriate buttons */
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->dccstat == STAT_QUEUED && dcc->type == TYPE_RECV)
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.accept_button, TRUE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.resume_button, TRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.accept_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.resume_button, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dcc_details_populate (dcc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slist_free (list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_dclick_cb (GtkTreeView *view, GtkTreePath *path,
|
|
|
|
|
GtkTreeViewColumn *column, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
|
|
list = dcc_get_selected ();
|
|
|
|
|
if (!list)
|
|
|
|
|
return;
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
g_slist_free (list);
|
|
|
|
|
|
|
|
|
|
if (dcc->type == TYPE_RECV)
|
|
|
|
|
{
|
|
|
|
|
accept_clicked (0, 0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (dcc->dccstat)
|
|
|
|
|
{
|
|
|
|
|
case STAT_FAILED:
|
|
|
|
|
case STAT_ABORTED:
|
|
|
|
|
case STAT_DONE:
|
|
|
|
|
dcc_abort (dcc->serv->front_session, dcc);
|
2016-05-08 09:48:13 +02:00
|
|
|
break;
|
|
|
|
|
case STAT_QUEUED:
|
|
|
|
|
case STAT_ACTIVE:
|
|
|
|
|
case STAT_CONNECTING:
|
|
|
|
|
break;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_add_column (GtkWidget *tree, int textcol, int colorcol, char *title, gboolean right_justified)
|
|
|
|
|
{
|
|
|
|
|
GtkCellRenderer *renderer;
|
|
|
|
|
|
|
|
|
|
renderer = gtk_cell_renderer_text_new ();
|
|
|
|
|
if (right_justified)
|
|
|
|
|
g_object_set (G_OBJECT (renderer), "xalign", (float) 1.0, NULL);
|
|
|
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree), -1, title, renderer,
|
2026-01-23 00:23:00 -07:00
|
|
|
"text", textcol, PALETTE_FOREGROUND_PROPERTY, colorcol,
|
2011-02-24 04:14:30 +01:00
|
|
|
NULL);
|
|
|
|
|
gtk_cell_renderer_text_set_fixed_height_from_font (GTK_CELL_RENDERER_TEXT (renderer), 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GtkWidget *
|
|
|
|
|
dcc_detail_label (char *text, GtkWidget *box, int num)
|
|
|
|
|
{
|
|
|
|
|
GtkWidget *label;
|
|
|
|
|
char buf[64];
|
|
|
|
|
|
|
|
|
|
label = gtk_label_new (NULL);
|
2014-12-17 18:49:59 -05:00
|
|
|
g_snprintf (buf, sizeof (buf), "<b>%s</b>", text);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_label_set_markup (GTK_LABEL (label), buf);
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (label, FALSE);
|
|
|
|
|
gtk_widget_set_vexpand (label, FALSE);
|
2026-01-23 20:18:49 -07:00
|
|
|
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
|
|
|
|
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (box), label, 0, 0 + num, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
label = gtk_label_new (NULL);
|
|
|
|
|
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (label, FALSE);
|
|
|
|
|
gtk_widget_set_vexpand (label, FALSE);
|
2026-01-23 20:18:49 -07:00
|
|
|
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
|
|
|
|
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (box), label, 1, 0 + num, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
return label;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_exp_cb (GtkWidget *exp, GtkWidget *box)
|
|
|
|
|
{
|
|
|
|
|
if (gtk_widget_get_visible (box))
|
2013-05-11 13:06:25 +02:00
|
|
|
{
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_hide (box);
|
2013-05-11 13:06:25 +02:00
|
|
|
}
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2013-05-11 13:06:25 +02:00
|
|
|
{
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_show (box);
|
2013-05-11 13:06:25 +02:00
|
|
|
}
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_toggle (GtkWidget *item, gpointer data)
|
|
|
|
|
{
|
2013-05-12 01:43:27 -04:00
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item)))
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
|
|
|
|
view_mode = GPOINTER_TO_INT (data);
|
|
|
|
|
dcc_fill_window (GPOINTER_TO_INT (data));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
dcc_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
/* remember the window size */
|
|
|
|
|
gtk_window_get_size (win, &win_width, &win_height);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fe_dcc_open_recv_win (int passive)
|
|
|
|
|
{
|
2026-02-16 18:40:15 -07:00
|
|
|
GtkWidget *radio, *table, *vbox, *bbox, *view, *view_scrolled, *exp, *detailbox;
|
2011-02-24 04:14:30 +01:00
|
|
|
GtkListStore *store;
|
|
|
|
|
GSList *group;
|
2017-09-15 17:36:02 -04:00
|
|
|
char buf[128];
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
if (dccfwin.window)
|
|
|
|
|
{
|
|
|
|
|
if (!passive)
|
|
|
|
|
mg_bring_tofront (dccfwin.window);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2017-09-15 17:36:02 -04:00
|
|
|
g_snprintf(buf, sizeof(buf), _("Uploads and Downloads - %s"), _(DISPLAY_NAME));
|
|
|
|
|
dccfwin.window = mg_create_generic_tab ("Transfers", buf, FALSE, TRUE, close_dcc_file_window,
|
|
|
|
|
NULL, win_width, win_height, &vbox, 0);
|
2013-03-17 15:11:23 -07:00
|
|
|
gtkutil_destroy_on_esc (dccfwin.window);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (dccfwin.window), 3);
|
|
|
|
|
gtk_box_set_spacing (GTK_BOX (vbox), 3);
|
|
|
|
|
|
|
|
|
|
store = gtk_list_store_new (N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
|
|
|
|
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
|
|
|
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
2026-01-19 22:50:17 -07:00
|
|
|
G_TYPE_STRING, G_TYPE_POINTER, PALETTE_GDK_TYPE);
|
2011-02-24 04:14:30 +01:00
|
|
|
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
|
2026-02-16 18:40:15 -07:00
|
|
|
view_scrolled = gtk_widget_get_parent (view);
|
|
|
|
|
gtk_widget_set_hexpand (view_scrolled, TRUE);
|
|
|
|
|
gtk_widget_set_vexpand (view_scrolled, TRUE);
|
|
|
|
|
gtk_widget_set_hexpand (view, TRUE);
|
|
|
|
|
gtk_widget_set_vexpand (view, TRUE);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
|
|
|
|
/* Up/Down Icon column */
|
|
|
|
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL,
|
|
|
|
|
gtk_cell_renderer_pixbuf_new (),
|
|
|
|
|
"pixbuf", COL_TYPE, NULL);
|
|
|
|
|
dcc_add_column (view, COL_STATUS, COL_COLOR, _("Status"), FALSE);
|
|
|
|
|
dcc_add_column (view, COL_FILE, COL_COLOR, _("File"), FALSE);
|
|
|
|
|
dcc_add_column (view, COL_SIZE, COL_COLOR, _("Size"), TRUE);
|
|
|
|
|
dcc_add_column (view, COL_POS, COL_COLOR, _("Position"), TRUE);
|
|
|
|
|
dcc_add_column (view, COL_PERC, COL_COLOR, "%", TRUE);
|
|
|
|
|
dcc_add_column (view, COL_SPEED, COL_COLOR, "KB/s", TRUE);
|
|
|
|
|
dcc_add_column (view, COL_ETA, COL_COLOR, _("ETA"), FALSE);
|
|
|
|
|
dcc_add_column (view, COL_NICK, COL_COLOR, _("Nick"), FALSE);
|
|
|
|
|
|
|
|
|
|
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), COL_FILE), TRUE);
|
|
|
|
|
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), COL_NICK), TRUE);
|
|
|
|
|
|
|
|
|
|
dccfwin.list = view;
|
|
|
|
|
dccfwin.store = store;
|
|
|
|
|
dccfwin.sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
|
|
|
|
|
view_mode = VIEW_BOTH;
|
|
|
|
|
gtk_tree_selection_set_mode (dccfwin.sel, GTK_SELECTION_MULTIPLE);
|
|
|
|
|
|
2012-10-22 13:49:28 +02:00
|
|
|
if (!prefs.hex_gui_tab_utils)
|
2011-02-24 04:14:30 +01:00
|
|
|
g_signal_connect (G_OBJECT (dccfwin.window), "configure_event",
|
|
|
|
|
G_CALLBACK (dcc_configure_cb), 0);
|
|
|
|
|
g_signal_connect (G_OBJECT (dccfwin.sel), "changed",
|
|
|
|
|
G_CALLBACK (dcc_row_cb), NULL);
|
|
|
|
|
/* double click */
|
|
|
|
|
g_signal_connect (G_OBJECT (view), "row-activated",
|
|
|
|
|
G_CALLBACK (dcc_dclick_cb), NULL);
|
|
|
|
|
|
2026-01-30 17:13:44 -07:00
|
|
|
table = gtk_grid_new ();
|
|
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (table), 16);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), table, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
radio = gtk_radio_button_new_with_mnemonic (NULL, _("Both"));
|
|
|
|
|
g_signal_connect (G_OBJECT (radio), "toggled",
|
|
|
|
|
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_BOTH));
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_vexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
|
|
|
|
|
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (table), radio, 3, 0, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
|
|
|
|
|
|
|
|
|
|
radio = gtk_radio_button_new_with_mnemonic (group, _("Uploads"));
|
|
|
|
|
g_signal_connect (G_OBJECT (radio), "toggled",
|
|
|
|
|
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_UPLOAD));
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_vexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
|
|
|
|
|
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (table), radio, 1, 0, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
|
|
|
|
|
|
|
|
|
|
radio = gtk_radio_button_new_with_mnemonic (group, _("Downloads"));
|
|
|
|
|
g_signal_connect (G_OBJECT (radio), "toggled",
|
|
|
|
|
G_CALLBACK (dcc_toggle), GINT_TO_POINTER (VIEW_DOWNLOAD));
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_vexpand (radio, FALSE);
|
|
|
|
|
gtk_widget_set_halign (radio, GTK_ALIGN_FILL);
|
|
|
|
|
gtk_widget_set_valign (radio, GTK_ALIGN_FILL);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (table), radio, 2, 0, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
exp = gtk_expander_new (_("Details"));
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (exp, TRUE);
|
|
|
|
|
gtk_widget_set_vexpand (exp, FALSE);
|
|
|
|
|
gtk_widget_set_halign (exp, GTK_ALIGN_FILL);
|
|
|
|
|
gtk_widget_set_valign (exp, GTK_ALIGN_FILL);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (table), exp, 0, 0, 1, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-30 17:13:44 -07:00
|
|
|
detailbox = gtk_grid_new ();
|
|
|
|
|
gtk_grid_set_column_spacing (GTK_GRID (detailbox), 6);
|
|
|
|
|
gtk_grid_set_row_spacing (GTK_GRID (detailbox), 2);
|
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (detailbox), 6);
|
2011-02-24 04:14:30 +01:00
|
|
|
g_signal_connect (G_OBJECT (exp), "activate",
|
|
|
|
|
G_CALLBACK (dcc_exp_cb), detailbox);
|
2026-01-30 16:04:50 -07:00
|
|
|
gtk_widget_set_hexpand (detailbox, TRUE);
|
|
|
|
|
gtk_widget_set_vexpand (detailbox, FALSE);
|
|
|
|
|
gtk_widget_set_halign (detailbox, GTK_ALIGN_FILL);
|
|
|
|
|
gtk_widget_set_valign (detailbox, GTK_ALIGN_FILL);
|
2026-01-30 17:13:44 -07:00
|
|
|
gtk_grid_attach (GTK_GRID (table), detailbox, 0, 1, 4, 1);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
dccfwin.file_label = dcc_detail_label (_("File:"), detailbox, 0);
|
|
|
|
|
dccfwin.address_label = dcc_detail_label (_("Address:"), detailbox, 1);
|
|
|
|
|
|
2026-01-30 17:03:27 -07:00
|
|
|
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
|
|
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
|
|
|
|
|
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
dccfwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_clicked, 0, _("Abort"));
|
|
|
|
|
dccfwin.accept_button = gtkutil_button (bbox, ICON_DCC_ACCEPT, 0, accept_clicked, 0, _("Accept"));
|
|
|
|
|
dccfwin.resume_button = gtkutil_button (bbox, ICON_DCC_RESUME, 0, resume_clicked, 0, _("Resume"));
|
|
|
|
|
dccfwin.clear_button = gtkutil_button (bbox, ICON_DCC_CLEAR, 0, clear_completed, 0, _("Clear"));
|
2011-02-24 04:14:30 +01:00
|
|
|
dccfwin.open_button = gtkutil_button (bbox, 0, 0, browse_dcc_folder, 0, _("Open Folder..."));
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.accept_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.resume_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dccfwin.abort_button, FALSE);
|
|
|
|
|
|
|
|
|
|
dcc_fill_window (3);
|
|
|
|
|
gtk_widget_show_all (dccfwin.window);
|
|
|
|
|
gtk_widget_hide (detailbox);
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fe_dcc_open_send_win (int passive)
|
|
|
|
|
{
|
|
|
|
|
/* combined send/recv GUI */
|
|
|
|
|
return fe_dcc_open_recv_win (passive);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* DCC CHAT GUIs BELOW */
|
|
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
|
dcc_chat_get_selected (void)
|
|
|
|
|
{
|
|
|
|
|
return treeview_get_selected (GTK_TREE_MODEL (dcccwin.store),
|
|
|
|
|
dcccwin.sel, CCOL_DCC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
accept_chat_clicked (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *start, *list;
|
|
|
|
|
|
|
|
|
|
start = list = dcc_chat_get_selected ();
|
|
|
|
|
for (; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
dcc_get (dcc);
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
abort_chat_clicked (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *start, *list;
|
|
|
|
|
|
|
|
|
|
start = list = dcc_chat_get_selected ();
|
|
|
|
|
for (; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
dcc_abort (dcc->serv->front_session, dcc);
|
|
|
|
|
}
|
|
|
|
|
g_slist_free (start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_chat_close_cb (void)
|
|
|
|
|
{
|
|
|
|
|
dcccwin.window = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_chat_append (struct DCC *dcc, GtkListStore *store, gboolean prepend)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
if (prepend)
|
|
|
|
|
gtk_list_store_prepend (store, &iter);
|
|
|
|
|
else
|
|
|
|
|
gtk_list_store_append (store, &iter);
|
|
|
|
|
|
|
|
|
|
dcc_prepare_row_chat (dcc, store, &iter, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_chat_fill_win (void)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *list;
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
gtk_list_store_clear (GTK_LIST_STORE (dcccwin.store));
|
|
|
|
|
|
|
|
|
|
list = dcc_list;
|
|
|
|
|
while (list)
|
|
|
|
|
{
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->type == TYPE_CHATSEND || dcc->type == TYPE_CHATRECV)
|
|
|
|
|
{
|
|
|
|
|
dcc_chat_append (dcc, dcccwin.store, FALSE);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
list = list->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if only one entry, select it (so Accept button can work) */
|
|
|
|
|
if (i == 1)
|
|
|
|
|
{
|
|
|
|
|
gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dcccwin.store), &iter);
|
|
|
|
|
gtk_tree_selection_select_iter (dcccwin.sel, &iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_chat_row_cb (GtkTreeSelection *sel, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
struct DCC *dcc;
|
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
|
|
list = dcc_chat_get_selected ();
|
|
|
|
|
if (!list)
|
|
|
|
|
{
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.accept_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.abort_button, FALSE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.abort_button, TRUE);
|
|
|
|
|
|
|
|
|
|
if (list->next) /* multi selection */
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.accept_button, TRUE);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* turn OFF/ON appropriate buttons */
|
|
|
|
|
dcc = list->data;
|
|
|
|
|
if (dcc->dccstat == STAT_QUEUED && dcc->type == TYPE_CHATRECV)
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.accept_button, TRUE);
|
|
|
|
|
else
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.accept_button, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slist_free (list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
dcc_chat_dclick_cb (GtkTreeView *view, GtkTreePath *path,
|
|
|
|
|
GtkTreeViewColumn *column, gpointer data)
|
|
|
|
|
{
|
|
|
|
|
accept_chat_clicked (0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fe_dcc_open_chat_win (int passive)
|
|
|
|
|
{
|
2026-02-16 18:40:15 -07:00
|
|
|
GtkWidget *view, *vbox, *bbox, *scroll;
|
2011-02-24 04:14:30 +01:00
|
|
|
GtkListStore *store;
|
2017-09-15 17:36:02 -04:00
|
|
|
char buf[128];
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
if (dcccwin.window)
|
|
|
|
|
{
|
|
|
|
|
if (!passive)
|
|
|
|
|
mg_bring_tofront (dcccwin.window);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-15 17:36:02 -04:00
|
|
|
g_snprintf(buf, sizeof(buf), _("DCC Chat List - %s"), _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
dcccwin.window =
|
2017-09-15 17:36:02 -04:00
|
|
|
mg_create_generic_tab ("DCCChat", buf, FALSE, TRUE, dcc_chat_close_cb,
|
|
|
|
|
NULL, 550, 180, &vbox, 0);
|
2013-03-17 15:11:23 -07:00
|
|
|
gtkutil_destroy_on_esc (dcccwin.window);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (dcccwin.window), 3);
|
|
|
|
|
gtk_box_set_spacing (GTK_BOX (vbox), 3);
|
|
|
|
|
|
|
|
|
|
store = gtk_list_store_new (CN_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
|
2026-02-16 18:40:15 -07:00
|
|
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
|
|
|
|
G_TYPE_POINTER, PALETTE_GDK_TYPE);
|
2011-02-24 04:14:30 +01:00
|
|
|
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
|
2026-02-16 18:40:15 -07:00
|
|
|
scroll = gtk_widget_get_parent (view);
|
|
|
|
|
gtk_box_set_child_packing (GTK_BOX (vbox), scroll, TRUE, TRUE, 0, GTK_PACK_START);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
dcc_add_column (view, CCOL_STATUS, CCOL_COLOR, _("Status"), FALSE);
|
|
|
|
|
dcc_add_column (view, CCOL_NICK, CCOL_COLOR, _("Nick"), FALSE);
|
|
|
|
|
dcc_add_column (view, CCOL_RECV, CCOL_COLOR, _("Recv"), TRUE);
|
|
|
|
|
dcc_add_column (view, CCOL_SENT, CCOL_COLOR, _("Sent"), TRUE);
|
|
|
|
|
dcc_add_column (view, CCOL_START, CCOL_COLOR, _("Start Time"), FALSE);
|
|
|
|
|
|
|
|
|
|
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 1), TRUE);
|
|
|
|
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
|
|
|
|
|
|
|
|
|
dcccwin.list = view;
|
|
|
|
|
dcccwin.store = store;
|
|
|
|
|
dcccwin.sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
|
|
|
|
|
gtk_tree_selection_set_mode (dcccwin.sel, GTK_SELECTION_MULTIPLE);
|
|
|
|
|
|
|
|
|
|
g_signal_connect (G_OBJECT (dcccwin.sel), "changed",
|
|
|
|
|
G_CALLBACK (dcc_chat_row_cb), NULL);
|
|
|
|
|
/* double click */
|
|
|
|
|
g_signal_connect (G_OBJECT (view), "row-activated",
|
|
|
|
|
G_CALLBACK (dcc_chat_dclick_cb), NULL);
|
|
|
|
|
|
2026-01-30 17:03:27 -07:00
|
|
|
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
|
|
|
|
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_SPREAD);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, FALSE, 2);
|
|
|
|
|
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
dcccwin.abort_button = gtkutil_button (bbox, ICON_DCC_CANCEL, 0, abort_chat_clicked, 0, _("Abort"));
|
|
|
|
|
dcccwin.accept_button = gtkutil_button (bbox, ICON_DCC_ACCEPT, 0, accept_chat_clicked, 0, _("Accept"));
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_set_sensitive (dcccwin.accept_button, FALSE);
|
|
|
|
|
gtk_widget_set_sensitive (dcccwin.abort_button, FALSE);
|
|
|
|
|
|
|
|
|
|
dcc_chat_fill_win ();
|
|
|
|
|
gtk_widget_show_all (dcccwin.window);
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_dcc_add (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
switch (dcc->type)
|
|
|
|
|
{
|
|
|
|
|
case TYPE_RECV:
|
|
|
|
|
if (dccfwin.window && (view_mode & VIEW_DOWNLOAD))
|
|
|
|
|
dcc_append (dcc, dccfwin.store, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TYPE_SEND:
|
|
|
|
|
if (dccfwin.window && (view_mode & VIEW_UPLOAD))
|
|
|
|
|
dcc_append (dcc, dccfwin.store, TRUE);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default: /* chat */
|
|
|
|
|
if (dcccwin.window)
|
|
|
|
|
dcc_chat_append (dcc, dcccwin.store, TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2013-07-10 18:29:10 +01:00
|
|
|
|
2013-10-03 17:43:44 -07:00
|
|
|
if (dccfwin.window)
|
|
|
|
|
update_clear_button_sensitivity();
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_dcc_remove (struct DCC *dcc)
|
|
|
|
|
{
|
|
|
|
|
GtkTreeIter iter;
|
|
|
|
|
|
|
|
|
|
switch (dcc->type)
|
|
|
|
|
{
|
|
|
|
|
case TYPE_SEND:
|
|
|
|
|
case TYPE_RECV:
|
|
|
|
|
if (dccfwin.window)
|
|
|
|
|
{
|
|
|
|
|
if (dcc_find_row (dcc, GTK_TREE_MODEL (dccfwin.store), &iter, COL_DCC))
|
|
|
|
|
gtk_list_store_remove (dccfwin.store, &iter);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default: /* chat */
|
|
|
|
|
if (dcccwin.window)
|
|
|
|
|
{
|
|
|
|
|
if (dcc_find_row (dcc, GTK_TREE_MODEL (dcccwin.store), &iter, CCOL_DCC))
|
|
|
|
|
gtk_list_store_remove (dcccwin.store, &iter);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|