Mercurial > pidgin.yaz
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 |