Compare commits
1 Commits
wip/gtk3
...
wip/checks
Author | SHA1 | Date | |
---|---|---|---|
![]() |
36f2528b78 |
1
.github/workflows/msys-build.yml
vendored
1
.github/workflows/msys-build.yml
vendored
@@ -19,7 +19,6 @@ jobs:
|
|||||||
mingw-w64-x86_64-python3-cffi
|
mingw-w64-x86_64-python3-cffi
|
||||||
mingw-w64-x86_64-meson
|
mingw-w64-x86_64-meson
|
||||||
mingw-w64-x86_64-gtk2
|
mingw-w64-x86_64-gtk2
|
||||||
mingw-w64-x86_64-gtk-update-icon-cache
|
|
||||||
mingw-w64-x86_64-luajit
|
mingw-w64-x86_64-luajit
|
||||||
mingw-w64-x86_64-desktop-file-utils
|
mingw-w64-x86_64-desktop-file-utils
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ gnome = import('gnome')
|
|||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
|
||||||
libgio_dep = dependency('gio-2.0', version: '>= 2.34.0')
|
libgio_dep = dependency('gio-2.0', version: '>= 2.36.0')
|
||||||
libgmodule_dep = dependency('gmodule-2.0')
|
libgmodule_dep = dependency('gmodule-2.0')
|
||||||
|
|
||||||
libcanberra_dep = dependency('libcanberra', version: '>= 0.22',
|
libcanberra_dep = dependency('libcanberra', version: '>= 0.22',
|
||||||
@@ -47,8 +47,8 @@ config_h.set('G_DISABLE_SINGLE_INCLUDES', true)
|
|||||||
config_h.set('GTK_DISABLE_DEPRECATED', true)
|
config_h.set('GTK_DISABLE_DEPRECATED', true)
|
||||||
config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true)
|
config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true)
|
||||||
config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true)
|
config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true)
|
||||||
config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_34')
|
config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_36')
|
||||||
config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_34')
|
config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_36')
|
||||||
|
|
||||||
# Detected features
|
# Detected features
|
||||||
config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr'))
|
config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr'))
|
||||||
|
@@ -22,218 +22,152 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <glib/gstdio.h>
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include "hexchat-plugin.h"
|
#include "hexchat-plugin.h"
|
||||||
|
|
||||||
#define BUFSIZE 32768
|
|
||||||
#define DEFAULT_LIMIT 256 /* default size is 256 MiB */
|
|
||||||
#define SHA256_DIGEST_LENGTH 32
|
|
||||||
#define SHA256_BUFFER_LENGTH 65
|
|
||||||
|
|
||||||
static hexchat_plugin *ph; /* plugin handle */
|
static hexchat_plugin *ph; /* plugin handle */
|
||||||
static char name[] = "Checksum";
|
static char name[] = "Checksum";
|
||||||
static char desc[] = "Calculate checksum for DCC file transfers";
|
static char desc[] = "Calculate checksum for DCC file transfers";
|
||||||
static char version[] = "3.1";
|
static char version[] = "4.0";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_limit (char *size)
|
print_sha256_result (hexchat_context *ctx, gboolean send_message, const char *checksum, const char *filename, GError *error)
|
||||||
{
|
{
|
||||||
int limit = atoi (size);
|
/* Context may have been destroyed. */
|
||||||
|
/* FIXME: This could still send the PRIVMSG even if the context was closed. */
|
||||||
|
if (!hexchat_set_context (ph, ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
if (limit > 0 && limit < INT_MAX)
|
if (error)
|
||||||
{
|
hexchat_printf (ph, "Failed to create checksum for %s: %s", filename, error->message);
|
||||||
if (hexchat_pluginpref_set_int (ph, "limit", limit))
|
else if (send_message)
|
||||||
hexchat_printf (ph, "Checksum: File size limit has successfully been set to: %d MiB\n", limit);
|
hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", hexchat_get_info (ph, "channel"), filename, checksum);
|
||||||
else
|
|
||||||
hexchat_printf (ph, "Checksum: File access error while saving!\n");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", filename, checksum);
|
||||||
hexchat_printf (ph, "Checksum: Invalid input!\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* TODO: We could put more info in task data and share the same callback. */
|
||||||
get_limit (void)
|
static void
|
||||||
|
on_received_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data)
|
||||||
{
|
{
|
||||||
int size = hexchat_pluginpref_get_int (ph, "limit");
|
hexchat_context *ctx = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
char *sha256 = NULL;
|
||||||
|
const char *filename = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
if (size <= 0 || size >= INT_MAX)
|
sha256 = g_task_propagate_pointer (G_TASK (result), &error);
|
||||||
return DEFAULT_LIMIT;
|
print_sha256_result (ctx, FALSE, sha256, filename, error);
|
||||||
else
|
|
||||||
return size;
|
g_free (sha256);
|
||||||
|
g_clear_error (&error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
check_limit (GFile *file)
|
on_sent_file_sha256_complete (GFile *file, GAsyncResult *result, gpointer user_data)
|
||||||
{
|
{
|
||||||
GFileInfo *file_info;
|
hexchat_context *ctx = user_data;
|
||||||
goffset file_size;
|
GError *error = NULL;
|
||||||
|
char *sha256 = NULL;
|
||||||
|
const char *filename = g_task_get_task_data (G_TASK (result));
|
||||||
|
|
||||||
file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE,
|
sha256 = g_task_propagate_pointer (G_TASK (result), &error);
|
||||||
NULL, NULL);
|
print_sha256_result (ctx, TRUE, sha256, filename, error);
|
||||||
|
|
||||||
if (!file_info)
|
g_free (sha256);
|
||||||
return FALSE;
|
g_clear_error (&error);
|
||||||
|
|
||||||
file_size = g_file_info_get_size (file_info);
|
|
||||||
g_object_unref (file_info);
|
|
||||||
|
|
||||||
if (file_size > get_limit () * 1048576ll)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
sha256_from_stream (GFileInputStream *file_stream, char out_buf[])
|
thread_sha256_file (GTask *task, GFile *file, gpointer task_data, GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
GChecksum *checksum;
|
GChecksum *checksum;
|
||||||
gssize bytes_read;
|
GFileInputStream *istream;
|
||||||
guint8 digest[SHA256_DIGEST_LENGTH];
|
guint8 buffer[32768];
|
||||||
gsize digest_len = sizeof(digest);
|
GError *error = NULL;
|
||||||
guchar buffer[BUFSIZE];
|
gssize ret;
|
||||||
gsize i;
|
|
||||||
|
istream = g_file_read (file, cancellable, &error);
|
||||||
|
if (error) {
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||||
|
|
||||||
while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (file_stream), buffer, sizeof (buffer), NULL, NULL)))
|
while ((ret = g_input_stream_read (G_INPUT_STREAM (istream), buffer, sizeof(buffer), cancellable, &error)) > 0)
|
||||||
{
|
g_checksum_update (checksum, buffer, ret);
|
||||||
if (bytes_read == -1)
|
|
||||||
{
|
|
||||||
g_checksum_free (checksum);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_checksum_update (checksum, buffer, bytes_read);
|
if (error) {
|
||||||
|
g_checksum_free (checksum);
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
g_task_return_pointer (task, g_strdup (g_checksum_get_string (checksum)), g_free);
|
||||||
g_checksum_free (checksum);
|
g_checksum_free (checksum);
|
||||||
|
|
||||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
|
||||||
{
|
|
||||||
/* out_buf will be exactly SHA256_BUFFER_LENGTH including null */
|
|
||||||
g_sprintf (out_buf + (i * 2), "%02x", digest[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
sha256_from_file (char *filename, char out_buf[])
|
|
||||||
{
|
|
||||||
GFileInputStream *file_stream;
|
|
||||||
char *filename_fs;
|
|
||||||
GFile *file;
|
|
||||||
|
|
||||||
filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
|
|
||||||
if (!filename_fs)
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
file = g_file_new_for_path (filename_fs);
|
|
||||||
g_free (filename_fs);
|
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Checksum: Failed to open %s\n", filename);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_limit (file))
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Checksum: %s is larger than size limit. You can increase it with /CHECKSUM SET.\n", filename);
|
|
||||||
g_object_unref (file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_stream = g_file_read (file, NULL, NULL);
|
|
||||||
if (!file_stream)
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Checksum: Failed to read file %s\n", filename);
|
|
||||||
g_object_unref (file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sha256_from_stream (file_stream, out_buf))
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Checksum: Failed to generate checksum for %s\n", filename);
|
|
||||||
g_object_unref (file_stream);
|
|
||||||
g_object_unref (file);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (file_stream);
|
|
||||||
g_object_unref (file);
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dccrecv_cb (char *word[], void *userdata)
|
dccrecv_cb (char *word[], void *userdata)
|
||||||
{
|
{
|
||||||
|
GTask *task;
|
||||||
|
char *filename_fs;
|
||||||
|
GFile *file;
|
||||||
|
hexchat_context *ctx;
|
||||||
const char *dcc_completed_dir;
|
const char *dcc_completed_dir;
|
||||||
char *filename, checksum[SHA256_BUFFER_LENGTH];
|
char *filename;
|
||||||
|
|
||||||
/* Print in the privmsg tab of the sender */
|
|
||||||
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
|
|
||||||
|
|
||||||
if (hexchat_get_prefs (ph, "dcc_completed_dir", &dcc_completed_dir, NULL) == 1 && dcc_completed_dir[0] != '\0')
|
if (hexchat_get_prefs (ph, "dcc_completed_dir", &dcc_completed_dir, NULL) == 1 && dcc_completed_dir[0] != '\0')
|
||||||
filename = g_build_filename (dcc_completed_dir, word[1], NULL);
|
filename = g_build_filename (dcc_completed_dir, word[1], NULL);
|
||||||
else
|
else
|
||||||
filename = g_strdup (word[2]);
|
filename = g_strdup (word[2]);
|
||||||
|
|
||||||
if (sha256_from_file (filename, checksum))
|
filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
|
||||||
{
|
if (!filename_fs) {
|
||||||
hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], checksum);
|
hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename);
|
||||||
|
g_free (filename);
|
||||||
|
return HEXCHAT_EAT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (filename);
|
/* Print in the privmsg tab of the sender */
|
||||||
|
ctx = hexchat_find_context (ph, NULL, word[3]);
|
||||||
|
|
||||||
|
file = g_file_new_for_path (filename_fs);
|
||||||
|
task = g_task_new (file, NULL, (GAsyncReadyCallback) on_received_file_sha256_complete, ctx);
|
||||||
|
g_task_set_task_data (task, filename, g_free);
|
||||||
|
g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file);
|
||||||
|
|
||||||
|
g_free (filename_fs);
|
||||||
|
g_object_unref (file);
|
||||||
|
g_object_unref (task);
|
||||||
|
|
||||||
return HEXCHAT_EAT_NONE;
|
return HEXCHAT_EAT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dccoffer_cb (char *word[], void *userdata)
|
dccoffer_cb (char *word[], void *userdata)
|
||||||
{
|
{
|
||||||
char checksum[SHA256_BUFFER_LENGTH];
|
GFile *file;
|
||||||
|
GTask *task;
|
||||||
|
hexchat_context *ctx;
|
||||||
|
char *filename;
|
||||||
|
|
||||||
/* Print in the privmsg tab of the receiver */
|
/* Print in the privmsg tab of the receiver */
|
||||||
hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3]));
|
ctx = hexchat_find_context (ph, NULL, word[3]);
|
||||||
|
|
||||||
if (sha256_from_file (word[3], checksum))
|
filename = g_strdup (word[3]);
|
||||||
{
|
file = g_file_new_for_path (filename);
|
||||||
hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], checksum);
|
task = g_task_new (file, NULL, (GAsyncReadyCallback) on_sent_file_sha256_complete, ctx);
|
||||||
}
|
g_task_set_task_data (task, filename, g_free);
|
||||||
|
g_task_run_in_thread (task, (GTaskThreadFunc) thread_sha256_file);
|
||||||
|
|
||||||
|
g_object_unref (file);
|
||||||
|
g_object_unref (task);
|
||||||
|
|
||||||
return HEXCHAT_EAT_NONE;
|
return HEXCHAT_EAT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
checksum (char *word[], char *word_eol[], void *userdata)
|
|
||||||
{
|
|
||||||
if (!g_ascii_strcasecmp ("GET", word[2]))
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
|
|
||||||
}
|
|
||||||
else if (!g_ascii_strcasecmp ("SET", word[2]))
|
|
||||||
{
|
|
||||||
set_limit (word[3]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hexchat_printf (ph, "Usage: /CHECKSUM GET|SET\n");
|
|
||||||
hexchat_printf (ph, " GET - print the maximum file size (in MiB) to be hashed\n");
|
|
||||||
hexchat_printf (ph, " SET <filesize> - set the maximum file size (in MiB) to be hashed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return HEXCHAT_EAT_ALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
|
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
|
||||||
{
|
{
|
||||||
@@ -243,13 +177,6 @@ hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **p
|
|||||||
*plugin_desc = desc;
|
*plugin_desc = desc;
|
||||||
*plugin_version = version;
|
*plugin_version = version;
|
||||||
|
|
||||||
/* this is required for the very first run */
|
|
||||||
if (hexchat_pluginpref_get_int (ph, "limit") == -1)
|
|
||||||
{
|
|
||||||
hexchat_pluginpref_set_int (ph, "limit", DEFAULT_LIMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", NULL);
|
|
||||||
hexchat_hook_print (ph, "DCC RECV Complete", HEXCHAT_PRI_NORM, dccrecv_cb, NULL);
|
hexchat_hook_print (ph, "DCC RECV Complete", HEXCHAT_PRI_NORM, dccrecv_cb, NULL);
|
||||||
hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_NORM, dccoffer_cb, NULL);
|
hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_NORM, dccoffer_cb, NULL);
|
||||||
|
|
||||||
|
@@ -468,7 +468,6 @@ const struct prefs vars[] =
|
|||||||
{"gui_win_fullscreen", P_OFFINT (hex_gui_win_fullscreen), TYPE_INT},
|
{"gui_win_fullscreen", P_OFFINT (hex_gui_win_fullscreen), TYPE_INT},
|
||||||
{"gui_win_left", P_OFFINT (hex_gui_win_left), TYPE_INT},
|
{"gui_win_left", P_OFFINT (hex_gui_win_left), TYPE_INT},
|
||||||
{"gui_win_modes", P_OFFINT (hex_gui_win_modes), TYPE_BOOL},
|
{"gui_win_modes", P_OFFINT (hex_gui_win_modes), TYPE_BOOL},
|
||||||
{"gui_win_nick", P_OFFINT (hex_gui_win_nick), TYPE_BOOL},
|
|
||||||
{"gui_win_save", P_OFFINT (hex_gui_win_save), TYPE_BOOL},
|
{"gui_win_save", P_OFFINT (hex_gui_win_save), TYPE_BOOL},
|
||||||
{"gui_win_state", P_OFFINT (hex_gui_win_state), TYPE_INT},
|
{"gui_win_state", P_OFFINT (hex_gui_win_state), TYPE_INT},
|
||||||
{"gui_win_swap", P_OFFINT (hex_gui_win_swap), TYPE_BOOL},
|
{"gui_win_swap", P_OFFINT (hex_gui_win_swap), TYPE_BOOL},
|
||||||
@@ -773,7 +772,6 @@ load_default_config(void)
|
|||||||
prefs.hex_gui_ulist_count = 1;
|
prefs.hex_gui_ulist_count = 1;
|
||||||
prefs.hex_gui_ulist_icons = 1;
|
prefs.hex_gui_ulist_icons = 1;
|
||||||
prefs.hex_gui_ulist_style = 1;
|
prefs.hex_gui_ulist_style = 1;
|
||||||
prefs.hex_gui_win_nick = 1;
|
|
||||||
prefs.hex_gui_win_save = 1;
|
prefs.hex_gui_win_save = 1;
|
||||||
prefs.hex_input_filter_beep = 1;
|
prefs.hex_input_filter_beep = 1;
|
||||||
prefs.hex_input_flash_hilight = 1;
|
prefs.hex_input_flash_hilight = 1;
|
||||||
|
@@ -150,7 +150,6 @@ struct hexchatprefs
|
|||||||
unsigned int hex_gui_ulist_style;
|
unsigned int hex_gui_ulist_style;
|
||||||
unsigned int hex_gui_usermenu;
|
unsigned int hex_gui_usermenu;
|
||||||
unsigned int hex_gui_win_modes;
|
unsigned int hex_gui_win_modes;
|
||||||
unsigned int hex_gui_win_nick;
|
|
||||||
unsigned int hex_gui_win_save;
|
unsigned int hex_gui_win_save;
|
||||||
unsigned int hex_gui_win_swap;
|
unsigned int hex_gui_win_swap;
|
||||||
unsigned int hex_gui_win_ucount;
|
unsigned int hex_gui_win_ucount;
|
||||||
|
@@ -1474,17 +1474,10 @@ inbound_user_info (session *sess, char *chan, char *user, char *host,
|
|||||||
for (list = sess_list; list; list = list->next)
|
for (list = sess_list; list; list = list->next)
|
||||||
{
|
{
|
||||||
sess = list->data;
|
sess = list->data;
|
||||||
if (sess->server != serv)
|
if (sess->type == SESS_CHANNEL && sess->server == serv)
|
||||||
continue;
|
|
||||||
|
|
||||||
if (sess->type == SESS_CHANNEL)
|
|
||||||
{
|
{
|
||||||
userlist_add_hostname (sess, nick, uhost, realname, servname, account, away);
|
userlist_add_hostname (sess, nick, uhost, realname, servname, account, away);
|
||||||
}
|
}
|
||||||
else if (sess->type == SESS_DIALOG && uhost && !serv->p_cmp (sess->channel, nick))
|
|
||||||
{
|
|
||||||
set_topic (sess, uhost, uhost);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1735,7 +1728,6 @@ static const char * const supported_caps[] = {
|
|||||||
"setname",
|
"setname",
|
||||||
"invite-notify",
|
"invite-notify",
|
||||||
"account-tag",
|
"account-tag",
|
||||||
"extended-monitor",
|
|
||||||
|
|
||||||
/* ZNC */
|
/* ZNC */
|
||||||
"znc.in/server-time-iso",
|
"znc.in/server-time-iso",
|
||||||
|
@@ -459,7 +459,7 @@ chanlist_join (GtkWidget * wid, server *serv)
|
|||||||
g_snprintf (tbuf, sizeof (tbuf), "join %s", chan);
|
g_snprintf (tbuf, sizeof (tbuf), "join %s", chan);
|
||||||
handle_command (serv->server_session, tbuf, FALSE);
|
handle_command (serv->server_session, tbuf, FALSE);
|
||||||
} else
|
} else
|
||||||
gdk_display_beep (gdk_display_get_default ());
|
gdk_beep ();
|
||||||
g_free (chan);
|
g_free (chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -777,6 +777,7 @@ chanlist_opengui (server *serv, int do_refresh)
|
|||||||
chanlist_add_column (view, COL_CHANNEL, 96, _("Channel"), FALSE);
|
chanlist_add_column (view, COL_CHANNEL, 96, _("Channel"), FALSE);
|
||||||
chanlist_add_column (view, COL_USERS, 50, _("Users"), TRUE);
|
chanlist_add_column (view, COL_USERS, 50, _("Users"), TRUE);
|
||||||
chanlist_add_column (view, COL_TOPIC, 50, _("Topic"), FALSE);
|
chanlist_add_column (view, COL_TOPIC, 50, _("Topic"), FALSE);
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
/* this is a speed up, but no horizontal scrollbar :( */
|
/* this is a speed up, but no horizontal scrollbar :( */
|
||||||
/*gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);*/
|
/*gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);*/
|
||||||
gtk_widget_show (view);
|
gtk_widget_show (view);
|
||||||
|
@@ -812,6 +812,7 @@ fe_dcc_open_recv_win (int passive)
|
|||||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
|
||||||
G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_COLOR);
|
G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_COLOR);
|
||||||
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
|
view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
/* Up/Down Icon column */
|
/* Up/Down Icon column */
|
||||||
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL,
|
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), -1, NULL,
|
||||||
gtk_cell_renderer_pixbuf_new (),
|
gtk_cell_renderer_pixbuf_new (),
|
||||||
@@ -1066,6 +1067,7 @@ fe_dcc_open_chat_win (int passive)
|
|||||||
dcc_add_column (view, CCOL_START, CCOL_COLOR, _("Start Time"), FALSE);
|
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_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.list = view;
|
||||||
dcccwin.store = store;
|
dcccwin.store = store;
|
||||||
|
@@ -288,6 +288,8 @@ editlist_treeview_new (GtkWidget *box, char *title1, char *title2)
|
|||||||
g_signal_connect (G_OBJECT (view), "key_press_event",
|
g_signal_connect (G_OBJECT (view), "key_press_event",
|
||||||
G_CALLBACK (editlist_keypress), NULL);
|
G_CALLBACK (editlist_keypress), NULL);
|
||||||
|
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
|
|
||||||
render = gtk_cell_renderer_text_new ();
|
render = gtk_cell_renderer_text_new ();
|
||||||
g_object_set (render, "editable", TRUE, NULL);
|
g_object_set (render, "editable", TRUE, NULL);
|
||||||
g_signal_connect (G_OBJECT (render), "edited",
|
g_signal_connect (G_OBJECT (render), "edited",
|
||||||
|
@@ -698,7 +698,7 @@ fe_beep (session *sess)
|
|||||||
|
|
||||||
if (ca_context_play (ca_con, 0, CA_PROP_EVENT_ID, "message-new-instant", NULL) != 0)
|
if (ca_context_play (ca_con, 0, CA_PROP_EVENT_ID, "message-new-instant", NULL) != 0)
|
||||||
#endif
|
#endif
|
||||||
gdk_display_beep (gdk_display_get_default ());
|
gdk_beep ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -674,6 +674,8 @@ key_dialog_treeview_new (GtkWidget *box)
|
|||||||
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW(view))),
|
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW(view))),
|
||||||
"changed", G_CALLBACK (key_dialog_selection_changed), NULL);
|
"changed", G_CALLBACK (key_dialog_selection_changed), NULL);
|
||||||
|
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
|
|
||||||
render = gtk_cell_renderer_accel_new ();
|
render = gtk_cell_renderer_accel_new ();
|
||||||
g_object_set (render, "editable", TRUE,
|
g_object_set (render, "editable", TRUE,
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
@@ -165,6 +165,7 @@ ignore_treeview_new (GtkWidget *box)
|
|||||||
UNIGNORE_COLUMN, _("Unignore"),
|
UNIGNORE_COLUMN, _("Unignore"),
|
||||||
-1);
|
-1);
|
||||||
|
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
|
gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (view), 0), TRUE);
|
||||||
|
|
||||||
/* attach to signals and customise columns */
|
/* attach to signals and customise columns */
|
||||||
|
@@ -399,22 +399,27 @@ fe_set_title (session *sess)
|
|||||||
_(DISPLAY_NAME));
|
_(DISPLAY_NAME));
|
||||||
break;
|
break;
|
||||||
case SESS_SERVER:
|
case SESS_SERVER:
|
||||||
g_snprintf (tbuf, sizeof (tbuf), "%s%s%s - %s",
|
g_snprintf (tbuf, sizeof (tbuf), "%s @ %s - %s",
|
||||||
prefs.hex_gui_win_nick ? sess->server->nick : "",
|
sess->server->nick, server_get_network (sess->server, TRUE),
|
||||||
prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE),
|
|
||||||
_(DISPLAY_NAME));
|
_(DISPLAY_NAME));
|
||||||
break;
|
break;
|
||||||
case SESS_CHANNEL:
|
case SESS_CHANNEL:
|
||||||
/* don't display keys in the titlebar */
|
/* don't display keys in the titlebar */
|
||||||
|
if (prefs.hex_gui_win_modes)
|
||||||
|
{
|
||||||
g_snprintf (tbuf, sizeof (tbuf),
|
g_snprintf (tbuf, sizeof (tbuf),
|
||||||
"%s%s%s / %s%s%s%s - %s",
|
"%s @ %s / %s (%s) - %s",
|
||||||
prefs.hex_gui_win_nick ? sess->server->nick : "",
|
sess->server->nick, server_get_network (sess->server, TRUE),
|
||||||
prefs.hex_gui_win_nick ? " @ " : "",
|
sess->channel, sess->current_modes ? sess->current_modes : "",
|
||||||
server_get_network (sess->server, TRUE), sess->channel,
|
_(DISPLAY_NAME));
|
||||||
prefs.hex_gui_win_modes && sess->current_modes ? " (" : "",
|
}
|
||||||
prefs.hex_gui_win_modes && sess->current_modes ? sess->current_modes : "",
|
else
|
||||||
prefs.hex_gui_win_modes && sess->current_modes ? ")" : "",
|
{
|
||||||
_(DISPLAY_NAME));
|
g_snprintf (tbuf, sizeof (tbuf),
|
||||||
|
"%s @ %s / %s - %s",
|
||||||
|
sess->server->nick, server_get_network (sess->server, TRUE),
|
||||||
|
sess->channel, _(DISPLAY_NAME));
|
||||||
|
}
|
||||||
if (prefs.hex_gui_win_ucount)
|
if (prefs.hex_gui_win_ucount)
|
||||||
{
|
{
|
||||||
g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total);
|
g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total);
|
||||||
@@ -422,9 +427,8 @@ fe_set_title (session *sess)
|
|||||||
break;
|
break;
|
||||||
case SESS_NOTICES:
|
case SESS_NOTICES:
|
||||||
case SESS_SNOTICES:
|
case SESS_SNOTICES:
|
||||||
g_snprintf (tbuf, sizeof (tbuf), "%s%s%s (notices) - %s",
|
g_snprintf (tbuf, sizeof (tbuf), "%s @ %s (notices) - %s",
|
||||||
prefs.hex_gui_win_nick ? sess->server->nick : "",
|
sess->server->nick, server_get_network (sess->server, TRUE),
|
||||||
prefs.hex_gui_win_nick ? " @ " : "", server_get_network (sess->server, TRUE),
|
|
||||||
_(DISPLAY_NAME));
|
_(DISPLAY_NAME));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -66,6 +66,7 @@ plugingui_treeview_new (GtkWidget *box)
|
|||||||
FILE_COLUMN, _("File"),
|
FILE_COLUMN, _("File"),
|
||||||
DESC_COLUMN, _("Description"),
|
DESC_COLUMN, _("Description"),
|
||||||
FILEPATH_COLUMN, NULL, -1);
|
FILEPATH_COLUMN, NULL, -1);
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id));
|
for (col_id=0; (col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), col_id));
|
||||||
col_id++)
|
col_id++)
|
||||||
gtk_tree_view_column_set_alignment (col, 0.5);
|
gtk_tree_view_column_set_alignment (col, 0.5);
|
||||||
|
@@ -176,7 +176,6 @@ static const setting appearance_settings[] =
|
|||||||
{ST_HEADER, N_("Title Bar"),0,0,0},
|
{ST_HEADER, N_("Title Bar"),0,0,0},
|
||||||
{ST_TOGGLE, N_("Show channel modes"), P_OFFINTNL(hex_gui_win_modes),0,0,0},
|
{ST_TOGGLE, N_("Show channel modes"), P_OFFINTNL(hex_gui_win_modes),0,0,0},
|
||||||
{ST_TOGGLR, N_("Show number of users"), P_OFFINTNL(hex_gui_win_ucount),0,0,0},
|
{ST_TOGGLR, N_("Show number of users"), P_OFFINTNL(hex_gui_win_ucount),0,0,0},
|
||||||
{ST_TOGGLE, N_("Show nickname"), P_OFFINTNL(hex_gui_win_nick),0,0,0},
|
|
||||||
|
|
||||||
{ST_END, 0, 0, 0, 0, 0}
|
{ST_END, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -909,7 +908,7 @@ setup_create_hscale (GtkWidget *table, int row, const setting *set)
|
|||||||
|
|
||||||
#ifndef WIN32 /* Windows always supports this */
|
#ifndef WIN32 /* Windows always supports this */
|
||||||
/* Only used for transparency currently */
|
/* Only used for transparency currently */
|
||||||
if (!gdk_screen_is_composited (gdk_window_get_screen (GDK_WINDOW (current_sess->gui->window))))
|
if (!gtk_widget_is_composited (current_sess->gui->window))
|
||||||
gtk_widget_set_sensitive (wid, FALSE);
|
gtk_widget_set_sensitive (wid, FALSE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -1794,6 +1793,7 @@ setup_create_sound_page (void)
|
|||||||
G_CALLBACK (setup_snd_row_cb), NULL);
|
G_CALLBACK (setup_snd_row_cb), NULL);
|
||||||
gtk_widget_show (sound_tree);
|
gtk_widget_show (sound_tree);
|
||||||
gtk_container_add (GTK_CONTAINER (scrolledwindow1), sound_tree);
|
gtk_container_add (GTK_CONTAINER (scrolledwindow1), sound_tree);
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (sound_tree), TRUE);
|
||||||
|
|
||||||
table1 = gtk_table_new (2, 3, FALSE);
|
table1 = gtk_table_new (2, 3, FALSE);
|
||||||
gtk_widget_show (table1);
|
gtk_widget_show (table1);
|
||||||
|
@@ -131,7 +131,7 @@ PrintTextRaw (void *xtbuf, unsigned char *text, int indent, time_t stamp)
|
|||||||
{
|
{
|
||||||
beep_done = TRUE;
|
beep_done = TRUE;
|
||||||
if (!prefs.hex_input_filter_beep)
|
if (!prefs.hex_input_filter_beep)
|
||||||
gdk_display_beep (gdk_display_get_default ());
|
gdk_beep ();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
text++;
|
text++;
|
||||||
@@ -356,6 +356,7 @@ pevent_treeview_new (GtkWidget *box)
|
|||||||
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
|
||||||
gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);
|
gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);
|
||||||
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), TRUE);
|
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), TRUE);
|
||||||
|
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
|
||||||
|
|
||||||
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
|
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
|
||||||
g_signal_connect (G_OBJECT (sel), "changed",
|
g_signal_connect (G_OBJECT (sel), "changed",
|
||||||
|
@@ -3811,8 +3811,7 @@ gtk_xtext_render_page (GtkXText * xtext)
|
|||||||
if (xtext->buffer->indent < MARGIN)
|
if (xtext->buffer->indent < MARGIN)
|
||||||
xtext->buffer->indent = MARGIN; /* 2 pixels is our left margin */
|
xtext->buffer->indent = MARGIN; /* 2 pixels is our left margin */
|
||||||
|
|
||||||
width = gdk_window_get_width (GTK_WIDGET (xtext)->window);
|
gdk_drawable_get_size (GTK_WIDGET (xtext)->window, &width, &height);
|
||||||
height = gdk_window_get_height (GTK_WIDGET (xtext)->window);
|
|
||||||
|
|
||||||
if (width < 34 || height < xtext->fontsize || width < xtext->buffer->indent + 32)
|
if (width < 34 || height < xtext->fontsize || width < xtext->buffer->indent + 32)
|
||||||
return;
|
return;
|
||||||
|
@@ -25,7 +25,7 @@ DefaultDirName={pf64}\HexChat
|
|||||||
DefaultDirName={pf32}\HexChat
|
DefaultDirName={pf32}\HexChat
|
||||||
#endif
|
#endif
|
||||||
DefaultGroupName=HexChat
|
DefaultGroupName=HexChat
|
||||||
AllowNoIcons=yes
|
DisableProgramGroupPage=yes
|
||||||
SolidCompression=yes
|
SolidCompression=yes
|
||||||
Compression=lzma2/ultra64
|
Compression=lzma2/ultra64
|
||||||
SourceDir=..\rel
|
SourceDir=..\rel
|
||||||
@@ -60,9 +60,6 @@ Name: "custom"; Description: "Custom Installation"; Flags: iscustom
|
|||||||
Name: "libs"; Description: "HexChat"; Types: normal minimal custom; Flags: fixed
|
Name: "libs"; Description: "HexChat"; Types: normal minimal custom; Flags: fixed
|
||||||
Name: "xctext"; Description: "HexChat-Text"; Types: custom; Flags: disablenouninstallwarning
|
Name: "xctext"; Description: "HexChat-Text"; Types: custom; Flags: disablenouninstallwarning
|
||||||
Name: "xtm"; Description: "HexChat Theme Manager"; Types: normal custom; Flags: disablenouninstallwarning
|
Name: "xtm"; Description: "HexChat Theme Manager"; Types: normal custom; Flags: disablenouninstallwarning
|
||||||
Name: "icons"; Description: "Create Shortcuts"; Types: custom; Flags: disablenouninstallwarning
|
|
||||||
Name: "icons\desktopicon"; Description: "Create Desktop Shortcut"; Types: custom; Flags: disablenouninstallwarning
|
|
||||||
Name: "icons\quicklaunchicon"; Description: "Create Quick Launch Shortcut"; Types: custom; Flags: disablenouninstallwarning
|
|
||||||
Name: "translations"; Description: "Translations"; Types: normal custom; Flags: disablenouninstallwarning
|
Name: "translations"; Description: "Translations"; Types: normal custom; Flags: disablenouninstallwarning
|
||||||
Name: "spell"; Description: "Spelling Dictionaries"; Types: custom; Flags: disablenouninstallwarning
|
Name: "spell"; Description: "Spelling Dictionaries"; Types: custom; Flags: disablenouninstallwarning
|
||||||
Name: "plugins"; Description: "Plugins"; Types: custom; Flags: disablenouninstallwarning
|
Name: "plugins"; Description: "Plugins"; Types: custom; Flags: disablenouninstallwarning
|
||||||
@@ -199,16 +196,14 @@ Source: "hexchat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components:
|
|||||||
Source: "thememan.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xtm
|
Source: "thememan.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xtm
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: "{group}\HexChat"; Filename: "{app}\hexchat.exe"; AppUserModelID: "HexChat.Desktop.Notify"; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat"; Filename: "{app}\hexchat.exe"; AppUserModelID: "HexChat.Desktop.Notify"; Tasks: not portable
|
||||||
Name: "{group}\HexChat Safe Mode"; Filename: "{app}\hexchat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat Safe Mode"; Filename: "{app}\hexchat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable
|
||||||
Name: "{group}\HexChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable
|
||||||
Name: "{group}\HexChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable
|
||||||
Name: "{group}\HexChat Config Folder"; Filename: "%APPDATA%\HexChat\"; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat Config Folder"; Filename: "%APPDATA%\HexChat\"; Tasks: not portable
|
||||||
Name: "{group}\HexChat-Text"; Filename: "{app}\hexchat-text.exe"; Components: xctext; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat-Text"; Filename: "{app}\hexchat-text.exe"; Components: xctext; Tasks: not portable
|
||||||
Name: "{group}\HexChat Theme Manager"; Filename: "{app}\thememan.exe"; Components: xtm; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\HexChat Theme Manager"; Filename: "{app}\thememan.exe"; Components: xtm; Tasks: not portable
|
||||||
Name: "{group}\Uninstall HexChat"; Filename: "{uninstallexe}"; Tasks: not portable; Check: not WizardNoIcons
|
Name: "{group}\Uninstall HexChat"; Filename: "{uninstallexe}"; Tasks: not portable
|
||||||
Name: "{commondesktop}\HexChat"; Filename: "{app}\hexchat.exe"; AppUserModelID: "HexChat.Desktop.Notify"; Components: icons\desktopicon; Tasks: not portable
|
|
||||||
Name: "{commonappdata}\Microsoft\Internet Explorer\Quick Launch\HexChat"; Filename: "{app}\hexchat.exe"; Components: icons\quicklaunchicon; Tasks: not portable
|
|
||||||
|
|
||||||
[Messages]
|
[Messages]
|
||||||
BeveledLabel= {#APPNAM}
|
BeveledLabel= {#APPNAM}
|
||||||
|
Reference in New Issue
Block a user