# HG changeset patch # User Sadrul Habib Chowdhury # Date 1154916958 0 # Node ID c5bfede3362256227966f8865fcbf0798881348e # Parent eb1a7d176149fc3f76d19ac71bf96832b6a2ebc7 [gaim-migrate @ 16660] A couple of minor adjustments, memory leak fixes. And request-ui is almost complete now. committer: Tailor Script diff -r eb1a7d176149 -r c5bfede33622 console/gntblist.c --- a/console/gntblist.c Sun Aug 06 23:47:34 2006 +0000 +++ b/console/gntblist.c Mon Aug 07 02:15:58 2006 +0000 @@ -61,7 +61,7 @@ static void add_chat(GaimChat *chat, GGBlist *ggblist); static void add_node(GaimBlistNode *node, GGBlist *ggblist); static void draw_tooltip(GGBlist *ggblist); -static void remove_typing_cb(gpointer null); +static gboolean remove_typing_cb(gpointer null); static void remove_peripherals(GGBlist *ggblist); static const char * get_display_name(GaimBlistNode *node); @@ -873,7 +873,7 @@ return; } -static void +static gboolean remove_typing_cb(gpointer null) { GaimSavedStatus *current; @@ -887,7 +887,7 @@ newmessage = gnt_entry_get_text(GNT_ENTRY(ggblist->statustext)); item = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(ggblist->status)); - g_return_if_fail(item->type == STATUS_PRIMITIVE); + g_return_val_if_fail(item->type == STATUS_PRIMITIVE, FALSE); newprim = item->u.prim; if (newprim != prim || ((message && !newmessage) || @@ -908,6 +908,7 @@ gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree); g_source_remove(ggblist->typing); ggblist->typing = 0; + return FALSE; } static void @@ -932,7 +933,7 @@ static gboolean status_text_changed(GntEntry *entry, const char *text, gpointer null) { - if (text[0] == 27 && ggblist->typing == 0) + if ((text[0] == 27 || (text[0] == '\t' && text[1] == '\0')) && ggblist->typing == 0) return FALSE; g_source_remove(ggblist->typing); diff -r eb1a7d176149 -r c5bfede33622 console/gntconv.c --- a/console/gntconv.c Sun Aug 06 23:47:34 2006 +0000 +++ b/console/gntconv.c Mon Aug 07 02:15:58 2006 +0000 @@ -107,17 +107,20 @@ } else { + char *escape = g_markup_escape_text(text, -1); switch (gaim_conversation_get_type(ggconv->conv)) { case GAIM_CONV_TYPE_IM: - gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), text, GAIM_MESSAGE_SEND); + gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), escape, GAIM_MESSAGE_SEND); break; case GAIM_CONV_TYPE_CHAT: - gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), text); + gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), escape); break; default: + g_free(escape); g_return_val_if_reached(FALSE); } + g_free(escape); } gnt_entry_clear(GNT_ENTRY(ggconv->entry)); return TRUE; diff -r eb1a7d176149 -r c5bfede33622 console/gntrequest.c --- a/console/gntrequest.c Sun Aug 06 23:47:34 2006 +0000 +++ b/console/gntrequest.c Mon Aug 07 02:15:58 2006 +0000 @@ -1,15 +1,19 @@ #include #include #include +#include #include #include #include +#include +#include +#include "gntgaim.h" #include "gntrequest.h" static GntWidget * setup_request_window(const char *title, const char *primary, - const char *secondary) + const char *secondary, GaimRequestType type) { GntWidget *window; @@ -24,6 +28,9 @@ if (secondary) gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary)); + g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gaim_request_close), + GINT_TO_POINTER(type)); + return window; } @@ -35,7 +42,7 @@ const char *text; gpointer callback; - box = gnt_hbox_new(TRUE); + box = gnt_hbox_new(FALSE); va_start(list, data); @@ -79,7 +86,7 @@ { GntWidget *window, *box, *entry; - window = setup_request_window(title, primary, secondary); + window = setup_request_window(title, primary, secondary, GAIM_REQUEST_INPUT); entry = gnt_entry_new(default_value); if (masked) @@ -131,7 +138,7 @@ const char *text; int val; - window = setup_request_window(title, primary, secondary); + window = setup_request_window(title, primary, secondary, GAIM_REQUEST_CHOICE); combo = gnt_combo_box_new(); gnt_box_add_widget(GNT_BOX(window), combo); @@ -173,7 +180,7 @@ GntWidget *window, *box, *button; int i; - window = setup_request_window(title, primary, secondary); + window = setup_request_window(title, primary, secondary, GAIM_REQUEST_ACTION); box = gnt_hbox_new(TRUE); gnt_box_add_widget(GNT_BOX(window), box); @@ -196,12 +203,212 @@ return window; } +static void +request_fields_cb(GntWidget *button, GaimRequestFields *fields) +{ + GaimRequestFieldsCb callback = g_object_get_data(G_OBJECT(button), "activate-callback"); + gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata"); + GList *list; + + /* Update the data of the fields. GtkGaim does this differently. Instead of + * updating the fields at the end like here, it updates the appropriate field + * instantly whenever a change is made. That allows it to make sure the + * 'required' fields are entered before the user can hit OK. It's not the case + * here, althought it can be done. I am not honouring the 'required' fields + * for the moment. */ + for (list = gaim_request_fields_get_groups(fields); list; list = list->next) + { + GaimRequestFieldGroup *group = list->data; + GList *fields = gaim_request_field_group_get_fields(group); + + for (; fields ; fields = fields->next) + { + GaimRequestField *field = fields->data; + GaimRequestFieldType type = gaim_request_field_get_type(field); + if (type == GAIM_REQUEST_FIELD_BOOLEAN) + { + GntWidget *check = field->ui_data; + gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check)); + gaim_request_field_bool_set_value(field, value); + } + else if (type == GAIM_REQUEST_FIELD_STRING) + { + GntWidget *entry = field->ui_data; + gaim_request_field_string_set_value(field, gnt_entry_get_text(GNT_ENTRY(entry))); + } + else if (type == GAIM_REQUEST_FIELD_INTEGER) + { + GntWidget *entry = field->ui_data; + const char *text = gnt_entry_get_text(GNT_ENTRY(entry)); + int value = (text && *text) ? atoi(text) : 0; + gaim_request_field_int_set_value(field, value); + } + else if (type == GAIM_REQUEST_FIELD_CHOICE) + { + GntWidget *combo = field->ui_data;; + int id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo))); + gaim_request_field_choice_set_value(field, id); + } + else if (type == GAIM_REQUEST_FIELD_LIST) + { + GntWidget *tree = field->ui_data; + gpointer data = gnt_tree_get_selection_data(GNT_TREE(tree)); + GList *list = g_list_append(NULL, data); /* XXX: Update when multi-select is allowed */ + gaim_request_field_list_set_selected(field, list); + g_list_free(list); + } + else if (type == GAIM_REQUEST_FIELD_ACCOUNT) + { + } + } + } + + if (callback) + callback(data, fields); + + while (button->parent) + button = button->parent; + + gaim_request_close(GAIM_REQUEST_FIELDS, button); +} + +static void * +gg_request_fields(const char *title, const char *primary, + const char *secondary, GaimRequestFields *fields, + const char *ok, GCallback ok_cb, + const char *cancel, GCallback cancel_cb, + void *userdata) +{ + GntWidget *window, *box; + GList *list; + + window = setup_request_window(title, primary, secondary, GAIM_REQUEST_FIELDS); + + /* This is how it's going to work: the request-groups are going to be + * stacked vertically one after the other. A GntLine will be separating + * the groups. */ + box = gnt_vbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(box), 0); + gnt_box_set_fill(GNT_BOX(box), TRUE); + for (list = gaim_request_fields_get_groups(fields); list; list = list->next) + { + GaimRequestFieldGroup *group = list->data; + GList *fields = gaim_request_field_group_get_fields(group); + GntWidget *hbox; + + /* XXX: Do something with the title, perhaps add a bold label */ + + for (; fields ; fields = fields->next) + { + GaimRequestField *field = fields->data; + GaimRequestFieldType type = gaim_request_field_get_type(field); + const char *label = gaim_request_field_get_label(field); + + hbox = gnt_hbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(hbox), 0); + gnt_box_add_widget(GNT_BOX(box), hbox); + + if (type != GAIM_REQUEST_FIELD_BOOLEAN) + gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(label)); + + if (type == GAIM_REQUEST_FIELD_BOOLEAN) + { + GntWidget *check = gnt_check_box_new(label); + gnt_check_box_set_checked(GNT_CHECK_BOX(check), + gaim_request_field_bool_get_default_value(field)); + gnt_box_add_widget(GNT_BOX(hbox), check); + field->ui_data = check; + } + else if (type == GAIM_REQUEST_FIELD_STRING) + { + GntWidget *entry = gnt_entry_new( + gaim_request_field_string_get_default_value(field)); + gnt_entry_set_masked(GNT_ENTRY(entry), + gaim_request_field_string_is_masked(field)); + gnt_box_add_widget(GNT_BOX(hbox), entry); + field->ui_data = entry; + } + else if (type == GAIM_REQUEST_FIELD_INTEGER) + { + GntWidget *entry = gnt_entry_new( + gaim_request_field_string_get_default_value(field)); + gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT); + gnt_box_add_widget(GNT_BOX(hbox), entry); + field->ui_data = entry; + } + else if (type == GAIM_REQUEST_FIELD_CHOICE) + { + int id; + const GList *list; + GntWidget *combo = gnt_combo_box_new(); + gnt_box_add_widget(GNT_BOX(hbox), combo); + field->ui_data = combo; + + list = gaim_request_field_choice_get_labels(field); + for (id = 1; list; list = list->next, id++) + { + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), + GINT_TO_POINTER(id), list->data); + } + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), + GINT_TO_POINTER(gaim_request_field_choice_get_default_value(field))); + } + else if (type == GAIM_REQUEST_FIELD_LIST) + { + /* XXX: Yet to allow multi-select, because the feature is absent in GntTree */ + const GList *list; + GntWidget *tree = gnt_tree_new(); + gnt_box_add_widget(GNT_BOX(hbox), tree); + field->ui_data = tree; + + list = gaim_request_field_list_get_items(field); + for (; list; list = list->next) + { + const char *text = list->data; + gpointer key = gaim_request_field_list_get_data(field, text); + gnt_tree_add_row_after(GNT_TREE(tree), key, + gnt_tree_create_row(GNT_TREE(tree), text), NULL, NULL); + if (gaim_request_field_list_is_selected(field, text)) + gnt_tree_set_selected(GNT_TREE(tree), key); + } + } +#if 0 + else if (type == GAIM_REQUEST_FIELD_ACCOUNT) + { + /* XXX: remember to set the field->ui_data */ + } +#endif + else + { + gnt_box_add_widget(GNT_BOX(hbox), + gnt_label_new_with_format(_("Not implemented yet."), + GNT_TEXT_FLAG_BOLD)); + } + if (fields->next) + gnt_box_add_widget(GNT_BOX(box), gnt_hline_new()); + } + } + gnt_box_add_widget(GNT_BOX(window), box); + + box = setup_button_box(userdata, request_fields_cb, fields, + ok, ok_cb, cancel, cancel_cb, NULL); + gnt_box_add_widget(GNT_BOX(window), box); + + gnt_widget_show(window); + + + return window; +} + static GaimRequestUiOps uiops = { .request_input = gg_request_input, .close_request = gg_close_request, .request_choice = gg_request_choice, .request_action = gg_request_action, + .request_fields = gg_request_fields, + .request_file = NULL, /* No plans for these */ + .request_folder = NULL }; GaimRequestUiOps *gg_request_get_ui_ops() diff -r eb1a7d176149 -r c5bfede33622 console/libgnt/gntcombobox.c --- a/console/libgnt/gntcombobox.c Sun Aug 06 23:47:34 2006 +0000 +++ b/console/libgnt/gntcombobox.c Mon Aug 07 02:15:58 2006 +0000 @@ -41,14 +41,12 @@ if (box->dropdown) { - text = (char *)gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); + text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown)); box->selected = gnt_tree_get_selection_data(GNT_TREE(box->dropdown)); } if (text == NULL) - text = ""; - - text = g_strdup(text); + text = g_strdup(text); if (gnt_widget_has_focus(widget)) type = GNT_COLOR_HIGHLIGHT; @@ -102,6 +100,7 @@ case '\t': set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown))); case 27: + gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected); gnt_widget_hide(box->dropdown->parent); return TRUE; break; @@ -118,18 +117,18 @@ strcmp(text + 1, GNT_KEY_DOWN) == 0) { GntWidget *parent = box->dropdown->parent; - gnt_widget_set_size(box->dropdown, widget->priv.width, 9); - gnt_widget_set_position(parent, - widget->priv.x, widget->priv.y + widget->priv.height - 1); + int height = g_list_length(GNT_TREE(box->dropdown)->list); + int y = widget->priv.y + widget->priv.height - 1; + gnt_widget_set_size(box->dropdown, widget->priv.width, height + 2); + + if (y + height + 2 >= getmaxy(stdscr)) + y = widget->priv.y - height - 1; + gnt_widget_set_position(parent, widget->priv.x, y); if (parent->window) { - if (mvwin(parent->window, widget->priv.y + widget->priv.height - 1, - widget->priv.x) == ERR) - mvwin(parent->window, - widget->priv.y - 9 + 1, widget->priv.x); + mvwin(parent->window, y, widget->priv.x); } - GNT_WIDGET_SET_FLAGS(parent, GNT_WIDGET_TRANSIENT); gnt_widget_draw(parent); return TRUE; } @@ -192,7 +191,7 @@ combo->dropdown = gnt_tree_new(); box = gnt_box_new(FALSE, FALSE); - GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER); + GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT); gnt_box_set_pad(GNT_BOX(box), 0); gnt_box_add_widget(GNT_BOX(box), combo->dropdown); diff -r eb1a7d176149 -r c5bfede33622 console/libgnt/gnttree.h --- a/console/libgnt/gnttree.h Sun Aug 06 23:47:34 2006 +0000 +++ b/console/libgnt/gnttree.h Mon Aug 07 02:15:58 2006 +0000 @@ -78,6 +78,7 @@ gpointer gnt_tree_get_selection_data(GntTree *tree); +/* Returned string needs to be freed */ char *gnt_tree_get_selection_text(GntTree *tree); GList *gnt_tree_get_selection_text_list(GntTree *tree); diff -r eb1a7d176149 -r c5bfede33622 console/libgnt/test/combo.c --- a/console/libgnt/test/combo.c Sun Aug 06 23:47:34 2006 +0000 +++ b/console/libgnt/test/combo.c Mon Aug 07 02:15:58 2006 +0000 @@ -46,6 +46,9 @@ gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "4", "4"); gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "5", "5"); gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "6", "6"); + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "7", "7"); + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "8", "8"); + gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "9", "9"); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new("Select")); gnt_box_add_widget(GNT_BOX(hbox), combo);