# HG changeset patch # User Sadrul Habib Chowdhury # Date 1153617006 0 # Node ID a71678d2da160b679e767081bff04fa4b5eba064 # Parent ea00953490a8fee46f9dabff1aeb327008ab8154 [gaim-migrate @ 16540] Complete the notify-ui. I have been unable to test the searchresult-ui. But "looks like" it will work. The accounts-ui is also mostly . I am yet to add the proxy-options. And you cannot still delete an account. That will happen after the request-ui is complete. The account-edit dialog needs some work, but it's usable. Added GntCheckBox, and add some features to some other gnt-widgets. committer: Tailor Script diff -r ea00953490a8 -r a71678d2da16 console/gntaccount.c --- a/console/gntaccount.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/gntaccount.c Sun Jul 23 01:10:06 2006 +0000 @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,8 @@ #include "gntaccount.h" #include "gntgaim.h" +#include + typedef struct { GntWidget *window; @@ -38,17 +41,157 @@ GntWidget *splits; GList *split_entries; + + GList *prpl_entries; + GntWidget *prpls; + + GntWidget *newmail; + GntWidget *remember; } AccountEditDialog; static void +account_add(GaimAccount *account) +{ + gnt_tree_add_choice(GNT_TREE(accounts.tree), account, + gnt_tree_create_row(GNT_TREE(accounts.tree), + gaim_account_get_username(account), + gaim_account_get_protocol_name(account)), + NULL, NULL); + gnt_tree_set_choice(GNT_TREE(accounts.tree), account, + gaim_account_get_enabled(account, GAIM_GNT_UI)); +} + +static void edit_dialog_destroy(AccountEditDialog *dialog) { + g_list_free(dialog->prpl_entries); + g_list_free(dialog->split_entries); g_free(dialog); } static void save_account_cb(AccountEditDialog *dialog) { + GaimAccount *account; + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + const char *value; + GString *username; + + /* XXX: Do some error checking first. */ + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + /* Screenname && user-splits */ + value = gnt_entry_get_text(GNT_ENTRY(dialog->screenname)); + + if (value == NULL || *value == '\0') + { + gaim_notify_error(NULL, _("Error"), _("Account was not added"), + _("Screenname of an account must be non-empty.")); + return; + } + + username = g_string_new(value); + + if (prplinfo != NULL) + { + GList *iter, *entries; + for (iter = prplinfo->user_splits, entries = dialog->split_entries; + iter && entries; iter = iter->next, entries = entries->next) + { + GaimAccountUserSplit *split = iter->data; + GntWidget *entry = entries->data; + + value = gnt_entry_get_text(GNT_ENTRY(entry)); + if (value == NULL || *value == '\0') + value = gaim_account_user_split_get_default_value(split); + g_string_append_printf(username, "%c%s", + gaim_account_user_split_get_separator(split), + value); + } + } + + if (dialog->account == NULL) + { + account = gaim_account_new(username->str, gaim_plugin_get_id(plugin)); + gaim_accounts_add(account); + } + else + { + account = dialog->account; + + /* Protocol */ + gaim_account_set_protocol_id(account, gaim_plugin_get_id(plugin)); + gaim_account_set_username(account, username->str); + } + g_string_free(username, TRUE); + + /* Alias */ + value = gnt_entry_get_text(GNT_ENTRY(dialog->alias)); + if (value && *value) + gaim_account_set_alias(account, value); + + /* Remember password and password */ + gaim_account_set_remember_password(account, + gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->remember))); + value = gnt_entry_get_text(GNT_ENTRY(dialog->password)); + if (value && *value && gaim_account_get_remember_password(account)) + gaim_account_set_password(account, value); + else + gaim_account_set_password(account, NULL); + + /* Mail notification */ + /* XXX: Only if the protocol has anything to do with emails */ + gaim_account_set_check_mail(account, + gnt_check_box_get_checked(GNT_CHECK_BOX(dialog->newmail))); + + /* Protocol options */ + if (prplinfo) + { + GList *iter, *entries; + + for (iter = prplinfo->protocol_options, entries = dialog->prpl_entries; + iter && entries; iter = iter->next, entries = entries->next) + { + GaimAccountOption *option = iter->data; + GntWidget *entry = entries->data; + GaimPrefType type = gaim_account_option_get_type(option); + const char *setting = gaim_account_option_get_setting(option); + + if (type == GAIM_PREF_STRING) + { + const char *value = gnt_entry_get_text(GNT_ENTRY(entry)); + gaim_account_set_string(account, setting, value); + } + else if (type == GAIM_PREF_INT) + { + const char *str = gnt_entry_get_text(GNT_ENTRY(entry)); + int value = 0; + if (str) + value = atoi(str); + gaim_account_set_int(account, setting, value); + } + else if (type == GAIM_PREF_BOOLEAN) + { + gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(entry)); + gaim_account_set_bool(account, setting, value); + } + else if (type == GAIM_PREF_STRING_LIST) + { + /* TODO: */ + } + else + { + g_assert_not_reached(); + } + } + } + + /* XXX: Proxy options */ + + gnt_widget_destroy(dialog->window); } static void @@ -57,7 +200,7 @@ GntWidget *hbox; GaimPlugin *plugin; GaimPluginProtocolInfo *prplinfo; - GList *iter; + GList *iter, *entries; char *username = NULL; if (dialog->splits) @@ -99,20 +242,180 @@ g_free(buf); } - /* XXX: Add default/custom values to the splits */ + for (iter = g_list_last(prplinfo->user_splits), entries = g_list_last(dialog->split_entries); + iter && entries; iter = iter->prev, entries = entries->prev) + { + GntWidget *entry = entries->data; + GaimAccountUserSplit *split = iter->data; + const char *value = NULL; + char *s; + + if (dialog->account) + { + s = strrchr(username, gaim_account_user_split_get_separator(split)); + if (s != NULL) + { + *s = '\0'; + s++; + value = s; + } + } + if (value == NULL) + value = gaim_account_user_split_get_default_value(split); + + if (value != NULL) + gnt_entry_set_text(GNT_ENTRY(entry), value); + } + + if (username != NULL) + gnt_entry_set_text(GNT_ENTRY(dialog->screenname), username); + g_free(username); } static void +add_protocol_options(AccountEditDialog *dialog) +{ + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + GList *iter; + GntWidget *vbox, *box; + GaimAccount *account; + + if (dialog->prpls) + gnt_box_remove_all(GNT_BOX(dialog->prpls)); + else + { + dialog->prpls = vbox = gnt_vbox_new(FALSE); + gnt_box_set_pad(GNT_BOX(vbox), 0); + gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_LEFT); + gnt_box_set_fill(GNT_BOX(vbox), TRUE); + } + + if (dialog->prpl_entries) + { + g_list_free(dialog->prpl_entries); + dialog->prpl_entries = NULL; + } + + vbox = dialog->prpls; + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + if (!plugin) + return; + + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + account = dialog->account; + + for (iter = prplinfo->protocol_options; iter; iter = iter->next) + { + GaimAccountOption *option = iter->data; + GaimPrefType type = gaim_account_option_get_type(option); + + box = gnt_hbox_new(TRUE); + gnt_box_set_pad(GNT_BOX(box), 0); + gnt_box_add_widget(GNT_BOX(vbox), box); + + if (type == GAIM_PREF_BOOLEAN) + { + GntWidget *widget = gnt_check_box_new(gaim_account_option_get_text(option)); + gnt_box_add_widget(GNT_BOX(box), widget); + dialog->prpl_entries = g_list_append(dialog->prpl_entries, widget); + + if (account) + gnt_check_box_set_checked(GNT_CHECK_BOX(widget), + gaim_account_get_bool(account, + gaim_account_option_get_setting(option), + gaim_account_option_get_default_bool(option))); + else + gnt_check_box_set_checked(GNT_CHECK_BOX(widget), + gaim_account_option_get_default_bool(option)); + } + else + { + gnt_box_add_widget(GNT_BOX(box), + gnt_label_new(gaim_account_option_get_text(option))); + + if (type == GAIM_PREF_STRING_LIST) + { + /* TODO: Use a combobox */ + /* Don't forget to append the widget to prpl_entries */ + } + else + { + GntWidget *entry = gnt_entry_new(NULL); + gnt_box_add_widget(GNT_BOX(box), entry); + dialog->prpl_entries = g_list_append(dialog->prpl_entries, entry); + + if (type == GAIM_PREF_STRING) + { + const char *dv = gaim_account_option_get_default_string(option); + + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), + gaim_account_get_string(account, + gaim_account_option_get_setting(option), dv)); + else + gnt_entry_set_text(GNT_ENTRY(entry), dv); + } + else if (type == GAIM_PREF_INT) + { + char str[32]; + int value = gaim_account_option_get_default_int(option); + if (account) + value = gaim_account_get_int(account, + gaim_account_option_get_setting(option), value); + snprintf(str, sizeof(str), "%d", value); + gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT); + gnt_entry_set_text(GNT_ENTRY(entry), str); + } + else + { + g_assert_not_reached(); + } + } + } + } +} + +static void +update_user_options(AccountEditDialog *dialog) +{ + GaimPlugin *plugin; + GaimPluginProtocolInfo *prplinfo; + + plugin = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(dialog->protocol)); + if (!plugin) + return; + + prplinfo = GAIM_PLUGIN_PROTOCOL_INFO(plugin); + + if (dialog->newmail == NULL) + dialog->newmail = gnt_check_box_new(_("New mail notifications")); + if (dialog->account) + gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->newmail), + gaim_account_get_check_mail(dialog->account)); + + if (dialog->remember == NULL) + dialog->remember = gnt_check_box_new(_("Remember password")); + if (dialog->account) + gnt_check_box_set_checked(GNT_CHECK_BOX(dialog->remember), + gaim_account_get_remember_password(dialog->account)); +} + +static void prpl_changed_cb(GntWidget *combo, GaimPlugin *old, GaimPlugin *new, AccountEditDialog *dialog) { update_user_splits(dialog); + add_protocol_options(dialog); + update_user_options(dialog); /* This may not be necessary here */ gnt_box_readjust(GNT_BOX(dialog->window)); gnt_widget_draw(dialog->window); } static void -add_account(GntWidget *b, gpointer null) +edit_account(GaimAccount *account) { GntWidget *window, *hbox; GntWidget *combo, *button, *entry; @@ -122,8 +425,9 @@ dialog = g_new0(AccountEditDialog, 1); dialog->window = window = gnt_box_new(FALSE, TRUE); + dialog->account = account; gnt_box_set_toplevel(GNT_BOX(window), TRUE); - gnt_box_set_title(GNT_BOX(window), _("New Account")); + gnt_box_set_title(GNT_BOX(window), account ? _("Modify Account") : _("New Account")); gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); gnt_box_set_pad(GNT_BOX(window), 0); @@ -138,6 +442,12 @@ gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data, ((GaimPlugin*)iter->data)->info->name); } + if (account) + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), + gaim_plugins_find_with_id(gaim_account_get_protocol_id(account))); + else + gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), list->data); + g_signal_connect(G_OBJECT(combo), "selection-changed", G_CALLBACK(prpl_changed_cb), dialog); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Protocol:"))); gnt_box_add_widget(GNT_BOX(hbox), combo); @@ -157,8 +467,11 @@ gnt_box_add_widget(GNT_BOX(window), hbox); dialog->password = entry = gnt_entry_new(NULL); + gnt_entry_set_masked(GNT_ENTRY(entry), TRUE); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Password:"))); gnt_box_add_widget(GNT_BOX(hbox), entry); + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_password(account)); hbox = gnt_box_new(TRUE, FALSE); gnt_box_add_widget(GNT_BOX(window), hbox); @@ -166,9 +479,23 @@ dialog->alias = entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(_("Alias:"))); gnt_box_add_widget(GNT_BOX(hbox), entry); + if (account) + gnt_entry_set_text(GNT_ENTRY(entry), gaim_account_get_alias(account)); + + /* User options */ + update_user_options(dialog); + gnt_box_add_widget(GNT_BOX(window), dialog->remember); + gnt_box_add_widget(GNT_BOX(window), dialog->newmail); gnt_box_add_widget(GNT_BOX(window), gnt_line_new(FALSE)); - + + /* The advanced box */ + add_protocol_options(dialog); + gnt_box_add_widget(GNT_BOX(window), dialog->prpls); + + /* TODO: Add proxy options */ + + /* The button box */ hbox = gnt_box_new(FALSE, FALSE); gnt_box_add_widget(GNT_BOX(window), hbox); @@ -183,6 +510,30 @@ g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(edit_dialog_destroy), dialog); gnt_widget_show(window); + gnt_box_readjust(GNT_BOX(window)); + gnt_widget_draw(window); +} + +static void +add_account_cb(GntWidget *widget, gpointer null) +{ + edit_account(NULL); +} + +static void +modify_account_cb(GntWidget *widget, GntTree *tree) +{ + GaimAccount *account = gnt_tree_get_selection_data(tree); + if (!account) + return; + edit_account(account); +} + +static void +delete_account_cb(GntWidget *widget, GntTree *tree) +{ + /* XXX: After the request-api is complete */ + /* Note: remove the modify-dialog for the account */ } static void @@ -193,7 +544,7 @@ gaim_account_set_enabled(account, GAIM_GNT_UI, gnt_tree_get_choice(GNT_TREE(widget), key)); } -void gg_accounts_init() +void gg_accounts_show_all() { GList *iter; GntWidget *box, *button; @@ -216,14 +567,7 @@ for (iter = gaim_accounts_get_all(); iter; iter = iter->next) { GaimAccount *account = iter->data; - - gnt_tree_add_choice(GNT_TREE(accounts.tree), account, - gnt_tree_create_row(GNT_TREE(accounts.tree), - gaim_account_get_username(account), - gaim_account_get_protocol_name(account)), - NULL, NULL); - gnt_tree_set_choice(GNT_TREE(accounts.tree), account, - gaim_account_get_enabled(account, GAIM_GNT_UI)); + account_add(account); } g_signal_connect(G_OBJECT(accounts.tree), "toggled", G_CALLBACK(account_toggled), NULL); @@ -238,19 +582,59 @@ button = gnt_button_new(_("Add")); gnt_box_add_widget(GNT_BOX(box), button); - g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account), NULL); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_account_cb), NULL); button = gnt_button_new(_("Modify")); gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(modify_account_cb), accounts.tree); button = gnt_button_new(_("Delete")); gnt_box_add_widget(GNT_BOX(box), button); + g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_account_cb), accounts.tree); gnt_box_add_widget(GNT_BOX(accounts.window), box); gnt_widget_show(accounts.window); } +static gpointer +gg_accounts_get_handle() +{ + static int handle; + + return &handle; +} + +static void +account_added_callback(GaimAccount *account) +{ + if (accounts.window == NULL) + return; + account_add(account); + gnt_widget_draw(accounts.tree); +} + +static void +account_removed_callback(GaimAccount *account) +{ + if (accounts.window == NULL) + return; + + gnt_tree_remove(GNT_TREE(accounts.tree), account); +} + +void gg_accounts_init() +{ + gaim_signal_connect(gaim_accounts_get_handle(), "account-added", + gg_accounts_get_handle(), GAIM_CALLBACK(account_added_callback), + NULL); + gaim_signal_connect(gaim_accounts_get_handle(), "account-removed", + gg_accounts_get_handle(), GAIM_CALLBACK(account_removed_callback), + NULL); + + gg_accounts_show_all(); +} + void gg_accounts_uninit() { gnt_widget_destroy(accounts.window); diff -r ea00953490a8 -r a71678d2da16 console/gntaccount.h --- a/console/gntaccount.h Sat Jul 22 18:11:34 2006 +0000 +++ b/console/gntaccount.h Sun Jul 23 01:10:06 2006 +0000 @@ -5,3 +5,6 @@ void gg_accounts_init(); void gg_accounts_uninit(); + +void gg_accounts_show_all(); + diff -r ea00953490a8 -r a71678d2da16 console/gntnotify.c --- a/console/gntnotify.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/gntnotify.c Sun Jul 23 01:10:06 2006 +0000 @@ -57,7 +57,13 @@ /* handle is, in all/most occasions, a GntWidget * */ static void gg_close_notify(GaimNotifyType type, void *handle) { - gnt_widget_destroy(GNT_WIDGET(handle)); + GntWidget *widget = handle; + while (widget->parent) + widget = widget->parent; + + if (type == GAIM_NOTIFY_SEARCHRESULTS) + gaim_notify_searchresults_free(g_object_get_data(handle, "notify-results")); + gnt_widget_destroy(widget); } static void *gg_notify_formatted(const char *title, const char *primary, @@ -180,6 +186,112 @@ return ui_handle; } +static void +notify_button_activated(GntWidget *widget, GaimNotifySearchButton *b) +{ + GList *list = NULL; + GaimAccount *account = g_object_get_data(G_OBJECT(widget), "notify-account"); + gpointer data = g_object_get_data(G_OBJECT(widget), "notify-data"); + + list = gnt_tree_get_selection_text_list(GNT_TREE(widget)); + + b->callback(gaim_account_get_connection(account), list, data); + g_list_foreach(list, (GFunc)g_free, NULL); + g_list_free(list); +} + +static void +gg_notify_sr_new_rows(GaimConnection *gc, + GaimNotifySearchResults *results, void *data) +{ + GntTree *tree = GNT_TREE(data); + GList *o; + + /* XXX: Do I need to empty the tree here? */ + + for (o = results->rows; o; o = o->next) + { + gnt_tree_add_row_after(GNT_TREE(tree), o->data, + gnt_tree_create_row_from_list(GNT_TREE(tree), o->data), + NULL, NULL); + } +} + +static void * +gg_notify_searchresults(GaimConnection *gc, const char *title, + const char *primary, const char *secondary, + GaimNotifySearchResults *results, gpointer data) +{ + GntWidget *window, *tree, *box, *button; + GList *iter; + + window = gnt_vbox_new(FALSE); + gnt_box_set_toplevel(GNT_BOX(window), TRUE); + gnt_box_set_title(GNT_BOX(window), title); + gnt_box_set_fill(GNT_BOX(window), FALSE); + gnt_box_set_pad(GNT_BOX(window), 0); + gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); + + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD)); + gnt_box_add_widget(GNT_BOX(window), + gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL)); + + tree = gnt_tree_new_with_columns(g_list_length(results->columns)); + gnt_tree_set_show_title(GNT_TREE(tree), TRUE); + gnt_box_add_widget(GNT_BOX(window), tree); + + box = gnt_hbox_new(TRUE); + + for (iter = results->buttons; iter; iter = iter->next) + { + GaimNotifySearchButton *b = iter->data; + const char *text; + + switch (b->type) + { + case GAIM_NOTIFY_BUTTON_LABELED: + text = b->label; + break; + case GAIM_NOTIFY_BUTTON_CONTINUE: + text = _("Continue"); + break; + case GAIM_NOTIFY_BUTTON_ADD: + text = _("Add"); + break; + case GAIM_NOTIFY_BUTTON_INFO: + text = _("Info"); + break; + case GAIM_NOTIFY_BUTTON_IM: + text = _("IM"); + break; + case GAIM_NOTIFY_BUTTON_JOIN: + text = _("Join"); + break; + case GAIM_NOTIFY_BUTTON_INVITE: + text = _("Invite"); + break; + } + + button = gnt_button_new(text); + g_object_set_data(G_OBJECT(button), "notify-account", gaim_connection_get_account(gc)); + g_object_set_data(G_OBJECT(button), "notify-data", data); + g_signal_connect_swapped(G_OBJECT(button), "activate", + G_CALLBACK(notify_button_activated), b); + + gnt_box_add_widget(GNT_BOX(box), button); + } + + gnt_box_add_widget(GNT_BOX(window), box); + + gg_notify_sr_new_rows(gc, results, tree); + + gnt_widget_show(window); + g_object_set_data(G_OBJECT(window), "notify-results", results); + + return tree; +} + static GaimNotifyUiOps ops = { .notify_message = gg_notify_message, @@ -190,8 +302,8 @@ .notify_emails = gg_notify_emails, .notify_userinfo = gg_notify_userinfo, - .notify_searchresults = NULL, /* We are going to need multi-column GntTree's for this */ - .notify_searchresults_new_rows = NULL, + .notify_searchresults = gg_notify_searchresults, + .notify_searchresults_new_rows = gg_notify_sr_new_rows, .notify_uri = NULL /* This is of low-priority to me */ }; diff -r ea00953490a8 -r a71678d2da16 console/libgnt/Makefile.am --- a/console/libgnt/Makefile.am Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/Makefile.am Sun Jul 23 01:10:06 2006 +0000 @@ -7,6 +7,7 @@ gntwidget.c \ gntbox.c \ gntbutton.c \ + gntcheckbox.c \ gntcolors.c \ gntcombobox.c \ gntentry.c \ @@ -21,6 +22,7 @@ gntwidget.h \ gntbox.h \ gntbutton.h \ + gntcheckbox.h \ gntcolors.h \ gntcombobox.h \ gntentry.h \ diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntbutton.c --- a/console/libgnt/gntbutton.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntbutton.c Sun Jul 23 01:10:06 2006 +0000 @@ -22,7 +22,7 @@ type = GNT_COLOR_NORMAL; wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); - mvwprintw(widget->window, 1, 1, button->priv->text); + mvwprintw(widget->window, 1, 2, button->priv->text); DEBUG; } @@ -31,8 +31,10 @@ gnt_button_size_request(GntWidget *widget) { GntButton *button = GNT_BUTTON(widget); - widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 2; - widget->priv.height = 3; + widget->priv.width = g_utf8_strlen(button->priv->text, -1) + 4; + widget->priv.height = 1; + if (!GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_NO_SHADOW)) + widget->priv.height += 2; } static void diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntcheckbox.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntcheckbox.c Sun Jul 23 01:10:06 2006 +0000 @@ -0,0 +1,153 @@ +#include "gntcheckbox.h" + +enum +{ + SIG_TOGGLED = 1, + SIGS, +}; + +static GntButtonClass *parent_class = NULL; +static guint signals[SIGS] = { 0 }; + +static void +gnt_check_box_draw(GntWidget *widget) +{ + GntCheckBox *cb = GNT_CHECK_BOX(widget); + GntColorType type; + char *text; + + if (gnt_widget_has_focus(widget)) + type = GNT_COLOR_HIGHLIGHT; + else + type = GNT_COLOR_NORMAL; + + wbkgdset(widget->window, '\0' | COLOR_PAIR(type)); + + text = g_strdup_printf("[%c]", cb->checked ? 'X' : ' '); + mvwprintw(widget->window, 0, 0, text); + g_free(text); + + wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); + mvwprintw(widget->window, 0, 4, GNT_BUTTON(cb)->priv->text); + + DEBUG; +} + +static void +gnt_check_box_size_request(GntWidget *widget) +{ +} + +static void +gnt_check_box_map(GntWidget *widget) +{ + if (widget->priv.width == 0 || widget->priv.height == 0) + gnt_widget_size_request(widget); + DEBUG; +} + +static gboolean +gnt_check_box_key_pressed(GntWidget *widget, const char *text) +{ + if (text[0] == ' ' && text[1] == '\0') + { + GNT_CHECK_BOX(widget)->checked = !GNT_CHECK_BOX(widget)->checked; + g_signal_emit(widget, signals[SIG_TOGGLED], 0); + gnt_widget_draw(widget); + return TRUE; + } + + return FALSE; +} + +static void +gnt_check_box_destroy(GntWidget *widget) +{ +} + +static void +gnt_check_box_class_init(GntCheckBoxClass *klass) +{ + GntWidgetClass *wclass = GNT_WIDGET_CLASS(klass); + + parent_class = GNT_BUTTON_CLASS(klass); + /*parent_class->destroy = gnt_check_box_destroy;*/ + wclass->draw = gnt_check_box_draw; + /*parent_class->map = gnt_check_box_map;*/ + /*parent_class->size_request = gnt_check_box_size_request;*/ + wclass->key_pressed = gnt_check_box_key_pressed; + + signals[SIG_TOGGLED] = + g_signal_new("toggled", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GntCheckBoxClass, toggled), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + DEBUG; +} + +static void +gnt_check_box_init(GTypeInstance *instance, gpointer class) +{ + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(instance), GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + DEBUG; +} + +/****************************************************************************** + * GntCheckBox API + *****************************************************************************/ +GType +gnt_check_box_get_gtype(void) +{ + static GType type = 0; + + if(type == 0) + { + static const GTypeInfo info = { + sizeof(GntCheckBoxClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)gnt_check_box_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(GntCheckBox), + 0, /* n_preallocs */ + gnt_check_box_init, /* instance_init */ + }; + + type = g_type_register_static(GNT_TYPE_BUTTON, + "GntCheckBox", + &info, 0); + } + + return type; +} + +GntWidget *gnt_check_box_new(const char *text) +{ + GntWidget *widget = g_object_new(GNT_TYPE_CHECK_BOX, NULL); + + GNT_BUTTON(widget)->priv->text = g_strdup(text); + gnt_widget_set_take_focus(widget, TRUE); + + return widget; +} + +void gnt_check_box_set_checked(GntCheckBox *box, gboolean set) +{ + if (set != box->checked) + { + box->checked = set; + g_signal_emit(box, signals[SIG_TOGGLED], 0); + } +} + +gboolean gnt_check_box_get_checked(GntCheckBox *box) +{ + return box->checked; +} + + + diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntcheckbox.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/console/libgnt/gntcheckbox.h Sun Jul 23 01:10:06 2006 +0000 @@ -0,0 +1,54 @@ +#ifndef GNT_CHECK_BOX_H +#define GNT_CHECK_BOX_H + +#include "gntbutton.h" +#include "gnt.h" +#include "gntcolors.h" +#include "gntkeys.h" + +#define GNT_TYPE_CHECK_BOX (gnt_check_box_get_gtype()) +#define GNT_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_CHECK_BOX, GntCheckBox)) +#define GNT_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) +#define GNT_IS_CHECK_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_CHECK_BOX)) +#define GNT_IS_CHECK_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_CHECK_BOX)) +#define GNT_CHECK_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_CHECK_BOX, GntCheckBoxClass)) + +#define GNT_CHECK_BOX_FLAGS(obj) (GNT_CHECK_BOX(obj)->priv.flags) +#define GNT_CHECK_BOX_SET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) |= flags) +#define GNT_CHECK_BOX_UNSET_FLAGS(obj, flags) (GNT_CHECK_BOX_FLAGS(obj) &= ~(flags)) + +typedef struct _GnCheckBox GntCheckBox; +typedef struct _GnCheckBoxPriv GntCheckBoxPriv; +typedef struct _GnCheckBoxClass GntCheckBoxClass; + +struct _GnCheckBox +{ + GntButton parent; + gboolean checked; +}; + +struct _GnCheckBoxClass +{ + GntButtonClass parent; + + void (*toggled)(void); + + void (*gnt_reserved1)(void); + void (*gnt_reserved2)(void); + void (*gnt_reserved3)(void); + void (*gnt_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType gnt_check_box_get_gtype(void); + +GntWidget *gnt_check_box_new(const char *text); + +void gnt_check_box_set_checked(GntCheckBox *box, gboolean set); + +gboolean gnt_check_box_get_checked(GntCheckBox *box); + +G_END_DECLS + +#endif /* GNT_CHECK_BOX_H */ diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntcombobox.c --- a/console/libgnt/gntcombobox.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntcombobox.c Sun Jul 23 01:10:06 2006 +0000 @@ -20,10 +20,14 @@ { if (box->selected != key) { + /* XXX: make sure the key actually does exist */ gpointer old = box->selected; box->selected = key; g_signal_emit(box, signals[SIG_SELECTION_CHANGED], 0, old, key); - gnt_widget_draw(GNT_WIDGET(box)); + if (GNT_WIDGET(box)->window) + gnt_widget_draw(GNT_WIDGET(box)); + if (box->dropdown) + gnt_tree_set_selected(GNT_TREE(box->dropdown), key); } } @@ -246,3 +250,8 @@ return box->selected; } +void gnt_combo_box_set_selected(GntComboBox *box, gpointer key) +{ + set_selection(box, key); +} + diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntcombobox.h --- a/console/libgnt/gntcombobox.h Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntcombobox.h Sun Jul 23 01:10:06 2006 +0000 @@ -50,6 +50,8 @@ gpointer gnt_combo_box_get_selected_data(GntComboBox *box); +void gnt_combo_box_set_selected(GntComboBox *box, gpointer key); + G_END_DECLS #endif /* GNT_COMBO_BOX_H */ diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntentry.c --- a/console/libgnt/gntentry.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntentry.c Sun Jul 23 01:10:06 2006 +0000 @@ -21,7 +21,14 @@ wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_TEXT_NORMAL)); else wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D)); - mvwprintw(widget->window, 0, 0, entry->scroll); + + if (entry->masked) + { + mvwhline(widget->window, 0, 0, gnt_ascii_only() ? '*' : ACS_BULLET, + entry->end - entry->scroll); + } + else + mvwprintw(widget->window, 0, 0, entry->scroll); stop = entry->end - entry->scroll; if (stop < widget->priv.width) @@ -283,4 +290,8 @@ entry_redraw(GNT_WIDGET(entry)); } +void gnt_entry_set_masked(GntEntry *entry, gboolean set) +{ + entry->masked = set; +} diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntentry.h --- a/console/libgnt/gntentry.h Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntentry.h Sun Jul 23 01:10:06 2006 +0000 @@ -49,6 +49,7 @@ size_t buffer; /* Size of the buffer */ int max; /* 0 means infinite */ + gboolean masked; }; struct _GnEntryClass @@ -78,6 +79,8 @@ void gnt_entry_clear(GntEntry *entry); +void gnt_entry_set_masked(GntEntry *entry, gboolean set); + G_END_DECLS #endif /* GNT_ENTRY_H */ diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gnttree.c --- a/console/libgnt/gnttree.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gnttree.c Sun Jul 23 01:10:06 2006 +0000 @@ -278,7 +278,11 @@ x += tree->columns[i].width; } if (pos) + { tree_mark_columns(tree, pos, 0, ACS_TTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); + tree_mark_columns(tree, pos, widget->priv.height - pos, + ACS_BTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); + } tree_mark_columns(tree, pos, pos + 1, ACS_PLUS | COLOR_PAIR(GNT_COLOR_NORMAL)); tree_mark_columns(tree, pos, pos, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL)); start = 2; @@ -691,10 +695,28 @@ char *gnt_tree_get_selection_text(GntTree *tree) { if (tree->current) - update_row_text(tree, tree->current); + return update_row_text(tree, tree->current); return NULL; } +GList *gnt_tree_get_selection_text_list(GntTree *tree) +{ + GList *list = NULL, *iter; + int i; + + if (!tree->current) + return NULL; + + for (i = 0, iter = tree->current->columns; i < tree->ncol && iter; + i++, iter = iter->next) + { + GntTreeCol *col = iter->data; + list = g_list_append(list, g_strdup(col->text)); + } + + return list; +} + /* XXX: Should this also remove all the children of the row being removed? */ void gnt_tree_remove(GntTree *tree, gpointer key) { @@ -859,24 +881,41 @@ return widget; } -GntTreeRow *gnt_tree_create_row(GntTree *tree, ...) +GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list) { - GntTreeRow *row = g_new0(GntTreeRow, 1); + GList *iter; int i; - va_list args; + GntTreeRow *row = g_new0(GntTreeRow, 1); - va_start(args, tree); - - for (i = 0; i < tree->ncol; i++) + for (i = 0, iter = list; i < tree->ncol && iter; iter = iter->next, i++) { GntTreeCol *col = g_new0(GntTreeCol, 1); col->span = 1; - col->text = g_strdup(va_arg(args, const char *)); + col->text = g_strdup(iter->data); row->columns = g_list_append(row->columns, col); } + + return row; +} + +GntTreeRow *gnt_tree_create_row(GntTree *tree, ...) +{ + int i; + va_list args; + GList *list = NULL; + GntTreeRow *row; + + va_start(args, tree); + for (i = 0; i < tree->ncol; i++) + { + list = g_list_append(list, va_arg(args, const char *)); + } va_end(args); + row = gnt_tree_create_row_from_list(tree, list); + g_list_free(list); + return row; } diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gnttree.h --- a/console/libgnt/gnttree.h Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gnttree.h Sun Jul 23 01:10:06 2006 +0000 @@ -80,6 +80,8 @@ char *gnt_tree_get_selection_text(GntTree *tree); +GList *gnt_tree_get_selection_text_list(GntTree *tree); + void gnt_tree_remove(GntTree *tree, gpointer key); /* Returns the visible line number of the selected row */ @@ -99,6 +101,8 @@ GntTreeRow *gnt_tree_create_row(GntTree *tree, ...); +GntTreeRow *gnt_tree_create_row_from_list(GntTree *tree, GList *list); + void gnt_tree_set_col_width(GntTree *tree, int col, int width); void gnt_tree_set_column_titles(GntTree *tree, ...); diff -r ea00953490a8 -r a71678d2da16 console/libgnt/gntwidget.c --- a/console/libgnt/gntwidget.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/gntwidget.c Sun Jul 23 01:10:06 2006 +0000 @@ -489,6 +489,8 @@ void gnt_widget_queue_update(GntWidget *widget) { + if (widget->window == NULL) + return; while (widget->parent) widget = widget->parent; diff -r ea00953490a8 -r a71678d2da16 console/libgnt/test/combo.c --- a/console/libgnt/test/combo.c Sat Jul 22 18:11:34 2006 +0000 +++ b/console/libgnt/test/combo.c Sun Jul 23 01:10:06 2006 +0000 @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,8 @@ gnt_box_add_widget(GNT_BOX(box), hbox); + gnt_box_add_widget(GNT_BOX(box), gnt_check_box_new("check box")); + gnt_widget_show(box); #ifdef STANDALONE