/* per-channel/dialog settings :: /CHANOPT */ #include #include #include #include #include #include #include #ifdef WIN32 #include #else #include #endif #include "xchat.h" #include "cfgfiles.h" #include "server.h" #include "text.h" #include "util.h" #include "xchatc.h" static GSList *chanopt_list = NULL; static gboolean chanopt_open = FALSE; static gboolean chanopt_changed = FALSE; typedef struct { char *name; char *alias; /* old names from 2.8.4 */ int offset; } channel_options; #define S_F(xx) STRUCT_OFFSET_STR(struct session,xx) static const channel_options chanopt[] = { {"alert_beep", "BEEP", S_F(alert_beep)}, {"alert_taskbar", NULL, S_F(alert_taskbar)}, {"alert_tray", "TRAY", S_F(alert_tray)}, {"text_hidejoinpart", "CONFMODE", S_F(text_hidejoinpart)}, {"text_logging", NULL, S_F(text_logging)}, {"text_scrollback", NULL, S_F(text_scrollback)}, }; #undef S_F static char * chanopt_value (guint8 val) { switch (val) { case SET_OFF: return "OFF"; case SET_ON: return "ON"; default: return "{unset}"; } } /* handle the /CHANOPT command */ int chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[]) { int dots, i = 0, j, p = 0; guint8 val; int offset = 2; char *find; gboolean quiet = FALSE; int newval = -1; if (!strcmp (word[2], "-quiet")) { quiet = TRUE; offset++; } find = word[offset++]; if (word[offset][0]) { if (!g_ascii_strcasecmp (word[offset], "ON")) newval = 1; else if (!g_ascii_strcasecmp (word[offset], "OFF")) newval = 0; else if (word[offset][0] == 'u') newval = SET_DEFAULT; else newval = atoi (word[offset]); } if (!quiet) PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n", sess->server->network ? server_get_network (sess->server, TRUE) : _(""), sess->channel[0] ? sess->channel : _("")); while (i < sizeof (chanopt) / sizeof (channel_options)) { if (find[0] == 0 || match (find, chanopt[i].name) || (chanopt[i].alias && match (find, chanopt[i].alias))) { if (newval != -1) /* set new value */ { *(guint8 *)G_STRUCT_MEMBER_P(sess, chanopt[i].offset) = newval; } if (!quiet) /* print value */ { strcpy (tbuf, chanopt[i].name); p = strlen (tbuf); tbuf[p++] = 3; tbuf[p++] = '2'; dots = 20 - strlen (chanopt[i].name); for (j = 0; j < dots; j++) tbuf[p++] = '.'; tbuf[p++] = 0; val = G_STRUCT_MEMBER (guint8, sess, chanopt[i].offset); PrintTextf (sess, "%s\0033:\017 %s", tbuf, chanopt_value (val)); } } i++; } return TRUE; } /* is a per-channel setting set? Or is it UNSET and * the global version is set? */ gboolean chanopt_is_set (unsigned int global, guint8 per_chan_setting) { if (per_chan_setting == SET_DEFAULT) return global; return per_chan_setting; } /* additive version */ gboolean chanopt_is_set_a (unsigned int global, guint8 per_chan_setting) { if (per_chan_setting == SET_DEFAULT) return global; return per_chan_setting || global; } /* === below is LOADING/SAVING stuff only === */ typedef struct { /* Per-Channel Alerts */ /* use a byte, because we need a pointer to each element */ guint8 alert_beep; guint8 alert_taskbar; guint8 alert_tray; /* Per-Channel Settings */ guint8 text_hidejoinpart; guint8 text_logging; guint8 text_scrollback; char *network; char *channel; } chanopt_in_memory; static chanopt_in_memory * chanopt_find (char *network, char *channel, gboolean add_new) { GSList *list; chanopt_in_memory *co; int i; for (list = chanopt_list; list; list = list->next) { co = list->data; if (!g_ascii_strcasecmp (co->channel, channel) && !g_ascii_strcasecmp (co->network, network)) return co; } if (!add_new) return NULL; /* allocate a new one */ co = g_malloc0 (sizeof (chanopt_in_memory)); co->channel = g_strdup (channel); co->network = g_strdup (network); /* set all values to SET_DEFAULT */ i = 0; while (i < sizeof (chanopt) / sizeof (channel_options)) { *(guint8 *)G_STRUCT_MEMBER_P(co, chanopt[i].offset) = SET_DEFAULT; i++; } chanopt_list = g_slist_prepend (chanopt_list, co); chanopt_changed = TRUE; return co; } static void chanopt_add_opt (chanopt_in_memory *co, char *var, int new_value) { int i; i = 0; while (i < sizeof (chanopt) / sizeof (channel_options)) { if (!strcmp (var, chanopt[i].name)) { *(guint8 *)G_STRUCT_MEMBER_P(co, chanopt[i].offset) = new_value; } i++; } } /* load chanopt.conf from disk into our chanopt_list GSList */ static void chanopt_load_