Yattm - unified GTK instant-messaging client logo
   [Generated for version 0.2-17 - Mon Jan 6 19:01:23 GMT+1 2003]

Home - Main Page - Data Structures - File List - Data Fields - Globals

trigger.c

Go to the documentation of this file.
00001 /*
00002  * Yattm 
00003  *
00004  * Copyright (C) 1999, Torrey Searle <tsearle@uci.edu>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 /*
00023  * trigger.c
00024  */
00025 #ifdef HAVE_CONFIG_H
00026 #  include <config.h>
00027 #endif
00028 
00029 #include "intl.h"
00030 #include <string.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 
00034 #include "chat_window.h"
00035 #include "dialog.h"
00036 #include "sound.h"
00037 #include "globals.h"
00038 #include "file_select.h"
00039 #include "util.h"
00040 
00041 #include "pixmaps/tb_preferences.xpm"
00042 #include "pixmaps/cancel.xpm"
00043 
00044 static gint window_open = 0;
00045 static GtkWidget *edit_trigger_window;
00046 static GtkWidget *trigger_list;
00047 static GtkWidget *account_name;
00048 static GtkWidget *parameter;
00049 static GtkWidget *action_name;
00050 
00051 static GList *triggers = NULL;
00052 static GList *actions = NULL;
00053 
00054 static void quick_message(gchar *message) {
00055 
00056   GtkWidget *dialog, *label, *okay_button;
00057    
00058   /* Create the widgets */
00059    
00060   dialog = gtk_dialog_new();
00061   label = gtk_label_new (message);
00062   okay_button = gtk_button_new_with_label(_("Okay"));
00063    
00064   /* Ensure that the dialog box is destroyed when the user clicks ok. */
00065    
00066   gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
00067                  GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT(dialog));
00068   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
00069              okay_button);
00070 
00071   /* Add the label, and show everything we've added to the dialog. */
00072 
00073   gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
00074              label);
00075   gtk_widget_show_all (dialog);
00076 }
00077 
00078 static void pounce_contact(struct contact *con, char *str) 
00079 {
00080   gint pos = 0;
00081 
00082   eb_chat_window_display_contact(con);
00083   gtk_editable_insert_text(GTK_EDITABLE(con->chatwindow->entry), str, strlen(str), &pos);
00084   send_message(NULL, con->chatwindow);             
00085 }
00086 
00087 void do_trigger_action(struct contact *con, int trigger_type)
00088 {
00089     gchar param_string[2048];
00090     gchar *substr;
00091     gchar *basestr;
00092     
00093     strcpy(param_string, "\0");
00094     substr = NULL;
00095     
00096     if(con->trigger.action == NO_ACTION)
00097     return;
00098     if(strlen(con->trigger.param) >= (sizeof(param_string)/2))
00099     {
00100     eb_debug(DBG_CORE, "Trigger parameter too long - ignoring");
00101     return;
00102     }
00103     /* replace all occurrences of %t with "online" or "offline" */
00104     basestr = con->trigger.param;
00105     while ((substr = strstr(basestr, "%t")) != NULL)
00106     {
00107     if (substr[-1] == '%')
00108     {
00109         strncat(param_string, basestr, (size_t)(substr-basestr + 2));
00110         basestr=substr + 2;
00111         continue;
00112     }
00113     else
00114     {
00115         strncat(param_string, basestr, (size_t)(substr-basestr));
00116         strcat(param_string, ((trigger_type == USER_ONLINE) ?
00117                     _("online") : _("offline")));
00118         basestr = substr + 2;
00119         }
00120         if((strlen(param_string) + strlen(basestr) + 8) >
00121         sizeof(param_string))
00122         {
00123         eb_debug(DBG_CORE, "Result string may be too long, no substitution done\n");
00124         basestr = con->trigger.param;
00125         strcpy(param_string, "");
00126         break;
00127         }
00128     }
00129     /* copy remainder (or all if no subst done) */
00130     strcat(param_string, basestr);
00131     
00132     if(con->trigger.action == PLAY_SOUND)
00133     {
00134         playsoundfile(param_string);
00135     } else if(con->trigger.action == EXECUTE)
00136     {
00137         system(param_string);
00138     } else if(con->trigger.action == DIALOG)
00139     {
00140         quick_message(param_string);
00141     } else if(con->trigger.action == POUNCE && con->trigger.type == USER_ONLINE)
00142     {
00143         pounce_contact(con, param_string);
00144     }
00145 
00146 }
00147 
00148 void do_trigger_online(struct contact *con)
00149 {
00150     if ((con->trigger.type == USER_ONLINE) || (con->trigger.type == USER_ON_OFF_LINE))
00151     {
00152     do_trigger_action(con, USER_ONLINE);
00153     }
00154 }
00155 
00156 void do_trigger_offline(struct contact *con)
00157 {
00158     if((con->trigger.type == USER_OFFLINE) || (con->trigger.type == USER_ON_OFF_LINE))
00159     {
00160     do_trigger_action(con, USER_OFFLINE);
00161     }
00162 }
00163 
00164 static void browse_done(char * filename, gpointer data)
00165 {
00166     if(!filename)
00167         return;
00168   gtk_entry_set_text(GTK_ENTRY(parameter), filename);
00169 }
00170 
00171 static void set_button_callback(GtkWidget* widget, struct contact * con)
00172 {
00173   strcpy( con->trigger.param, gtk_entry_get_text(GTK_ENTRY(parameter)));
00174   con -> trigger.type = g_list_index(GTK_LIST(GTK_COMBO(trigger_list)->list)->children, 
00175                      GTK_LIST(GTK_COMBO(trigger_list)->list)->selection->data);
00176   con -> trigger.action = g_list_index(GTK_LIST(GTK_COMBO(action_name)->list)->children, 
00177                        GTK_LIST(GTK_COMBO(action_name)->list)->selection->data);
00178 
00179   write_contact_list();
00180     
00181   destroy_window();
00182 }
00183 
00184 void destroy_window()
00185 {
00186   window_open = 0;
00187     
00188   gtk_widget_destroy(edit_trigger_window);
00189 }
00190 
00191 static void browse_file(GtkWidget* widget, gpointer data)
00192 {
00193     eb_do_file_selector(NULL, _("Select parameter"), browse_done, NULL);
00194 }
00195 
00196 
00197 trigger_type get_trigger_type_num(gchar *text)
00198 {
00199   if(!text) return -1;
00200 
00201   if(!strcmp(text, "USER_ONLINE"))
00202     {
00203       return USER_ONLINE;
00204     }   
00205   else if(!strcmp(text, "USER_OFFLINE"))
00206     {
00207       return USER_OFFLINE;
00208     }
00209     else if(!strcmp(text, "USER_ON_OFF_LINE"))
00210     {
00211     return USER_ON_OFF_LINE;
00212     }
00213     
00214   return -1;
00215 }
00216 
00217 trigger_action get_trigger_action_num(gchar *text)
00218 {
00219   if(!text) return -1;
00220     
00221   if(!strcmp(text, "PLAY_SOUND"))
00222     {
00223       return PLAY_SOUND;
00224     }
00225   else if(!strcmp(text, "EXECUTE"))
00226     {
00227       return EXECUTE;
00228     } 
00229   else if(!strcmp(text, "DIALOG"))
00230     {
00231       return DIALOG;
00232     }
00233   else if(!strcmp(text, "POUNCE"))
00234     {
00235       return POUNCE;
00236     }
00237     
00238   return -1;
00239 }
00240 
00241 gchar* get_trigger_type_text(trigger_type type)
00242 {
00243   if(type == USER_ONLINE)
00244     return "USER_ONLINE";
00245   else if(type == USER_OFFLINE)
00246     return "USER_OFFLINE";
00247     else if(type == USER_ON_OFF_LINE)
00248     return "USER_ON_OFF_LINE";
00249     else
00250     return "\0";
00251         
00252 }
00253 
00254 gchar* get_trigger_action_text(trigger_action action)
00255 {
00256   if(action == PLAY_SOUND)
00257     return "PLAY_SOUND";
00258   else if(action == EXECUTE)
00259     return "EXECUTE";
00260   else if(action == DIALOG)
00261     return "DIALOG";
00262   else if(action == POUNCE) 
00263     return "POUNCE";
00264   else
00265     return "\0";
00266 }
00267 
00268 GList *get_trigger_list()
00269 {
00270   triggers = NULL;
00271 
00272   triggers = g_list_append(triggers, _("None"));
00273   triggers = g_list_append(triggers, _("User goes online"));
00274   triggers = g_list_append(triggers, _("User goes offline"));
00275   triggers = g_list_append(triggers, _("User goes on or offline"));
00276     
00277   return triggers;
00278 }
00279 
00280 GList *get_action_list()
00281 {
00282   actions = NULL;
00283 
00284   actions = g_list_append(actions, _("None"));
00285   actions = g_list_append(actions, _("Play sound"));
00286   actions = g_list_append(actions, _("Execute command"));
00287   actions = g_list_append(actions, _("Show alert dialog"));
00288   actions = g_list_append(actions, _("Send message"));
00289   return actions;
00290 }
00291 
00292 
00293 void show_trigger_window(struct contact * con)
00294 {
00295   GtkWidget *hbox;
00296   GtkWidget *hbox2;
00297   GtkWidget *vbox;
00298   GtkWidget *label;
00299   GtkWidget *button;
00300   GtkWidget *iconwid;
00301   GtkWidget *table;
00302   GtkWidget *frame;
00303   GtkWidget *separator;
00304   GList *list;
00305   GdkPixmap *icon;
00306   GdkBitmap *mask;
00307   GtkWidget *hbox_param;
00308   GtkWidget *browse_button;
00309      
00310   if(window_open) return;
00311   window_open = 1;
00312 
00313   edit_trigger_window = gtk_window_new(GTK_WINDOW_DIALOG);
00314   gtk_window_set_position(GTK_WINDOW(edit_trigger_window), GTK_WIN_POS_MOUSE);
00315   gtk_widget_realize(edit_trigger_window);
00316   gtk_container_set_border_width(GTK_CONTAINER(edit_trigger_window), 5);      
00317      
00318   table = gtk_table_new(2, 4, FALSE);
00319   gtk_table_set_row_spacings(GTK_TABLE(table), 5);
00320   gtk_table_set_row_spacings(GTK_TABLE(table), 5);
00321   gtk_container_set_border_width(GTK_CONTAINER(table), 5);
00322   vbox = gtk_vbox_new(FALSE, 5);
00323   hbox = gtk_hbox_new(FALSE, 0);
00324      
00325   /*Section for letting the user know which trigger they are editing*/
00326      
00327   label = gtk_label_new(_("User:"));
00328   gtk_box_pack_end(GTK_BOX(hbox), label, FALSE, FALSE, 5);
00329   gtk_widget_show(label);
00330   gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 0, 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
00331   gtk_widget_show(hbox);
00332      
00333   account_name = gtk_label_new(con -> nick);
00334   gtk_misc_set_alignment(GTK_MISC(account_name), 0, .5);
00335   gtk_table_attach(GTK_TABLE(table), account_name, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
00336   gtk_widget_show(account_name);
00337      
00338   /*Section for declaring the trigger*/
00339   hbox = gtk_hbox_new(FALSE, 0);
00340      
00341   label = gtk_label_new(_("Trigger:"));
00342   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
00343   gtk_widget_show(label);
00344   gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 0, 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
00345   gtk_widget_show(hbox);
00346      
00347   /*List of trigger types*/
00348      
00349   trigger_list = gtk_combo_new();
00350   list = get_trigger_list();
00351   gtk_combo_set_popdown_strings(GTK_COMBO(trigger_list), list );
00352   gtk_list_select_item(GTK_LIST(GTK_COMBO(trigger_list)->list), con->trigger.type);
00353     
00354   gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(trigger_list)->entry), 0);
00355   g_list_free(list);
00356   gtk_table_attach(GTK_TABLE(table), trigger_list, 3, 4, 0, 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
00357   gtk_widget_show(trigger_list);
00358      
00359   /*Section for action declaration*/
00360      
00361   hbox = gtk_hbox_new(FALSE, 0);
00362      
00363   label = gtk_label_new(_("Action:"));
00364   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
00365   gtk_widget_show(label);
00366   gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
00367   gtk_widget_show(hbox);
00368      
00369   /*List of available actions*/
00370   action_name = gtk_combo_new();
00371   list = get_action_list();
00372   gtk_combo_set_popdown_strings(GTK_COMBO(action_name), list );
00373 
00374   gtk_list_select_item(GTK_LIST(GTK_COMBO(action_name)->list), con->trigger.action);
00375 
00376   g_list_free(list);
00377   gtk_table_attach(GTK_TABLE(table), action_name, 1, 2, 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
00378   gtk_widget_show(action_name);
00379       
00380   /*Section for Contact Name*/
00381   hbox = gtk_hbox_new(FALSE, 0);
00382       
00383   label = gtk_label_new(_("Parameter:"));
00384   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
00385   gtk_widget_show(label);
00386   gtk_table_attach(GTK_TABLE(table), hbox, 2, 3, 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
00387   gtk_widget_show(hbox);
00388      
00389   /*Entry for parameter*/
00390   hbox_param = gtk_hbox_new(FALSE, 0);
00391   parameter = gtk_entry_new();
00392     
00393   gtk_entry_set_text(GTK_ENTRY(parameter), con->trigger.param);
00394     
00395   gtk_box_pack_start(GTK_BOX(hbox_param), parameter, FALSE, FALSE, 0);
00396     
00397   browse_button = gtk_button_new_with_label(_("Browse"));
00398   gtk_signal_connect(GTK_OBJECT(browse_button), "clicked",
00399              GTK_SIGNAL_FUNC(browse_file),
00400              con);
00401   gtk_box_pack_start(GTK_BOX(hbox_param), browse_button, FALSE, FALSE, 0);
00402     
00403   gtk_table_attach(GTK_TABLE(table), hbox_param, 3, 4, 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
00404   gtk_widget_show(parameter);
00405   gtk_widget_show(browse_button);
00406   gtk_widget_show(hbox_param);
00407     
00408 
00409   /*Lets create a frame to put all of this in*/
00410   frame = gtk_frame_new(NULL);
00411   gtk_frame_set_label(GTK_FRAME(frame), _("Edit Trigger"));
00412 
00413   gtk_container_add(GTK_CONTAINER(frame), table);
00414   gtk_widget_show(table);
00415       
00416   gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
00417   gtk_widget_show(frame);
00418      
00419   /*Lets try adding a separator*/
00420   separator = gtk_hseparator_new();
00421   gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 5);
00422   gtk_widget_show(separator);
00423         
00424   hbox = gtk_hbox_new(FALSE, 5);
00425   hbox2 = gtk_hbox_new(TRUE, 5);
00426      
00427   /*Add Button*/
00428   gtk_widget_set_usize(hbox2, 200,25);
00429       
00430   icon = gdk_pixmap_create_from_xpm_d(edit_trigger_window->window, &mask, NULL, tb_preferences_xpm);
00431   iconwid = gtk_pixmap_new(icon, mask);
00432   label = gtk_label_new(_("Update"));
00433       
00434   gtk_box_pack_start(GTK_BOX(hbox), iconwid, FALSE, FALSE, 2);
00435   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
00436       
00437   gtk_widget_show(iconwid);
00438   gtk_widget_show(label);
00439       
00440   button = gtk_button_new();
00441       
00442   gtk_signal_connect(GTK_OBJECT(button), "clicked",
00443              GTK_SIGNAL_FUNC(set_button_callback),
00444              con);
00445   gtk_widget_show(hbox);     
00446      
00447   gtk_container_add(GTK_CONTAINER(button), hbox);       
00448      
00449   gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
00450   gtk_widget_show(button);
00451       
00452   /*Cancel Button*/
00453       
00454   hbox = gtk_hbox_new(FALSE, 5);
00455   icon = gdk_pixmap_create_from_xpm_d(edit_trigger_window->window, &mask, NULL, cancel_xpm);
00456   iconwid = gtk_pixmap_new(icon, mask);
00457   label = gtk_label_new(_("Cancel"));
00458      
00459   gtk_box_pack_start(GTK_BOX(hbox), iconwid, FALSE, FALSE, 2);
00460   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
00461      
00462   gtk_widget_show(iconwid);
00463   gtk_widget_show(label);
00464      
00465   button = gtk_button_new();
00466      
00467   gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
00468                 GTK_SIGNAL_FUNC(gtk_widget_destroy),
00469                 GTK_OBJECT(edit_trigger_window));
00470   gtk_widget_show(hbox);     
00471      
00472   gtk_container_add(GTK_CONTAINER (button), hbox);      
00473      
00474   gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
00475   gtk_widget_show(button);
00476       
00477   /*Buttons End*/
00478       
00479   hbox = gtk_hbox_new(FALSE, 0);
00480   table = gtk_table_new(1, 1, FALSE);
00481       
00482     
00483   gtk_box_pack_end(GTK_BOX(hbox),hbox2, FALSE, FALSE, 0);
00484   gtk_widget_show(hbox2);      
00485       
00486   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
00487   gtk_widget_show(hbox);
00488       
00489 
00490   gtk_table_attach(GTK_TABLE(table), vbox, 0, 1, 0, 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
00491   gtk_widget_show(vbox);
00492      
00493   gtk_container_add(GTK_CONTAINER(edit_trigger_window), table);
00494     
00495   gtk_widget_show(table);
00496       
00497 
00498   gtk_window_set_title(GTK_WINDOW(edit_trigger_window), _("Yattm - Edit Trigger"));
00499   eb_icon(edit_trigger_window->window); 
00500   gtk_widget_show(edit_trigger_window);
00501      
00502   gtk_signal_connect(GTK_OBJECT(edit_trigger_window), "destroy",
00503              GTK_SIGNAL_FUNC(destroy_window), NULL);
00504       
00505   window_open = 1;
00506 }

Contact: Andy Maloney     [Documentation generated by doxygen]