This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/dialogs/gm-triggers-dialog.c

992 lines
28 KiB
C

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <libgnomeui/libgnomeui.h>
#include <glade/glade.h>
#include "../gm-support.h"
#include "../gm-debug.h"
#include "gm-triggers-dialog.h"
#include "../gm-app.h"
#include "../gm-pixbuf.h"
#include "../gm-scripts.h"
typedef struct _GmTriggersDialog {
GtkWidget *dialog;
GladeXML *xml;
GmWorld *world;
GmTrigger *trigger;
gboolean is_new;
GtkWidget *entry_name;
GtkWidget *button_ok;
GtkWidget *button_next;
GtkWidget *vbox_conditions;
GtkWidget *vbox_actions;
GtkWidget *notebook_triggers;
GtkWidget *tree_view_event_types;
GtkWidget *hbox_add_condition;
GtkWidget *hbox_add_action;
GtkTreeModel *action_model;
GtkTreeModel *condition_model;
GtkTreeModel *highlight_model;
#ifdef HAVE_RUBY
GtkTreeModel *script_model;
#endif
} GmTriggersDialog;
enum {
NO_ARGS,
SINGLE_ARGS,
CUSTOM_ARGS
};
typedef enum _CustomArgType {
CUSTOM_ARG_CREATE,
CUSTOM_ARG_GET_DATA
} CustomArgType;
gpointer gm_triggers_dialog_custom_arg_highlight(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data);
gpointer gm_triggers_dialog_custom_arg_browse(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data);
#ifdef HAVE_RUBY
gpointer gm_triggers_dialog_custom_arg_script(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data);
#endif
#define CUSTOM_ARG_FUNC(x) (CustomArgFunc *)(x)
typedef gpointer (*CustomArgFunc) (GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data);
enum {
COLUMN_NAME,
COLUMN_DATA,
N_COLUMNS
};
enum {
COLUMN_HIGH_NAME,
COLUMN_HIGH_TAG,
N_COLUMNS_HIGH
};
typedef struct _ModelData {
gint type;
gchar *title;
gint args;
CustomArgFunc func;
} ModelData;
typedef struct _TagPair {
const gchar *name;
const gchar *tag;
} TagPair;
typedef struct _ComboBoxTypeData {
GmTriggersDialog *triggers;
GmTriggerData *data;
} ComboBoxTypeData;
static const TagPair highlightTags[] = {
{N_("Black"), "bg_black"},
{N_("Red"), "bg_red"},
{N_("Green"), "bg_green"},
{N_("Yellow"), "bg_yellow"},
{N_("Blue"), "bg_blue"},
{N_("Purple"), "bg_purple"},
{N_("Cyan"), "bg_cyan"},
{N_("White"), "bg_white"},
{NULL, NULL}
};
static const ModelData dataConditionOutput[] = {
{TCT_CONTAINS, N_("Contains"), SINGLE_ARGS, NULL},
{TCT_NOT_CONTAINS, N_("Not contains"), SINGLE_ARGS, NULL},
{TCT_BEGINS, N_("Begins with"), SINGLE_ARGS, NULL},
{TCT_NOT_BEGINS, N_("Not begins with"), SINGLE_ARGS, NULL},
{TCT_ENDS, N_("Ends with"), SINGLE_ARGS, NULL},
{TCT_NOT_ENDS, N_("Not ends with"), SINGLE_ARGS, NULL},
{TCT_MATCHES, N_("Matches"), SINGLE_ARGS, NULL},
{TCT_NOT_MATCHES, N_("Not matches"), SINGLE_ARGS, NULL},
{-1, NULL, 0, NULL}
};
static const ModelData dataConditionUsers[] = {
{TCT_USER_ONLINE, N_("Online"), SINGLE_ARGS, NULL},
{TCT_USER_OFFLINE, N_("Offline"), SINGLE_ARGS, NULL},
{TCT_USER_IDLE, N_("Idle"), SINGLE_ARGS, NULL},
{TCT_USER_IDLE_OFF, N_("No longer idle"), SINGLE_ARGS, NULL},
{TCT_USER_AWAY, N_("Away"), SINGLE_ARGS, NULL},
{TCT_USER_AWAY_OFF, N_("No longer away"), SINGLE_ARGS, NULL},
{-1, NULL, 0, NULL}
};
static const ModelData dataActionOutput[] = {
{TAT_HIGHLIGHT_LINE, N_("Highlight line"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_highlight},
{TAT_HIGHLIGHT_MATCH, N_("Highlight match"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_highlight},
{TAT_BEEP, N_("Beep"), NO_ARGS, NULL},
{TAT_PLAY_SOUND, N_("Play sound"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_browse},
{TAT_NOTIFY, N_("Notify"), SINGLE_ARGS, NULL},
#ifdef HAVE_RUBY
{TAT_RUN_SCRIPT, N_("Run script"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_script},
#endif
{TAT_RUN, N_("Run"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_browse},
{-1, NULL, 0, NULL}
};
static const ModelData dataActionUsers[] = {
{TAT_BEEP, N_("Beep"), NO_ARGS, NULL},
{TAT_PLAY_SOUND, N_("Play sound"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_browse},
{TAT_NOTIFY, N_("Notify"), SINGLE_ARGS, NULL},
#ifdef HAVE_RUBY
{TAT_RUN_SCRIPT, N_("Run script"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_script},
#endif
{TAT_RUN, N_("Run"), CUSTOM_ARGS,
gm_triggers_dialog_custom_arg_browse},
{-1, NULL, 0, NULL}
};
void on_button_next_clicked(GtkButton *button, GmTriggersDialog *triggers);
void on_button_add_condition_clicked(GtkButton *button,
GmTriggersDialog *triggers);
void on_button_add_action_clicked(GtkButton *button,
GmTriggersDialog *triggers);
void on_notebook_triggers_switch_page(GtkNotebook *notebook, GtkNotebookPage
*page, guint page_num, GmTriggersDialog *triggers);
void on_combo_box_type_changed(GtkComboBox *widget, ComboBoxTypeData *tdata);
void on_combo_box_type_destroy(GtkObject *object, ComboBoxTypeData *tdata);
void on_button_remove_clicked(GtkButton *button, GmTriggersDialog *triggers);
void on_tree_view_event_types_changed(GtkTreeSelection *treeselection,
GmTriggersDialog *triggers);
#define G_TRIGGERS_XML PACKAGE_DATA_DIR "/" PACKAGE "/ui/gm-triggers.glade"
void
gm_triggers_dialog_create_models(GmTriggersDialog *triggers,
const ModelData *conditionData, const ModelData *actionData) {
int i;
GtkTreeIter iter;
ModelData *data;
GList *scripts, *item;
#ifdef HAVE_RUBY
GmScript *script;
GmScriptFunction *func;
#endif
triggers->action_model = GTK_TREE_MODEL(gtk_list_store_new(
N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER));
triggers->condition_model = GTK_TREE_MODEL(gtk_list_store_new(
N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER));
triggers->highlight_model = GTK_TREE_MODEL(gtk_list_store_new(
N_COLUMNS_HIGH, G_TYPE_STRING, G_TYPE_STRING));
#ifdef HAVE_RUBY
triggers->script_model = GTK_TREE_MODEL(gtk_list_store_new(1,
G_TYPE_STRING));
#endif
for (i = 0; conditionData[i].type != -1; i++) {
data = (ModelData *)(&(conditionData[i]));
gtk_list_store_append(GTK_LIST_STORE(triggers->condition_model), &iter);
gtk_list_store_set(GTK_LIST_STORE(triggers->condition_model), &iter,
COLUMN_NAME, _(data->title), COLUMN_DATA, data, -1);
}
for (i = 0; actionData[i].type != -1; i++) {
data = (ModelData *)(&(actionData[i]));
gtk_list_store_append(GTK_LIST_STORE(triggers->action_model), &iter);
gtk_list_store_set(GTK_LIST_STORE(triggers->action_model), &iter,
COLUMN_NAME, _(data->title), COLUMN_DATA, data, -1);
}
for (i = 0; highlightTags[i].name != NULL; i++) {
gtk_list_store_append(GTK_LIST_STORE(triggers->highlight_model), &iter);
gtk_list_store_set(GTK_LIST_STORE(triggers->highlight_model), &iter,
COLUMN_HIGH_NAME, _(highlightTags[i].name), COLUMN_HIGH_TAG,
highlightTags[i].tag, -1);
}
#ifdef HAVE_RUBY
for (scripts = gm_scripts_scripts(gm_app_scripts(gm_app_instance()));
scripts; scripts = scripts->next) {
script = (GmScript *)(scripts->data);
for (item = script->functions; item; item = item->next) {
func = (GmScriptFunction *)(item->data);
gtk_list_store_append(GTK_LIST_STORE(triggers->script_model),
&iter);
gtk_list_store_set(GTK_LIST_STORE(triggers->script_model), &iter,
0, func->name, -1);
}
}
#endif
}
ModelData *
gm_triggers_dialog_combo_get_selected_data(GmTriggersDialog *triggers,
GtkComboBox *combo) {
GtkTreeIter iter;
ModelData *data;
gtk_combo_box_get_active_iter(combo, &iter);
gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter, COLUMN_DATA, &data,
-1);
return data;
}
GList *
gm_triggers_dialog_collect_rules(GmTriggersDialog *triggers, GtkWidget *vbox) {
gchar *text;
GList *children, *child, *item, *result = NULL;
GtkComboBox *combo;
GtkEntry *entry;
ModelData *data;
GmTriggerData *d;
children = gtk_container_get_children(GTK_CONTAINER(vbox));
for (item = children; item; item = item->next) {
if (item->data == triggers->hbox_add_condition ||
item->data == triggers->hbox_add_action) {
break;
}
if (GTK_IS_HBOX(item->data)) {
child = gtk_container_get_children(GTK_CONTAINER(item->data));
combo = GTK_COMBO_BOX(child->data);
data = gm_triggers_dialog_combo_get_selected_data(triggers, combo);
d = NULL;
switch (data->args) {
case NO_ARGS:
d = gm_trigger_data_new(data->type, NULL);
break;
case SINGLE_ARGS:
if (child->next) {
entry = GTK_ENTRY(child->next->data);
text = (gchar *)gtk_entry_get_text(entry);
if (g_utf8_strlen(text, -1) > 0) {
d = gm_trigger_data_new(data->type, g_strdup(text));
}
}
break;
case CUSTOM_ARGS:
text = (gchar *)(data->func(triggers, CUSTOM_ARG_GET_DATA,
child->next, NULL));
if (text != NULL && g_utf8_strlen(text, -1) > 0) {
d = gm_trigger_data_new(data->type, text);
} else {
g_free(text);
}
break;
default:
break;
}
if (d) {
result = g_list_append(result, d);
}
g_list_free(child);
}
}
g_list_free(children);
return result;
}
gboolean
gm_triggers_dialog_fill_trigger(GmTriggersDialog *triggers) {
const gchar *name = gtk_entry_get_text(GTK_ENTRY(triggers->entry_name));
GList *conditions = NULL;
GList *actions = NULL;
if (g_utf8_strlen(name, -1) == 0) {
gm_error_dialog(_("Please fill in a trigger name"),
GTK_WINDOW(triggers->dialog));
gtk_widget_grab_focus(triggers->entry_name);
return FALSE;
}
conditions = gm_triggers_dialog_collect_rules(triggers,
triggers->vbox_conditions);
if (conditions == NULL) {
gm_error_dialog(_("Please specify at least one condition"),
GTK_WINDOW(triggers->dialog));
return FALSE;
}
actions = gm_triggers_dialog_collect_rules(triggers, triggers->vbox_actions);
if (actions == NULL) {
gm_trigger_free_list(conditions);
gm_error_dialog(_("Please specify at least one action"),
GTK_WINDOW(triggers->dialog));
return FALSE;
}
gm_trigger_set_name(triggers->trigger, name);
gm_trigger_set_conditions(triggers->trigger, conditions);
gm_trigger_set_actions(triggers->trigger, actions);
return TRUE;
}
void
gm_triggers_dialog_initialize_event_types(GmTriggersDialog *triggers) {
GtkListStore *store = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING,
G_TYPE_INT);
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeIter iter;
gtk_tree_view_set_model(GTK_TREE_VIEW(triggers->tree_view_event_types),
GTK_TREE_MODEL(store));
renderer = gtk_cell_renderer_pixbuf_new();
column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "pixbuf",
0, NULL);
gtk_tree_view_column_set_min_width(column, 40);
gtk_tree_view_append_column(GTK_TREE_VIEW(triggers->tree_view_event_types),
column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "markup",
1, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(triggers->tree_view_event_types),
column);
gtk_list_store_prepend(store, &iter);
gtk_list_store_set(store, &iter, 0,
gm_pixbuf_get_at_size("ice-userlist/programmer.svg", 32, 32), 1,
_("<b>Player event</b>\nPlayer events are triggered on userlist "
"activity"), 2, TT_USERS, -1);
gtk_list_store_prepend(store, &iter);
gtk_list_store_set(store, &iter, 0,
gm_pixbuf_get_at_size("world.svg", 32, 32), 1,
_("<b>World event</b>\nWorld events are triggered on incoming "
"lines of text"), 2, TT_OUTPUT, -1);
gtk_tree_selection_select_iter(gtk_tree_view_get_selection(
GTK_TREE_VIEW(triggers->tree_view_event_types)), &iter);
g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(
triggers->tree_view_event_types)), "changed",
G_CALLBACK(on_tree_view_event_types_changed), triggers);
}
GmTrigger *
gm_triggers_dialog_run_dialog(GmTriggersDialog *triggers) {
gboolean done = FALSE;
GmTrigger *result = NULL;
while (!done) {
done = TRUE;
switch (gtk_dialog_run(GTK_DIALOG(triggers->dialog))) {
case GTK_RESPONSE_OK:
done = gm_triggers_dialog_fill_trigger(triggers);
if (done) {
result = triggers->trigger;
}
break;
default:
break;
}
}
if (triggers->action_model != NULL)
g_object_unref(triggers->action_model);
if (triggers->condition_model != NULL)
g_object_unref(triggers->condition_model);
if (triggers->highlight_model != NULL)
g_object_unref(triggers->highlight_model);
#ifdef HAVE_RUBY
if (triggers->script_model != NULL)
g_object_unref(triggers->script_model);
#endif
if (!result && triggers->is_new) {
gm_trigger_free(triggers->trigger);
}
g_object_unref(triggers->xml);
gtk_widget_destroy(triggers->dialog);
g_free(triggers);
return result;
}
GmTrigger *
gm_triggers_dialog_run_priv(GmWorld *world, GmTrigger *trigger,
gboolean is_new) {
GmTriggersDialog *triggers = g_new0(GmTriggersDialog, 1);
triggers->is_new = is_new;
triggers->world = world;
triggers->xml = glade_xml_new(G_TRIGGERS_XML, "gm_triggers_dialog", NULL);
triggers->dialog = glade_xml_get_widget(triggers->xml,
"gm_triggers_dialog");
triggers->entry_name = glade_xml_get_widget(triggers->xml, "entry_name");
triggers->vbox_conditions = glade_xml_get_widget(triggers->xml,
"vbox_conditions");
triggers->vbox_actions = glade_xml_get_widget(triggers->xml,
"vbox_actions");
triggers->notebook_triggers = glade_xml_get_widget(triggers->xml,
"notebook_triggers");
triggers->tree_view_event_types = glade_xml_get_widget(triggers->xml,
"tree_view_event_types");
triggers->button_ok = glade_xml_get_widget(triggers->xml, "button_ok");
triggers->hbox_add_condition = glade_xml_get_widget(triggers->xml,
"hbox_add_condition");
triggers->hbox_add_action = glade_xml_get_widget(triggers->xml,
"hbox_add_action");
triggers->button_next = glade_xml_get_widget(triggers->xml, "button_next");
gm_triggers_dialog_initialize_event_types(triggers);
glade_xml_signal_connect_data(triggers->xml, "on_button_next_clicked",
G_CALLBACK(on_button_next_clicked), triggers);
glade_xml_signal_connect_data(triggers->xml,
"on_button_add_condition_clicked",
G_CALLBACK(on_button_add_condition_clicked), triggers);
glade_xml_signal_connect_data(triggers->xml, "on_button_add_action_clicked",
G_CALLBACK(on_button_add_action_clicked), triggers);
glade_xml_signal_connect_data(triggers->xml,
"on_notebook_triggers_switch_page",
G_CALLBACK(on_notebook_triggers_switch_page), triggers);
triggers->trigger = trigger;
if (is_new) {
gtk_notebook_set_current_page(
GTK_NOTEBOOK(triggers->notebook_triggers), 0);
} else {
gtk_notebook_set_current_page(
GTK_NOTEBOOK(triggers->notebook_triggers), 1);
}
gtk_widget_show_all(triggers->dialog);
return gm_triggers_dialog_run_dialog(triggers);
}
GmTrigger *
gm_triggers_dialog_run(GmWorld *world, GmTrigger *trigger) {
return gm_triggers_dialog_run_priv(world, trigger, FALSE);
}
GmTrigger *
gm_triggers_dialog_run_new(GmWorld *world, GmTrigger *trigger) {
if (!trigger) {
trigger = gm_trigger_new();
}
return gm_triggers_dialog_run_priv(world, trigger, TRUE);
}
void
gm_triggers_dialog_select_combo_by_type(GmTriggersDialog *triggers,
GtkComboBox *combo, gint type) {
GtkTreeModel *model = gtk_combo_box_get_model(combo);
GtkTreeIter iter;
ModelData *data;
if (gtk_tree_model_get_iter_first(model, &iter)) {
do {
gtk_tree_model_get(model, &iter, COLUMN_DATA, &data, -1);
if (type == data->type) {
gtk_combo_box_set_active_iter(combo, &iter);
return;
}
} while (gtk_tree_model_iter_next(model, &iter));
}
}
GtkWidget *
gm_triggers_dialog_create_item(GmTriggersDialog *triggers, GtkTreeModel *model,
GmTriggerData *t) {
GtkWidget *hbox, *combo, *button;
ComboBoxTypeData *data;
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
hbox = gtk_hbox_new(FALSE, 6);
combo = gtk_combo_box_new_with_model(model);
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text",
COLUMN_NAME, NULL);
data = g_new0(ComboBoxTypeData, 1);
data->triggers = triggers;
data->data = t;
g_signal_connect(combo, "changed", G_CALLBACK(on_combo_box_type_changed),
data);
g_signal_connect(combo, "destroy", G_CALLBACK(on_combo_box_type_destroy),
data);
button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
g_signal_connect(button, "clicked", G_CALLBACK(on_button_remove_clicked),
triggers);
gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, TRUE, 0);
gtk_widget_show_all(hbox);
return hbox;
}
void
gm_triggers_dialog_new_condition(GmTriggersDialog *triggers) {
GtkWidget *hbox;
GList *children;
hbox = gm_triggers_dialog_create_item(triggers, triggers->condition_model,
NULL);
children = gtk_container_get_children(GTK_CONTAINER(hbox));
if (triggers->trigger->event == TT_OUTPUT) {
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), dataConditionOutput[0].type);
} else {
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), dataConditionUsers[0].type);
}
gtk_box_pack_start(GTK_BOX(triggers->vbox_conditions), hbox, FALSE, TRUE,
0);
g_list_free(children);
}
void
gm_triggers_dialog_populate_conditions(GmTriggersDialog *triggers) {
GList *item;
GtkWidget *hbox;
GmTriggerData *t;
GList *children;
if (triggers->trigger->conditions) {
for (item = triggers->trigger->conditions; item; item = item->next) {
t = (GmTriggerData *)(item->data);
hbox = gm_triggers_dialog_create_item(triggers,
triggers->condition_model, t);
children = gtk_container_get_children(GTK_CONTAINER(hbox));
gtk_box_pack_start(GTK_BOX(triggers->vbox_conditions), hbox,
FALSE, TRUE, 0);
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), t->type);
g_list_free(children);
}
} else {
gm_triggers_dialog_new_condition(triggers);
}
}
void
gm_triggers_dialog_new_action(GmTriggersDialog *triggers) {
GtkWidget *hbox;
GList *children;
hbox = gm_triggers_dialog_create_item(triggers, triggers->action_model,
NULL);
children = gtk_container_get_children(GTK_CONTAINER(hbox));
if (triggers->trigger->event == TT_OUTPUT) {
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), dataActionOutput[0].type);
} else {
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), dataActionUsers[0].type);
}
gtk_box_pack_start(GTK_BOX(triggers->vbox_actions), hbox, FALSE, TRUE, 0);
g_list_free(children);
}
void
gm_triggers_dialog_populate_actions(GmTriggersDialog *triggers) {
GList *item;
GtkWidget *hbox;
GmTriggerData *t;
GList *children;
if (triggers->trigger->actions) {
for (item = triggers->trigger->actions; item; item = item->next) {
t = (GmTriggerData *)(item->data);
hbox = gm_triggers_dialog_create_item(triggers,
triggers->action_model, t);
children = gtk_container_get_children(GTK_CONTAINER(hbox));
gtk_box_pack_start(GTK_BOX(triggers->vbox_actions), hbox, FALSE,
TRUE, 0);
gm_triggers_dialog_select_combo_by_type(triggers,
GTK_COMBO_BOX(children->data), t->type);
g_list_free(children);
}
} else {
gm_triggers_dialog_new_action(triggers);
}
}
/* CALLBACKS */
void
on_button_next_clicked(GtkButton *button, GmTriggersDialog *triggers) {
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
gint type;
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(
triggers->tree_view_event_types));
model = gtk_tree_view_get_model(GTK_TREE_VIEW(
triggers->tree_view_event_types));
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
gtk_tree_model_get(model, &iter, 2, &type, -1);
triggers->trigger->event = type;
gtk_notebook_set_current_page(GTK_NOTEBOOK(
triggers->notebook_triggers), 1);
} else {
gm_error_dialog(_("Select a event type first"),
GTK_WINDOW(triggers->dialog));
}
}
void
on_tree_view_event_types_changed(GtkTreeSelection *treeselection,
GmTriggersDialog *triggers) {
GtkTreeIter iter;
GtkTreeModel *model;
gint type;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(
triggers->tree_view_event_types));
if (!gtk_tree_selection_get_selected(treeselection, &model, &iter)) {
gtk_widget_set_sensitive(triggers->button_next, FALSE);
return;
}
gtk_widget_set_sensitive(triggers->button_next, TRUE);
gtk_tree_model_get(model, &iter, 2, &type, -1);
switch (type) {
case TT_OUTPUT:
gtk_window_set_icon(GTK_WINDOW(triggers->dialog),
gm_pixbuf_get_at_size("world.svg", 16, 16));
break;
case TT_USERS:
gtk_window_set_icon(GTK_WINDOW(triggers->dialog),
gm_pixbuf_get_at_size("ice-userlist/programmer.svg",
16, 16));
break;
default:
break;
}
}
void
on_notebook_triggers_switch_page(GtkNotebook *notebook, GtkNotebookPage *page,
guint page_num, GmTriggersDialog *triggers) {
const ModelData *conditionData = NULL;
const ModelData *actionData = NULL;
if (page_num != 1) {
return;
}
gtk_widget_set_sensitive(triggers->button_ok, TRUE);
switch (triggers->trigger->event) {
case TT_OUTPUT:
gtk_window_set_icon(GTK_WINDOW(triggers->dialog),
gm_pixbuf_get_at_size("world.svg", 16, 16));
conditionData = dataConditionOutput;
actionData = dataActionOutput;
break;
case TT_USERS:
gtk_window_set_icon(GTK_WINDOW(triggers->dialog),
gm_pixbuf_get_at_size("ice-userlist/programmer.svg",
16, 16));
conditionData = dataConditionUsers;
actionData = dataActionUsers;
break;
default:
break;
}
gm_triggers_dialog_create_models(triggers, conditionData, actionData);
if (triggers->trigger->name) {
gtk_entry_set_text(GTK_ENTRY(triggers->entry_name),
triggers->trigger->name);
}
gm_triggers_dialog_populate_conditions(triggers);
gm_triggers_dialog_populate_actions(triggers);
}
gpointer
gm_triggers_dialog_custom_arg_highlight(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data) {
GtkWidget *hbox;
GtkWidget *combo;
GtkCellRenderer *renderer;
GList *item;
GtkTreeIter iter;
GtkTreeModel *model;
gchar *tag;
GmTriggerData *t = (GmTriggerData *)(user_data);
switch (type) {
case CUSTOM_ARG_CREATE:
hbox = GTK_WIDGET(data);
combo = gtk_combo_box_new_with_model(triggers->highlight_model);
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer,
"text", COLUMN_HIGH_NAME, NULL);
if (!user_data) {
gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
} else {
model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
if (gtk_tree_model_get_iter_first(model, &iter)) {
do {
gtk_tree_model_get(model, &iter, COLUMN_HIGH_TAG,
&tag, -1);
if (strcmp(tag, t->data) == 0) {
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo),
&iter);
break;
}
g_free(tag);
} while (gtk_tree_model_iter_next(model, &iter));
}
}
gtk_widget_show(combo);
gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0);
break;
case CUSTOM_ARG_GET_DATA:
item = (GList *)(data);
model = gtk_combo_box_get_model(GTK_COMBO_BOX(item->data));
gtk_combo_box_get_active_iter(GTK_COMBO_BOX(item->data), &iter);
gtk_tree_model_get(model, &iter, COLUMN_HIGH_TAG, &tag, -1);
return tag;
break;
}
return NULL;
}
void
on_button_browse_clicked(GtkButton *widget, GtkEntry *entry) {
gchar *tmp;
GtkWidget *d = gtk_file_chooser_dialog_new(_("Select file"),
NULL, GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
if (gtk_dialog_run(GTK_DIALOG(d)) == GTK_RESPONSE_ACCEPT) {
tmp = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d));
gtk_entry_set_text(entry, tmp);
g_free(tmp);
}
gtk_widget_destroy(d);
}
gpointer
gm_triggers_dialog_custom_arg_browse(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data) {
GtkWidget *hbox;
GtkWidget *entry;
GtkWidget *browse, *tmp;
GmTriggerData *t = (GmTriggerData *)(user_data);
GList *item;
switch (type) {
case CUSTOM_ARG_CREATE:
hbox = GTK_WIDGET(data);
entry = gtk_entry_new();
if (t) {
gtk_entry_set_text(GTK_ENTRY(entry), t->data);
}
browse = gtk_button_new();
tmp = gtk_hbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(browse), tmp);
gtk_box_pack_start(GTK_BOX(tmp), gtk_image_new_from_stock(
GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON), FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(tmp), gtk_label_new(_("Browse")),
TRUE, TRUE, 0);
g_signal_connect(browse, "clicked",
G_CALLBACK(on_button_browse_clicked), entry);
gtk_widget_show(entry);
gtk_widget_show_all(browse);
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), browse, FALSE, TRUE, 0);
break;
case CUSTOM_ARG_GET_DATA:
item = (GList *)(data);
return g_strdup(gtk_entry_get_text(GTK_ENTRY(item->data)));
break;
}
return NULL;
}
void
on_combo_box_type_changed(GtkComboBox *widget, ComboBoxTypeData *tdata) {
GtkWidget *parent = gtk_widget_get_parent(GTK_WIDGET(widget));
GList *item, *children = gtk_container_get_children(GTK_CONTAINER(parent));
ModelData *data;
GtkTreeIter iter;
GtkWidget *tmp;
for (item = children->next; item && item->next; item = item->next) {
gtk_widget_destroy(GTK_WIDGET(item->data));
}
g_list_free(children);
if (gtk_combo_box_get_active_iter(widget, &iter)) {
gtk_tree_model_get(gtk_combo_box_get_model(widget), &iter,
COLUMN_DATA, &data, -1);
switch (data->args) {
case SINGLE_ARGS:
tmp = gtk_entry_new();
if (tdata->data) {
gtk_entry_set_text(GTK_ENTRY(tmp), tdata->data->data);
}
gtk_widget_show(tmp);
gtk_box_pack_start(GTK_BOX(parent), tmp, TRUE, TRUE, 0);
break;
case CUSTOM_ARGS:
data->func(tdata->triggers,
CUSTOM_ARG_CREATE, (gpointer)parent,
(gpointer)tdata->data);
break;
default:
break;
}
if (tdata->data != NULL) {
tdata->data = NULL;
}
} else {
gm_debug_msg(DEBUG_ALWAYS, "No active iter!");
}
}
void
on_combo_box_type_destroy(GtkObject *object, ComboBoxTypeData *tdata) {
g_free(tdata);
}
#ifdef HAVE_RUBY
gpointer
gm_triggers_dialog_custom_arg_script(GmTriggersDialog *triggers,
CustomArgType type, gpointer data, gpointer user_data) {
GtkWidget *hbox;
GtkWidget *entry;
GtkEntryCompletion *entry_completion;
GList *item;
GmTriggerData *t = (GmTriggerData *)(user_data);
switch (type) {
case CUSTOM_ARG_CREATE:
hbox = GTK_WIDGET(data);
entry = gtk_entry_new();
entry_completion = gtk_entry_completion_new();
gtk_entry_completion_set_model(entry_completion,
triggers->script_model);
gtk_entry_completion_set_text_column(entry_completion, 0);
gtk_entry_set_completion(GTK_ENTRY(entry), entry_completion);
if (user_data) {
gtk_entry_set_text(GTK_ENTRY(entry), t->data);
}
gtk_widget_show(entry);
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
break;
case CUSTOM_ARG_GET_DATA:
item = (GList *)(data);
return g_strdup(gtk_entry_get_text(GTK_ENTRY(item->data)));
break;
}
return NULL;
}
#endif
gboolean
gm_triggers_dialog_idle_remove_item(GtkWidget *parent) {
gtk_widget_destroy(parent);
return FALSE;
}
void
on_button_remove_clicked(GtkButton *button, GmTriggersDialog *triggers) {
g_idle_add((GSourceFunc)(gm_triggers_dialog_idle_remove_item),
gtk_widget_get_parent(GTK_WIDGET(button)));
}
void
on_button_add_condition_clicked(GtkButton *button, GmTriggersDialog *triggers) {
gm_triggers_dialog_new_condition(triggers);
}
void
on_button_add_action_clicked(GtkButton *button, GmTriggersDialog *triggers) {
gm_triggers_dialog_new_action(triggers);
}