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_server.c < prev    next >
C/C++ Source or Header  |  1998-05-11  |  17KB  |  542 lines

  1. /*
  2.  
  3.  gui_setup_server.c : Servers notebook entry for setup
  4.  
  5.     Copyright (C) 1998 Timo Sirainen
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <string.h>
  24.  
  25. #include <gtk/gtk.h>
  26. #include <glib.h>
  27.  
  28. #include "os.h"
  29. #include "gui.h"
  30. #include "gui_setup_server.h"
  31.  
  32. GList *servers; /* list of local servers */
  33. GList *globalservers; /* list of global servers */
  34.  
  35. /* temp entry widgets */
  36. static GtkWidget *nick_text, *name_text;
  37. static GtkWidget *server_text, *port_text, *ircnet_text, *location_text;
  38.  
  39. int compare_servers(SETUP_SERVER_REC *p1, SETUP_SERVER_REC *p2)
  40. {
  41.     int n;
  42.  
  43.     if (p1 == NULL) return -1;
  44.     if (p2 == NULL) return 1;
  45.  
  46.     n = strcasecmp(p1->ircnet, p2->ircnet);
  47.     if (n == 0)
  48.     {
  49.         n = strcasecmp(p1->location, p2->location);
  50.         if (n == 0)
  51.             n = strcasecmp(p1->name, p2->name);
  52.     }
  53.     return n;
  54. }
  55.  
  56. /* add new server to server list */
  57. SETUP_SERVER_REC *add_server_list(GList **servers, char *net, char *name, int port, char *location)
  58. {
  59.     SETUP_SERVER_REC *server;
  60.     GList *tmp;
  61.  
  62.     g_return_val_if_fail(net != NULL, NULL);
  63.     g_return_val_if_fail(location != NULL, NULL);
  64.     g_return_val_if_fail(name != NULL, NULL);
  65.  
  66.     /* check if there's any existing servers with that name.. */
  67.     for (tmp = g_list_first(*servers); tmp != NULL; tmp = tmp->next)
  68.     {
  69.         server = (SETUP_SERVER_REC *) tmp->data;
  70.         if (strcasecmp(server->name, name) == 0)
  71.         {
  72.             /* found, remove it. */
  73.             *servers = g_list_remove_link(*servers, tmp);
  74.             break;
  75.         }
  76.     }
  77.     server = (SETUP_SERVER_REC *) g_malloc(sizeof(SETUP_SERVER_REC));
  78.     server->ircnet = g_strdup(net);
  79.     server->name = g_strdup(name);
  80.     server->location = g_strdup(location);
  81.     server->port = port;
  82.  
  83.     if (*servers == globalservers)
  84.         *servers = g_list_insert_sorted(*servers, server, (GCompareFunc) compare_servers);
  85.     else
  86.         *servers = g_list_append(*servers, server);
  87.     return server;
  88. }
  89.  
  90. /* remove server from server list */
  91. void remove_server_list(GList **servers, SETUP_SERVER_REC *rec)
  92. {
  93.     g_return_if_fail(rec != NULL);
  94.  
  95.     *servers = g_list_remove(*servers, rec);
  96.  
  97.     g_free(rec->ircnet);
  98.     g_free(rec->name);
  99.     g_free(rec->location);
  100.     g_free(rec);
  101. }
  102.  
  103. /* Add server to GtkList */
  104. static GList *server_list_add(SETUP_SERVER_REC *server)
  105. {
  106.     GtkWidget *li;
  107.     GList *list;
  108.     char *str;
  109.  
  110.     /* create list item widget */
  111.     str = (char *) g_malloc(strlen(server->ircnet)+
  112.                             strlen(server->name)+
  113.                             strlen(server->location)+10);
  114.     sprintf(str, "%s: [%s] %s", server->ircnet, server->location, server->name);
  115.     li = gtk_list_item_new_with_label(str);
  116.     g_free(str);
  117.  
  118.     gtk_object_set_data(GTK_OBJECT(li), "server", server);
  119.     gtk_widget_show(li);
  120.  
  121.     /* add to local server list */
  122.     list = g_list_append(NULL, li);
  123.     return list;
  124. }
  125.  
  126. /* Add new server to both GList and GtkList */
  127. static SETUP_SERVER_REC *local_server_add(GtkList *gtklist, char *ircnet, char *name, int port, char *location)
  128. {
  129.     SETUP_SERVER_REC *server;
  130.  
  131.     /* add to list */
  132.     server = add_server_list(&servers, ircnet, name, port, location);
  133.     gtk_list_append_items(gtklist, server_list_add(server));
  134.  
  135.     return server;
  136. }
  137.  
  138. /* Remove server from both GList and GtkList */
  139. static void local_server_remove(GtkList *gtklist, GtkWidget *widget)
  140. {
  141.     SETUP_SERVER_REC *rec;
  142.     int pos, len;
  143.  
  144.     rec = gtk_object_get_data(GTK_OBJECT(widget), "server");
  145.     remove_server_list(&servers, rec);
  146.  
  147.     pos = gtk_list_child_position(gtklist, widget);
  148.     gtk_list_clear_items(gtklist, pos, pos+1);
  149.  
  150.     len = g_list_length(gtklist->children)-1;
  151.     gtk_list_select_item(gtklist, pos > len ? len : pos);
  152. }
  153.  
  154. /* make a tree list of servers */
  155. static void create_server_tree(GList *servers, GtkTree *tree)
  156. {
  157.     GList *tmp;
  158.     GtkWidget *li, *subtree, *subitem;
  159.     char *ircnet;
  160.  
  161.     g_return_if_fail(tree != NULL);
  162.  
  163.     /* clear previous tree */
  164.     gtk_tree_clear_items(tree, 0, -1);
  165.  
  166.     ircnet = ""; subtree = GTK_WIDGET(tree); subitem = NULL;
  167.     for (tmp = g_list_first(servers); tmp != NULL; tmp = tmp->next)
  168.     {
  169.         SETUP_SERVER_REC *serv;
  170.         char *str;
  171.  
  172.         serv = (SETUP_SERVER_REC *) tmp->data;
  173.         str = (char *) g_malloc(strlen(serv->ircnet)+strlen(serv->location)+strlen(serv->name)+10);
  174.         sprintf(str, "[%s] %s", serv->location, serv->name);
  175.  
  176.         if (strcasecmp(ircnet, serv->ircnet) != 0)
  177.         {
  178.             if (subitem != NULL)
  179.             {
  180.                 gtk_tree_item_set_subtree(GTK_TREE_ITEM(subitem), subtree);
  181.             }
  182.             li = gtk_tree_item_new_with_label(serv->ircnet);
  183.             gtk_widget_show (li);
  184.             subtree = gtk_tree_new();
  185.             subitem = li;
  186.             gtk_tree_append(tree, li);
  187.             ircnet = serv->ircnet;
  188.         }
  189.         li = gtk_tree_item_new_with_label(str);
  190.         gtk_widget_show (li);
  191.         gtk_tree_append(GTK_TREE(subtree), li);
  192.         gtk_object_set_data(GTK_OBJECT(li), "server", serv);
  193.  
  194.         g_free(str);
  195.     }
  196.  
  197.     if (subitem != NULL)
  198.     {
  199.         gtk_tree_item_set_subtree(GTK_TREE_ITEM(subitem), subtree);
  200.     }
  201. }
  202.  
  203. /* make a list of servers */
  204. static void create_server_list(GList *servers, GtkList *list)
  205. {
  206.     g_return_if_fail(list != NULL);
  207.  
  208.     /* clear previous list */
  209.     gtk_list_clear_items(list, 0, -1);
  210.  
  211.     for (servers = g_list_first(servers); servers != NULL; servers = servers->next)
  212.         gtk_list_append_items(list, server_list_add((SETUP_SERVER_REC *) servers->data));
  213. }
  214.  
  215. /* draw server setup dialog */
  216. static void server_dialog(GtkList *gtklist, char *net, char *location, char *server, int port, GtkSignalFunc func)
  217. {
  218.     GtkWidget *win;
  219.     GtkWidget *button;
  220.     char tmp[20];
  221.  
  222.     g_return_if_fail(net != NULL);
  223.     g_return_if_fail(server != NULL);
  224.     g_return_if_fail(location != NULL);
  225.     g_return_if_fail(func != NULL);
  226.  
  227.     win = gtk_dialog_new();
  228.     gtk_object_set_data(GTK_OBJECT(win), "gtklist", gtklist);
  229.     gtk_grab_add (GTK_WIDGET (win));
  230.  
  231.     ircnet_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "IRC net:", net);
  232.     location_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Location:", location);
  233.     server_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Server:", server);
  234.     sprintf(tmp, "%d", port);
  235.     port_text = gui_add_label(GTK_WIDGET(GTK_DIALOG(win)->vbox), "Port:", tmp);
  236.  
  237.     button = gtk_button_new_with_label ("Ok");
  238.     gtk_box_pack_start (GTK_BOX (GTK_DIALOG(win)->action_area), button, TRUE, TRUE, 0);
  239.     gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
  240.                                func, GTK_OBJECT(win));
  241.     /*GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
  242.     gtk_widget_grab_default (button);*/
  243.     gtk_widget_show (button);
  244.  
  245.     button = gtk_button_new_with_label ("Cancel");
  246.     gtk_box_pack_start (GTK_BOX (GTK_DIALOG(win)->action_area), button, TRUE, TRUE, 0);
  247.     gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
  248.                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
  249.                                GTK_OBJECT(win));
  250.     gtk_widget_show (button);
  251.  
  252.     gtk_widget_show(win);
  253. }
  254.  
  255. /* signal: OK button pressed in add server dialog */
  256. static SETUP_SERVER_REC *add_server_ok(GtkWidget *widget, GtkWidget *dialog)
  257. {
  258.     SETUP_SERVER_REC *serv;
  259.     GtkList *gtklist;
  260.  
  261.     char *net, *servtext, *location, *tmp;
  262.     int port;
  263.  
  264.     g_return_val_if_fail(dialog != NULL, NULL);
  265.  
  266.     gui_get_label(net, ircnet_text);
  267.     gui_get_label(location, location_text);
  268.     gui_get_label(servtext, server_text);
  269.     gui_get_label(tmp, port_text);
  270.     sscanf(tmp, "%d", &port);
  271.     g_free(tmp);
  272.  
  273.     gtklist = gtk_object_get_data(GTK_OBJECT(dialog), "gtklist");
  274.     serv = local_server_add(gtklist, net, servtext, port, location);
  275.  
  276.     g_free(net);
  277.     g_free(location);
  278.     g_free(servtext);
  279.  
  280.     gtk_widget_destroy(dialog);
  281.     return serv;
  282. }
  283.  
  284. /* signal: add server button pressed */
  285. static void sig_add_server(GtkWidget *widget, GtkList *list)
  286. {
  287.     server_dialog(list, "", "", "", 6667, GTK_SIGNAL_FUNC(add_server_ok));
  288. }
  289.  
  290. /* signal: OK button pressed in edit server dialog */
  291. static void edit_server_ok(GtkWidget *widget, GtkWidget *dialog)
  292. {
  293.     GtkList *gtklist;
  294.  
  295.     g_return_if_fail(dialog != NULL);
  296.  
  297.     /* remove old entry */
  298.     gtklist = gtk_object_get_data(GTK_OBJECT(dialog), "gtklist");
  299.     local_server_remove(gtklist, GTK_WIDGET(gtklist->selection->data));
  300.  
  301.     /* add new entry */
  302.     add_server_ok(widget, dialog);
  303.     gtk_widget_destroy(dialog);
  304. }
  305.  
  306. /* signal: edit server button pressed */
  307. static void sig_edit_server(GtkWidget *widget, GtkList *list)
  308. {
  309.     SETUP_SERVER_REC *server;
  310.  
  311.     g_return_if_fail(list != NULL);
  312.     if (list->selection == NULL) return;
  313.  
  314.     server = gtk_object_get_data(GTK_OBJECT(list->selection->data), "server");
  315.     server_dialog(list, server->ircnet, server->location, server->name,
  316.                   server->port, GTK_SIGNAL_FUNC(edit_server_ok));
  317. }
  318.  
  319. /* signal: delete server button pressed */
  320. static void sig_delete_server(GtkWidget *widget, GtkList *list)
  321. {
  322.     g_return_if_fail(list != NULL);
  323.     if (list->selection == NULL) return;
  324.  
  325.     local_server_remove(list, GTK_WIDGET(list->selection->data));
  326. }
  327.  
  328. /* signal: "move up" button pressed */
  329. static void sig_move_server_up(GtkWidget *widget, GtkList *gtklist)
  330. {
  331.     SETUP_SERVER_REC *server;
  332.     GList *list;
  333.     gpointer data;
  334.     int pos;
  335.  
  336.     g_return_if_fail(gtklist != NULL);
  337.     if (gtklist->selection == NULL) return;
  338.  
  339.     pos = gtk_list_child_position(gtklist, gtklist->selection->data);
  340.     g_return_if_fail(pos != -1);
  341.  
  342.     if (pos == 0) return;
  343.  
  344.     server = gtk_object_get_data(GTK_OBJECT(gtklist->selection->data), "server");
  345.     list = server_list_add(server);
  346.  
  347.     gtk_list_clear_items(gtklist, pos, pos+1);
  348.     gtk_list_insert_items(gtklist, list, pos-1);
  349.     gtk_list_select_item(gtklist, pos-1);
  350.  
  351.     /* modify also glist.. */
  352.     list = g_list_nth(servers, pos);
  353.     g_return_if_fail(list != NULL);
  354.  
  355.     data = list->data;
  356.     servers = g_list_remove_link(servers, list);
  357.     servers = g_list_insert(servers, data, pos-1);
  358. }
  359.  
  360. /* signal: "move down" button pressed */
  361. static void sig_move_server_down(GtkWidget *widget, GtkList *gtklist)
  362. {
  363.     SETUP_SERVER_REC *server;
  364.     GList *list;
  365.     gpointer data;
  366.     int pos;
  367.  
  368.     g_return_if_fail(gtklist != NULL);
  369.     if (gtklist->selection == NULL) return;
  370.  
  371.     pos = gtk_list_child_position(gtklist, gtklist->selection->data);
  372.     g_return_if_fail(pos != -1);
  373.  
  374.     if (pos >= g_list_length(gtklist->children)-1) return;
  375.  
  376.     server = gtk_object_get_data(GTK_OBJECT(gtklist->selection->data), "server");
  377.     list = server_list_add(server);
  378.  
  379.     gtk_list_clear_items(gtklist, pos, pos+1);
  380.     gtk_list_insert_items(gtklist, list, pos+1);
  381.     gtk_list_select_item(gtklist, pos+1);
  382.  
  383.     /* modify also glist.. */
  384.     list = g_list_nth(servers, pos);
  385.     g_return_if_fail(list != NULL);
  386.  
  387.     data = list->data;
  388.     servers = g_list_remove_link(servers, list);
  389.     servers = g_list_insert(servers, data, pos+1);
  390. }
  391.  
  392. /* signal: move server button pressed */
  393. static void sig_move_server(GtkWidget *widget, GtkTree *tree)
  394. {
  395.     GtkList *list;
  396.     GList *tmp, *next;
  397.  
  398.     g_return_if_fail(tree != NULL);
  399.  
  400.     list = gtk_object_get_data(GTK_OBJECT(widget), "list");
  401.  
  402.     for (tmp = g_list_first(tree->selection); tmp != NULL; tmp = next)
  403.     {
  404.         SETUP_SERVER_REC *server;
  405.  
  406.         next = tmp->next;
  407.         server = gtk_object_get_data(GTK_OBJECT(tmp->data), "server");
  408.         if (server != NULL)
  409.         {
  410.             local_server_add(list, server->ircnet, server->name, server->port,
  411.                              server->location);
  412.         }
  413.         gtk_tree_unselect_child(tree, tmp->data);
  414.     }
  415. }
  416.  
  417. static GtkWidget *create_global_servers(GtkWidget *vbox)
  418. {
  419.     GtkWidget *tree;
  420.     GtkWidget *scrollbox;
  421.  
  422.     scrollbox = gtk_scrolled_window_new(NULL, NULL);
  423.     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox),
  424.                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  425.     gtk_box_pack_start(GTK_BOX(vbox), scrollbox, TRUE, TRUE, 0);
  426.     gtk_widget_show(scrollbox);
  427.  
  428.     /* server list */
  429.     tree = gtk_tree_new();
  430.     gtk_tree_set_selection_mode(GTK_TREE(tree), GTK_SELECTION_MULTIPLE);
  431.     gtk_container_add(GTK_CONTAINER(scrollbox), tree);
  432.     gtk_widget_show(tree);
  433.  
  434.     create_server_tree(globalservers, GTK_TREE(tree));
  435.  
  436.     return tree;
  437. }
  438.  
  439. GtkWidget *create_local_servers(GtkWidget *vbox, int max)
  440. {
  441.     GtkWidget *hbox, *vbox2;
  442.     GtkWidget *scrollbox;
  443.     GtkWidget *list;
  444.     GtkWidget *button;
  445.     GtkWidget *arrow;
  446.  
  447.     hbox = gtk_hbox_new(FALSE, 0);
  448.     gtk_box_pack_start(GTK_BOX(vbox), hbox, max, max, 5);
  449.     gtk_widget_show(hbox);
  450.  
  451.     /* Create server list widget */
  452.     scrollbox = gtk_scrolled_window_new(NULL, NULL);
  453.     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox),
  454.                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  455.     gtk_box_pack_start(GTK_BOX(hbox), scrollbox, TRUE, TRUE, 0);
  456.     gtk_widget_show(scrollbox);
  457.  
  458.     list = gtk_list_new();
  459.     gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_BROWSE);
  460.     gtk_container_add(GTK_CONTAINER(scrollbox), list);
  461.     gtk_widget_show(list);
  462.  
  463.     create_server_list(servers, GTK_LIST(list));
  464.  
  465.     /* create buttons to move server up/down in list */
  466.     vbox2 = gtk_vbox_new(FALSE, 0);
  467.     gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
  468.     gtk_widget_show(vbox2);
  469.  
  470.     button = gtk_button_new();
  471.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  472.                         GTK_SIGNAL_FUNC(sig_move_server_up), list);
  473.     arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_OUT);
  474.     gtk_container_add(GTK_CONTAINER(button), arrow);
  475.     gtk_widget_show(arrow);
  476.     gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
  477.     gtk_widget_show(button);
  478.  
  479.     button = gtk_button_new();
  480.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  481.                         GTK_SIGNAL_FUNC(sig_move_server_down), list);
  482.     arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
  483.     gtk_container_add(GTK_CONTAINER(button), arrow);
  484.     gtk_widget_show(arrow);
  485.     gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
  486.     gtk_widget_show(button);
  487.  
  488.     hbox = gtk_hbox_new(FALSE, 0);
  489.     gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
  490.     gtk_widget_show(hbox);
  491.  
  492.     /* add/edit/delete buttons */
  493.     button = gtk_button_new_with_label(_("Add"));
  494.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  495.                         GTK_SIGNAL_FUNC(sig_add_server), list);
  496.     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
  497.     gtk_widget_show(button);
  498.     button = gtk_button_new_with_label(_("Edit"));
  499.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  500.                         GTK_SIGNAL_FUNC(sig_edit_server), list);
  501.     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
  502.     gtk_widget_show(button);
  503.     button = gtk_button_new_with_label(_("Delete"));
  504.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  505.                         GTK_SIGNAL_FUNC(sig_delete_server), list);
  506.     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 10);
  507.     gtk_widget_show(button);
  508.  
  509.     return list;
  510. }
  511.  
  512. /* draw server notebook section */
  513. void gui_setup_servers(GtkWidget *vbox)
  514. {
  515.     GtkWidget *button;
  516.     GtkWidget *tree, *list;
  517.  
  518.     tree = create_global_servers(vbox);
  519.  
  520.     button = gtk_button_new_with_label("copy server(s) to local list");
  521.     gtk_signal_connect (GTK_OBJECT (button), "clicked",
  522.                         GTK_SIGNAL_FUNC(sig_move_server), tree);
  523.     gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 5);
  524.     gtk_widget_show(button);
  525.  
  526.     list = create_local_servers(vbox, FALSE);
  527.     gtk_object_set_data(GTK_OBJECT(button), "list", list);
  528.  
  529.     nick_text = gui_add_label(vbox, "Nick:", default_nick);
  530.     name_text = gui_add_label(vbox, "Name:", real_name);
  531. }
  532.  
  533. /* OK button pressed in dialog - accept changes */
  534. void gui_setup_servers_accept(void)
  535. {
  536.     if (default_nick != NULL) g_free(default_nick);
  537.     if (real_name != NULL) g_free(real_name);
  538.  
  539.     gui_get_label(default_nick, nick_text);
  540.     gui_get_label(real_name, name_text);
  541. }
  542.