comparison src/gtkrequest.c @ 8294:d5e59ea083be

[gaim-migrate @ 9018] Added auto-completion for screen names to the New Instant Message and Get User Info dialogs. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Thu, 19 Feb 2004 09:47:44 +0000
parents e39ea2b4f6cd
children 462ead6fc1a0
comparison
equal deleted inserted replaced
8293:a1b7c7f3d9a7 8294:d5e59ea083be
29 #include "gtkrequest.h" 29 #include "gtkrequest.h"
30 #include "gtkutils.h" 30 #include "gtkutils.h"
31 #include "stock.h" 31 #include "stock.h"
32 #include "ui.h" 32 #include "ui.h"
33 33
34 #include <gdk/gdkkeysyms.h>
35
36 #if GTK_CHECK_VERSION(2,3,0)
37 # define NEW_STYLE_COMPLETION
38 #endif
39
34 typedef struct 40 typedef struct
35 { 41 {
36 GaimRequestType type; 42 GaimRequestType type;
37 43
38 void *user_data; 44 void *user_data;
60 } multifield; 66 } multifield;
61 67
62 } u; 68 } u;
63 69
64 } GaimGtkRequestData; 70 } GaimGtkRequestData;
71
72 #ifndef NEW_STYLE_COMPLETION
73 typedef struct
74 {
75 GCompletion *completion;
76
77 gboolean completion_started;
78
79 } GaimGtkCompletionData;
80 #endif
65 81
66 static void 82 static void
67 input_response_cb(GtkDialog *dialog, gint id, GaimGtkRequestData *data) 83 input_response_cb(GtkDialog *dialog, gint id, GaimGtkRequestData *data)
68 { 84 {
69 const char *value; 85 const char *value;
458 474
459 gtk_widget_set_sensitive(req_data->ok_button, 475 gtk_widget_set_sensitive(req_data->ok_button,
460 gaim_request_fields_all_required_filled(field->group->fields_list)); 476 gaim_request_fields_all_required_filled(field->group->fields_list));
461 } 477 }
462 478
479 GList *
480 get_online_screennames(void)
481 {
482 GList *screennames = NULL;
483 GaimBlistNode *gnode, *cnode, *bnode;
484
485 for (gnode = gaim_get_blist()->root; gnode != NULL; gnode = gnode->next)
486 {
487 if (!GAIM_BLIST_NODE_IS_GROUP(gnode))
488 continue;
489
490 for (cnode = gnode->child; cnode != NULL; cnode = cnode->next)
491 {
492 if (!GAIM_BLIST_NODE_IS_CONTACT(cnode))
493 continue;
494
495 for (bnode = cnode->child; bnode != NULL; bnode = bnode->next)
496 {
497 GaimBuddy *buddy = (GaimBuddy *)bnode;
498
499 if (!gaim_account_is_connected(buddy->account))
500 continue;
501
502 screennames = g_list_append(screennames, g_strdup(buddy->name));
503 }
504 }
505 }
506
507 return screennames;
508 }
509
510 #ifndef NEW_STYLE_COMPLETION
511 static gboolean
512 completion_entry_event(GtkEditable *entry, GdkEventKey *event,
513 GaimGtkCompletionData *data)
514 {
515 int pos, end_pos;
516
517 if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Tab)
518 {
519 gtk_editable_get_selection_bounds(entry, &pos, &end_pos);
520
521 if (data->completion_started &&
522 pos != end_pos && pos > 1 &&
523 end_pos == strlen(gtk_entry_get_text(GTK_ENTRY(entry))))
524 {
525 gtk_editable_select_region(entry, 0, 0);
526 gtk_editable_set_position(entry, -1);
527
528 return TRUE;
529 }
530 }
531 else if (event->type == GDK_KEY_PRESS && event->length > 0)
532 {
533 char *prefix, *nprefix;
534
535 gtk_editable_get_selection_bounds(entry, &pos, &end_pos);
536
537 if (data->completion_started &&
538 pos != end_pos && pos > 1 &&
539 end_pos == strlen(gtk_entry_get_text(GTK_ENTRY(entry))))
540 {
541 char *temp;
542
543 temp = gtk_editable_get_chars(entry, 0, pos);
544 prefix = g_strconcat(temp, event->string, NULL);
545 g_free(temp);
546 }
547 else if (pos == end_pos && pos > 1 &&
548 end_pos == strlen(gtk_entry_get_text(GTK_ENTRY(entry))))
549 {
550 prefix = g_strconcat(gtk_entry_get_text(GTK_ENTRY(entry)),
551 event->string, NULL);
552 }
553 else
554 return FALSE;
555
556 pos = strlen(prefix);
557 nprefix = NULL;
558
559 g_completion_complete(data->completion, prefix, &nprefix);
560
561 if (nprefix != NULL)
562 {
563 gtk_entry_set_text(GTK_ENTRY(entry), nprefix);
564 gtk_editable_set_position(entry, pos);
565 gtk_editable_select_region(entry, pos, -1);
566
567 data->completion_started = TRUE;
568
569 g_free(nprefix);
570 g_free(prefix);
571
572 return TRUE;
573 }
574
575 g_free(prefix);
576 }
577
578 return FALSE;
579 }
580
581 static void
582 destroy_completion_data(GtkWidget *w, GaimGtkCompletionData *data)
583 {
584 g_list_foreach(data->completion->items, (GFunc)g_free, NULL);
585 g_completion_free(data->completion);
586
587 g_free(data);
588 }
589 #endif /* !NEW_STYLE_COMPLETION */
590
591 static void
592 setup_screenname_autocomplete(GtkWidget *entry, GaimRequestField *field)
593 {
594 #ifdef NEW_STYLE_COMPLETION
595 GtkListStore *store;
596 GtkTreeIter iter;
597 GtkEntryCompletion *completion;
598 GList *screennames, *l;
599
600 store = gtk_list_store_new(1, G_TYPE_STRING);
601
602 screennames = get_online_screennames();
603
604 for (l = screennames; l != NULL; l = l->next)
605 {
606 gtk_list_store_append(store, &iter);
607 gtk_list_store_set(store, &iter, 0, l->data, -1);
608 }
609
610 g_list_foreach(screennames, (GFunc)g_free, NULL);
611 g_list_free(screennames);
612
613 completion = gtk_entry_completion_new();
614 gtk_entry_set_completion(GTK_ENTRY(entry), completion);
615 g_object_unref(completion);
616
617 gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store));
618 g_object_unref(store);
619
620 gtk_entry_completion_set_text_column(completion, 0);
621
622 #else /* !NEW_STYLE_COMPLETION */
623 GaimGtkCompletionData *data;
624 GList *screennames;
625
626 data = g_new0(GaimGtkCompletionData, 1);
627
628 data->completion = g_completion_new(NULL);
629
630 g_completion_set_compare(data->completion, g_ascii_strncasecmp);
631
632 screennames = get_online_screennames();
633
634 g_completion_add_items(data->completion, screennames);
635
636 g_list_free(screennames);
637
638 g_signal_connect(G_OBJECT(entry), "event",
639 G_CALLBACK(completion_entry_event), data);
640 g_signal_connect(G_OBJECT(entry), "destroy",
641 G_CALLBACK(destroy_completion_data), data);
642
643 #endif /* !NEW_STYLE_COMPLETION */
644 }
645
463 static void 646 static void
464 setup_entry_field(GtkWidget *entry, GaimRequestField *field) 647 setup_entry_field(GtkWidget *entry, GaimRequestField *field)
465 { 648 {
649 const char *type_hint;
650
466 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); 651 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
467 652
468 if (gaim_request_field_is_required(field)) 653 if (gaim_request_field_is_required(field))
469 { 654 {
470 g_signal_connect(G_OBJECT(entry), "changed", 655 g_signal_connect(G_OBJECT(entry), "changed",
471 G_CALLBACK(req_entry_field_changed_cb), field); 656 G_CALLBACK(req_entry_field_changed_cb), field);
657 }
658
659 if ((type_hint = gaim_request_field_get_type_hint(field)) != NULL)
660 {
661 if (!strcmp(type_hint, "screenname"))
662 {
663 setup_screenname_autocomplete(entry, field);
664 }
472 } 665 }
473 } 666 }
474 667
475 static GtkWidget * 668 static GtkWidget *
476 create_string_field(GaimRequestField *field) 669 create_string_field(GaimRequestField *field)