home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 52
/
Amiga_Dream_52.iso
/
Linux
/
Divers
/
yagirc-0.51.tar.gz
/
yagirc-0.51.tar
/
yagirc-0.51
/
gui_setup.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-05-11
|
24KB
|
813 lines
/*
gui_setup.c : Setup dialog
Copyright (C) 1998 Timo Sirainen
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include <fcntl.h>
#include <gtk/gtk.h>
#include <glib.h>
#include "os.h"
#include "irc.h"
#include "gui.h"
#include "misc.h"
#include "gui_setup_alias.h"
#include "gui_setup_server.h"
#include "gui_setup_dcc.h"
#include "gui_setup_lists.h"
char *default_nick;
char *real_name;
char *user_name;
char *default_text_pixmap;
SETUP_THEME_REC *default_theme;
static SETUP_THEME_REC deftheme;
enum
{
SETUP_TYPE_UNKNOWN,
SETUP_TYPE_STR,
SETUP_TYPE_INT,
SETUP_TYPE_COLOR,
SETUP_TYPE_COLORS,
SETUP_TYPE_SERVER,
SETUP_TYPE_LIST,
SETUP_TYPE_ALIAS,
SETUP_TYPE_THEME,
};
typedef struct
{
char *name;
int type;
int multiple;
void *ptr;
}
SETUP_REC;
static SETUP_REC setups[] =
{
{ "Nick", SETUP_TYPE_STR, 0, &default_nick },
{ "RealName", SETUP_TYPE_STR, 0, &real_name },
{ "GlobalServer", SETUP_TYPE_SERVER, 1, &globalservers },
{ "LocalServer", SETUP_TYPE_SERVER, 1, &servers },
{ "Ignore", SETUP_TYPE_LIST, 1, &ignores },
{ "Notify", SETUP_TYPE_LIST, 1, ¬ifies },
{ "Channel", SETUP_TYPE_LIST, 1, &joinlist },
{ "Alias", SETUP_TYPE_ALIAS, 1, NULL },
{ "Theme", SETUP_TYPE_THEME, 1, &themes },
{ NULL, 0, 0, NULL }
};
static GtkWidget *setupwin = NULL; /* setup window widget */
static int setup_open = 0; /* setup window is opened */
/* create text field with label */
GtkWidget *gui_add_label(GtkWidget *box, char *text, char *field)
{
GtkWidget *label;
GtkWidget *entry;
GtkWidget *hbox;
g_return_val_if_fail(box != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
hbox = gtk_hbox_new(FALSE, 0);
gtk_container_border_width (GTK_CONTAINER (hbox), 4);
gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new(text);
gtk_widget_set_usize (label, 60, -1);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
entry = gtk_entry_new();
if (field != NULL) gtk_entry_set_text (GTK_ENTRY (entry), field);
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
gtk_widget_show (entry);
return entry;
}
void gui_setup_init(void)
{
struct passwd *entry;
char *ptr;
int n;
if (setup_open)
{
/* setup dialog is open - don't initialize. */
return;
}
for (n = 0; setups[n].name != NULL; n++)
{
switch (setups[n].type)
{
case SETUP_TYPE_INT:
*((int *) setups[n].ptr) = 0;
break;
case SETUP_TYPE_STR:
*((char **) setups[n].ptr) = NULL;
break;
}
}
/* get user information */
user_name = getenv("IRCUSER");
real_name = getenv("IRCNAME");
globalservers = servers = NULL;
aliases = NULL;
ignores = NULL;
notifies = NULL;
themes = NULL;
default_theme = NULL;
deftheme.name = _("default theme");
deftheme.pixmap = NULL;
deftheme.fg = colors[BLACK];
deftheme.bg = colors[BWHITE];
deftheme.colors[0] = colors[CYAN];
deftheme.colors[1] = colors[BMAGENTA];
deftheme.colors[2] = colors[GREEN];
deftheme.colors[3] = colors[BMAGENTA];
deftheme.colors[4] = colors[MAGENTA];
deftheme.colors[5] = colors[RED];
deftheme.colors[6] = colors[BRED];
deftheme.colors[7] = colors[BMAGENTA];
deftheme.colors[8] = colors[MAGENTA];
deftheme.colors[9] = colors[GREEN];
deftheme.colors[10] = colors[BLACK];
deftheme.colors[11] = colors[BRED];
deftheme.colors[12] = colors[BBLUE];
deftheme.colors[13] = colors[GREEN];
deftheme.colors[14] = deftheme.fg;
/* get passwd-entry */
entry = getpwuid(getuid());
if (entry != NULL)
{
user_name = entry->pw_name;
if (real_name == NULL) real_name = entry->pw_gecos;
}
ptr = getenv("IRCNICK");
if (ptr == NULL)
{
if (user_name != NULL)
ptr = user_name;
else
ptr = "someone";
}
default_nick = ptr;
if (user_name == NULL || *user_name == '\0') user_name = default_nick;
if (real_name == NULL || *real_name == '\0') real_name = user_name;
user_name = g_strdup(user_name);
real_name = g_strdup(real_name);
default_nick = g_strdup(default_nick);
}
void gui_setup_deinit(void)
{
int n;
if (setup_open)
{
/* setup dialog is open - don't deinitialize. */
return;
}
for (n = 0; setups[n].name != NULL; n++)
{
char **str;
str = setups[n].ptr;
if (setups[n].type == SETUP_TYPE_STR && *str != NULL)
{
g_free(*str);
*str = NULL;
}
}
while (servers != NULL)
remove_server_list(&servers, (SETUP_SERVER_REC *) servers->data);
while (globalservers != NULL)
remove_server_list(&globalservers, (SETUP_SERVER_REC *) globalservers->data);
while (aliases != NULL)
remove_alias_list((ALIAS_REC *) aliases->data);
while (ignores != NULL)
{
g_free(ignores->data);
ignores = g_list_remove_link(ignores, ignores);
}
while (notifies != NULL)
{
g_free(notifies->data);
notifies = g_list_remove_link(notifies, notifies);
}
if (default_text_pixmap != NULL) g_free(default_text_pixmap);
while (themes != NULL)
gui_remove_theme_rec(&themes, themes->data);
g_free(user_name);
g_free(real_name);
g_free(default_nick);
}
/* Get next count parameters from data */
static char *get_params(char *data, int count, ...)
{
char **str, *tmp;
va_list args;
va_start(args, count);
while (count-- > 0)
{
str = (char **) va_arg(args, char **);
tmp = data;
while (*data != '\0' && *data != '\t') data++;
if (*data == '\t') *data++ = '\0';
if (str != NULL) *str = tmp;
}
va_end(args);
return data;
}
static void mkcolor(char *str, GdkColor *color)
{
unsigned long num;
if (sscanf(str, "%lu", &num) != 1) num = 0;
color->blue = (num & 0xff)*256;
color->green = num & 0xff00;
color->red = (num & 0xff0000)/256;
color->pixel = num;
}
/* Read yagIRC's configuration file */
static int read_config_file(char *fname)
{
char *tmp, str[500], *cmd, *value;
long linenum;
int n;
FILE *f;
tmp = convhome(fname);
f = fopen(tmp, "rb");
g_free(tmp);
if (f == NULL) return 0;
linenum = 0;
while (fgets(str, sizeof(str), f) != NULL)
{
linenum++;
if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0';
if (str[0] == '\0' || str[0] == '#') continue;
cmd = str;
while (*cmd == ' ') cmd++;
if (*cmd == '\0') continue;
value = strchr(cmd, '=');
if (value == NULL)
{
g_warning("%s:%ld Error in configuration file: missing '=', line ignored", fname, linenum);
continue;
}
if (value == cmd)
{
g_warning("%s:%ld Error in configuration file: missing command, line ignored", fname, linenum);
continue;
}
/* remove whitespace */
tmp = value-1;
while (*tmp == ' ') tmp--; *(tmp+1) = '\0';
while (*(++value) == ' ') ;
for (n = 0; setups[n].name != NULL; n++)
{
if (strcasecmp(cmd, setups[n].name) == 0)
{
switch (setups[n].type)
{
case SETUP_TYPE_STR:
{
char **str = (char **) setups[n].ptr;
if (*str != NULL) g_free(*str);
*str = g_strdup(value);
}
break;
case SETUP_TYPE_INT:
{
int *num = (int *) setups[n].ptr;
if (sscanf(value, "%d", num) != 1)
g_warning("%s:%ld Error in configuration file: value should be numeric, line ignored", fname, linenum);
}
break;
case SETUP_TYPE_COLOR:
{
unsigned long num;
GdkColor *color = (GdkColor *) setups[n].ptr;
if (sscanf(value, "%lu", &num) != 1)
g_warning("%s:%ld Error in configuration file: value should be numeric, line ignored", fname, linenum);
color->blue = (num & 0xff)*256;
color->green = num & 0xff00;
color->red = (num & 0xff0000)/256;
color->pixel = num;
}
break;
case SETUP_TYPE_COLORS:
{
unsigned long num;
int i;
GdkColor *color = (GdkColor *) setups[n].ptr;
for (i = 0; value != NULL; i++)
{
char *ptr;
ptr = strchr(value, ' ');
if (ptr != NULL) *ptr++ = '\0';
if (sscanf(value, "%lu", &num) != 1)
g_warning("%s:%ld Error in configuration file: value should be numeric, line ignored", fname, linenum);
color[i].blue = (num & 0xff)*256;
color[i].green = num & 0xff00;
color[i].red = (num & 0xff0000)/256;
color[i].pixel = num;
value = ptr;
}
}
break;
case SETUP_TYPE_SERVER:
{
GList **servers = (GList **) setups[n].ptr;
char *net, *name, *ports, *location;
int port;
get_params(value, 4, &net, &name, &ports, &location);
if (sscanf(ports, "%d", &port) != 1) port = 6667;
add_server_list(servers, net, name, port, location);
}
break;
case SETUP_TYPE_ALIAS:
{
char *alias, *cmd;
alias = value;
while (*value != '\0' && *value != '\t') value++;
if (*value == '\t') *value++ = '\0';
cmd = value;
add_alias_list(alias, cmd);
}
break;
case SETUP_TYPE_LIST:
{
GList **list = (GList **) setups[n].ptr;
if (glist_case_find_string(*list, value) == NULL)
*list = g_list_append(*list, g_strdup(value));
}
break;
case SETUP_TYPE_THEME:
{
GList **list = (GList **) setups[n].ptr;
char *def, *name, *fgs, *bgs, *colors[15];
int n;
get_params(value, 20, &def, &name, &default_text_pixmap, &fgs, &bgs,
&colors[0], &colors[1], &colors[2],
&colors[3], &colors[4], &colors[5],
&colors[6], &colors[7], &colors[8],
&colors[9], &colors[10], &colors[11],
&colors[12], &colors[13], &colors[14]);
mkcolor(fgs, &default_color);
mkcolor(bgs, &default_bgcolor);
if (*default_text_pixmap == '\0')
default_text_pixmap = NULL;
for (n = 0; n < 15; n++)
mkcolor(colors[n], &yag_colors[n]);
n = gui_add_theme_rec(list, name);
if (*def == '*')
{
/* this theme is the default */
default_theme = g_list_nth(*list, n)->data;
}
}
break;
}
break;
}
}
if (setups[n].name == NULL)
g_warning("%s:%ld Error in configuration file: unknown command '%s', line ignored", fname, linenum, cmd);
}
fclose(f);
return 1;
}
int gui_read_config(void)
{
int ret;
if (setup_open)
{
/* setup dialog is open - don't read anything.. */
return 0;
}
read_config_file(GLOBAL_CONFIG_FILE);
read_config_file(SITE_CONFIG_FILE);
ret = read_config_file(CONFIG_FILE);
if (default_theme == NULL)
{
if (themes != NULL)
default_theme = g_list_first(themes)->data;
else
{
SETUP_THEME_REC *theme;
theme = (SETUP_THEME_REC *) g_malloc(sizeof(SETUP_THEME_REC));
memcpy(theme, &deftheme, sizeof(deftheme));
theme->name = g_strdup(deftheme.name);
theme->pixmap = NULL;
themes = g_list_append(NULL, theme);
default_theme = theme;
}
}
default_text_pixmap = g_strdup(default_theme->pixmap);
default_color = default_theme->fg;
default_bgcolor = default_theme->bg;
memcpy(yag_colors, default_theme->colors, sizeof(yag_colors));
return ret;
}
/* read all data from configuration file to linked list */
GList *init_config_write(GList *list, char *fname)
{
FILE *f;
char *tmp, *str;
tmp = convhome(fname);
f = fopen(tmp, "rb");
g_free(tmp);
if (f == NULL) return list;
str = g_malloc(1000);
tmp = g_malloc(1000);
while (fgets(str, 1000, f) != NULL)
{
char *cmd, *value;
if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0';
if (str[0] == '\0' || str[0] == '#') continue;
cmd = str;
while (*cmd == ' ') cmd++;
if (*cmd == '\0') continue;
/* get command name */
value = strchr(cmd, '=');
if (value == NULL || value == cmd) continue;
/* remove whitespace */
{
char *tmp;
tmp = value-1;
while (*tmp == ' ') tmp--; *(tmp+1) = '\0';
while (*(++value) == ' ') ;
}
sprintf(tmp, "%s = %s", cmd, value);
list = g_list_append(list, g_strdup(tmp));
}
g_free(str);
g_free(tmp);
fclose(f);
return list;
}
/* check if this line is already found from global/site configs, if not,
write it to user config file .. */
static void write_config_line(FILE *f, GList *list, char *str)
{
while (list != NULL)
{
if (strcmp((char *) list->data, str) == 0)
return;
list = list->next;
}
fprintf(f, "%s\n", str);
}
int gui_write_config(void)
{
GList *tmp, *config;
char *str;
int n;
FILE *f;
if (setup_open)
{
/* setup dialog is open - don't save changes. */
return 0;
}
str = convhome(CONFIG_FILE);
f = fopen(str, "w+t");
g_free(str);
if (f == NULL)
{
/* couldn't create config file */
return 0;
}
config = init_config_write(NULL, GLOBAL_CONFIG_FILE);
config = init_config_write(config, SITE_CONFIG_FILE);
config = g_list_first(config);
/* save generic things.. */
str = g_malloc(1000); /* enough? */
for (n = 0; setups[n].name != NULL; n++)
{
*str = '\0';
switch (setups[n].type)
{
case SETUP_TYPE_STR:
{
char **s = (char **) setups[n].ptr;
if (*s != NULL)
sprintf(str, "%s = %s", setups[n].name, *s);
}
break;
case SETUP_TYPE_INT:
sprintf(str, "%s = %d", setups[n].name, *((int *) setups[n].ptr));
break;
case SETUP_TYPE_COLOR:
{
unsigned long num;
GdkColor *color = (GdkColor *) setups[n].ptr;
num =
(color->blue & 0xff00)/256 |
(color->green & 0xff00) |
(color->red & 0xff00)*256;
sprintf(str, "%s = %lu", setups[n].name, num);
}
break;
case SETUP_TYPE_LIST:
{
GList **list = (GList **) setups[n].ptr;
for (tmp = g_list_first(*list); tmp != NULL; tmp = tmp->next)
{
sprintf(str, "%s = %s", setups[n].name, (char *) tmp->data);
write_config_line(f, config, str);
}
*str = '\0';
}
break;
}
if (*str != '\0')
write_config_line(f, config, str);
}
/* save global servers list */
/*for (tmp = g_list_first(globalservers); tmp != NULL; tmp = tmp->next)
{
SETUP_SERVER_REC *serv;
serv = (SETUP_SERVER_REC *) tmp->data;
sprintf(str, "GlobalServer = %s\t%s\t%d\t%s", serv->ircnet, serv->name, serv->port, serv->location);
write_config_line(f, config, str);
}*/
/* save list of local servers list */
for (tmp = g_list_first(servers); tmp != NULL; tmp = tmp->next)
{
SETUP_SERVER_REC *serv;
serv = (SETUP_SERVER_REC *) tmp->data;
sprintf(str, "LocalServer = %s\t%s\t%d\t%s", serv->ircnet, serv->name, serv->port, serv->location);
write_config_line(f, config, str);
}
/* save alias list */
for (tmp = g_list_first(aliases); tmp != NULL; tmp = tmp->next)
{
ALIAS_REC *al;
al = (ALIAS_REC *) tmp->data;
sprintf(str, "Alias = %s\t%s", al->alias, al->cmd);
write_config_line(f, config, str);
}
/* save themes */
for (tmp = g_list_first(themes); tmp != NULL; tmp = tmp->next)
{
SETUP_THEME_REC *theme;
unsigned long num, num2;
int n, pos;
theme = (SETUP_THEME_REC *) tmp->data;
num = (theme->fg.blue & 0xff00)/256 | (theme->fg.green & 0xff00) |
(theme->fg.red & 0xff00)*256;
num2 = (theme->bg.blue & 0xff00)/256 | (theme->bg.green & 0xff00) |
(theme->bg.red & 0xff00)*256;
pos = sprintf(str, "Theme = %s\t%s\t%s\t%lu\t%lu",
theme == default_theme ? "*" : "",
theme->name,
theme->pixmap == NULL ? "" : theme->pixmap,
num, num2);
for (n = 0; n < 15; n++)
{
num =
(theme->colors[n].blue & 0xff00)/256 |
(theme->colors[n].green & 0xff00) |
(theme->colors[n].red & 0xff00)*256;
pos += sprintf(str+pos, "\t%lu", num);
}
write_config_line(f, config, str);
}
g_free(str);
fclose(f);
return 1;
}
/* signal: Apply button pressed */
static void gui_setup_apply(GtkWidget *win)
{
setup_open = 0;
gui_setup_servers_accept();
gui_setup_outlook_accept();
gui_write_config();
setup_open = 1;
gui_refresh_windows();
}
/* signal: OK button pressed */
static void gui_setup_ok(GtkWidget *win)
{
gui_setup_apply(win);
gtk_widget_destroy(win);
}
/* signal: CANCEL button pressed */
static void gui_setup_cancel(GtkWidget *win)
{
setup_open = 0;
gui_setup_deinit();
gui_setup_init();
gui_read_config();
gtk_widget_destroy(win);
}
/* signal: setup window gets destroyed */
static void setup_destroy(GtkWidget *window)
{
setup_open = 0;
}
/* signal: setup window is closed */
static int setup_delete_event(GtkWidget *window)
{
setup_open = 0;
return 0;
}
static void add_page(GtkWidget *notebook, char *text, GUI_SETUP_FUNC func)
{
GtkWidget *vbox;
GtkWidget *label;
label = gtk_label_new(text);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_border_width(GTK_CONTAINER(vbox), 10);
gtk_widget_show(vbox);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
func(vbox);
}
/* Run setup */
void gui_setup(void)
{
GtkWidget *notebook;
GtkWidget *button;
if (setup_open)
{
/* setup window already created */
gdk_window_raise(setupwin->window);
return;
}
setup_open = 1;
setupwin = gtk_dialog_new();
gtk_signal_connect (GTK_OBJECT (setupwin), "delete_event",
GTK_SIGNAL_FUNC(setup_delete_event), NULL);
gtk_signal_connect (GTK_OBJECT (setupwin), "destroy",
GTK_SIGNAL_FUNC(setup_destroy), NULL);
gtk_window_set_title (GTK_WINDOW (setupwin), "yagIRC setup");
gtk_window_position (GTK_WINDOW (setupwin), GTK_WIN_POS_CENTER);
notebook = gtk_notebook_new();
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(setupwin)->vbox), notebook);
gtk_widget_show(notebook);
add_page(notebook, _("Servers"), (GUI_SETUP_FUNC) gui_setup_servers);
add_page(notebook, _("Aliases"), (GUI_SETUP_FUNC) gui_setup_aliases);
add_page(notebook, _("Ignore list"), (GUI_SETUP_FUNC) gui_setup_ignorelist);
add_page(notebook, _("Notify list"), (GUI_SETUP_FUNC) gui_setup_notifylist);
add_page(notebook, _("DCC"), (GUI_SETUP_FUNC) gui_setup_dcc);
add_page(notebook, _("Outlook"), (GUI_SETUP_FUNC) gui_setup_outlook);
button = gtk_button_new_with_label (_("Ok"));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(setupwin)->action_area), button, TRUE, TRUE, 10);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gui_setup_ok), GTK_OBJECT(setupwin));
/*GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);*/
gtk_widget_show (button);
button = gtk_button_new_with_label (_("Cancel"));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(setupwin)->action_area), button, TRUE, TRUE, 10);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gui_setup_cancel),
GTK_OBJECT(setupwin));
gtk_widget_show (button);
button = gtk_button_new_with_label (_("Apply"));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(setupwin)->action_area), button, TRUE, TRUE, 10);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (gui_setup_apply),
GTK_OBJECT(setupwin));
gtk_widget_show (button);
gtk_widget_show(setupwin);
}