comparison src/gtkblist.c @ 10475:94fd0bf8c4b1

[gaim-migrate @ 11762] sf patch #1094341, from Richard Laager implements sf rfe #1090971 "tracks when a buddy was last seen and displays this value in the tooltip for offline and "signing on" buddies." The changes for this feature were pretty small and self-contained, and it's a neat feature. Then I started changing other things. I changed the way tooltips are created to use GStrings. I think it's easier to make changes without screwing stuff up, and the code is hopefully a bit easier to read through. I also changed how Add a Chat and Join a Chat work slightly. Now PRPLs can specify if a field is required or not, and the dialogs will not allow the user to click on "ok" if the field is not filled in. For example, when joining an oscar chat, the room name MUST be specified. This change and I think something else minor should fix the problem with adding chats to the buddy list that didn't have names. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Wed, 05 Jan 2005 05:52:10 +0000
parents 911530134bf8
children d02e70b5d197
comparison
equal deleted inserted replaced
10474:ae1fa1218e5c 10475:94fd0bf8c4b1
653 gtk_widget_destroy(GTK_WIDGET(dialog)); 653 gtk_widget_destroy(GTK_WIDGET(dialog));
654 g_list_free(info->entries); 654 g_list_free(info->entries);
655 g_free(info); 655 g_free(info);
656 } 656 }
657 657
658 /*
659 * Check the values of all the text entry boxes. If any required input
660 * strings are empty then don't allow the user to click on "OK."
661 */
662 static void
663 joinchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data)
664 {
665 GaimGtkJoinChatData *data;
666 GList *tmp;
667 const char *text;
668 gboolean required;
669 gboolean sensitive = TRUE;
670
671 data = user_data;
672
673 for (tmp = data->entries; tmp != NULL; tmp = tmp->next)
674 {
675 if (!g_object_get_data(tmp->data, "is_spin"))
676 {
677 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required"));
678 text = gtk_entry_get_text(tmp->data);
679 if (required && (*text == '\0'))
680 sensitive = FALSE;
681 }
682 }
683
684 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive);
685 }
686
658 static void 687 static void
659 rebuild_joinchat_entries(GaimGtkJoinChatData *data) 688 rebuild_joinchat_entries(GaimGtkJoinChatData *data)
660 { 689 {
661 GaimConnection *gc; 690 GaimConnection *gc;
662 GList *list = NULL, *tmp = NULL; 691 GList *list = NULL, *tmp = NULL;
687 716
688 for (tmp = list; tmp; tmp = tmp->next) 717 for (tmp = list; tmp; tmp = tmp->next)
689 { 718 {
690 GtkWidget *label; 719 GtkWidget *label;
691 GtkWidget *rowbox; 720 GtkWidget *rowbox;
721 GtkWidget *input;
692 722
693 pce = tmp->data; 723 pce = tmp->data;
694 724
695 rowbox = gtk_hbox_new(FALSE, 12); 725 rowbox = gtk_hbox_new(FALSE, 12);
696 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); 726 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0);
701 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); 731 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
702 732
703 if (pce->is_int) 733 if (pce->is_int)
704 { 734 {
705 GtkObject *adjust; 735 GtkObject *adjust;
706 GtkWidget *spin;
707 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, 736 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
708 1, 10, 10); 737 1, 10, 10);
709 spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); 738 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
710 g_object_set_data(G_OBJECT(spin), "is_spin", 739 gtk_widget_set_size_request(input, 50, -1);
711 GINT_TO_POINTER(TRUE)); 740 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0);
712 g_object_set_data(G_OBJECT(spin), "identifier", pce->identifier);
713 data->entries = g_list_append(data->entries, spin);
714 gtk_widget_set_size_request(spin, 50, -1);
715 gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0);
716 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(spin));
717 gaim_set_accessible_label (spin, label);
718 } 741 }
719 else 742 else
720 { 743 {
721 GtkWidget *entry = gtk_entry_new();
722 char *value; 744 char *value;
723 745 input = gtk_entry_new();
724 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); 746 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE);
725 g_object_set_data(G_OBJECT(entry), "identifier", pce->identifier);
726 data->entries = g_list_append(data->entries, entry);
727
728 value = g_hash_table_lookup(defaults, pce->identifier); 747 value = g_hash_table_lookup(defaults, pce->identifier);
729 if (value != NULL) 748 if (value != NULL)
730 gtk_entry_set_text(GTK_ENTRY(entry), value); 749 gtk_entry_set_text(GTK_ENTRY(input), value);
731
732 if (focus)
733 {
734 gtk_widget_grab_focus(entry);
735 focus = FALSE;
736 }
737
738 if (pce->secret) 750 if (pce->secret)
739 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); 751 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE);
740 752 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0);
741 gtk_box_pack_end(GTK_BOX(rowbox), entry, TRUE, TRUE, 0); 753 g_signal_connect(G_OBJECT(input), "changed",
742 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(entry)); 754 G_CALLBACK(joinchat_set_sensitive_if_input_cb), data);
743 gaim_set_accessible_label (entry, label); 755 }
744 } 756
757 /* Do the following for any type of input widget */
758 if (focus)
759 {
760 gtk_widget_grab_focus(input);
761 focus = FALSE;
762 }
763 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input);
764 gaim_set_accessible_label(input, label);
765 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier);
766 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int));
767 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required));
768 data->entries = g_list_append(data->entries, input);
745 769
746 g_free(pce); 770 g_free(pce);
747 } 771 }
748 772
749 g_list_free(list); 773 g_list_free(list);
774 g_hash_table_destroy(defaults);
775
776 /* Set whether the "OK" button should be clickable initially */
777 joinchat_set_sensitive_if_input_cb(NULL, data);
750 778
751 gtk_widget_show_all(data->entries_box); 779 gtk_widget_show_all(data->entries_box);
752 } 780 }
753 781
754 static void 782 static void
755 joinchat_select_account_cb(GObject *w, GaimAccount *account, 783 joinchat_select_account_cb(GObject *w, GaimAccount *account,
756 GaimGtkJoinChatData *data) 784 GaimGtkJoinChatData *data)
757 { 785 {
758 if (strcmp(gaim_account_get_protocol_id(data->account), 786 if (strcmp(gaim_account_get_protocol_id(data->account),
759 gaim_account_get_protocol_id(account)) == 0) 787 gaim_account_get_protocol_id(account)) == 0)
760 { 788 {
761 data->account = account; 789 data->account = account;
762 } 790 }
763 else 791 else
764 { 792 {
2463 _("Cancel"), NULL, g); 2491 _("Cancel"), NULL, g);
2464 } 2492 }
2465 2493
2466 static char *gaim_get_tooltip_text(GaimBlistNode *node) 2494 static char *gaim_get_tooltip_text(GaimBlistNode *node)
2467 { 2495 {
2496 GString *str = g_string_new("");
2468 GaimPlugin *prpl; 2497 GaimPlugin *prpl;
2469 GaimPluginProtocolInfo *prpl_info = NULL; 2498 GaimPluginProtocolInfo *prpl_info = NULL;
2470 char *text = NULL; 2499 char *tmp;
2471 2500
2472 if(GAIM_BLIST_NODE_IS_CHAT(node)) { 2501 if (GAIM_BLIST_NODE_IS_CHAT(node))
2473 GaimChat *chat = (GaimChat *)node; 2502 {
2474 char *name = NULL; 2503 GaimChat *chat;
2504 GList *cur;
2475 struct proto_chat_entry *pce; 2505 struct proto_chat_entry *pce;
2476 GList *parts = NULL, *tmp = NULL; 2506 char *name, *value;
2477 GString *parts_text = g_string_new(""); 2507
2478 2508 chat = (GaimChat *)node;
2479 prpl = gaim_find_prpl(gaim_account_get_protocol_id(chat->account)); 2509 prpl = gaim_find_prpl(gaim_account_get_protocol_id(chat->account));
2480 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); 2510 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
2481 2511
2512 tmp = g_markup_escape_text(gaim_chat_get_name(chat), -1);
2513 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp);
2514 g_free(tmp);
2515
2516 if (g_list_length(gaim_connections_get_all()) > 1)
2517 {
2518 tmp = g_markup_escape_text(chat->account->username, -1);
2519 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp);
2520 g_free(tmp);
2521 }
2522
2482 if (prpl_info->chat_info != NULL) 2523 if (prpl_info->chat_info != NULL)
2483 parts = prpl_info->chat_info(chat->account->gc); 2524 cur = prpl_info->chat_info(chat->account->gc);
2484 2525 else
2485 name = g_markup_escape_text(gaim_chat_get_name(chat), -1); 2526 cur = NULL;
2486 2527
2487 if(g_list_length(gaim_connections_get_all()) > 1) { 2528 while (cur != NULL)
2488 char *account = g_markup_escape_text(chat->account->username, -1); 2529 {
2489 g_string_append_printf(parts_text, _("\n<b>Account:</b> %s"), 2530 pce = cur->data;
2490 account); 2531
2491 g_free(account); 2532 if (!pce->secret && (!pce->required &&
2492 } 2533 g_hash_table_lookup(chat->components, pce->identifier) == NULL))
2493 for(tmp = parts; tmp; tmp = tmp->next) { 2534 {
2494 char *label, *tmp2, *value; 2535 tmp = gaim_text_strip_mnemonic(pce->label);
2495 pce = tmp->data; 2536 name = g_markup_escape_text(tmp, -1);
2496 2537 g_free(tmp);
2497 if(!pce->secret) { 2538 value = g_markup_escape_text(g_hash_table_lookup(
2498 2539 chat->components, pce->identifier), -1);
2499 tmp2 = g_markup_escape_text(pce->label, -1); 2540 g_string_append_printf(str, "\n<b>%s</b> %s", name, value);
2500 label = gaim_text_strip_mnemonic(tmp2); 2541 g_free(name);
2501 g_free(tmp2);
2502
2503 value = g_markup_escape_text(g_hash_table_lookup(chat->components,
2504 pce->identifier), -1);
2505
2506 g_string_append_printf(parts_text, "\n<b>%s</b> %s", label, value);
2507 g_free(label);
2508 g_free(value); 2542 g_free(value);
2509 } 2543 }
2544
2510 g_free(pce); 2545 g_free(pce);
2511 } 2546 cur = g_list_remove(cur, pce);
2512 g_list_free(parts); 2547 }
2513 2548 }
2514 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>%s", 2549 else if (GAIM_BLIST_NODE_IS_CONTACT(node) || GAIM_BLIST_NODE_IS_BUDDY(node))
2515 name, parts_text->str); 2550 {
2516 g_string_free(parts_text, TRUE); 2551 GaimContact *c;
2517 g_free(name);
2518 } else if(GAIM_BLIST_NODE_IS_CONTACT(node) ||
2519 GAIM_BLIST_NODE_IS_BUDDY(node)) {
2520 GaimBuddy *b; 2552 GaimBuddy *b;
2521 GaimPresence *presence; 2553 GaimPresence *presence;
2554 char *tmp;
2522 gboolean idle; 2555 gboolean idle;
2523 time_t idle_secs; 2556 time_t idle_secs;
2557 int lastseen;
2524 unsigned int warning_level; 2558 unsigned int warning_level;
2525 char *statustext = NULL; 2559
2526 char *contactaliastext = NULL; 2560 if (GAIM_BLIST_NODE_IS_CONTACT(node))
2527 char *aliastext = NULL, *nicktext = NULL; 2561 {
2528 char *loggedin = NULL, *idletime = NULL; 2562 c = (GaimContact *)node;
2529 char *warning = NULL; 2563 b = gaim_contact_get_priority_buddy(c);
2530 char *accounttext = NULL; 2564 }
2531 2565 else
2532 if(GAIM_BLIST_NODE_IS_CONTACT(node)) { 2566 {
2533 GaimContact *contact = (GaimContact*)node;
2534 b = gaim_contact_get_priority_buddy(contact);
2535 if(contact->alias)
2536 contactaliastext = g_markup_escape_text(contact->alias, -1);
2537 } else {
2538 b = (GaimBuddy *)node; 2567 b = (GaimBuddy *)node;
2568 c = gaim_buddy_get_contact(b);
2539 } 2569 }
2540 2570
2541 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account)); 2571 prpl = gaim_find_prpl(gaim_account_get_protocol_id(b->account));
2542 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); 2572 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl);
2543 2573
2544 if (prpl_info && prpl_info->tooltip_text) { 2574 presence = gaim_buddy_get_presence(b);
2575
2576 /* Buddy Name */
2577 tmp = g_markup_escape_text(gaim_buddy_get_name(b), -1);
2578 g_string_append_printf(str, "<span size='larger' weight='bold'>%s</span>", tmp);
2579 g_free(tmp);
2580
2581 /* Account */
2582 if (g_list_length(gaim_connections_get_all()) > 1)
2583 {
2584 tmp = g_markup_escape_text(gaim_account_get_username(
2585 gaim_buddy_get_account(b)), -1);
2586 g_string_append_printf(str, _("\n<b>Account:</b> %s"), tmp);
2587 g_free(tmp);
2588 }
2589
2590 /* Contact Alias */
2591 if (GAIM_BLIST_NODE_IS_CONTACT(node) &&
2592 (gaim_contact_get_alias(c) != NULL))
2593 {
2594 tmp = g_markup_escape_text(gaim_contact_get_alias(c), -1);
2595 g_string_append_printf(str, _("\n<b>Contact Alias:</b> %s"), tmp);
2596 g_free(tmp);
2597 }
2598
2599 /* Alias */
2600 if ((b->alias != NULL) && (b->alias[0] != '\0'))
2601 {
2602 tmp = g_markup_escape_text(b->alias, -1);
2603 g_string_append_printf(str, _("\n<b>Alias:</b> %s"), tmp);
2604 g_free(tmp);
2605 }
2606
2607 /* Nickname/Server Alias */
2608 if (b->server_alias != NULL)
2609 {
2610 tmp = g_markup_escape_text(b->server_alias, -1);
2611 g_string_append_printf(str, _("\n<b>Nickname:</b> %s"), tmp);
2612 g_free(tmp);
2613 }
2614
2615 /* Logged In */
2616 if (b->signon > 0)
2617 {
2618 tmp = gaim_str_seconds_to_string(time(NULL) - b->signon);
2619 g_string_append_printf(str, _("\n<b>Logged In:</b> %s"), tmp);
2620 g_free(tmp);
2621 }
2622
2623 /* Idle */
2624 idle = gaim_presence_is_idle(presence);
2625 if (idle)
2626 {
2627 idle_secs = gaim_presence_get_idle_time(presence);
2628 if (idle_secs > 0)
2629 {
2630 tmp = gaim_str_seconds_to_string(time(NULL) - idle_secs);
2631 g_string_append_printf(str, _("\n<b>Idle:</b> %s"), tmp);
2632 g_free(tmp);
2633 }
2634 else
2635 g_string_append_printf(str, _("\n<b>Idle</b>"));
2636 }
2637
2638 /* Last Seen */
2639 if ((b->present == GAIM_BUDDY_SIGNING_ON) ||
2640 (b->present == GAIM_BUDDY_OFFLINE))
2641 {
2642 lastseen = gaim_blist_node_get_int(&b->node, "last_seen");
2643 if (lastseen > 0)
2644 {
2645 tmp = gaim_str_seconds_to_string(time(NULL) - lastseen);
2646 g_string_append_printf(str, _("\n<b>Last Seen:</b> %s ago"), tmp);
2647 g_free(tmp);
2648 }
2649 }
2650
2651 /* Warning */
2652 warning_level = gaim_presence_get_warning_level(presence);
2653 if (warning_level > 0)
2654 {
2655 tmp = g_strdup_printf(_("%d%%"), warning_level);
2656 g_string_append_printf(str, _("\n<b>Warned:</b> %s"), tmp);
2657 g_free(tmp);
2658 }
2659
2660 /* Offline? */
2661 if (!GAIM_BUDDY_IS_ONLINE(b)) {
2662 g_string_append_printf(str, _("\n<b>Status:</b> Offline"));
2663 }
2664 else if (prpl_info && prpl_info->tooltip_text)
2665 {
2666 /* Additional text from the PRPL */
2545 const char *end; 2667 const char *end;
2546 statustext = prpl_info->tooltip_text(b); 2668 tmp = prpl_info->tooltip_text(b);
2547 2669
2548 if(statustext && !g_utf8_validate(statustext, -1, &end)) { 2670 if (tmp && !g_utf8_validate(tmp, -1, &end))
2549 char *new = g_strndup(statustext, 2671 {
2550 g_utf8_pointer_to_offset(statustext, end)); 2672 char *new = g_strndup(tmp, g_utf8_pointer_to_offset(tmp, end));
2551 g_free(statustext); 2673 g_free(tmp);
2552 statustext = new; 2674 tmp = new;
2553 } 2675 }
2554 } 2676
2555 2677 g_string_append(str, tmp);
2556 presence = gaim_buddy_get_presence(b); 2678 }
2557 2679
2558 idle = gaim_presence_is_idle(presence); 2680 /* These are Easter Eggs. Patches to remove them will be rejected. */
2559 idle_secs = gaim_presence_get_idle_time(presence); 2681 if (!g_ascii_strcasecmp(b->name, "robflynn"))
2560 warning_level = gaim_presence_get_warning_level(presence); 2682 g_string_append(str, _("\n<b>Description:</b> Spooky"));
2561 2683 if (!g_ascii_strcasecmp(b->name, "seanegn"))
2562 if (!statustext && !GAIM_BUDDY_IS_ONLINE(b)) 2684 g_string_append(str, _("\n<b>Status:</b> Awesome"));
2563 statustext = g_strdup(_("\n<b>Status:</b> Offline")); 2685 if (!g_ascii_strcasecmp(b->name, "chipx86"))
2564 2686 g_string_append(str, _("\n<b>Status:</b> Rockin'"));
2565 if (b->signon > 0) 2687 }
2566 loggedin = gaim_str_seconds_to_string(time(NULL) - b->signon); 2688
2567
2568 if (idle && idle_secs > 0)
2569 idletime = gaim_str_seconds_to_string(time(NULL) - idle_secs);
2570
2571 if(b->alias && b->alias[0])
2572 aliastext = g_markup_escape_text(b->alias, -1);
2573
2574 if(b->server_alias)
2575 nicktext = g_markup_escape_text(b->server_alias, -1);
2576
2577 if (warning_level > 0)
2578 warning = g_strdup_printf(_("%d%%"), warning_level);
2579
2580 if(g_list_length(gaim_connections_get_all()) > 1)
2581 accounttext = g_markup_escape_text(b->account->username, -1);
2582
2583 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>"
2584 "%s %s" /* Account */
2585 "%s %s" /* Contact Alias */
2586 "%s %s" /* Alias */
2587 "%s %s" /* Nickname */
2588 "%s %s" /* Logged In */
2589 "%s %s" /* Idle */
2590 "%s %s" /* Warning */
2591 "%s" /* Status */
2592 "%s",
2593 b->name,
2594 accounttext ? _("\n<b>Account:</b>") : "", accounttext ? accounttext : "",
2595 contactaliastext ? _("\n<b>Contact Alias:</b>") : "", contactaliastext ? contactaliastext : "",
2596 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "",
2597 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "",
2598 loggedin ? _("\n<b>Logged In:</b>") : "", loggedin ? loggedin : "",
2599 idle ? (idle_secs > 0 ? _("\n<b>Idle:</b>") : _("\n<b>Idle</b>")) : "",
2600 idletime ? idletime : "",
2601 warning_level ? _("\n<b>Warned:</b>") : "", warning_level ? warning : "",
2602 statustext ? statustext : "",
2603 !g_ascii_strcasecmp(b->name, "robflynn") ? _("\n<b>Description:</b> Spooky") :
2604 !g_ascii_strcasecmp(b->name, "seanegn") ? _("\n<b>Status</b>: Awesome") :
2605 !g_ascii_strcasecmp(b->name, "chipx86") ? _("\n<b>Status</b>: Rockin'") : "");
2606
2607 if(warning)
2608 g_free(warning);
2609 if(loggedin)
2610 g_free(loggedin);
2611 if(idletime)
2612 g_free(idletime);
2613 if(statustext)
2614 g_free(statustext);
2615 if(nicktext)
2616 g_free(nicktext);
2617 if(aliastext)
2618 g_free(aliastext);
2619 if(accounttext)
2620 g_free(accounttext);
2621 }
2622 gaim_signal_emit(gaim_gtk_blist_get_handle(), 2689 gaim_signal_emit(gaim_gtk_blist_get_handle(),
2623 "drawing-tooltip", node, &text); 2690 "drawing-tooltip", node, &str->str);
2624 return text; 2691
2692 return g_string_free(str, FALSE);
2625 } 2693 }
2626 2694
2627 struct _emblem_data { 2695 struct _emblem_data {
2628 const char *filename; 2696 const char *filename;
2629 int x; 2697 int x;
4158 GaimChat *chat; 4226 GaimChat *chat;
4159 GaimGroup *group; 4227 GaimGroup *group;
4160 const char *group_name; 4228 const char *group_name;
4161 char *chat_name = NULL; 4229 char *chat_name = NULL;
4162 GaimConversation *conv = NULL; 4230 GaimConversation *conv = NULL;
4231 const char *value;
4163 4232
4164 components = g_hash_table_new_full(g_str_hash, g_str_equal, 4233 components = g_hash_table_new_full(g_str_hash, g_str_equal,
4165 g_free, g_free); 4234 g_free, g_free);
4166 4235
4167 for (tmp = data->entries; tmp; tmp = tmp->next) 4236 for (tmp = data->entries; tmp; tmp = tmp->next)
4173 g_strdup_printf("%d", 4242 g_strdup_printf("%d",
4174 gtk_spin_button_get_value_as_int(tmp->data))); 4243 gtk_spin_button_get_value_as_int(tmp->data)));
4175 } 4244 }
4176 else 4245 else
4177 { 4246 {
4178 g_hash_table_replace(components, 4247 value = gtk_entry_get_text(tmp->data);
4179 g_strdup(g_object_get_data(tmp->data, "identifier")), 4248 if (*value != '\0')
4180 g_strdup(gtk_entry_get_text(tmp->data))); 4249 g_hash_table_replace(components,
4250 g_strdup(g_object_get_data(tmp->data, "identifier")),
4251 g_strdup(value));
4181 } 4252 }
4182 } 4253 }
4183 4254
4184 chat = gaim_chat_new(data->account, 4255 chat = gaim_chat_new(data->account,
4185 gtk_entry_get_text(GTK_ENTRY(data->alias_entry)), 4256 gtk_entry_get_text(GTK_ENTRY(data->alias_entry)),
4232 g_list_free(data->entries); 4303 g_list_free(data->entries);
4233 g_free(data); 4304 g_free(data);
4234 } 4305 }
4235 } 4306 }
4236 4307
4308 /*
4309 * Check the values of all the text entry boxes. If any required input
4310 * strings are empty then don't allow the user to click on "OK."
4311 */
4312 static void
4313 addchat_set_sensitive_if_input_cb(GtkWidget *entry, gpointer user_data)
4314 {
4315 GaimGtkAddChatData *data;
4316 GList *tmp;
4317 const char *text;
4318 gboolean required;
4319 gboolean sensitive = TRUE;
4320
4321 data = user_data;
4322
4323 for (tmp = data->entries; tmp != NULL; tmp = tmp->next)
4324 {
4325 if (!g_object_get_data(tmp->data, "is_spin"))
4326 {
4327 required = GPOINTER_TO_INT(g_object_get_data(tmp->data, "required"));
4328 text = gtk_entry_get_text(tmp->data);
4329 if (required && (*text == '\0'))
4330 sensitive = FALSE;
4331 }
4332 }
4333
4334 gtk_dialog_set_response_sensitive(GTK_DIALOG(data->window), GTK_RESPONSE_OK, sensitive);
4335 }
4336
4237 static void 4337 static void
4238 rebuild_addchat_entries(GaimGtkAddChatData *data) 4338 rebuild_addchat_entries(GaimGtkAddChatData *data)
4239 { 4339 {
4240 GaimConnection *gc; 4340 GaimConnection *gc;
4241 GList *list = NULL, *tmp = NULL; 4341 GList *list = NULL, *tmp = NULL;
4248 gc = gaim_account_get_connection(data->account); 4348 gc = gaim_account_get_connection(data->account);
4249 4349
4250 while (GTK_BOX(data->entries_box)->children) 4350 while (GTK_BOX(data->entries_box)->children)
4251 { 4351 {
4252 gtk_container_remove(GTK_CONTAINER(data->entries_box), 4352 gtk_container_remove(GTK_CONTAINER(data->entries_box),
4253 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget); 4353 ((GtkBoxChild *)GTK_BOX(data->entries_box)->children->data)->widget);
4254 } 4354 }
4255 4355
4256 if (data->entries != NULL) 4356 if (data->entries != NULL)
4257 g_list_free(data->entries); 4357 g_list_free(data->entries);
4258 4358
4260 4360
4261 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL) 4361 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info != NULL)
4262 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc); 4362 list = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info(gc);
4263 4363
4264 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) 4364 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL)
4265 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, 4365 defaults = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, data->default_chat_name);
4266 data->default_chat_name);
4267 4366
4268 for (tmp = list; tmp; tmp = tmp->next) 4367 for (tmp = list; tmp; tmp = tmp->next)
4269 { 4368 {
4270 GtkWidget *label; 4369 GtkWidget *label;
4271 GtkWidget *rowbox; 4370 GtkWidget *rowbox;
4371 GtkWidget *input;
4272 4372
4273 pce = tmp->data; 4373 pce = tmp->data;
4274 4374
4275 rowbox = gtk_hbox_new(FALSE, 5); 4375 rowbox = gtk_hbox_new(FALSE, 5);
4276 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0); 4376 gtk_box_pack_start(GTK_BOX(data->entries_box), rowbox, FALSE, FALSE, 0);
4281 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); 4381 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
4282 4382
4283 if (pce->is_int) 4383 if (pce->is_int)
4284 { 4384 {
4285 GtkObject *adjust; 4385 GtkObject *adjust;
4286 GtkWidget *spin;
4287 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max, 4386 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
4288 1, 10, 10); 4387 1, 10, 10);
4289 spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0); 4388 input = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
4290 g_object_set_data(G_OBJECT(spin), "is_spin", GINT_TO_POINTER(TRUE)); 4389 gtk_widget_set_size_request(input, 50, -1);
4291 g_object_set_data(G_OBJECT(spin), "identifier", pce->identifier); 4390 gtk_box_pack_end(GTK_BOX(rowbox), input, FALSE, FALSE, 0);
4292 data->entries = g_list_append(data->entries, spin);
4293 gtk_widget_set_size_request(spin, 50, -1);
4294 gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0);
4295 gtk_label_set_mnemonic_widget(GTK_LABEL(label), spin);
4296 gaim_set_accessible_label (spin, label);
4297 } 4391 }
4298 else 4392 else
4299 { 4393 {
4300 GtkWidget *entry = gtk_entry_new();
4301 char *value; 4394 char *value;
4302 4395 input = gtk_entry_new();
4303 g_object_set_data(G_OBJECT(entry), "identifier", pce->identifier); 4396 gtk_entry_set_activates_default(GTK_ENTRY(input), TRUE);
4304 data->entries = g_list_append(data->entries, entry);
4305
4306 value = g_hash_table_lookup(defaults, pce->identifier); 4397 value = g_hash_table_lookup(defaults, pce->identifier);
4307 if (value != NULL) 4398 if (value != NULL)
4308 gtk_entry_set_text(GTK_ENTRY(entry), value); 4399 gtk_entry_set_text(GTK_ENTRY(input), value);
4309
4310 if (focus)
4311 {
4312 gtk_widget_grab_focus(entry);
4313 focus = FALSE;
4314 }
4315
4316 if (pce->secret) 4400 if (pce->secret)
4317 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); 4401 gtk_entry_set_visibility(GTK_ENTRY(input), FALSE);
4318 4402 gtk_box_pack_end(GTK_BOX(rowbox), input, TRUE, TRUE, 0);
4319 gtk_box_pack_end(GTK_BOX(rowbox), entry, TRUE, TRUE, 0); 4403 g_signal_connect(G_OBJECT(input), "changed",
4320 4404 G_CALLBACK(addchat_set_sensitive_if_input_cb), data);
4321 g_signal_connect(G_OBJECT(entry), "activate", 4405 }
4322 G_CALLBACK(add_chat_cb), data); 4406
4323 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); 4407 /* Do the following for any type of input widget */
4324 gaim_set_accessible_label (entry, label); 4408 if (focus)
4325 } 4409 {
4410 gtk_widget_grab_focus(input);
4411 focus = FALSE;
4412 }
4413 gtk_label_set_mnemonic_widget(GTK_LABEL(label), input);
4414 gaim_set_accessible_label(input, label);
4415 g_object_set_data(G_OBJECT(input), "identifier", pce->identifier);
4416 g_object_set_data(G_OBJECT(input), "is_spin", GINT_TO_POINTER(pce->is_int));
4417 g_object_set_data(G_OBJECT(input), "required", GINT_TO_POINTER(pce->required));
4418 data->entries = g_list_append(data->entries, input);
4326 4419
4327 g_free(pce); 4420 g_free(pce);
4328 } 4421 }
4329 4422
4330 g_list_free(list); 4423 g_list_free(list);
4331 g_hash_table_destroy(defaults); 4424 g_hash_table_destroy(defaults);
4332 4425
4426 /* Set whether the "OK" button should be clickable initially */
4427 addchat_set_sensitive_if_input_cb(NULL, data);
4428
4333 gtk_widget_show_all(data->entries_box); 4429 gtk_widget_show_all(data->entries_box);
4334 } 4430 }
4335 4431
4336 static void 4432 static void
4337 add_chat_select_account_cb(GObject *w, GaimAccount *account, 4433 addchat_select_account_cb(GObject *w, GaimAccount *account,
4338 GaimGtkAddChatData *data) 4434 GaimGtkAddChatData *data)
4339 { 4435 {
4340 if (strcmp(gaim_account_get_protocol_id(data->account), 4436 if (strcmp(gaim_account_get_protocol_id(data->account),
4341 gaim_account_get_protocol_id(account)) == 0) 4437 gaim_account_get_protocol_id(account)) == 0)
4342 { 4438 {
4438 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 4534 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4439 gtk_size_group_add_widget(data->sg, label); 4535 gtk_size_group_add_widget(data->sg, label);
4440 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0); 4536 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
4441 4537
4442 data->account_menu = gaim_gtk_account_option_menu_new(account, FALSE, 4538 data->account_menu = gaim_gtk_account_option_menu_new(account, FALSE,
4443 G_CALLBACK(add_chat_select_account_cb), 4539 G_CALLBACK(addchat_select_account_cb),
4444 chat_account_filter_func, data); 4540 chat_account_filter_func, data);
4445 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0); 4541 gtk_box_pack_start(GTK_BOX(rowbox), data->account_menu, TRUE, TRUE, 0);
4446 gaim_set_accessible_label (data->account_menu, label); 4542 gaim_set_accessible_label (data->account_menu, label);
4447 4543
4448 data->entries_box = gtk_vbox_new(FALSE, 5); 4544 data->entries_box = gtk_vbox_new(FALSE, 5);