comparison src/dialogs.c @ 2956:b68c648618a3

[gaim-migrate @ 2969] I Love Rock & Roll.... committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Sun, 17 Feb 2002 18:08:12 +0000
parents 538c58b43eff
children a67cae459b01
comparison
equal deleted inserted replaced
2955:8b03506b8c1e 2956:b68c648618a3
4207 return 1; 4207 return 1;
4208 } 4208 }
4209 4209
4210 return 0; 4210 return 0;
4211 } 4211 }
4212
4213 /*------------------------------------------------------------------------*/
4214 /* The dialog for setting V-Card info */
4215 /*------------------------------------------------------------------------*/
4216 /*
4217 * There are actually two "chunks" of code following: generic "multi-entry dialog"
4218 * support and V-Card dialog specific support.
4219 *
4220 * At first blush, this may seem like an unnecessary duplication of effort given
4221 * that a "set dir info" dialog already exists. However, this is not so because:
4222 *
4223 * 1. V-Cards can have a lot more data in them than what the current
4224 * "set dir" dialog supports.
4225 *
4226 * 2. V-Card data, at least with respect to Jabber, is currently in a
4227 * state of flux. As the data and format changes, all that need be
4228 * changed with the V-Card support I've written is the "template"
4229 * data.
4230 *
4231 * 3. The "multi entry dialog" support itself was originally written
4232 * to support Jabber server user registration (TBD). A "dynamically
4233 * configurable" multi-entry dialog is needed for that, as different
4234 * servers may require different registration information. It just
4235 * turned out to be well-suited to adding V-Card setting support, as
4236 * well :-).
4237 *
4238 * TBD: Add check-box support to the generic multi-entry dialog support so that
4239 * it can be used to "replace" the "set dir info" support?
4240 *
4241 * Multiple-language support. Currently Not In There. I think this should
4242 * be easy. Note that when it's added: if anybody saved their data in
4243 * English, it'll be lost when MLS is added and they'll have to re-enter it.
4244 *
4245 * More "TBDs" noted in the code.
4246 */
4247
4248
4249 /*------------------------------------*/
4250 /* generic multi-entry dialog support */
4251 /*------------------------------------*/
4252
4253 /*
4254 * Print all multi-entry items
4255 *
4256 * Note: Simply a debug helper
4257 */
4258 void multi_entry_item_print_all(const GSList *list) {
4259
4260 int cnt = 0;
4261
4262 /* While there's something to print... */
4263 while(list != NULL) {
4264 fprintf(stderr, "label %2d: \"%s\"", ++cnt, ((MultiEntryData *) (list->data))->label);
4265 if(((MultiEntryData *) (list->data))->text != NULL) {
4266 fprintf(stderr, ", text: \"%s\"", ((MultiEntryData *) (list->data))->text);
4267 }
4268 fputs("\n", stderr);
4269 list = list->next;
4270 }
4271 }
4272
4273 /*
4274 * Print all multi-text items
4275 *
4276 * Note: Simply a debug helper
4277 */
4278 void multi_text_item_print_all(const GSList *list) {
4279
4280 int cnt = 0;
4281
4282 /* While there's something to print... */
4283 while(list != NULL) {
4284 fprintf(stderr, "label %2d: \"%s\"", ++cnt, ((MultiTextData *) (list->data))->label);
4285 if(((MultiTextData *) (list->data))->text != NULL) {
4286 fprintf(stderr, ", text: \"%s\"", ((MultiTextData *) (list->data))->text);
4287 }
4288 fputs("\n", stderr);
4289 list = list->next;
4290 }
4291 }
4292
4293
4294 /*
4295 * Free all multi-entry item allocs and NULL the list pointer
4296 */
4297 void multi_entry_items_free_all(GSList **list)
4298 {
4299
4300 GSList *next = *list;
4301 MultiEntryData *data;
4302
4303 /* While there's something to free() ... */
4304 while(next != NULL) {
4305 data = (MultiEntryData *) next->data;
4306 g_free(data->label);
4307 g_free(data->text);
4308 g_free(data);
4309 next = next->next;
4310 }
4311 g_slist_free(*list);
4312 *list = NULL;
4313 }
4314
4315 /*
4316 * Free all multi-text item allocs and NULL the list pointer
4317 */
4318 void multi_text_items_free_all(GSList **list)
4319 {
4320
4321 GSList *next = *list;
4322 MultiTextData *data;
4323
4324 /* While there's something to free() ... */
4325 while(next != NULL) {
4326 data = (MultiTextData *) next->data;
4327 g_free(data->label);
4328 g_free(data->text);
4329 g_free(data);
4330 next = next->next;
4331 }
4332 g_slist_free(*list);
4333 *list = NULL;
4334 }
4335
4336 /*
4337 * See if a MultiEntryData item contains a given label
4338 *
4339 * See: glib docs for g_slist_compare_custom() for details
4340 */
4341 static gint multi_entry_data_label_compare(gconstpointer data, gconstpointer label)
4342 {
4343 return(strcmp(((MultiEntryData *) (data))->label, (char *) label));
4344 }
4345
4346 /*
4347 * Add a new multi-entry item to list
4348 *
4349 * If adding to existing list: will search the list for existence of
4350 * "label" and change/create "text" entry if necessary.
4351 */
4352
4353 MultiEntryData *multi_entry_list_update(GSList **list, const char *label, const char *text, int add_it)
4354 {
4355 GSList *found;
4356 MultiEntryData *data;
4357
4358 if((found = g_slist_find_custom(*list, label, multi_entry_data_label_compare)) == NULL) {
4359 if(add_it) {
4360 data = (MultiEntryData *) g_slist_last(*list =
4361 g_slist_append(*list, g_malloc(sizeof(MultiEntryData))))->data;
4362 data->label = strcpy(g_malloc(strlen(label) +1), label);
4363 data->text = NULL;
4364 /*
4365 * default to setting "visible" and editable to TRUE - they can be
4366 * overridden later, of course.
4367 */
4368 data->visible = TRUE;
4369 data->editable = TRUE;
4370 } else {
4371 data = NULL;
4372 }
4373 } else {
4374 data = found->data;
4375 }
4376
4377 if(data != NULL && text != NULL && text[0] != '\0') {
4378 if(data->text == NULL) {
4379 data->text = g_malloc(strlen(text) + 1);
4380 } else {
4381 data->text = g_realloc(data->text, strlen(text) + 1);
4382 }
4383 strcpy(data->text, text);
4384 }
4385
4386 return(data);
4387 }
4388
4389 /*
4390 * See if a MultiTextData item contains a given label
4391 *
4392 * See: glib docs for g_slist_compare_custom() for details
4393 */
4394 static gint multi_text_data_label_compare(gconstpointer data, gconstpointer label)
4395 {
4396 return(strcmp(((MultiTextData *) (data))->label, (char *) label));
4397 }
4398
4399 /*
4400 * Add a new multi-text item to list
4401 *
4402 * If adding to existing list: will search the list for existence of
4403 * "label" and change/create "text" text if necessary.
4404 */
4405
4406 MultiTextData *multi_text_list_update(GSList **list, const char *label, const char *text, int add_it)
4407 {
4408 GSList *found;
4409 MultiTextData *data;
4410
4411 if((found = g_slist_find_custom(*list, label, multi_text_data_label_compare)) == NULL) {
4412 if(add_it) {
4413 data = (MultiTextData *) g_slist_last(*list =
4414 g_slist_append(*list, g_malloc(sizeof(MultiTextData))))->data;
4415 data->label = strcpy(g_malloc(strlen(label) +1), label);
4416 data->text = NULL;
4417 } else {
4418 data = NULL;
4419 }
4420 } else {
4421 data = found->data;
4422 }
4423
4424 if(data != NULL && text != NULL && text[0] != '\0') {
4425 if(data->text == NULL) {
4426 data->text = g_malloc(strlen(text) + 1);
4427 } else {
4428 data->text = g_realloc(data->text, strlen(text) + 1);
4429 }
4430 strcpy(data->text, text);
4431 }
4432
4433 return(data);
4434 }
4435
4436 /*
4437 * Free-up the multi-entry item list and the MultiEntryDlg
4438 * struct alloc.
4439 */
4440 void multi_entry_free(struct multi_entry_dlg *b)
4441 {
4442 multi_entry_items_free_all(&(b->multi_entry_items));
4443 multi_text_items_free_all(&(b->multi_text_items));
4444 g_free(b->instructions->text);
4445 g_free(b->instructions);
4446 g_free(b);
4447 }
4448
4449 /*
4450 * Multi-Entry dialog "destroyed" catcher
4451 *
4452 * Free-up the multi-entry item list, destroy the dialog widget
4453 * and free the MultiEntryDlg struct alloc.
4454 *
4455 */
4456 void multi_entry_dialog_destroy(GtkWidget *widget, gpointer data)
4457 {
4458 MultiEntryDlg *b = data;
4459
4460 multi_entry_free(b);
4461 }
4462
4463 /*
4464 * Show/Re-show instructions
4465 */
4466 void re_show_multi_entry_instr(MultiInstrData *instructions)
4467 {
4468 if(instructions->label != NULL) {
4469 if(instructions->text == NULL) {
4470 gtk_widget_hide(instructions->label);
4471 } else {
4472 gtk_label_set_text(GTK_LABEL (instructions->label), instructions->text);
4473 gtk_widget_show(instructions->label);
4474 }
4475 }
4476 }
4477
4478 /*
4479 * Show/Re-show entry boxes
4480 */
4481 void re_show_multi_entry_entries(GtkWidget **entries_table,
4482 GtkWidget *entries_frame,
4483 GSList *multi_entry_items)
4484 {
4485 GtkWidget *label;
4486 GSList *multi_entry;
4487 MultiEntryData *med;
4488 int rows = 0;
4489 int rowNum;
4490
4491 /* Figure-out number of rows needed for table */
4492 rows = g_slist_length(multi_entry_items);
4493
4494 if(*entries_table != NULL) {
4495 gtk_widget_destroy(GTK_WIDGET (*entries_table));
4496 }
4497 *entries_table = gtk_table_new(rows, 3, FALSE);
4498 gtk_container_add(GTK_CONTAINER (entries_frame), *entries_table);
4499
4500 for(rowNum = 0, multi_entry = multi_entry_items;
4501 multi_entry != NULL; ++rowNum, multi_entry = multi_entry->next) {
4502
4503 med = (MultiEntryData *) multi_entry->data;
4504
4505 label = gtk_label_new(med->label);
4506 gtk_misc_set_alignment(GTK_MISC(label), (gfloat) 1.0, (gfloat) 0.5);
4507 gtk_table_attach_defaults(GTK_TABLE (*entries_table), label, 0, 1, rowNum, rowNum +1);
4508 gtk_widget_show(label);
4509
4510 label = gtk_label_new(": ");
4511 gtk_misc_set_alignment(GTK_MISC(label), (gfloat) 0.0, (gfloat) 0.5);
4512 gtk_table_attach_defaults(GTK_TABLE (*entries_table), label, 1, 2, rowNum, rowNum +1);
4513 gtk_widget_show(label);
4514
4515 med->widget = gtk_entry_new_with_max_length(50);
4516 if(med->text != NULL) {
4517 gtk_entry_set_text(GTK_ENTRY (med->widget), med->text);
4518 }
4519 gtk_entry_set_visibility(GTK_ENTRY (med->widget), med->visible);
4520 gtk_entry_set_editable(GTK_ENTRY (med->widget), med->editable);
4521 gtk_table_attach_defaults(GTK_TABLE (*entries_table),
4522 med->widget, 2, 3, rowNum, rowNum +1);
4523 gtk_widget_show(med->widget);
4524 }
4525
4526 gtk_widget_show(*entries_table);
4527 }
4528
4529 /*
4530 * Show/Re-show textboxes
4531 */
4532 void re_show_multi_entry_textboxes(GtkWidget **texts_ibox,
4533 GtkWidget *texts_obox,
4534 GSList *multi_text_items)
4535 {
4536 GSList *multi_text;
4537 MultiTextData *mtd;
4538 GtkWidget *frame;
4539 GtkWidget *hbox;
4540 GtkWidget *vscrollbar;
4541
4542 if(*texts_ibox != NULL) {
4543 gtk_widget_destroy(GTK_WIDGET (*texts_ibox));
4544 }
4545 *texts_ibox = gtk_vbox_new(FALSE, 5);
4546 gtk_container_add(GTK_CONTAINER (texts_obox), *texts_ibox);
4547
4548 for(multi_text = multi_text_items; multi_text != NULL; multi_text = multi_text->next) {
4549 mtd = (MultiTextData *) multi_text->data;
4550 frame = gtk_frame_new(mtd->label);
4551 gtk_container_add(GTK_CONTAINER (*texts_ibox), frame);
4552 hbox = gtk_hbox_new(FALSE, 0);
4553 gtk_container_add(GTK_CONTAINER (frame), hbox);
4554 mtd->textbox = gtk_text_new(NULL, NULL);
4555 gtk_text_set_editable(GTK_TEXT(mtd->textbox), TRUE);
4556 gtk_text_set_word_wrap(GTK_TEXT(mtd->textbox), TRUE);
4557 gtk_widget_set_usize(mtd->textbox, 300, 100);
4558 gtk_text_insert(GTK_TEXT(mtd->textbox), NULL, NULL, NULL, mtd->text, -1);
4559 gtk_box_pack_start(GTK_BOX (hbox), mtd->textbox, FALSE, FALSE, 0);
4560 vscrollbar = gtk_vscrollbar_new (GTK_TEXT(mtd->textbox)->vadj);
4561 gtk_box_pack_start(GTK_BOX (hbox), vscrollbar, FALSE, FALSE, 0);
4562 gtk_widget_show(mtd->textbox);
4563 gtk_widget_show (vscrollbar);
4564 gtk_widget_show(hbox);
4565 gtk_widget_show(frame);
4566 }
4567
4568 gtk_widget_show(*texts_ibox);
4569 }
4570
4571 /*
4572 * Create and initialize a new Multi-Entry Dialog struct
4573 */
4574 MultiEntryDlg *multi_entry_dialog_new()
4575 {
4576 MultiEntryDlg *b = g_new0(MultiEntryDlg, 1);
4577 b->instructions = g_new0(MultiInstrData, 1);
4578 b->multi_entry_items = NULL;
4579 b->multi_text_items = NULL;
4580 return(b);
4581 }
4582
4583 /*
4584 * Instantiate a new multi-entry dialog
4585 *
4586 * data == pointer to MultiEntryDlg with the following
4587 * initialized:
4588 *
4589 * wmclass_name
4590 * wmclass_class
4591 * title
4592 * user
4593 * multi_entry_items - pointers to MultiEntryData list
4594 * and MultiTextData list
4595 * instructions (optional)
4596 * ok function pointer
4597 * cancel function pointer (actually used to set
4598 * window destroy signal--cancel asserts destroy)
4599 *
4600 * sets the following in the MultiEntryDialog struct:
4601 *
4602 * window
4603 */
4604 void show_multi_entry_dialog(gpointer data)
4605 {
4606 GtkWidget *vbox, *hbox;
4607 GtkWidget *button;
4608 MultiEntryDlg *b = data;
4609
4610 GAIM_DIALOG(b->window);
4611 gtk_window_set_wmclass(GTK_WINDOW(b->window), b->wmclass_name, b->wmclass_class);
4612 gtk_window_set_title(GTK_WINDOW (b->window), b->title);
4613 /* Clean up if user dismisses window via window manager! */
4614 gtk_signal_connect(GTK_OBJECT(b->window), "destroy", GTK_SIGNAL_FUNC(b->cancel), (gpointer) b);
4615 gtk_widget_realize(b->window);
4616 aol_icon(b->window->window);
4617
4618 vbox = gtk_vbox_new(FALSE, 5);
4619 gtk_container_add(GTK_CONTAINER (b->window), vbox);
4620
4621 b->instructions->label = gtk_label_new(NULL);
4622 gtk_label_set_line_wrap(GTK_LABEL (b->instructions->label), TRUE);
4623 gtk_box_pack_start(GTK_BOX (vbox), b->instructions->label, TRUE, TRUE, 5);
4624 re_show_multi_entry_instr(b->instructions);
4625
4626 b->entries_frame = gtk_frame_new(NULL);
4627 gtk_box_pack_start(GTK_BOX (vbox), b->entries_frame, TRUE, TRUE, 5);
4628 gtk_widget_show(b->entries_frame);
4629 b->entries_table = NULL;
4630 re_show_multi_entry_entries(&(b->entries_table), b->entries_frame, b->multi_entry_items);
4631
4632 b->texts_obox = gtk_vbox_new(FALSE, 0);
4633 gtk_box_pack_start(GTK_BOX (vbox), b->texts_obox, TRUE, TRUE, 0);
4634 gtk_widget_show(b->texts_obox);
4635 b->texts_ibox = NULL;
4636 re_show_multi_entry_textboxes(&(b->texts_ibox), b->texts_obox, b->multi_text_items);
4637
4638 hbox = gtk_hbox_new(FALSE, 0);
4639 gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
4640 gtk_widget_show(hbox);
4641
4642 button = picture_button(b->window, _("Cancel"), cancel_xpm);
4643 /* Let "destroy handling" (set above) handle cleanup */
4644 gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
4645 GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (b->window));
4646 gtk_box_pack_end(GTK_BOX (hbox), button, FALSE, FALSE, 0);
4647 gtk_widget_show(button);
4648
4649 button = picture_button(b->window, _("Save"), save_xpm);
4650 gtk_signal_connect(GTK_OBJECT (button), "clicked",
4651 GTK_SIGNAL_FUNC (b->ok), (gpointer) b);
4652 gtk_box_pack_end(GTK_BOX (hbox), button, FALSE, FALSE, 0);
4653 gtk_widget_show(button);
4654
4655 gtk_widget_show(vbox);
4656 gtk_widget_show(b->window);
4657 }
4658
4659
4660 /*------------------------------------*/
4661 /* V-Card dialog specific support */
4662 /*------------------------------------*/
4663
4664 /*
4665 * V-Card "set info" dialog "Save" clicked
4666 *
4667 * Copy data from GTK+ dialogs into GSLists, call protocol-specific
4668 * formatter and save the user info data.
4669 */
4670 void set_vcard_dialog_ok_clicked(GtkWidget *widget, gpointer data)
4671 {
4672 MultiEntryDlg *b = (MultiEntryDlg *) data;
4673 struct gaim_connection *gc;
4674 gchar *tmp;
4675 GSList *list;
4676
4677 for(list = b->multi_entry_items; list != NULL; list = list->next) {
4678 if(((MultiEntryData *) list->data)->text != NULL) {
4679 g_free(((MultiEntryData *) list->data)->text);
4680 }
4681 ((MultiEntryData *) list->data)->text =
4682 g_strdup(gtk_entry_get_text(GTK_ENTRY(((MultiEntryData *) list->data)->widget)));
4683 }
4684
4685 for(list = b->multi_text_items; list != NULL; list = list->next) {
4686 if(((MultiTextData *) list->data)->text != NULL) {
4687 g_free(((MultiTextData *) list->data)->text);
4688 }
4689 ((MultiTextData *) list->data)->text =
4690 gtk_editable_get_chars((GtkEditable *) (((MultiTextData *) list->data)->textbox),
4691 0, -1);
4692 }
4693
4694
4695 tmp = b->custom(b);
4696
4697 /*
4698 * Set the user info and (possibly) send to the server
4699 */
4700 if (b->user) {
4701 strncpy(b->user->user_info, tmp, sizeof b->user->user_info);
4702 gc = b->user->gc;
4703
4704 save_prefs();
4705
4706 if (gc)
4707 serv_set_info(gc, b->user->user_info);
4708 }
4709
4710 g_free(tmp);
4711
4712 /* Let multi-edit dialog window "destroy" event catching handle remaining cleanup */
4713 gtk_widget_destroy(GTK_WIDGET (b->window));
4714 }
4715
4716 /*
4717 * Instantiate a v-card dialog
4718 */
4719 void show_set_vcard(MultiEntryDlg *b)
4720 {
4721 b->ok = set_vcard_dialog_ok_clicked;
4722 b->cancel = multi_entry_dialog_destroy;
4723
4724 show_multi_entry_dialog(b);
4725 }
4726
4727
4728 /*------------------------------------------------------------------------*/
4729 /* End dialog for setting v-card info */
4730 /*------------------------------------------------------------------------*/
4731