|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/desktop/dlgutil1.c |
source navigation diff markup identifier search freetext search file search |
1 /* dlgutil1.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: dlgutil1.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 1/22/95
31 *
32 * $Revision: 6.151 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 *
42 * ==========================================================================
43 */
44
45 #include <dlogutil.h>
46 #include <document.h>
47 #include <gather.h>
48 #include <subutil.h>
49 #include <objfdef.h>
50 #include <gbfeat.h>
51 #include <gbftdef.h>
52 #include <edutil.h>
53 #include <explore.h>
54 #include <sqnutils.h>
55 #include <alignmgr2.h>
56 #include <toasn3.h>
57 #include <vibforms.h>
58 #include <cdrgn.h>
59 #include <findrepl.h>
60
61 #define NUMBER_OF_SUFFIXES 8
62
63 static CharPtr name_suffix_labels [] = {
64 " ", "Jr.", "Sr.", "II", "III", "IV", "V", "VI", NULL
65 };
66
67 static ENUM_ALIST(name_suffix_alist)
68 {" ", 0},
69 {"Jr.", 1},
70 {"Sr.", 2},
71 {"II", 3},
72 {"III", 4},
73 {"IV", 5},
74 {"V", 6},
75 {"VI", 7},
76 END_ENUM_ALIST
77
78 Uint2 author_types [] = {
79 TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_POPUP
80 };
81
82 Uint2 std_author_widths [] = {
83 8, 4, 9, 0
84 };
85
86 static EnumFieldAssocPtr author_popups [] = {
87 NULL, NULL, NULL, name_suffix_alist
88 };
89
90 Uint2 str_author_widths [] = {
91 24
92 };
93
94 typedef struct authordialog {
95 DIALOG_MESSAGE_BLOCK
96 DialoG stdAuthor;
97 DialoG strAuthor;
98 GrouP stdGrp;
99 GrouP strGrp;
100 Uint1 type;
101 } AuthorDialog, PNTR AuthorDialogPtr;
102
103 StdPrintOptionsPtr spop = NULL;
104
105 extern Boolean SetupPrintOptions (void)
106
107 {
108 if (spop == NULL) {
109 spop = StdPrintOptionsNew (NULL);
110 if (spop != NULL) {
111 spop->newline = "\r";
112 spop->indent = "";
113 } else {
114 Message (MSG_FATAL, "StdPrintOptionsNew failed");
115 }
116 }
117 return (Boolean) (spop != NULL);
118 }
119
120 extern void FreePrintOptions (void)
121
122 {
123 spop = StdPrintOptionsFree (spop);
124 }
125
126 ENUM_ALIST(months_alist)
127 {" ", 0},
128 {"Jan", 1},
129 {"Feb", 2},
130 {"Mar", 3},
131 {"Apr", 4},
132 {"May", 5},
133 {"Jun", 6},
134 {"Jul", 7},
135 {"Aug", 8},
136 {"Sep", 9},
137 {"Oct", 10},
138 {"Nov", 11},
139 {"Dec", 12},
140 END_ENUM_ALIST
141
142 extern void SetDescriptorPropagate (BioseqSetPtr bssp)
143 {
144 BioseqPtr bsp;
145 SeqEntryPtr seqentry;
146 ValNodePtr sourcedescr;
147
148 if (bssp != NULL) {
149 sourcedescr = bssp->descr;
150 if (sourcedescr != NULL) {
151 bssp->descr = NULL;
152 seqentry = bssp->seq_set;
153 while (seqentry != NULL) {
154 if (seqentry->data.ptrvalue != NULL) {
155 if (seqentry->choice == 1) {
156 bsp = (BioseqPtr) seqentry->data.ptrvalue;
157 ValNodeLink (&(bsp->descr),
158 AsnIoMemCopy ((Pointer) sourcedescr,
159 (AsnReadFunc) SeqDescrAsnRead,
160 (AsnWriteFunc) SeqDescrAsnWrite));
161 } else if (seqentry->choice == 2) {
162 bssp = (BioseqSetPtr) seqentry->data.ptrvalue;
163 ValNodeLink (&(bssp->descr),
164 AsnIoMemCopy ((Pointer) sourcedescr,
165 (AsnReadFunc) SeqDescrAsnRead,
166 (AsnWriteFunc) SeqDescrAsnWrite));
167 }
168 }
169 seqentry = seqentry->next;
170 }
171 SeqDescrFree (sourcedescr);
172 }
173 }
174 }
175
176
177 static void CopyOneDescriptorToSeqEntry (SeqDescrPtr sdp, SeqEntryPtr sep)
178 {
179 BioseqPtr bsp;
180 BioseqSetPtr bssp;
181
182 if (sdp == NULL || sep == NULL) {
183 return;
184 }
185
186 /* NOTE - we are using SeqDescAsnRead and SeqDescAsnWrite
187 * instead of SeqDescrAsnWrite and SeqDescrAsnWrite
188 * so that only THIS descriptor is propagated, rather than than chain
189 */
190 if (sep->choice == 1) {
191 bsp = (BioseqPtr) sep->data.ptrvalue;
192 ValNodeLink (&(bsp->descr),
193 AsnIoMemCopy ((Pointer) sdp,
194 (AsnReadFunc) SeqDescAsnRead,
195 (AsnWriteFunc) SeqDescAsnWrite));
196 } else if (sep->choice == 2) {
197 bssp = (BioseqSetPtr) sep->data.ptrvalue;
198 ValNodeLink (&(bssp->descr),
199 AsnIoMemCopy ((Pointer) sdp,
200 (AsnReadFunc) SeqDescAsnRead,
201 (AsnWriteFunc) SeqDescAsnWrite));
202 }
203 }
204
205
206 extern Int2 LIBCALLBACK DescriptorPropagate (Pointer data)
207
208 {
209 BioseqSetPtr bssp = NULL;
210 OMProcControlPtr ompcp;
211 SeqDescrPtr sdp;
212 ObjValNodePtr ovp;
213 SeqEntryPtr sep;
214
215 ompcp = (OMProcControlPtr) data;
216 if (ompcp == NULL || ompcp->input_entityID == 0) {
217 Message (MSG_ERROR, "Please select a BioseqSet");
218 return OM_MSG_RET_ERROR;
219 }
220 switch (ompcp->input_itemtype) {
221 case OBJ_BIOSEQSET :
222 bssp = (BioseqSetPtr) ompcp->input_data;
223 break;
224 case OBJ_SEQDESC:
225 /* special case - propagate just this descriptor */
226 sdp = (SeqDescrPtr) ompcp->input_data;
227 if (sdp != NULL && sdp->extended > 0) {
228 ovp = (ObjValNodePtr) sdp;
229 if (ovp->idx.parenttype == OBJ_BIOSEQSET && ovp->idx.parentptr != NULL) {
230 bssp = ovp->idx.parentptr;
231 for (sep = bssp->seq_set; sep != NULL; sep = sep->next) {
232 CopyOneDescriptorToSeqEntry (sdp, sep);
233 }
234 ovp->idx.deleteme = TRUE;
235 DeleteMarkedObjects (ompcp->input_entityID, 0, NULL);
236 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
237 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
238 return OM_MSG_RET_DONE;
239 }
240 }
241 return OM_MSG_RET_ERROR;
242 break;
243 case 0 :
244 Message (MSG_ERROR, "Please select a BioseqSet");
245 return OM_MSG_RET_ERROR;
246 default :
247 Message (MSG_ERROR, "Please select a BioseqSet");
248 return OM_MSG_RET_ERROR;
249 }
250
251 SetDescriptorPropagate (bssp);
252
253 ObjMgrSetDirtyFlag (ompcp->input_entityID, TRUE);
254 ObjMgrSendMsg (OM_MSG_UPDATE, ompcp->input_entityID, 0, 0);
255 return OM_MSG_RET_DONE;
256 }
257
258 extern Boolean DescFormReplaceWithoutUpdateProc (ForM f)
259
260 {
261 MsgAnswer ans;
262 DescriptorFormPtr dfp;
263 Int4Ptr intptr;
264 OMProcControl ompc;
265 Boolean rsult;
266 ValNodePtr sdp;
267 SeqEntryPtr sep;
268 BioseqSetPtr bssp;
269
270 rsult = FALSE;
271 dfp = (DescriptorFormPtr) GetObjectExtra (f);
272 if (dfp != NULL) {
273 MemSet ((Pointer) &ompc, 0, sizeof (OMProcControl));
274 ompc.input_entityID = dfp->input_entityID;
275 ompc.input_itemID = dfp->input_itemID;
276 ompc.input_itemtype = dfp->input_itemtype;
277 ompc.output_itemtype = dfp->input_itemtype;
278 sdp = SeqDescrNew (NULL);
279 if (sdp != NULL) {
280 sdp->choice = (Uint1)dfp->this_subtype;
281 switch (sdp->choice) {
282 case Seq_descr_mol_type :
283 case Seq_descr_method :
284 intptr = (Int4Ptr) DialogToPointer (dfp->data);
285 if (intptr != NULL) {
286 sdp->data.intvalue = *intptr;
287 }
288 break;
289 default :
290 sdp->data.ptrvalue = DialogToPointer (dfp->data);
291 break;
292 }
293 FixSpecialCharactersForObject (OBJ_SEQDESC, sdp, "You may not include special characters in the text.\nIf you do not choose replacement characters, these special characters will be replaced with '#'.", TRUE, NULL);
294
295 ompc.output_data = (Pointer) sdp;
296 if (ompc.input_entityID == 0) {
297 if (! ObjMgrRegister (OBJ_SEQDESC, (Pointer) sdp)) {
298 Message (MSG_ERROR, "ObjMgrRegister failed");
299 }
300 } else if (ompc.input_itemtype != OBJ_SEQDESC) {
301 ompc.output_itemtype = OBJ_SEQDESC;
302 if (! AttachDataForProc (&ompc, FALSE)) {
303 Message (MSG_ERROR, "AttachDataForProc failed");
304 }
305 rsult = TRUE;
306 } else {
307 if (! ReplaceDataForProc (&ompc, FALSE)) {
308 Message (MSG_ERROR, "ReplaceDataForProc failed");
309 }
310 rsult = TRUE;
311 }
312 }
313
314 /* If the descriptor was added to a GenBank set then*/
315 /* optionally propagate it to the set's Bioseqs. */
316
317 if (ompc.input_itemtype == OBJ_BIOSEQSET) {
318 sep = (SeqEntryPtr) ompc.input_choice;
319 bssp = (BioseqSetPtr) sep->data.ptrvalue;
320 if (bssp->_class == BioseqseqSet_class_genbank) {
321 ans = Message (MSG_YN, "Do you wish to propagate the descriptor to "
322 "the set's Bioseqs?");
323 if (ANS_YES == ans)
324 DescriptorPropagate (&ompc);
325 }
326 }
327
328 }
329 return rsult;
330 }
331
332 extern void StdDescFormActnProc (ForM f)
333
334 {
335 DescriptorFormPtr dfp;
336
337 if (DescFormReplaceWithoutUpdateProc (f)) {
338 dfp = (DescriptorFormPtr) GetObjectExtra (f);
339 if (dfp != NULL) {
340 GetRidOfEmptyFeatsDescStrings (dfp->input_entityID, NULL);
341 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
342 ExtendGeneFeatIfOnMRNA (dfp->input_entityID, NULL);
343 }
344 ObjMgrSetDirtyFlag (dfp->input_entityID, TRUE);
345 ObjMgrSendMsg (OM_MSG_UPDATE, dfp->input_entityID,
346 dfp->input_itemID, dfp->input_itemtype);
347 }
348 }
349 }
350
351 extern void StdDescFormCleanupProc (GraphiC g, VoidPtr data)
352
353 {
354 DescriptorFormPtr dfp;
355 Uint2 userkey;
356
357 dfp = (DescriptorFormPtr) data;
358 if (dfp != NULL) {
359 if (dfp->input_entityID > 0 && dfp->userkey > 0) {
360 userkey = dfp->userkey;
361 dfp->userkey = 0;
362 ObjMgrFreeUserData (dfp->input_entityID, dfp->procid, dfp->proctype, userkey);
363 }
364 }
365 StdCleanupExtraProc (g, data);
366 }
367
368 extern OMUserDataPtr ItemAlreadyHasEditor (Uint2 entityID, Uint4 itemID, Uint2 itemtype, Uint2 procid)
369
370 {
371 BaseFormPtr bfp;
372 Uint4 j;
373 Uint4 num;
374 ObjMgrPtr omp;
375 ObjMgrDataPtr PNTR omdpp;
376 OMUserDataPtr omudp;
377 ObjMgrDataPtr tmp;
378
379 if (entityID == 0 || itemID == 0 || itemtype == 0 || procid == 0) return NULL;
380 omp = ObjMgrGet ();
381 if (omp == NULL) return NULL;
382 num = omp->currobj;
383 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
384 tmp = *omdpp;
385 if (tmp->parentptr == NULL && tmp->EntityID == entityID) {
386
387 for (omudp = tmp->userdata; omudp != NULL; omudp = omudp->next) {
388 if (omudp->proctype == OMPROC_EDIT && omudp->procid == procid) {
389 bfp = (BaseFormPtr) omudp->userdata.ptrvalue;
390 if (bfp != NULL) {
391 if (bfp->input_itemID == itemID && bfp->input_itemtype == itemtype) {
392 return omudp;
393 }
394 }
395 }
396 }
397 }
398 }
399 return NULL;
400 }
401
402
403 extern Uint2 GetProcIdForItemEditor (Uint2 entityID, Uint2 itemID, Uint1 itemtype, Uint2 subinputtype)
404 {
405 ObjMgrPtr omp;
406 ObjMgrProcPtr ompp=NULL;
407 Uint2 best_procid = 0;
408
409 omp = ObjMgrGet ();
410
411 while ((ompp = ObjMgrProcFindNext(omp, OMPROC_EDIT, itemtype, itemtype, ompp)) != NULL)
412 {
413 if (ompp->subinputtype == subinputtype)
414 {
415 return ompp->procid;
416 }
417 else if (! ompp->subinputtype) /* general proc found */
418 {
419 best_procid = ompp->procid;
420 }
421 }
422 return best_procid;
423 }
424
425
426 /* Note - if a viewer displays features from a far sequence mapped to
427 * the current sequence, it will register an interest in the entityID
428 * for the far sequence.
429 * To find the "main" viewer for just the original sequence, we want
430 * to find a view for which only one entityID is registered.
431 */
432 extern OMUserDataPtr EntityAlreadyHasViewer (Uint2 entityID)
433
434 {
435 BaseFormPtr bfp;
436 Uint4 j;
437 Uint4 num;
438 ObjMgrPtr omp;
439 ObjMgrDataPtr PNTR omdpp;
440 OMUserDataPtr omudp;
441 ObjMgrDataPtr tmp;
442 ValNodePtr found_views = NULL, vnp_view;
443 ValNodePtr view_forms = NULL, vnp_form;
444 Boolean not_this_one;
445
446 if (entityID == 0) return NULL;
447 omp = ObjMgrGet ();
448 if (omp == NULL) return NULL;
449 num = omp->currobj;
450 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
451 tmp = *omdpp;
452 if (tmp->parentptr == NULL && tmp->EntityID == entityID) {
453
454 for (omudp = tmp->userdata; omudp != NULL; omudp = omudp->next) {
455 if (omudp->proctype == OMPROC_VIEW) {
456 bfp = (BaseFormPtr) omudp->userdata.ptrvalue;
457 if (bfp != NULL) {
458 ValNodeAddPointer (&found_views, 0, omudp);
459 ValNodeAddPointer (&view_forms, 0, bfp);
460 }
461 }
462 }
463 }
464 }
465
466 /* now look to see if the form is also a view for another entityID */
467 for (vnp_view = found_views, vnp_form = view_forms;
468 vnp_view != NULL && vnp_form != NULL;
469 vnp_view = vnp_view->next, vnp_form = vnp_form->next) {
470 not_this_one = FALSE;
471 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL && !not_this_one; j++, omdpp++) {
472 tmp = *omdpp;
473 if (tmp->parentptr == NULL && tmp->EntityID != entityID) {
474
475 for (omudp = tmp->userdata; omudp != NULL && !not_this_one; omudp = omudp->next) {
476 if (omudp->proctype == OMPROC_VIEW) {
477 bfp = (BaseFormPtr) omudp->userdata.ptrvalue;
478 if (bfp != NULL && bfp == (BaseFormPtr) vnp_form->data.ptrvalue) {
479 not_this_one = TRUE;
480 }
481 }
482 }
483 }
484 }
485 if (!not_this_one) {
486 omudp = vnp_view->data.ptrvalue;
487 found_views = ValNodeFree (found_views);
488 view_forms = ValNodeFree (view_forms);
489 return omudp;
490 }
491 }
492 found_views = ValNodeFree (found_views);
493 view_forms = ValNodeFree (view_forms);
494
495 return NULL;
496 }
497
498
499 extern Boolean MakeViewerIndependent (Uint2 entityID, OMUserDataPtr omudp)
500 {
501 Uint4 j;
502 Uint4 num;
503 ObjMgrPtr omp;
504 ObjMgrDataPtr PNTR omdpp;
505 OMUserDataPtr omudp_tmp;
506 ObjMgrDataPtr tmp;
507
508 if (entityID == 0 || omudp == NULL) return FALSE;
509 omp = ObjMgrGet ();
510 if (omp == NULL) return FALSE;
511 num = omp->currobj;
512 for (j = 0, omdpp = omp->datalist; j < num && omdpp != NULL; j++, omdpp++) {
513 tmp = *omdpp;
514 if (tmp->parentptr == NULL && tmp->EntityID == entityID) {
515 omudp_tmp = tmp->userdata;
516 while (omudp_tmp != NULL && omudp_tmp != omudp) {
517 omudp_tmp = omudp_tmp->next;
518 }
519 if (omudp_tmp != NULL) {
520 tmp->tempload = TL_NOT_TEMP;
521 return TRUE;
522 }
523 }
524 }
525 return FALSE;
526 }
527
528
529 typedef struct genegatherlist {
530 FeatureFormPtr ffp;
531 ObjMgrPtr omp;
532 SeqLocPtr slp;
533 GeneRefPtr genexref;
534 Boolean xrefmatch;
535 Int2 idx;
536 Int2 val;
537 Int4 min;
538 Uint2 geneEntityID;
539 Uint4 geneItemID;
540 Uint2 geneItemtype;
541 Boolean geneFound;
542 SeqLocPtr old_feature_location;
543 ValNodePtr lastgene;
544 } GeneGatherList, PNTR GeneGatherPtr;
545
546 static Boolean GeneFindFunc (GatherContextPtr gcp)
547
548 {
549 GeneGatherPtr ggp;
550 ObjMgrTypePtr omtp;
551 SeqFeatPtr sfp;
552 Char thislabel [41];
553
554 if (gcp == NULL) return TRUE;
555
556 ggp = (GeneGatherPtr) gcp->userdata;
557 if (ggp == NULL ) return TRUE;
558
559 thislabel [0] = '\0';
560
561 if (gcp->thistype == OBJ_SEQFEAT) {
562 sfp = (SeqFeatPtr) gcp->thisitem;
563 if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE) {
564 omtp = ObjMgrTypeFind (ggp->omp, gcp->thistype, NULL, NULL);
565 if (omtp == NULL) {
566 return TRUE;
567 }
568 if (omtp->labelfunc != NULL) {
569 (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
570 }
571 if (thislabel [0] != '\0') {
572 ggp->idx++;
573 if (ggp->idx == ggp->val) {
574 ggp->geneEntityID = gcp->entityID;
575 ggp->geneItemID = gcp->itemID;
576 ggp->geneItemtype = gcp->thistype;
577 ggp->geneFound = TRUE;
578 return FALSE;
579 }
580 }
581 }
582 }
583 return TRUE;
584 }
585
586 extern void Nlm_LaunchGeneFeatEd (ButtoN b);
587 extern void Nlm_LaunchGeneFeatEd (ButtoN b)
588
589 {
590 FeatureFormPtr ffp;
591 GeneGatherList ggl;
592 GatherScope gs;
593 Int2 handled;
594 Int2 val;
595
596 ffp = (FeatureFormPtr) GetObjectExtra (b);
597 if (ffp != NULL && ffp->gene != NULL && GetValue (ffp->useGeneXref) == 1) {
598 val = GetValue (ffp->gene);
599 if (val > 2) {
600 ggl.ffp = ffp;
601 ggl.omp = ObjMgrGet ();
602 ggl.idx = 2;
603 ggl.val = val;
604 ggl.min = INT4_MAX;
605 ggl.geneFound = FALSE;
606 ggl.geneEntityID = 0;
607 ggl.geneItemID = 0;
608 ggl.geneItemtype = 0;
609 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
610 gs.seglevels = 1;
611 gs.get_feats_location = TRUE;
612 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
613 gs.ignore[OBJ_BIOSEQ] = FALSE;
614 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
615 gs.ignore[OBJ_SEQFEAT] = FALSE;
616 gs.ignore[OBJ_SEQANNOT] = FALSE;
617 gs.scope = GetBestTopParentForItemID (ffp->input_entityID,
618 ffp->input_itemID,
619 ffp->input_itemtype);
620 GatherEntity (ffp->input_entityID, (Pointer) &ggl, GeneFindFunc, &gs);
621 if (ggl.geneFound) {
622 WatchCursor ();
623 Update ();
624 handled = GatherProcLaunch (OMPROC_EDIT, FALSE, ggl.geneEntityID, ggl.geneItemID,
625 ggl.geneItemtype, 0, 0, ggl.geneItemtype, 0);
626 ArrowCursor ();
627 Update ();
628 if (handled != OM_MSG_RET_DONE || handled == OM_MSG_RET_NOPROC) {
629 Message (MSG_ERROR, "Unable to launch editor on gene feature.");
630 }
631 }
632 }
633 }
634 }
635
636 extern void UpdateGeneLocation
637 (SeqFeatPtr gene,
638 SeqLocPtr old_feat_loc,
639 SeqLocPtr new_feat_loc,
640 Uint2 entityID)
641 {
642 Uint1 strandfeat, strandgene, strandold;
643 BioseqPtr bsp;
644 SeqLocPtr tmpslp, slp;
645 Boolean hasNulls;
646 Boolean noLeft;
647 Boolean noRight;
648 Boolean noLeftFeat;
649 Boolean noLeftGene;
650 Boolean noRightFeat;
651 Boolean noRightGene;
652
653 if (gene == NULL || new_feat_loc == NULL)
654 {
655 return;
656 }
657
658 strandfeat = SeqLocStrand (new_feat_loc);
659 strandgene = SeqLocStrand (gene->location);
660 if (old_feat_loc == NULL)
661 {
662 strandold = strandfeat;
663 }
664 else
665 {
666 strandold = SeqLocStrand (old_feat_loc);
667 }
668
669 /* only correct gene location if gene is on same strand as old feature
670 * location and contained in new feature location (on either strand).
671 */
672 if (SeqLocAinB (new_feat_loc, gene->location) <= 0
673 && ((strandold == Seq_strand_minus && strandgene == Seq_strand_minus)
674 || (strandold != Seq_strand_minus && strandgene != Seq_strand_minus)))
675 {
676 bsp = GetBioseqGivenSeqLoc (gene->location, entityID);
677 if (bsp != NULL) {
678 hasNulls = LocationHasNullsBetween (gene->location);
679 if ((strandfeat == Seq_strand_minus && strandgene != Seq_strand_minus)
680 || (strandfeat != Seq_strand_minus && strandgene == Seq_strand_minus))
681 {
682 tmpslp = SeqLocCopy (gene->location);
683 SeqLocRevCmp (tmpslp);
684 slp = SeqLocMerge (bsp, tmpslp, new_feat_loc, TRUE, FALSE, hasNulls);
685 tmpslp = SeqLocFree (tmpslp);
686 }
687 else
688 {
689 slp = SeqLocMergeExEx (bsp, gene->location, new_feat_loc, TRUE, FALSE, TRUE, hasNulls, TRUE, TRUE);
690 }
691
692 if (slp != NULL) {
693 CheckSeqLocForPartial (gene->location, &noLeftGene, &noRightGene);
694 gene->location = SeqLocFree (gene->location);
695 gene->location = slp;
696 CheckSeqLocForPartial (new_feat_loc, &noLeftFeat, &noRightFeat);
697 if (bsp->repr == Seq_repr_seg) {
698 slp = SegLocToPartsEx (bsp, gene->location, TRUE);
699 gene->location = SeqLocFree (gene->location);
700 gene->location = slp;
701 hasNulls = LocationHasNullsBetween (gene->location);
702 gene->partial = (gene->partial || hasNulls);
703 }
704 FreeAllFuzz (gene->location);
705 noLeft = (noLeftFeat || noLeftGene);
706 noRight = (noRightFeat || noRightGene);
707 SetSeqLocPartial (gene->location, noLeft, noRight);
708 gene->partial = (gene->partial || noLeft || noRight);
709 }
710 }
711 }
712 }
713
714 static Boolean DlgStrandsMatch (Uint1 featstrand, Uint1 locstrand)
715
716 {
717 if (featstrand == locstrand) return TRUE;
718 if (locstrand == Seq_strand_unknown && featstrand != Seq_strand_minus) return TRUE;
719 if (featstrand == Seq_strand_unknown && locstrand != Seq_strand_minus) return TRUE;
720 if (featstrand == Seq_strand_both && locstrand != Seq_strand_minus) return TRUE;
721 if (locstrand == Seq_strand_both) return TRUE;
722 return FALSE;
723 }
724
725 static Boolean GeneUpdateFunc (GatherContextPtr gcp)
726
727 {
728 GeneGatherPtr ggp;
729 ObjMgrTypePtr omtp;
730 SeqFeatPtr sfp;
731 Uint1 strand1, strand2;
732 Char thislabel [41];
733
734 if (gcp == NULL) return TRUE;
735
736 ggp = (GeneGatherPtr) gcp->userdata;
737 if (ggp == NULL ) return TRUE;
738
739 thislabel [0] = '\0';
740
741 if (gcp->thistype == OBJ_SEQFEAT) {
742 sfp = (SeqFeatPtr) gcp->thisitem;
743 if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE) {
744 omtp = ObjMgrTypeFind (ggp->omp, gcp->thistype, NULL, NULL);
745 if (omtp == NULL) {
746 return TRUE;
747 }
748 if (omtp->labelfunc != NULL) {
749 (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
750 }
751 if (thislabel [0] != '\0') {
752 ggp->idx++;
753 if (ggp->idx == ggp->val) {
754 strand1 = SeqLocStrand (sfp->location);
755 strand2 = SeqLocStrand (ggp->slp);
756 if (DlgStrandsMatch (strand1, strand2)) {
757 UpdateGeneLocation (sfp, ggp->old_feature_location, ggp->slp, gcp->entityID);
758 return FALSE;
759 }
760 }
761 }
762 }
763 }
764 return TRUE;
765 }
766
767 static Boolean GeneGatherFunc (GatherContextPtr gcp)
768
769 {
770 FeatureFormPtr ffp;
771 GeneGatherPtr ggp;
772 GeneRefPtr grp;
773 ObjMgrTypePtr omtp;
774 SeqFeatPtr sfp;
775 Char thislabel [41];
776 ValNodePtr vnp;
777
778 if (gcp == NULL) return TRUE;
779
780 ggp = (GeneGatherPtr) gcp->userdata;
781 if (ggp == NULL || ggp->ffp == NULL) return TRUE;
782
783 thislabel [0] = '\0';
784
785 if (gcp->thistype == OBJ_SEQFEAT) {
786 sfp = (SeqFeatPtr) gcp->thisitem;
787 if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE) {
788 omtp = ObjMgrTypeFind (ggp->omp, gcp->thistype, NULL, NULL);
789 if (omtp == NULL) {
790 return TRUE;
791 }
792 if (omtp->labelfunc != NULL) {
793 (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
794 }
795 if (thislabel [0] != '\0') {
796 ffp = (FeatureFormPtr) ggp->ffp;
797 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
798 if (grp != NULL
799 && (grp->locus != NULL || grp->locus_tag != NULL || grp->desc != NULL))
800 {
801 vnp = ValNodeNew (ggp->lastgene);
802 if (ffp->geneNames == NULL) {
803 ffp->geneNames = vnp;
804 }
805 ggp->lastgene = vnp;
806 if (vnp != NULL) {
807 vnp->data.ptrvalue = StringSave (thislabel);
808 if (grp->locus != NULL) {
809 vnp->choice = 1;
810 } else if (grp->desc != NULL) {
811 vnp->choice = 2;
812 } else if (grp->locus_tag != NULL) {
813 vnp->choice = 3;
814 }
815 }
816 }
817 }
818 }
819 }
820
821 return TRUE;
822 }
823
824 extern void PopulateGenePopup (FeatureFormPtr ffp)
825
826 {
827 Int2 count;
828 GeneGatherList ggl;
829 GatherScope gs;
830 CharPtr str;
831 Boolean usePopupForGene;
832 ValNodePtr vnp;
833
834 if (ffp != NULL && ffp->genePopup != NULL && ffp->geneList != NULL) {
835 ggl.ffp = ffp;
836 ggl.omp = ObjMgrGet ();
837 ggl.slp = NULL;
838 ggl.genexref = NULL;
839 ggl.xrefmatch = FALSE;
840 ggl.idx = 0;
841 ggl.val = 0;
842 ggl.min = 0;
843 ggl.lastgene = NULL;
844 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
845 gs.seglevels = 1;
846 gs.get_feats_location = TRUE;
847 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
848 gs.ignore[OBJ_BIOSEQ] = FALSE;
849 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
850 gs.ignore[OBJ_SEQFEAT] = FALSE;
851 gs.ignore[OBJ_SEQANNOT] = FALSE;
852 gs.scope = GetBestTopParentForItemID (ffp->input_entityID,
853 ffp->input_itemID,
854 ffp->input_itemtype);
855 GatherEntity (ffp->input_entityID, (Pointer) &ggl, GeneGatherFunc, &gs);
856 count = 0;
857 for (vnp = ffp->geneNames; vnp != NULL; vnp = vnp->next) {
858 count++;
859 }
860 if (count < 32) {
861 usePopupForGene = TRUE;
862 ffp->gene = ffp->genePopup;
863 } else {
864 usePopupForGene = FALSE;
865 ffp->gene = ffp->geneList;
866 }
867 for (vnp = ffp->geneNames; vnp != NULL; vnp = vnp->next) {
868 str = (CharPtr) vnp->data.ptrvalue;
869 if (StringHasNoText (str)) {
870 str = "??";
871 }
872 if (usePopupForGene) {
873 PopupItem (ffp->gene, str);
874 } else {
875 ListItem (ffp->gene, str);
876 }
877 }
878 Show (ffp->gene);
879 }
880 }
881
882 static Boolean GeneMatchFunc (GatherContextPtr gcp)
883
884 {
885 Int4 diff;
886 FeatureFormPtr ffp;
887 GeneRefPtr genexref;
888 GeneGatherPtr ggp;
889 GeneRefPtr grp;
890 ObjMgrTypePtr omtp;
891 SeqFeatPtr sfp;
892 Uint1 strand1, strand2;
893 Char thislabel [41];
894
895 if (gcp == NULL) return TRUE;
896
897 ggp = (GeneGatherPtr) gcp->userdata;
898 if (ggp == NULL || ggp->ffp == NULL) return TRUE;
899
900 thislabel [0] = '\0';
901
902 if (gcp->thistype == OBJ_SEQFEAT) {
903 sfp = (SeqFeatPtr) gcp->thisitem;
904 if (sfp != NULL && sfp->data.choice == SEQFEAT_GENE && sfp->data.value.ptrvalue != NULL) {
905 omtp = ObjMgrTypeFind (ggp->omp, gcp->thistype, NULL, NULL);
906 if (omtp == NULL) {
907 return TRUE;
908 }
909 if (omtp->labelfunc != NULL) {
910 (*(omtp->labelfunc)) (gcp->thisitem, thislabel, 40, OM_LABEL_CONTENT);
911 }
912 if (thislabel [0] != '\0') {
913 ffp = (FeatureFormPtr) ggp->ffp;
914 ggp->idx++;
915 genexref = ggp->genexref;
916 if (genexref != NULL) {
917 grp = (GeneRefPtr) sfp->data.value.ptrvalue;
918 if (! StringHasNoText (genexref->locus)) {
919 if (StringICmp (genexref->locus, grp->locus) == 0) {
920 ggp->val = ggp->idx;
921 ggp->xrefmatch = TRUE;
922 if (ffp != NULL) {
923 SetValue (ffp->useGeneXref, 2);
924 }
925 }
926 } else if (! StringHasNoText (genexref->locus_tag)) {
927 if (StringICmp (genexref->locus_tag, grp->locus_tag) == 0) {
928 ggp->val = ggp->idx;
929 ggp->xrefmatch = TRUE;
930 if (ffp != NULL) {
931 SetValue (ffp->useGeneXref, 2);
932 }
933 }
934 } else if (! StringHasNoText (genexref->desc)) {
935 if (StringICmp (genexref->desc, grp->desc) == 0) {
936 ggp->val = ggp->idx;
937 ggp->xrefmatch = TRUE;
938 if (ffp != NULL) {
939 SetValue (ffp->useGeneXref, 2);
940 }
941 }
942 }
943 }
944 diff = SeqLocAinB (ggp->slp, sfp->location);
945 if (diff >= 0) {
946 if (diff < ggp->min) {
947 strand1 = SeqLocStrand (ggp->slp);
948 strand2 = SeqLocStrand (sfp->location);
949 if (DlgStrandsMatch (strand1, strand2)) {
950 ggp->min = diff;
951 if (! ggp->xrefmatch) {
952 ggp->val = ggp->idx;
953 }
954 }
955 }
956 }
957 }
958 }
959 }
960
961 return TRUE;
962 }
963
964 static void SaveGoTermsInSfp (UserObjectPtr uop, Pointer userdata)
965
966 {
967 FeatureFormPtr ffp;
968 ObjectIdPtr oip;
969
970 if (uop == NULL || userdata == NULL) return;
971 oip = uop->type;
972 if (oip == NULL) return;
973 if (StringCmp (oip->str, "GeneOntology") == 0) {
974 ffp = (FeatureFormPtr) userdata;
975 ffp->goTermUserObj = AsnIoMemCopy (uop, (AsnReadFunc) UserObjectAsnRead,
976 (AsnWriteFunc) UserObjectAsnWrite);
977 }
978 }
979
980 static void FeatIDtoText (TexT t, ChoicePtr cp)
981
982 {
983 Char buf [32];
984 ObjectIdPtr oip;
985
986 if (t == NULL) return;
987 if (cp == NULL) {
988 SetTitle (t, "");
989 return;
990 }
991
992 if (cp->choice == 3) {
993 oip = (ObjectIdPtr) cp->value.ptrvalue;
994 if (oip != NULL) {
995 if (StringDoesHaveText (oip->str)) {
996 SetTitle (t, oip->str);
997 return;
998 } else {
999 sprintf (buf, "%ld", (long) oip->id);
1000 SetTitle (t, buf);
1001 return;
1002 }
1003 }
1004 }
1005
1006 SetTitle (t, "");
1007 }
1008
1009 static void TextToFeatID (TexT t, ChoicePtr cp)
1010
1011 {
1012 Boolean all_digits = TRUE;
1013 Char buf [128];
1014 Char ch;
1015 ObjectIdPtr oip;
1016 CharPtr str;
1017 long int val;
1018
1019 if (t == NULL || cp == NULL) return;
1020
1021 GetTitle (t, buf, sizeof (buf) - 1);
1022 if (StringHasNoText (buf)) {
1023 SeqFeatIdFree (cp);
1024 cp->choice = 0;
1025 return;
1026 }
1027
1028 oip = ObjectIdNew ();
1029 if (oip == NULL) return;
1030
1031 str = buf;
1032 ch = *str;
1033 while (ch != '\0') {
1034 if (! IS_DIGIT (ch)) {
1035 all_digits = FALSE;
1036 }
1037 str++;
1038 ch = *str;
1039 }
1040
1041 if (all_digits && sscanf (buf, "%ld", &val) == 1) {
1042 oip->id = (Int4) val;
1043 } else {
1044 oip->str = StringSave (buf);
1045 }
1046 SeqFeatIdFree (cp);
1047 cp->choice = 3;
1048 cp->value.ptrvalue = (Pointer) oip;
1049 }
1050
1051 static void FeatXreftoText (TexT t, SeqFeatPtr sfp)
1052
1053 {
1054 Char buf [32];
1055 ObjectIdPtr oip;
1056 SeqFeatXrefPtr xref;
1057
1058 if (t == NULL) return;
1059 if (sfp == NULL) {
1060 SetTitle (t, "");
1061 return;
1062 }
1063
1064 for (xref = sfp->xref; xref != NULL; xref = xref->next) {
1065 if (xref->id.choice != 3) continue;
1066 oip = (ObjectIdPtr) xref->id.value.ptrvalue;
1067 if (oip != NULL) {
1068 if (StringDoesHaveText (oip->str)) {
1069 SetTitle (t, oip->str);
1070 return;
1071 } else {
1072 sprintf (buf, "%ld", (long) oip->id);
1073 SetTitle (t, buf);
1074 return;
1075 }
1076 }
1077 }
1078
1079 SetTitle (t, "");
1080 }
1081
1082 static void TextToFeatXref (TexT t, SeqFeatPtr sfp)
1083
1084 {
1085 Boolean all_digits = TRUE;
1086 Char buf [128];
1087 Char ch;
1088 ObjectIdPtr oip;
1089 CharPtr str;
1090 long int val;
1091 SeqFeatXrefPtr xref;
1092
1093 if (t == NULL || sfp == NULL) return;
1094
1095 GetTitle (t, buf, sizeof (buf) - 1);
1096 if (StringHasNoText (buf)) {
1097 ClearFeatIDXrefs (sfp);
1098 return;
1099 }
1100
1101 ClearFeatIDXrefs (sfp);
1102
1103 oip = ObjectIdNew ();
1104 if (oip == NULL) return;
1105
1106 str = buf;
1107 ch = *str;
1108 while (ch != '\0') {
1109 if (! IS_DIGIT (ch)) {
1110 all_digits = FALSE;
1111 }
1112 str++;
1113 ch = *str;
1114 }
1115
1116 if (all_digits && sscanf (buf, "%ld", &val) == 1) {
1117 oip->id = (Int4) val;
1118 } else {
1119 oip->str = StringSave (buf);
1120 }
1121
1122 xref = SeqFeatXrefNew ();
1123 if (xref != NULL) {
1124 xref->id.choice = 3;
1125 xref->id.value.ptrvalue = (Pointer) oip;
1126 xref->next = sfp->xref;
1127 sfp->xref = xref;
1128 }
1129 }
1130
1131 static void GbqualsToVisStringDialog (SeqFeatPtr sfp, DialoG d, CharPtr qual)
1132
1133 {
1134 GBQualPtr gbq;
1135 ValNodePtr head = NULL;
1136
1137 if (sfp == NULL || StringHasNoText (qual)) {
1138 PointerToDialog (d, NULL);
1139 return;
1140 }
1141 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
1142 if (StringICmp (gbq->qual, qual) != 0) continue;
1143 ValNodeCopyStr (&head, 0, gbq->val);
1144 }
1145 PointerToDialog (d, head);
1146 ValNodeFreeData (head);
1147 }
1148
1149 extern void VisStringDialogToGbquals (SeqFeatPtr sfp, DialoG d, CharPtr qual);
1150 extern void VisStringDialogToGbquals (SeqFeatPtr sfp, DialoG d, CharPtr qual)
1151
1152 {
1153 GBQualPtr gbq, gbqlast = NULL;
1154 ValNodePtr head = NULL, vnp;
1155 CharPtr str;
1156
1157 if (sfp == NULL || StringHasNoText (qual)) return;
1158 head = DialogToPointer (d);
1159 for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
1160 gbqlast = gbq;
1161 }
1162 for (vnp = head; vnp != NULL; vnp = vnp->next) {
1163 str = (CharPtr) vnp->data.ptrvalue;
1164 if (StringHasNoText (str)) continue;
1165 gbq = GBQualNew ();
1166 if (gbq == NULL) continue;
1167 gbq->qual = StringSave (qual);
1168 gbq->val = StringSave (str);
1169 if (gbqlast == NULL) {
1170 sfp->qual = gbq;
1171 } else {
1172 gbqlast->next = gbq;
1173 }
1174 gbqlast = gbq;
1175 }
1176 ValNodeFreeData (head);
1177 }
1178
1179 extern void SeqFeatPtrToFieldPage (DialoG d, SeqFeatPtr sfp);
1180
1181 extern void SeqFeatPtrToCommon (FeatureFormPtr ffp, SeqFeatPtr sfp)
1182
1183 {
1184 GeneGatherList ggl;
1185 GeneRefPtr grp;
1186 GatherScope gs;
1187 ProtRefPtr prp;
1188 CharPtr str;
1189 ValNodePtr vnp;
1190 SeqFeatXrefPtr xref;
1191 /*
1192 Char ch;
1193 CharPtr ptr;
1194 */
1195
1196 if (ffp != NULL) {
1197 if (sfp != NULL) {
1198 str = StringSave (sfp->comment);
1199 /*
1200 ptr = str;
1201 if (ptr != NULL) {
1202 ch = *ptr;
1203 while (ch != '\0') {
1204 if (ch == '~') {
1205 #ifdef WIN_MAC
1206 *ptr = '\015';
1207 #else
1208 *ptr = '\n';
1209 #endif
1210 }
1211 ptr++;
1212 ch = *ptr;
1213 }
1214 }
1215 */
1216 SetTitle (ffp->comment, str);
1217 SetTitle (ffp->title, sfp->title);
1218 SetValue (ffp->evidence, sfp->exp_ev + 1);
1219 if (GetAppProperty ("InternalNcbiSequin") == NULL) {
1220 if (sfp->exp_ev == 0) {
1221 SafeDisable (ffp->evidence);
1222 }
1223 }
1224 SetStatus (ffp->partial, sfp->partial);
1225 SetStatus (ffp->exception, sfp->excpt);
1226 SetStatus (ffp->pseudo, sfp->pseudo);
1227 SetTitle (ffp->exceptText, sfp->except_text);
1228 SetValue (ffp->useGeneXref, 1);
1229 SetTitle (ffp->geneSymbol, "");
1230 SetTitle (ffp->geneAllele, "");
1231 SetTitle (ffp->geneDesc, "");
1232 SetTitle (ffp->locusTag, "");
1233 SetTitle (ffp->geneSynonym, "");
1234 ggl.ffp = ffp;
1235 ggl.omp = ObjMgrGet ();
1236 ggl.slp = sfp->location;
1237 ggl.genexref = NULL;
1238 grp = NULL;
1239 xref = sfp->xref;
1240 while (xref != NULL && xref->data.choice != SEQFEAT_PROT) {
1241 xref = xref->next;
1242 }
1243 if (xref != NULL) {
1244 prp = (ProtRefPtr) xref->data.value.ptrvalue;
1245 if (prp != NULL && ffp->protXrefName != NULL) {
1246 vnp = prp->name;
1247 if (vnp != NULL) {
1248 SetTitle (ffp->protXrefName, (CharPtr) vnp->data.ptrvalue);
1249 }
1250 }
1251 if (prp != NULL && StringDoesHaveText (prp->desc)) {
1252 SetTitle (ffp->protXrefDesc, prp->desc);
1253 }
1254 }
1255 xref = sfp->xref;
1256 while (xref != NULL && xref->data.choice != SEQFEAT_GENE) {
1257 xref = xref->next;
1258 }
1259 if (xref != NULL) {
1260 grp = (GeneRefPtr) xref->data.value.ptrvalue;
1261 ggl.genexref = grp;
1262 }
1263 ggl.xrefmatch = FALSE;
1264 ggl.idx = 2;
1265 ggl.val = 1;
1266 ggl.min = INT4_MAX;
1267 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
1268 gs.seglevels = 1;
1269 gs.get_feats_location = TRUE;
1270 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
1271 gs.ignore[OBJ_BIOSEQ] = FALSE;
1272 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
1273 gs.ignore[OBJ_SEQFEAT] = FALSE;
1274 gs.ignore[OBJ_SEQANNOT] = FALSE;
1275 gs.scope = GetBestTopParentForItemID (ffp->input_entityID,
1276 ffp->input_itemID,
1277 ffp->input_itemtype);
1278 GatherEntity (ffp->input_entityID, (Pointer) &ggl, GeneMatchFunc, &gs);
1279 if (grp != NULL && StringHasNoText (grp->locus) && StringHasNoText (grp->allele) &&
1280 StringHasNoText (grp->desc) && StringHasNoText (grp->maploc) &&
1281 grp->db == NULL && grp->syn == NULL && grp->locus_tag == NULL) {
1282 SetValue (ffp->gene, 1);
1283 SetValue (ffp->useGeneXref, 3);
1284 SetTitle (ffp->geneSymbol, grp->locus);
1285 SetTitle (ffp->geneAllele, grp->allele);
1286 SetTitle (ffp->geneDesc, grp->desc);
1287 SetTitle (ffp->locusTag, grp->locus_tag);
1288 if (grp->syn == NULL) {
1289 SetTitle (ffp->geneSynonym, "");
1290 } else {
1291 SetTitle (ffp->geneSynonym, grp->syn->data.ptrvalue);
1292 }
1293 SafeHide (ffp->editGeneBtn);
1294 SafeHide (ffp->newGeneGrp);
1295 } else if (ggl.val == 1 && grp != NULL && (! ggl.xrefmatch)) {
1296 SetValue (ffp->gene, 2);
1297 SetValue (ffp->useGeneXref, 2);
1298 SetTitle (ffp->geneSymbol, grp->locus);
1299 SetTitle (ffp->geneAllele, grp->allele);
1300 SetTitle (ffp->geneDesc, grp->desc);
1301 SetTitle (ffp->locusTag, grp->locus_tag);
1302 if (grp->syn == NULL) {
1303 SetTitle (ffp->geneSynonym, "");
1304 } else {
1305 SetTitle (ffp->geneSynonym, grp->syn->data.ptrvalue);
1306 }
1307 SafeHide (ffp->editGeneBtn);
1308 SafeShow (ffp->newGeneGrp);
1309 } else if (grp != NULL && (! ggl.xrefmatch)) {
1310 SetValue (ffp->gene, 2);
1311 SetValue (ffp->useGeneXref, 2);
1312 SetTitle (ffp->geneSymbol, grp->locus);
1313 SetTitle (ffp->geneAllele, grp->allele);
1314 SetTitle (ffp->geneDesc, grp->desc);
1315 SetTitle (ffp->locusTag, grp->locus_tag);
1316 if (grp->syn == NULL) {
1317 SetTitle (ffp->geneSynonym, "");
1318 } else {
1319 SetTitle (ffp->geneSynonym, grp->syn->data.ptrvalue);
1320 }
1321 SafeHide (ffp->editGeneBtn);
1322 SafeShow (ffp->newGeneGrp);
1323 } else if (ggl.val > 2) {
1324 SetValue (ffp->gene, ggl.val);
1325 SafeShow (ffp->editGeneBtn);
1326 if (ffp->gene == ffp->geneList) {
1327 SetOffset (ffp->gene, 0, (Int2) (ggl.val - 1));
1328 }
1329 if (grp != NULL && (! ggl.xrefmatch)) {
1330 SetValue (ffp->useGeneXref, 2);
1331 }
1332 } else {
1333 SetValue (ffp->gene, ggl.val);
1334 }
1335 PointerToDialog (ffp->featcits, sfp->cit);
1336 PointerToDialog (ffp->dbxrefs, sfp->dbxref);
1337 PointerToDialog (ffp->gbquals, sfp->qual);
1338 SeqFeatPtrToFieldPage (ffp->gbquals, sfp);
1339 GbqualsToVisStringDialog (sfp, ffp->experiment, "experiment");
1340 GBQualsToInferenceDialog (ffp->inference, sfp);
1341 PointerToDialog (ffp->usrobjext, sfp->ext);
1342 VisitUserObjectsInUop (sfp->ext, (Pointer) ffp, SaveGoTermsInSfp);
1343 FeatIDtoText (ffp->featid, &(sfp->id));
1344 FeatXreftoText (ffp->fidxref, sfp);
1345 } else {
1346 SetTitle (ffp->comment, "");
1347 SetValue (ffp->evidence, 1);
1348 if (GetAppProperty ("InternalNcbiSequin") == NULL) {
1349 SafeDisable (ffp->evidence);
1350 }
1351 SetStatus (ffp->partial, FALSE);
1352 SetStatus (ffp->exception, FALSE);
1353 SetStatus (ffp->pseudo, FALSE);
1354 SetTitle (ffp->exceptText, "");
1355 SetValue (ffp->gene, 1);
1356 SafeHide (ffp->newGeneGrp);
1357 SafeHide (ffp->editGeneBtn);
1358 SetValue (ffp->useGeneXref, 1);
1359 SetTitle (ffp->geneSymbol, "");
1360 SetTitle (ffp->geneAllele, "");
1361 SetTitle (ffp->geneDesc, "");
1362 SetTitle (ffp->locusTag, "");
1363 SetTitle (ffp->geneSynonym, "");
1364 PointerToDialog (ffp->featcits, NULL);
1365 PointerToDialog (ffp->dbxrefs, NULL);
1366 PointerToDialog (ffp->gbquals, NULL);
1367 PointerToDialog (ffp->experiment, NULL);
1368 GBQualsToInferenceDialog (ffp->inference, NULL);
1369 PointerToDialog (ffp->usrobjext, NULL);
1370 ffp->goTermUserObj = NULL;
1371 FeatIDtoText (ffp->featid, NULL);
1372 FeatXreftoText (ffp->fidxref, NULL);
1373 }
1374 }
1375 }
1376
1377 extern void CleanupEvidenceGBQuals (GBQualPtr PNTR prevgbq)
1378
1379 {
1380 GBQualPtr gbq;
1381 GBQualPtr next;
1382 Boolean unlink;
1383
1384 if (prevgbq == NULL) return;
1385 gbq = *prevgbq;
1386 while (gbq != NULL) {
1387 next = gbq->next;
1388 unlink = FALSE;
1389 if (StringICmp (gbq->qual, "experiment") == 0 || StringICmp (gbq->qual, "inference") == 0) {
1390 unlink = TRUE;
1391 }
1392 if (unlink) {
1393 *prevgbq = gbq->next;
1394 gbq->next = NULL;
1395 GBQualFree (gbq);
1396 } else {
1397 prevgbq = (GBQualPtr PNTR) &(gbq->next);
1398 }
1399 gbq = next;
1400 }
1401 }
1402
1403 static UserObjectPtr CombineGOTermUserObjects (UserObjectPtr origuop, UserObjectPtr newuop)
1404
1405 {
1406 ObjectIdPtr oip;
1407
1408 if (newuop == NULL) return origuop;
1409 if (origuop == NULL) return newuop;
1410
1411 oip = origuop->type;
1412 if (oip != NULL && StringCmp (oip->str, "GeneOntology") == 0) return origuop;
1413
1414 return CombineUserObjects (origuop, newuop);
1415 }
1416
1417 typedef struct replacesdata {
1418 FeatureFormPtr ffp;
1419 SeqFeatPtr sfp;
1420 } ReplaceData, PNTR ReplaceDataPtr;
1421
1422 static Boolean ReplaceFeatureExtras (GatherContextPtr gcp)
1423
1424 {
1425 SeqFeatXrefPtr curr;
1426 FeatureFormPtr ffp;
1427 SeqFeatXrefPtr PNTR last;
1428 SeqFeatXrefPtr next;
1429 SeqFeatPtr old;
1430 ReplaceDataPtr rdp;
1431 SeqFeatPtr sfp;
1432
1433 rdp = (ReplaceDataPtr) gcp->userdata;
1434 if (rdp != NULL && rdp->sfp != NULL && rdp->ffp != NULL) {
1435 sfp = rdp->sfp;
1436 ffp = rdp->ffp;
1437 old = gcp->thisitem;
1438 if (old != NULL) {
1439 if (ffp->gbquals != NULL) {
1440 sfp->qual = DialogToPointer (ffp->gbquals);
1441 } else if (sfp->qual == NULL) {
1442 sfp->qual = old->qual;
1443 old->qual = NULL;
1444 }
1445 CleanupEvidenceGBQuals (&(sfp->qual));
1446 VisStringDialogToGbquals (sfp, ffp->experiment, "experiment");
1447 InferenceDialogToGBQuals (ffp->inference, sfp, TRUE);
1448 if (ffp->usrobjext != NULL) {
1449 sfp->ext = DialogToPointer (ffp->usrobjext);
1450 } else if (sfp->ext == NULL) {
1451 sfp->ext = old->ext;
1452 old->ext = NULL;
1453 }
1454 if (ffp->goTermUserObj != NULL) {
1455 sfp->ext = CombineGOTermUserObjects (sfp->ext, ffp->goTermUserObj);
1456 }
1457 if (ffp->featid != NULL) {
1458 TextToFeatID (ffp->featid, &(sfp->id));
1459 }
1460 /*
1461 if (sfp->cit == NULL) {
1462 sfp->cit = old->cit;
1463 old->cit = NULL;
1464 }
1465 */
1466 if (old->xref != NULL) {
1467 last = (SeqFeatXrefPtr PNTR) &(old->xref);
1468 curr = old->xref;
1469 while (curr != NULL) {
1470 next = curr->next;
1471 if (curr->data.choice == SEQFEAT_GENE) {
1472 *last = next;
1473 curr->next = NULL;
1474 SeqFeatXrefFree (curr);
1475 } else {
1476 last = &(curr->next);
1477 }
1478 curr = next;
1479 }
1480 }
1481 if (sfp->xref == NULL) {
1482 sfp->xref = old->xref;
1483 } else {
1484 curr = sfp->xref;
1485 while (curr->next != NULL) {
1486 curr = curr->next;
1487 }
1488 if (curr != NULL) {
1489 curr->next = old->xref;
1490 }
1491 }
1492 old->xref = NULL;
1493 }
1494 }
1495 return TRUE;
1496 }
1497
1498 static Boolean GetOldFeatureLocation (GatherContextPtr gcp)
1499 {
1500 SeqLocPtr PNTR old_loc;
1501 SeqFeatPtr old_feat;
1502
1503 if (gcp == NULL || gcp->userdata == NULL)
1504 {
1505 return FALSE;
1506 }
1507 old_loc = (SeqLocPtr PNTR) gcp->userdata;
1508 if (*old_loc != NULL)
1509 {
1510 return TRUE;
1511 }
1512 old_feat = gcp->thisitem;
1513 if (old_feat != NULL)
1514 {
1515 *old_loc = (SeqLocPtr) AsnIoMemCopy (old_feat->location,
1516 (AsnReadFunc) SeqLocAsnRead,
1517 (AsnWriteFunc) SeqLocAsnWrite);
1518 }
1519 return TRUE;
1520 }
1521
1522 static Boolean HasExceptionGBQual (SeqFeatPtr sfp)
1523
1524 {
1525 GBQualPtr qual;
1526 Boolean rsult;
1527
1528 rsult = FALSE;
1529 if (sfp != NULL) {
1530 qual = sfp->qual;
1531 while (qual != NULL) {
1532 if (StringICmp (qual->qual, "exception") == 0) {
1533 if (! StringHasNoText (qual->val)) {
1534 rsult = TRUE;
1535 }
1536 }
1537 qual = qual->next;
1538 }
1539 }
1540 return rsult;
1541 }
1542
1543 static void AddProtRefXref (SeqFeatPtr sfp, TexT protXrefName, TexT protXrefDesc)
1544
1545 {
1546 Char desc [256];
1547 Char name [256];
1548 ProtRefPtr prp;
1549 SeqFeatXrefPtr xref;
1550
1551 if (sfp == NULL) return;
1552 if (protXrefName == NULL && protXrefDesc == NULL) return;
1553 GetTitle (protXrefName, name, sizeof (name) - 1);
1554 GetTitle (protXrefDesc, desc, sizeof (desc) - 1);
1555 if (StringHasNoText (name) && StringHasNoText (desc)) return;
1556 for (xref = sfp->xref; xref != NULL; xref = xref->next) {
1557 if (xref->data.choice == SEQFEAT_PROT) break;
1558 }
1559 if (xref == NULL) {
1560 xref = SeqFeatXrefNew ();
1561 if (xref != NULL) {
1562 prp = ProtRefNew ();
1563 xref->data.choice = SEQFEAT_PROT;
1564 xref->data.value.ptrvalue = (Pointer) prp;
1565 xref->next = sfp->xref;
1566 sfp->xref = xref;
1567 }
1568 }
1569 if (xref != NULL && xref->data.choice == SEQFEAT_PROT) {
1570 prp = (ProtRefPtr) xref->data.value.ptrvalue;
1571 xref->data.value.ptrvalue = ProtRefFree (prp);
1572 prp = CreateNewProtRef (name, desc, NULL, NULL);
1573 xref->data.value.ptrvalue = (Pointer) prp;
1574 }
1575 }
1576
1577 static Boolean FeatIsPseudo (SeqFeatPtr sfp)
1578 {
1579 Boolean pseudo = FALSE;
1580 GBQualPtr qual;
1581
1582 if (sfp != NULL)
1583 {
1584 if (sfp->pseudo)
1585 {
1586 pseudo = TRUE;
1587 }
1588 else
1589 {
1590 qual = sfp->qual;
1591 while (qual != NULL)
1592 {
1593 if (StringICmp (qual->qual, "pseudo") == 0)
1594 {
1595 pseudo = TRUE;
1596 }
1597 qual = qual->next;
1598 }
1599 }
1600 }
1601 return pseudo;
1602 }
1603
1604 static void RemoveProtXrefs (SeqFeatPtr sfp)
1605 {
1606 SeqFeatXrefPtr xref_prev = NULL, xref_next, xref;
1607
1608 if (sfp == NULL || sfp->xref == NULL) return;
1609
1610 for (xref = sfp->xref; xref != NULL; xref = xref_next)
1611 {
1612 xref_next = xref->next;
1613 if (xref->data.choice == SEQFEAT_PROT)
1614 {
1615 if (xref_prev == NULL)
1616 {
1617 sfp->xref = xref->next;
1618 }
1619 else
1620 {
1621 xref_prev->next = xref->next;
1622 }
1623 xref->next = NULL;
1624 xref->data.value.ptrvalue = ProtRefFree (xref->data.value.ptrvalue);
1625 SeqFeatXrefFree (xref);
1626 }
1627 else
1628 {
1629 xref_prev = xref;
1630 }
1631 }
1632 }
1633
1634 static CharPtr infDetails [] = {
1635 "unknown error",
1636 "empty inference string",
1637 "bad inference prefix",
1638 "bad inference body",
1639 "single inference field",
1640 "spaces in inference",
1641 "same species misused",
1642 "bad inference accession",
1643 "accession is missing version",
1644 "accession.version not public",
1645 NULL
1646 };
1647
1648 extern Boolean TestInference (FeatureFormPtr ffp, CharPtr badInfQual, size_t len, CharPtr badInfMssg)
1649
1650 {
1651 GBQualPtr gbq;
1652 Int2 inferenceCode;
1653 Boolean rsult = TRUE;
1654 CharPtr str;
1655 SeqFeatPtr tmp;
1656
1657 if (ffp == NULL) return FALSE;
1658 tmp = SeqFeatNew ();
1659 if (tmp == NULL) return FALSE;
1660 if (badInfQual != NULL) {
1661 *badInfQual = '\0';
1662 }
1663 if (badInfMssg != NULL) {
1664 *badInfMssg = '\0';
1665 }
1666 InferenceDialogToGBQuals (ffp->inference, tmp, FALSE);
1667 for (gbq = tmp->qual; gbq != NULL; gbq = gbq->next) {
1668 str = gbq->val;
1669 if (StringICmp (gbq->qual, "inference") != 0) continue;
1670 inferenceCode = ValidateInferenceQualifier (str, FALSE);
1671 if (inferenceCode != VALID_INFERENCE) {
1672 if (inferenceCode < VALID_INFERENCE || inferenceCode > ACC_VERSION_NOT_PUBLIC) {
1673 inferenceCode = VALID_INFERENCE;
1674 }
1675 if (badInfQual != NULL) {
1676 StringNCpy_0 (badInfQual, str, len);
1677 }
1678 if (badInfMssg != NULL) {
1679 StringCpy (badInfMssg, infDetails [(int) inferenceCode]);
1680 }
1681 rsult = FALSE;
1682 break;
1683 }
1684 }
1685 SeqFeatFree (tmp);
1686 return rsult;
1687 }
1688
1689 static CharPtr infWarning1 =
1690 "Bad inference qualifier! You must conform to international nucleotide sequence database\nconventions for inference qualifiers!";
1691
1692 static CharPtr infWarning2 =
1693 "Still has bad inference! You must conform to international nucleotide sequence database\nconventions for inference qualifiers!";
1694
1695 static CharPtr infAccept =
1696 "Do you want to accept changes with bad inference data? The bad qualifier will be converted to a note!";
1697
1698 extern Boolean FeatFormReplaceWithoutUpdateProc (ForM f)
1699
1700 {
1701 Char allele [128];
1702 MsgAnswer ans;
1703 Int2 attempts = 3;
1704 Char badInfMssg [32];
1705 Char badInfQual [256];
1706 BioseqPtr bsp;
1707 Char desc [128];
1708 Int2 expev;
1709 SeqMgrFeatContext fcontext;
1710 FeatureFormPtr ffp;
1711 SeqFeatPtr gene;
1712 GeneGatherList ggl;
1713 GeneRefPtr grp;
1714 GeneRefPtr grpfeat;
1715 GatherScope gs;
1716 SeqLocPtr gslp;
1717 Boolean hasNulls;
1718 Int2 i;
1719 Int4Ptr intptr;
1720 Uint4 itemID;
1721 Char locustag [128];
1722 Boolean noLeft;
1723 Boolean noRight;
1724 SeqEntryPtr oldscope;
1725 OMProcControl ompc;
1726 ReplaceData rd;
1727 Boolean rsult;
1728 SeqAnnotPtr sap;
1729 SeqEntryPtr sep;
1730 SeqFeatPtr sfp;
1731 SeqLocPtr slp;
1732 CharPtr str;
1733 Char symbol [128];
1734 Int2 usexref;
1735 Int2 val;
1736 ValNodePtr vnp, err_list;
1737 SeqFeatXrefPtr xref;
1738 SeqLocPtr old_location = NULL; /* we need the old location of the feature
1739 * if we're going to do a gene update
1740 */
1741 Boolean fix_interval_order;
1742
1743 rsult = FALSE;
1744 ffp = (FeatureFormPtr) GetObjectExtra (f);
1745 if (ffp != NULL) {
1746 MemSet ((Pointer) &ompc, 0, sizeof (OMProcControl));
1747 ompc.input_entityID = ffp->input_entityID;
1748 ompc.input_itemID = ffp->input_itemID;
1749 ompc.input_itemtype = ffp->input_itemtype;
1750 ompc.output_itemtype = ffp->input_itemtype;
1751 sfp = SeqFeatNew ();
1752 if (sfp != NULL) {
1753 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
1754 oldscope = SeqEntrySetScope (sep);
1755 sfp->data.choice = FindFeatFromFeatDefType (ffp->this_subtype);
1756 switch (sfp->data.choice) {
1757 case SEQFEAT_BOND :
1758 case SEQFEAT_SITE :
1759 case SEQFEAT_PSEC_STR :
1760 intptr = (Int4Ptr) DialogToPointer (ffp->data);
1761 if (intptr != NULL) {
1762 sfp->data.value.intvalue = *intptr;
1763 }
1764 break;
1765 case SEQFEAT_COMMENT:
1766 sfp->data.value.ptrvalue = NULL;
1767 break;
1768 default :
1769 sfp->data.value.ptrvalue = DialogToPointer (ffp->data);
1770 break;
1771 }
1772 sfp->comment = SaveStringFromText (ffp->comment);
1773 NewlinesToTildes (sfp->comment);
1774 expev = GetValue (ffp->evidence);
1775 if (expev > 0 && expev <= 3) {
1776 sfp->exp_ev = expev - 1;
1777 } else {
1778 sfp->exp_ev = 0;
1779 }
1780 sfp->partial = GetStatus (ffp->partial);
1781 sfp->excpt = GetStatus (ffp->exception);
1782 sfp->pseudo = GetStatus (ffp->pseudo);
1783 sfp->except_text = SaveStringFromText (ffp->exceptText);
1784 sfp->title = NULL;
1785 sfp->product = DialogToPointer (ffp->product);
1786 sfp->location = DialogToPointer (ffp->location);
1787 if (sfp->location == NULL) {
1788 SeqEntrySetScope (oldscope);
1789 ErrPostEx (SEV_ERROR, 0, 0, "Feature must have a location!");
1790 err_list = TestDialog (ffp->location);
1791 DisplayErrorMessages ("Location Errors", err_list);
1792 err_list = ValNodeFree (err_list);
1793 return FALSE;
1794 }
1795 if ((! ffp->acceptBadInf) && (! TestInference (ffp, badInfQual, sizeof (badInfQual), badInfMssg))) {
1796 (ffp->badInfAttempts)++;
1797 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
1798 attempts = 2;
1799 }
1800 if (ffp->badInfAttempts < attempts) {
1801 if (ffp->badInfAttempts == 2) {
1802 Message (MSG_OK, "%s - Please fix the %s error in\n%s", infWarning2, badInfMssg, badInfQual);
1803 } else {
1804 Message (MSG_OK, "%s - Please fix the %s error in\n%s", infWarning1, badInfMssg, badInfQual);
1805 }
1806 return FALSE;
1807 } else {
1808 if (Message (MSG_YN, "%s", infAccept) == ANS_NO) return FALSE;
1809 ffp->acceptBadInf = TRUE;
1810 }
1811 }
1812 bsp = GetBioseqGivenSeqLoc (sfp->location, ffp->input_entityID);
1813 if (bsp != NULL) {
1814 if (SeqLocBadSortOrder (bsp, sfp->location)) {
1815 fix_interval_order = FALSE;
1816 if (StringICmp (sfp->except_text, "trans-splicing") == 0)
1817 {
1818 ans = Message (MSG_YN, "Your feature intervals are out of order, but this coding region has a trans-splicing exception. Continue without correcting interval order?");
1819 if (ans == ANS_NO)
1820 {
1821 fix_interval_order = TRUE;
1822 }
1823 }
1824 else
1825 {
1826 ans = Message (MSG_YN,
1827 "Feature location intervals are out of order. Do you want them repaired?");
1828 if (ans == ANS_YES)
1829 {
1830 fix_interval_order = TRUE;
1831 }
1832 }
1833 if (fix_interval_order) {
1834 hasNulls = LocationHasNullsBetween (sfp->location);
1835 gslp = SeqLocMerge (bsp, sfp->location, NULL, FALSE, FALSE, hasNulls);
1836 if (gslp != NULL) {
1837 CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
1838 sfp->location = SeqLocFree (sfp->location);
1839 sfp->location = gslp;
1840 if (bsp->repr == Seq_repr_seg) {
1841 gslp = SegLocToParts (bsp, sfp->location);
1842 sfp->location = SeqLocFree (sfp->location);
1843 sfp->location = gslp;
1844 }
1845 FreeAllFuzz (sfp->location);
1846 SetSeqLocPartial (sfp->location, noLeft, noRight);
1847 }
1848 }
1849 }
1850 }
1851 if (CheckSeqLocForPartial (sfp->location, NULL, NULL)) {
1852 sfp->partial = TRUE;
1853 }
1854 sfp->cit = DialogToPointer (ffp->featcits);
1855 sfp->dbxref = DialogToPointer (ffp->dbxrefs);
1856 slp = AsnIoMemCopy (sfp->location, (AsnReadFunc) SeqLocAsnRead,
1857 (AsnWriteFunc) SeqLocAsnWrite);
1858 usexref = GetValue (ffp->useGeneXref);
1859 if (ffp->gene != NULL) {
1860 val = GetValue (ffp->gene);
1861 if (usexref == 3 || (val > 1 && usexref == 2)) {
1862 grp = NULL;
1863 if (usexref == 3) {
1864 grp = GeneRefNew ();
1865 } else if (val == 2) {
1866 GetTitle (ffp->geneSymbol, symbol, sizeof (symbol));
1867 GetTitle (ffp->geneAllele, allele, sizeof (allele));
1868 GetTitle (ffp->geneDesc, desc, sizeof (desc));
1869 GetTitle (ffp->locusTag, locustag, sizeof (locustag));
1870 grp = CreateNewGeneRef (symbol, allele, desc, FALSE);
1871 if (! StringHasNoText (locustag)) {
1872 if (grp == NULL) {
1873 grp = GeneRefNew ();
1874 }
1875 grp->locus_tag = StringSave (locustag);
1876 }
1877 if (!TextHasNoText (ffp->geneSynonym)) {
1878 if (grp == NULL) {
1879 grp = GeneRefNew ();
1880 }
1881 ValNodeAddPointer (&(grp->syn), 0, SaveStringFromText (ffp->geneSynonym));
1882 }
1883 } else {
1884 vnp = ffp->geneNames;
1885 i = val - 3;
1886 while (i > 0 && vnp != NULL) {
1887 vnp = vnp->next;
1888 i--;
1889 }
1890 if (vnp != NULL) {
1891 if (vnp->choice == 1) {
1892 str = (CharPtr) vnp->data.ptrvalue;
1893 if (StringDoesHaveText (str)) {
1894 grp = CreateNewGeneRef (str, NULL, NULL, FALSE);
1895 gene = SeqMgrGetFeatureByLabel (bsp, str, SEQFEAT_GENE, 0, &fcontext);
1896 if (gene != NULL && gene->data.choice == SEQFEAT_GENE) {
1897 grpfeat = (GeneRefPtr) gene->data.value.ptrvalue;
1898 if (grpfeat != NULL) {
1899 grp->locus_tag = StringSaveNoNull (grpfeat->locus_tag);
1900 }
1901 }
1902 }
1903 } else if (vnp->choice == 2) {
1904 grp = GeneRefNew ();
1905 if (grp != NULL) {
1906 grp->desc = StringSave ((CharPtr) vnp->data.ptrvalue);
1907 }
1908 } else if (vnp->choice == 3) {
1909 grp = GeneRefNew ();
1910 if (grp != NULL) {
1911 grp->locus_tag = StringSave ((CharPtr) vnp->data.ptrvalue);
1912 }
1913 }
1914 }
1915 }
1916 if (grp != NULL) {
1917 xref = SeqFeatXrefNew ();
1918 sfp->xref = xref;
1919 if (xref != NULL) {
1920 xref->data.choice = SEQFEAT_GENE;
1921 xref->data.value.ptrvalue = (Pointer) grp;
1922 }
1923 }
1924 }
1925 } else if (usexref == 3) {
1926 /* protein feature can now suppress gene on GenBank view */
1927 grp = GeneRefNew ();
1928 if (grp != NULL) {
1929 xref = SeqFeatXrefNew ();
1930 sfp->xref = xref;
1931 if (xref != NULL) {
1932 xref->data.choice = SEQFEAT_GENE;
1933 xref->data.value.ptrvalue = (Pointer) grp;
1934 }
1935 }
1936 }
1937
1938 ompc.output_data = (Pointer) sfp;
1939 if (ompc.input_entityID == 0) {
1940 sfp->qual = DialogToPointer (ffp->gbquals);
1941 VisStringDialogToGbquals (sfp, ffp->experiment, "experiment");
1942 InferenceDialogToGBQuals (ffp->inference, sfp, TRUE);
1943
1944 sfp->ext = DialogToPointer (ffp->usrobjext);
1945 if (ffp->goTermUserObj != NULL) {
1946 sfp->ext = CombineGOTermUserObjects (sfp->ext, ffp->goTermUserObj);
1947 }
1948 if (ffp->featid != NULL) {
1949 TextToFeatID (ffp->featid, &(sfp->id));
1950 }
1951 if (HasExceptionGBQual (sfp)) {
1952 sfp->excpt = TRUE;
1953 }
1954 if (ffp->fidxref != NULL) {
1955 TextToFeatXref (ffp->fidxref, sfp);
1956 }
1957 AddProtRefXref (sfp, ffp->protXrefName, ffp->protXrefDesc);
1958 FixSpecialCharactersForObject (OBJ_SEQFEAT, sfp, "You may not include special characters in the text.\nIf you do not choose replacement characters, these special characters will be replaced with '#'.", TRUE, NULL);
1959 if (! ObjMgrRegister (OBJ_SEQFEAT, (Pointer) sfp)) {
1960 Message (MSG_ERROR, "ObjMgrRegister failed");
1961 }
1962 SeqLocFree (slp);
1963 SeqEntrySetScope (oldscope);
1964 return TRUE;
1965 } else if (ompc.input_itemtype != OBJ_SEQFEAT) {
1966 sfp->qual = DialogToPointer (ffp->gbquals);
1967 VisStringDialogToGbquals (sfp, ffp->experiment, "experiment");
1968 InferenceDialogToGBQuals (ffp->inference, sfp, TRUE);
1969
1970 sfp->ext = DialogToPointer (ffp->usrobjext);
1971 if (ffp->goTermUserObj != NULL) {
1972 sfp->ext = CombineGOTermUserObjects (sfp->ext, ffp->goTermUserObj);
1973 }
1974 if (ffp->featid != NULL) {
1975 TextToFeatID (ffp->featid, &(sfp->id));
1976 }
1977 if (HasExceptionGBQual (sfp)) {
1978 sfp->excpt = TRUE;
1979 }
1980 if (ffp->fidxref != NULL) {
1981 TextToFeatXref (ffp->fidxref, sfp);
1982 }
1983 AddProtRefXref (sfp, ffp->protXrefName, ffp->protXrefDesc);
1984 FixSpecialCharactersForObject (OBJ_SEQFEAT, sfp, "You may not include special characters in the text.\nIf you do not choose replacement characters, these special characters will be replaced with '#'.", TRUE, NULL);
1985 ompc.output_itemtype = OBJ_SEQFEAT;
1986 if (ompc.input_itemtype == OBJ_BIOSEQ) {
1987 bsp = GetBioseqGivenIDs (ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype);
1988 if (bsp != NULL) {
1989 sap = bsp->annot;
1990 while (sap != NULL && (sap->name != NULL || sap->desc != NULL || sap->type != 1)) {
1991 sap = sap->next;
1992 }
1993 if (sap == NULL) {
1994 sap = SeqAnnotNew ();
1995 if (sap != NULL) {
1996 sap->type = 1;
1997 sap->next = bsp->annot;
1998 bsp->annot = sap;
1999 }
2000 }
2001 if (sap != NULL) {
2002 itemID = GetItemIDGivenPointer (ompc.input_entityID, OBJ_SEQANNOT, (Pointer) sap);
2003 if (itemID > 0) {
2004 ompc.input_itemID = itemID;
2005 ompc.input_itemtype = OBJ_SEQANNOT;
2006 }
2007 }
2008 }
2009 }
2010 if (! AttachDataForProc (&ompc, FALSE)) {
2011 Message (MSG_ERROR, "AttachDataForProc failed");
2012 }
2013 rsult = TRUE;
2014 } else {
2015 GatherItem (ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype,
2016 (Pointer) &old_location, GetOldFeatureLocation);
2017
2018 rd.ffp = ffp;
2019 rd.sfp = sfp;
2020 GatherItem (ompc.input_entityID, ompc.input_itemID, ompc.input_itemtype,
2021 (Pointer) &rd, ReplaceFeatureExtras);
2022 if (HasExceptionGBQual (sfp)) {
2023 sfp->excpt = TRUE;
2024 }
2025 if (ffp->fidxref != NULL) {
2026 TextToFeatXref (ffp->fidxref, sfp);
2027 }
2028 if (FeatIsPseudo (sfp))
2029 {
2030 RemoveProtXrefs (sfp);
2031 }
2032 else
2033 {
2034 AddProtRefXref (sfp, ffp->protXrefName, ffp->protXrefDesc);
2035 }
2036 FixSpecialCharactersForObject (OBJ_SEQFEAT, sfp, "You may not include special characters in the text.\nIf you do not choose replacement characters, these special characters will be replaced with '#'.", TRUE, NULL);
2037 if (! ReplaceDataForProc (&ompc, FALSE)) {
2038 Message (MSG_ERROR, "ReplaceDataForProc failed");
2039 }
2040 rsult = TRUE;
2041 }
2042 if (ffp->gene != NULL && usexref == 1) {
2043 val = GetValue (ffp->gene);
2044 if (val == 2) {
2045 sep = GetBestTopParentForItemID (ffp->input_entityID,
2046 ffp->input_itemID,
2047 ffp->input_itemtype);
2048 /*
2049 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
2050 */
2051 if (sep != NULL) {
2052 sep = FindNucSeqEntry (sep);
2053 }
2054 if (sep != NULL && sep->data.ptrvalue != NULL) {
2055 GetTitle (ffp->geneSymbol, symbol, sizeof (symbol));
2056 GetTitle (ffp->geneAllele, allele, sizeof (allele));
2057 GetTitle (ffp->geneDesc, desc, sizeof (desc));
2058 GetTitle (ffp->locusTag, locustag, sizeof (locustag));
2059 grp = CreateNewGeneRef (symbol, allele, desc, FALSE);
2060 if (! StringHasNoText (locustag)) {
2061 if (grp == NULL) {
2062 grp = GeneRefNew ();
2063 }
2064 grp->locus_tag = StringSave (locustag);
2065 }
2066 if (!TextHasNoText (ffp->geneSynonym)) {
2067 if (grp == NULL) {
2068 grp = GeneRefNew ();
2069 }
2070 ValNodeAddPointer (&(grp->syn), 0, SaveStringFromText (ffp->geneSynonym));
2071 }
2072 if (grp != NULL) {
2073 sfp = CreateNewFeature (sep, NULL, SEQFEAT_GENE, NULL);
2074 if (sfp != NULL) {
2075 sfp->data.value.ptrvalue = (Pointer) grp;
2076 FixSpecialCharactersForObject (OBJ_SEQFEAT, sfp, "You may not include special characters in the text.\nIf you do not choose replacement characters, these special characters will be replaced with '#'.", TRUE, NULL);
2077 sfp->location = SeqLocFree (sfp->location);
2078 sfp->location = DialogToPointer (ffp->location);
2079 bsp = GetBioseqGivenSeqLoc (sfp->location, ffp->input_entityID);
2080 if (bsp != NULL) {
2081 hasNulls = LocationHasNullsBetween (sfp->location);
2082 gslp = SeqLocMerge (bsp, sfp->location, NULL, TRUE, FALSE, FALSE);
2083 if (gslp != NULL) {
2084 CheckSeqLocForPartial (sfp->location, &noLeft, &noRight);
2085 sfp->location = SeqLocFree (sfp->location);
2086 sfp->location = gslp;
2087 if (bsp->repr == Seq_repr_seg) {
2088 gslp = SegLocToPartsEx (bsp, sfp->location, TRUE);
2089 sfp->location = SeqLocFree (sfp->location);
2090 sfp->location = gslp;
2091 hasNulls = LocationHasNullsBetween (sfp->location);
2092 sfp->partial = (sfp->partial || hasNulls);
2093 }
2094 FreeAllFuzz (sfp->location);
2095 SetSeqLocPartial (sfp->location, noLeft, noRight);
2096 sfp->partial = (sfp->partial || noLeft || noRight);
2097 }
2098 }
2099 }
2100 }
2101 }
2102 } else if (val > 2) {
2103 ggl.ffp = ffp;
2104 ggl.omp = ObjMgrGet ();
2105 ggl.slp = slp;
2106 ggl.genexref = NULL;
2107 ggl.xrefmatch = FALSE;
2108 ggl.idx = 2;
2109 ggl.val = val;
2110 ggl.min = INT4_MAX;
2111 ggl.old_feature_location = old_location;
2112 MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
2113 gs.seglevels = 1;
2114 gs.get_feats_location = TRUE;
2115 MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
2116 gs.ignore[OBJ_BIOSEQ] = FALSE;
2117 gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
2118 gs.ignore[OBJ_SEQFEAT] = FALSE;
2119 gs.ignore[OBJ_SEQANNOT] = FALSE;
2120 gs.scope = GetBestTopParentForItemID (ffp->input_entityID,
2121 ffp->input_itemID,
2122 ffp->input_itemtype);
2123 GatherEntity (ffp->input_entityID, (Pointer) &ggl, GeneUpdateFunc, &gs);
2124 }
2125 }
2126 SeqLocFree (slp);
2127 SeqEntrySetScope (oldscope);
2128 }
2129 }
2130 old_location = SeqLocFree (old_location);
2131 return rsult;
2132 }
2133
2134 extern void StdFeatFormActnProc (ForM f)
2135
2136 {
2137 FeatureFormPtr ffp;
2138
2139 if (FeatFormReplaceWithoutUpdateProc (f)) {
2140 ffp = (FeatureFormPtr) GetObjectExtra (f);
2141 if (ffp != NULL) {
2142 GetRidOfEmptyFeatsDescStrings (ffp->input_entityID, NULL);
2143 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
2144 ExtendGeneFeatIfOnMRNA (ffp->input_entityID, NULL);
2145 }
2146 ObjMgrSetDirtyFlag (ffp->input_entityID, TRUE);
2147 ObjMgrSendMsg (OM_MSG_UPDATE, ffp->input_entityID,
2148 ffp->input_itemID, ffp->input_itemtype);
2149 }
2150 }
2151 }
2152
2153 extern void StdSeqFeatPtrToFeatFormProc (ForM f, Pointer data)
2154
2155 {
2156 FeatureFormPtr ffp;
2157 SeqEntryPtr oldsep;
2158 SeqEntryPtr sep;
2159 SeqFeatPtr sfp;
2160 Int4 val;
2161
2162 ffp = (FeatureFormPtr) GetObjectExtra (f);
2163 if (ffp != NULL) {
2164 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
2165 oldsep = SeqEntrySetScope (sep);
2166 sfp = (SeqFeatPtr) data;
2167 if (sfp != NULL) {
2168 switch (sfp->data.choice) {
2169 case SEQFEAT_BOND :
2170 case SEQFEAT_SITE :
2171 case SEQFEAT_PSEC_STR :
2172 val = (Int4) sfp->data.value.intvalue;
2173 PointerToDialog (ffp->data, (Pointer) &(val));
2174 break;
2175 case SEQFEAT_COMMENT:
2176 break;
2177 default :
2178 PointerToDialog (ffp->data, sfp->data.value.ptrvalue);
2179 break;
2180 }
2181 SeqFeatPtrToCommon (ffp, sfp);
2182 PointerToDialog (ffp->location, sfp->location);
2183 }
2184 SeqEntrySetScope (oldsep);
2185 }
2186 }
2187
2188 extern void StdInitFeatFormProc (ForM f)
2189
2190 {
2191 FeatureFormPtr ffp;
2192
2193 ffp = (FeatureFormPtr) GetObjectExtra (f);
2194 if (ffp != NULL) {
2195 PopulateGenePopup (ffp);
2196 }
2197 }
2198
2199 extern void StdFeatFormAcceptButtonProc (ButtoN b)
2200
2201 {
2202 Int2 attempts = 3;
2203 Char badInfMssg [32];
2204 Char badInfQual [256];
2205 FeatureFormPtr ffp;
2206 SeqLocPtr slp;
2207 WindoW w;
2208 ValNodePtr err_list;
2209 SeqEntryPtr oldscope, sep;
2210
2211 if (b != NULL) {
2212 w = ParentWindow (b);
2213 ffp = (FeatureFormPtr) GetObjectExtra (b);
2214 if (ffp != NULL && ffp->form != NULL && ffp->actproc != NULL) {
2215 sep = GetTopSeqEntryForEntityID (ffp->input_entityID);
2216 oldscope = SeqEntrySetScope (sep);
2217 slp = DialogToPointer (ffp->location);
2218 if (slp == NULL) {
2219 ErrPostEx (SEV_ERROR, 0, 0, "Feature must have a location!");
2220 err_list = TestDialog (ffp->location);
2221 DisplayErrorMessages ("Location Errors", err_list);
2222 err_list = ValNodeFree (err_list);
2223 SeqEntrySetScope (oldscope);
2224 return;
2225 }
2226 SeqLocFree (slp);
2227 if ((! ffp->acceptBadInf) && (! TestInference (ffp, badInfQual, sizeof (badInfQual), badInfMssg))) {
2228 (ffp->badInfAttempts)++;
2229 if (GetAppProperty ("InternalNcbiSequin") != NULL) {
2230 attempts = 2;
2231 }
2232 if (ffp->badInfAttempts < attempts) {
2233 if (ffp->badInfAttempts == 2) {
2234 Message (MSG_OK, "%s - Please fix the %s error in\n%s", infWarning2, badInfMssg, badInfQual);
2235 } else {
2236 Message (MSG_OK, "%s - Please fix the %s error in\n%s", infWarning1, badInfMssg, badInfQual);
2237 }
2238 return;
2239 } else {
2240 if (Message (MSG_YN, "%s", infAccept) == ANS_NO) return;
2241 ffp->acceptBadInf = TRUE;
2242 }
2243 }
2244 Hide (w);
2245 (ffp->actproc) (ffp->form);
2246 SeqEntrySetScope (oldscope);
2247 }
2248 Update ();
2249 if (ffp != NULL && (ffp->leave_dlg_up == NULL || ! GetStatus (ffp->leave_dlg_up)))
2250 {
2251 Remove (w);
2252 }
2253 else
2254 {
2255 /* set strand and sequence ID, but clear other location information */
2256 SendMessageToDialog (ffp->location, NUM_VIB_MSG + 1);
2257 SendMessageToDialog (ffp->location, NUM_VIB_MSG + 2);
2258 Show (w);
2259 }
2260 }
2261 }
2262
2263 extern void StdFeatFormCleanupProc (GraphiC g, VoidPtr data)
2264
2265 {
2266 FeatureFormPtr ffp;
2267 Uint2 userkey;
2268
2269 ffp = (FeatureFormPtr) data;
2270 if (ffp != NULL) {
2271 ValNodeFreeData (ffp->geneNames);
2272 if (ffp->input_entityID > 0 && ffp->userkey > 0) {
2273 userkey = ffp->userkey;
2274 ffp->userkey = 0;
2275 ObjMgrFreeUserData (ffp->input_entityID, ffp->procid, ffp->proctype, userkey);
2276 }
2277 }
2278 StdCleanupFormProc (g, data);
2279 }
2280
2281 extern ValNodePtr AddStringToValNodeChain (ValNodePtr head, CharPtr str, Uint1 choice)
2282
2283 {
2284 ValNodePtr vnp;
2285
2286 vnp = ValNodeNew (head);
2287 if (head == NULL) {
2288 head = vnp;
2289 }
2290 if (vnp != NULL) {
2291 vnp->choice = choice;
2292 vnp->data.ptrvalue = StringSave (str);
2293 }
2294 return head;
2295 }
2296
2297 static void StripPeriods (CharPtr str)
2298
2299 {
2300 Char ch;
2301 CharPtr dst;
2302
2303 if (str != NULL) {
2304 dst = str;
2305 ch = *str;
2306 while (ch != '\0') {
2307 if (ch != '.') {
2308 *dst = ch;
2309 dst++;
2310 }
2311 str++;
2312 ch = *str;
2313 }
2314 *dst = '\0';
2315 }
2316 }
2317
2318 static void TrimLeadingSpaces (CharPtr str)
2319
2320 {
2321 Char ch;
2322 CharPtr dst;
2323
2324 if (str != NULL && str [0] != '\0') {
2325 dst = str;
2326 ch = *str;
2327 while (ch != '\0' && ch <= ' ') {
2328 str++;
2329 ch = *str;
2330 }
2331 while (ch != '\0') {
2332 *dst = ch;
2333 dst++;
2334 str++;
2335 ch = *str;
2336 }
2337 *dst = '\0';
2338 }
2339 }
2340
2341 extern CharPtr NameStdPtrToAuthorSpreadsheetString (NameStdPtr nsp);
2342 extern CharPtr NameStdPtrToAuthorSpreadsheetString (NameStdPtr nsp)
2343
2344 {
2345 Char first [256];
2346 Char frstinits [64];
2347 Char initials [64];
2348 Int2 j;
2349 Char last [256];
2350 Char middle [128];
2351 Char str [512];
2352 Char suffix [64];
2353 Char suffixPosition[64];
2354 Int2 i;
2355
2356 if (nsp == NULL) return NULL;
2357 str [0] = '\0';
2358 StringNCpy_0 (first, nsp->names [1], sizeof (first));
2359 TrimSpacesAroundString (first);
2360 StringNCpy_0 (initials, nsp->names [4], sizeof (initials));
2361 StripPeriods (initials);
2362 TrimLeadingSpaces (initials);
2363 StringNCpy_0 (last, nsp->names [0], sizeof (last));
2364 TrimLeadingSpaces (last);
2365 StringNCpy_0 (middle, nsp->names [2], sizeof (middle));
2366 TrimLeadingSpaces (middle);
2367 if (StringCmp (initials, "al") == 0 &&
2368 StringCmp (last, "et") == 0 &&
2369 first [0] == '\0') {
2370 initials [0] = '\0';
2371 StringCpy (last, "et al.");
2372 }
2373 if (first [0] == '\0') {
2374 StringNCpy_0 (first, initials, sizeof (first));
2375 if (IS_ALPHA (first [0])) {
2376 if (first [1] == '-') {
2377 first [3] = '\0';
2378 } else {
2379 first [1] = '\0';
2380 }
2381 } else {
2382 first [0] = '\0';
2383 }
2384 }
2385 FirstNameToInitials (first, frstinits, sizeof (frstinits) - 1);
2386 StripPeriods (first);
2387 TrimLeadingSpaces (first);
2388 if (first [0] != '\0') {
2389 StringCat (str, first);
2390 } else {
2391 }
2392 StringCat (str, "\t");
2393 j = 0;
2394 while (initials [j] != '\0' && TO_UPPER (initials [j]) == TO_UPPER (frstinits [j])) {
2395 j++;
2396 }
2397 if (initials [j] != '\0') {
2398 StringCat (str, initials + j);
2399 } else {
2400 }
2401 StringCat (str, "\t");
2402 StringCat (str, last);
2403 StringNCpy_0 (suffix, nsp->names [5], sizeof (suffix));
2404 for (i = 0; i <= NUMBER_OF_SUFFIXES; i++)
2405 if (StringICmp (suffix, name_suffix_labels [i]) == 0) {
2406 sprintf (suffixPosition, "%d", i);
2407 break;
2408 }
2409 if (i == NUMBER_OF_SUFFIXES)
2410 sprintf (suffixPosition, "%d", 0);
2411 StringCat (str, "\t");
2412 if (suffix [0] != '\0') {
2413 StringCat (str, suffixPosition);
2414 } else {
2415 }
2416 StringCat (str, "\t");
2417 StringCat (str, middle);
2418 StringCat (str, "\n");
2419 return StringSave (str);
2420 }
2421
2422 static void StdAuthListPtrToAuthorDialog (DialoG d, Pointer data)
2423
2424 {
2425 AuthListPtr alp;
2426 AuthorPtr ap;
2427 ValNodePtr head;
2428 Int2 j;
2429 ValNodePtr names;
2430 NameStdPtr nsp;
2431 PersonIdPtr pid;
2432 TagListPtr tlp;
2433 ValNodePtr vnp;
2434
2435 tlp = (TagListPtr) GetObjectExtra (d);
2436 alp = (AuthListPtr) data;
2437 if (tlp != NULL) {
2438 head = NULL;
2439 if (alp != NULL) {
2440 if (alp->choice == 1) {
2441 names = alp->names;
2442 while (names != NULL) {
2443 ap = names->data.ptrvalue;
2444 if (ap != NULL) {
2445 pid = ap->name;
2446 if (pid != NULL) {
2447 if (pid->choice == 2) {
2448 nsp = pid->data;
2449 if (nsp != NULL) {
2450 vnp = ValNodeNew (head);
2451 if (head == NULL) {
2452 head = vnp;
2453 }
2454 if (vnp != NULL) {
2455 vnp->data.ptrvalue = NameStdPtrToAuthorSpreadsheetString (nsp);
2456 }
2457 }
2458 }
2459 }
2460 }
2461 names = names->next;
2462 }
2463 } else {
2464 Message (MSG_ERROR, "Unable to handle author type %d", (int) alp->choice);
2465 }
2466 }
2467 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
2468 tlp->vnp = head;
2469 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
2470 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
2471 }
2472 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
2473 CorrectBarMax (tlp->bar, tlp->max);
2474 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
2475 }
2476 }
2477
2478 extern NameStdPtr AuthorSpreadsheetStringToNameStdPtr (CharPtr txt);
2479 extern NameStdPtr AuthorSpreadsheetStringToNameStdPtr (CharPtr txt)
2480
2481 {
2482 Char ch;
2483 CharPtr first;
2484 Char initials [64];
2485 Int2 j;
2486 Int2 k;
2487 Char last;
2488 NameStdPtr nsp;
2489 Char periods [128];
2490 CharPtr str;
2491 Char str1 [64];
2492 CharPtr suffix;
2493 Char suffixVal [80];
2494
2495 if (txt == NULL) return NULL;
2496 nsp = NameStdNew ();
2497 if (nsp == NULL) return NULL;
2498 nsp->names [0] = ExtractTagListColumn (txt, 2);
2499 TrimLeadingSpaces (nsp->names [0]);
2500 first = ExtractTagListColumn (txt, 0);
2501 StripPeriods (first);
2502 nsp->names [1] = StringSave (first);
2503 TrimLeadingSpaces (nsp->names [1]);
2504 FirstNameToInitials (first, str1, sizeof (str1) - 1);
2505 str = ExtractTagListColumn (txt, 1);
2506 StringNCat (str1, str, sizeof (str1) - 1);
2507 MemFree (str);
2508 j = 0;
2509 k = 0;
2510 ch = str1 [j];
2511 while (ch != '\0') {
2512 if (ch != ' ') {
2513 initials [k] = ch;
2514 k++;
2515 }
2516 j++;
2517 ch = str1 [j];
2518 }
2519 initials [k] = '\0';
2520 periods [0] = '\0';
2521 j = 0;
2522 ch = initials [j];
2523 while (ch != '\0') {
2524 if (ch == ',') {
2525 initials [j] = '.';
2526 }
2527 j++;
2528 ch = initials [j];
2529 }
2530 str = StringStr (initials, ".ST.");
2531 if (str != NULL) {
2532 *(str + 2) = 't';
2533 }
2534 j = 0;
2535 k = 0;
2536 ch = initials [j];
2537 while (ch != '\0') {
2538 if (ch == '-') {
2539 periods [k] = ch;
2540 k++;
2541 j++;
2542 ch = initials [j];
2543 } else if (ch == '.') {
2544 j++;
2545 ch = initials [j];
2546 } else if (ch == ' ') {
2547 j++;
2548 ch = initials [j];
2549 } else {
2550 periods [k] = ch;
2551 last = ch;
2552 k++;
2553 j++;
2554 ch = initials [j];
2555 if (ch == '\0') {
2556 if (! (IS_LOWER (last))) {
2557 periods [k] = '.';
2558 k++;
2559 }
2560 /* } else if (ch == '.' && initials [j + 1] == '\0') { */
2561 } else if (! (IS_LOWER (ch))) {
2562 periods [k] = '.';
2563 k++;
2564 }
2565 }
2566 }
2567 periods [k] = '\0';
2568 nsp->names [4] = StringSave (periods);
2569 TrimLeadingSpaces (nsp->names [4]);
2570 str = ExtractTagListColumn (txt, 3);
2571 StringNCpy_0 (str1, str, sizeof (str1));
2572 MemFree (str);
2573 j = 0;
2574 k = 0;
2575 ch = str1 [j];
2576 while (ch != '\0') {
2577 if (ch != ' ') {
2578 suffixVal [k] = ch;
2579 k++;
2580 }
2581 j++;
2582 ch = str1 [j];
2583 }
2584 suffixVal [k] = '\0';
2585 if (suffixVal [0] != '\0') {
2586 suffix = GetEnumName (atoi(suffixVal), name_suffix_alist);
2587 nsp->names [5] = StringSave (suffix);
2588 TrimLeadingSpaces (nsp->names [5]);
2589 if (StringHasNoText (nsp->names [5])) {
2590 nsp->names [5] = MemFree (nsp->names [5]);
2591 }
2592 }
2593 if (StringCmp (nsp->names [0], "et al") == 0) {
2594 nsp->names [0] = MemFree (nsp->names [0]);
2595 nsp->names [0] = StringSave ("et al.");
2596 }
2597 nsp->names [2] = ExtractTagListColumn (txt, 4);
2598 TrimLeadingSpaces (nsp->names [2]);
2599 if (StringHasNoText (nsp->names [2])) {
2600 nsp->names [2] = MemFree (nsp->names [2]);
2601 }
2602 return nsp;
2603 }
2604
2605 static Pointer AuthorDialogToStdAuthListPtr (DialoG d)
2606
2607 {
2608 AuthListPtr alp;
2609 AuthorPtr ap;
2610 Char ch;
2611 Int2 j;
2612 Int2 len;
2613 ValNodePtr names;
2614 NameStdPtr nsp;
2615 Boolean okay;
2616 PersonIdPtr pid;
2617 CharPtr str;
2618 TagListPtr tlp;
2619 ValNodePtr vnp;
2620
2621 alp = NULL;
2622 tlp = (TagListPtr) GetObjectExtra (d);
2623 if (tlp != NULL && tlp->vnp != NULL) {
2624 alp = AuthListNew ();
2625 if (alp != NULL) {
2626 alp->choice = 1;
2627 names = NULL;
2628 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
2629 str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 2);
2630 okay = FALSE;
2631 len = StringLen (str);
2632 for (j = 0; j < len; j++) {
2633 ch = str [j];
2634 if (ch != ' ' && ch != '\t' && ch != '\n') {
2635 okay = TRUE;
2636 }
2637 }
2638 MemFree (str);
2639 if (okay) {
2640 names = ValNodeNew (names);
2641 if (alp->names == NULL) {
2642 alp->names = names;
2643 }
2644 if (names != NULL) {
2645 ap = AuthorNew ();
2646 names->choice = 1;
2647 names->data.ptrvalue = ap;
2648 if (ap != NULL) {
2649 pid = PersonIdNew ();
2650 ap->name = pid;
2651 if (pid != NULL) {
2652 pid->choice = 2;
2653 nsp = AuthorSpreadsheetStringToNameStdPtr ((CharPtr) vnp->data.ptrvalue);
2654 pid->data = nsp;
2655 }
2656 }
2657 }
2658 }
2659 }
2660 if (alp->names == NULL) {
2661 alp = AuthListFree (alp);
2662 }
2663 }
2664 }
2665 return (Pointer) alp;
2666 }
2667
2668 static void StrAuthListPtrToAuthorDialog (DialoG d, Pointer data)
2669
2670 {
2671 AuthListPtr alp;
2672 ValNodePtr head;
2673 Int2 j;
2674 ValNodePtr names;
2675 Char str [128];
2676 TagListPtr tlp;
2677 ValNodePtr vnp;
2678
2679 tlp = (TagListPtr) GetObjectExtra (d);
2680 alp = (AuthListPtr) data;
2681 if (tlp != NULL) {
2682 head = NULL;
2683 if (alp != NULL) {
2684 if (alp->choice == 2 || alp->choice == 3) {
2685 names = alp->names;
2686 while (names != NULL) {
2687 StringNCpy_0 (str, names->data.ptrvalue, sizeof (str) - 2);
2688 StringCat (str, "\n");
2689 vnp = ValNodeNew (head);
2690 if (head == NULL) {
2691 head = vnp;
2692 }
2693 if (vnp != NULL) {
2694 vnp->data.ptrvalue = StringSave (str);
2695 }
2696 names = names->next;
2697 }
2698 } else {
2699 Message (MSG_ERROR, "Unable to handle author type %d", (int) alp->choice);
2700 }
2701 }
2702 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
2703 tlp->vnp = head;
2704 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
2705 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
2706 }
2707 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
2708 CorrectBarMax (tlp->bar, tlp->max);
2709 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
2710 }
2711 }
2712
2713 static Pointer AuthorDialogToStrAuthListPtr (DialoG d)
2714
2715 {
2716 AuthListPtr alp;
2717 Char ch;
2718 Int2 j;
2719 Int2 len;
2720 ValNodePtr names;
2721 Boolean okay;
2722 CharPtr str;
2723 TagListPtr tlp;
2724 ValNodePtr vnp;
2725
2726 alp = NULL;
2727 tlp = (TagListPtr) GetObjectExtra (d);
2728 if (tlp != NULL && tlp->vnp != NULL) {
2729 alp = AuthListNew ();
2730 if (alp != NULL) {
2731 alp->choice = 2;
2732 names = NULL;
2733 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
2734 str = (CharPtr) vnp->data.ptrvalue;
2735 okay = FALSE;
2736 len = StringLen (str);
2737 for (j = 0; j < len; j++) {
2738 ch = str [j];
2739 if (ch != ' ' && ch != '\t' && ch != '\n') {
2740 okay = TRUE;
2741 }
2742 }
2743 if (okay) {
2744 names = ValNodeNew (names);
2745 if (alp->names == NULL) {
2746 alp->names = names;
2747 }
2748 if (names != NULL) {
2749 names->choice = 2;
2750 names->data.ptrvalue = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
2751
2752 }
2753 }
2754 }
2755 if (alp->names == NULL) {
2756 alp = AuthListFree (alp);
2757 }
2758 }
2759 }
2760 return (Pointer) alp;
2761 }
2762
2763 static void AuthListPtrToAuthorDialog (DialoG d, Pointer data)
2764
2765 {
2766 AuthorDialogPtr adp;
2767 AuthListPtr alp;
2768
2769 adp = (AuthorDialogPtr) GetObjectExtra (d);
2770 if (adp != NULL) {
2771 alp = (AuthListPtr) data;
2772 if (alp != NULL) {
2773 adp->type = alp->choice;
2774 }
2775 if (adp->type == 1) {
2776 Hide (adp->strGrp);
2777 Show (adp->stdGrp);
2778 PointerToDialog (adp->stdAuthor, data);
2779 } else if (adp->type == 2 || adp->type == 3) {
2780 Hide (adp->stdGrp);
2781 Show (adp->strGrp);
2782 PointerToDialog (adp->strAuthor, data);
2783 }
2784 }
2785 }
2786
2787 static Pointer AuthorDialogToAuthListPtr (DialoG d)
2788
2789 {
2790 AuthorDialogPtr adp;
2791 AuthListPtr alp;
2792
2793 adp = (AuthorDialogPtr) GetObjectExtra (d);
2794 alp = NULL;
2795 if (adp != NULL) {
2796 if (adp->type == 1) {
2797 alp = (AuthListPtr) DialogToPointer (adp->stdAuthor);
2798 } else if (adp->type == 2 || adp->type == 3) {
2799 if ((alp = (AuthListPtr) DialogToPointer (adp->strAuthor)) != NULL)
2800 alp->choice = adp->type;
2801 }
2802 }
2803 return (Pointer) alp;
2804 }
2805
2806 static void AuthorDialogMessage (DialoG d, Int2 mssg)
2807
2808 {
2809 AuthorDialogPtr adp;
2810
2811 adp = (AuthorDialogPtr) GetObjectExtra (d);
2812 if (adp != NULL) {
2813 switch (mssg) {
2814 case VIB_MSG_ENTER :
2815 if (adp->type == 1) {
2816 SendMessageToDialog (adp->stdAuthor, VIB_MSG_ENTER);
2817 } else if (adp->type == 2 || adp->type == 3) {
2818 SendMessageToDialog (adp->strAuthor, VIB_MSG_ENTER);
2819 }
2820 break;
2821 default :
2822 break;
2823 }
2824 }
2825 }
2826
2827
2828 static Boolean IsAuthList (CharPtr path)
2829 {
2830 FILE *fp;
2831 Char buffer[10];
2832 Int4 len;
2833 Boolean rval = FALSE;
2834
2835 fp = FileOpen (path, "r");
2836 if (fp == NULL) return FALSE;
2837
2838 len = fread (buffer, 1, 9, fp);
2839 buffer[9] = 0;
2840 if (StringCmp (buffer, "Auth-list") == 0)
2841 {
2842 rval = TRUE;
2843 }
2844 FileClose (fp);
2845 return rval;
2846 }
2847
2848
2849 static NameStdPtr ReadNameFromString (CharPtr str, CharPtr PNTR next_name, BoolPtr found_special)
2850 {
2851 CharPtr cp_end, cp_space;
2852 NameStdPtr n;
2853
2854 if (StringHasNoText (str))
2855 {
2856 if (next_name != NULL)
2857 {
2858 *next_name = NULL;
2859 }
2860 return NULL;
2861 }
2862
2863 /* skip over any leading spaces */
2864 str += StringSpn (str, " \t");
2865
2866 /* skip over "and" if found */
2867 if (StringNCmp (str, "and ", 4) == 0)
2868 {
2869 str += 4;
2870 }
2871 if (StringHasNoText (str)) return NULL;
2872
2873 cp_end = StringChr (str, ',');
2874 if (cp_end != NULL)
2875 {
2876 *cp_end = 0;
2877 if (next_name != NULL)
2878 {
2879 if (StringHasNoText (cp_end + 1))
2880 {
2881 *next_name = NULL;
2882 }
2883 else
2884 {
2885 *next_name = cp_end + 1;
2886 }
2887 }
2888 }
2889 else if (next_name != NULL)
2890 {
2891 *next_name = NULL;
2892 }
2893
2894 n = NameStdNew ();
2895 /* look for elements in name */
2896 cp_space = StringRChr (str, ' ');
2897 if (cp_space == NULL)
2898 {
2899 n->names[0] = StringSave (str);
2900 }
2901 else
2902 {
2903 n->names[0] = StringSave (cp_space + 1);
2904 while (isspace (*cp_space))
2905 {
2906 cp_space--;
2907 }
2908 *(cp_space + 1) = 0;
2909 cp_space = StringChr (str, ' ');
2910 if (cp_space == NULL)
2911 {
2912 n->names[1] = StringSave (str);
2913 n->names[4] = (CharPtr) MemNew (sizeof (Char) * 3);
2914 sprintf (n->names[4], "%c.", *(n->names[1]));
2915 }
2916 else
2917 {
2918 *(cp_space) = 0;
2919 n->names[1] = StringSave (str);
2920
2921 cp_space++;
2922 while (isspace (*cp_space))
2923 {
2924 cp_space++;
2925 }
2926
2927 n->names[4] = (CharPtr) MemNew (sizeof (Char) * (4 + StringLen (cp_space)));
2928 sprintf (n->names[4], "%c.%s.", *(n->names[1]), cp_space);
2929 }
2930 SpecialCharReplace (&(n->names[1]), NULL, found_special, NULL);
2931 SpecialCharReplace (&(n->names[4]), NULL, found_special, NULL);
2932 }
2933 SpecialCharReplace (&(n->names[0]), NULL, found_special, NULL);
2934
2935 return n;
2936 }
2937
2938
2939 static Boolean EndsWithComma (CharPtr str)
2940 {
2941 CharPtr cp;
2942
2943 if (StringHasNoText (str)) return FALSE;
2944 cp = str + StringLen (str) - 1;
2945 while (isspace (*cp) && cp > str)
2946 {
2947 cp--;
2948 }
2949 if (*cp == ',')
2950 {
2951 return TRUE;
2952 }
2953 else
2954 {
2955 return FALSE;
2956 }
2957 }
2958
2959
2960 static CharPtr ExtendToComma (CharPtr line, ReadBufferPtr rbp)
2961 {
2962 CharPtr next_line = NULL, tmp;
2963 Boolean end_of_file = FALSE;
2964
2965 while (!EndsWithComma (line) && !end_of_file)
2966 {
2967 next_line = AbstractReadFunction (rbp);
2968 if (next_line == NULL)
2969 {
2970 end_of_file = TRUE;
2971 }
2972 else if (StringHasNoText (next_line))
2973 {
2974 next_line = MemFree (next_line);
2975 }
2976 else if (StringHasNoText (line))
2977 {
2978 line = MemFree (line);
2979 line = next_line;
2980 }
2981 else
2982 {
2983 tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (line) + StringLen (next_line) + 2));
2984 sprintf (tmp, "%s %s", line, next_line);
2985 next_line = MemFree (next_line);
2986 line = MemFree (line);
2987 line = tmp;
2988 }
2989 }
2990 return line;
2991 }
2992
2993
2994 static AuthListPtr ReadAuthorListFromTextFile (CharPtr path)
2995 {
2996 ReadBufferData rbd;
2997 CharPtr line;
2998 AuthListPtr alp = NULL;
2999 AuthorPtr ap;
3000 CharPtr cp, next_cp;
3001 NameStdPtr n;
3002 ValNodePtr names = NULL;
3003 Boolean found_special = FALSE;
3004
3005 rbd.fp = FileOpen (path, "r");
3006 if (rbd.fp == NULL) return FALSE;
3007 rbd.current_data = NULL;
3008
3009 line = ExtendToComma (NULL, &rbd);
3010 while (line != NULL)
3011 {
3012 cp = line;
3013 next_cp = NULL;
3014 while (cp != NULL)
3015 {
3016 n = ReadNameFromString (cp, &next_cp, &found_special);
3017 if (n != NULL)
3018 {
3019 ap = AuthorNew ();
3020 ap->name = PersonIdNew ();
3021 ap->name->choice = 2;
3022 ap->name->data = n;
3023 ValNodeAddPointer (&names, 0, ap);
3024 }
3025 cp = next_cp;
3026 }
3027 line = MemFree (line);
3028 line = ExtendToComma (NULL, &rbd);
3029 }
3030 if (names != NULL)
3031 {
3032 alp = AuthListNew ();
3033 alp->choice = 1;
3034 alp->names = names;
3035 }
3036 if (found_special)
3037 {
3038 Message (MSG_OK, "Special characters in names were converted");
3039 }
3040
3041 FileClose (rbd.fp);
3042 return alp;
3043 }
3044
3045
3046 static Boolean ReadAuthorDialog (DialoG d, CharPtr filename)
3047
3048 {
3049 AuthorDialogPtr adp;
3050 AsnIoPtr aip;
3051 AuthListPtr alp = NULL;
3052 Char path [PATH_MAX];
3053
3054 path [0] = '\0';
3055 StringNCpy_0 (path, filename, sizeof (path));
3056 adp = (AuthorDialogPtr) GetObjectExtra (d);
3057 if (adp != NULL) {
3058 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
3059 if (IsAuthList (path)) {
3060 aip = AsnIoOpen (path, "r");
3061 if (aip != NULL) {
3062 alp = AuthListAsnRead (aip, NULL);
3063 AsnIoClose (aip);
3064 }
3065 } else {
3066 alp = ReadAuthorListFromTextFile (path);
3067 }
3068 if (alp != NULL) {
3069 PointerToDialog (adp->dialog, (Pointer) alp);
3070 alp = AuthListFree (alp);
3071 Update ();
3072 return TRUE;
3073 }
3074 }
3075 }
3076 return FALSE;
3077 }
3078
3079 static Boolean WriteAuthorDialog (DialoG d, CharPtr filename)
3080
3081 {
3082 AuthorDialogPtr adp;
3083 AsnIoPtr aip;
3084 AuthListPtr alp;
3085 Char path [PATH_MAX];
3086 #ifdef WIN_MAC
3087 FILE *f;
3088 #endif
3089
3090 path [0] = '\0';
3091 StringNCpy_0 (path, filename, sizeof (path));
3092 adp = (AuthorDialogPtr) GetObjectExtra (d);
3093 if (adp != NULL) {
3094 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
3095 #ifdef WIN_MAC
3096 f = FileOpen (path, "r");
3097 if (f != NULL) {
3098 FileClose (f);
3099 } else {
3100 FileCreate (path, "TEXT", "ttxt");
3101 }
3102 #endif
3103 aip = AsnIoOpen (path, "w");
3104 if (aip != NULL) {
3105 alp = DialogToPointer (adp->dialog);
3106 AuthListAsnWrite (alp, aip, NULL);
3107 AsnIoClose (aip);
3108 alp = AuthListFree (alp);
3109 return TRUE;
3110 }
3111 }
3112 }
3113 return FALSE;
3114 }
3115
3116
3117 static void InsertFirstAuthor (ButtoN b)
3118 {
3119 AuthorDialogPtr adp;
3120 AuthListPtr alp;
3121 AuthorPtr ap;
3122 NameStdPtr nsp;
3123 ValNodePtr vnp;
3124
3125 adp = (AuthorDialogPtr) GetObjectExtra (b);
3126 if (adp == NULL) {
3127 return;
3128 }
3129
3130 alp = DialogToPointer (adp->dialog);
3131 if (alp != NULL && alp->names != NULL) {
3132 vnp = ValNodeNew (NULL);
3133 vnp->next = alp->names;
3134 alp->names = vnp;
3135 if (alp->choice == 1) {
3136 ap = AuthorNew ();
3137 ap->name = PersonIdNew ();
3138 ap->name->choice = 2;
3139 nsp = NameStdNew ();
3140 ap->name->data = nsp;
3141 vnp->data.ptrvalue = ap;
3142 } else {
3143 vnp->data.ptrvalue = StringSave ("");
3144 }
3145 PointerToDialog (adp->dialog, alp);
3146 SendMessageToDialog (adp->dialog, VIB_MSG_ENTER);
3147 }
3148 alp = AuthListFree (alp);
3149 }
3150
3151
3152 extern DialoG CreateAuthorDialog (GrouP prnt, Uint2 rows, Int2 spacing)
3153
3154 {
3155 AuthorDialogPtr adp;
3156 GrouP k;
3157 GrouP p, list_grp;
3158 PrompT p1, p2, p3, p4, p5;
3159 TagListPtr tlp;
3160 ButtoN b;
3161
3162 p = HiddenGroup (prnt, -1, 0, NULL);
3163
3164 adp = (AuthorDialogPtr) MemNew (sizeof (AuthorDialog));
3165 if (adp != NULL) {
3166
3167 SetObjectExtra (p, adp, StdCleanupExtraProc);
3168 adp->dialog = (DialoG) p;
3169 adp->todialog = AuthListPtrToAuthorDialog;
3170 adp->fromdialog = AuthorDialogToAuthListPtr;
3171 adp->testdialog = NULL;
3172 adp->importdialog = ReadAuthorDialog;
3173 adp->exportdialog = WriteAuthorDialog;
3174 adp->dialogmessage = AuthorDialogMessage;
3175
3176 list_grp = HiddenGroup (p, 0, 0, NULL);
3177
3178 adp->strGrp = HiddenGroup (list_grp, -1, 0, NULL);
3179 SetGroupSpacing (adp->strGrp, 3, 2);
3180
3181 k = HiddenGroup (adp->strGrp, -4, 0, NULL);
3182 SetGroupSpacing (k, spacing, spacing);
3183 p1 = StaticPrompt (k, "Name", 0, 0, programFont, 'c');
3184
3185 adp->strAuthor = CreateTagListDialog (adp->strGrp, rows, 1, spacing,
3186 author_types, str_author_widths, NULL,
3187 StrAuthListPtrToAuthorDialog,
3188 AuthorDialogToStrAuthListPtr);
3189 Hide (adp->strGrp);
3190
3191 adp->stdGrp = HiddenGroup (list_grp, -1, 0, NULL);
3192 SetGroupSpacing (adp->stdGrp, 3, 2);
3193
3194 k = HiddenGroup (adp->stdGrp, -4, 0, NULL);
3195 SetGroupSpacing (k, spacing, spacing);
3196 p2 = StaticPrompt (k, "First Name", 0, 0, programFont, 'c');
3197 p3 = StaticPrompt (k, "M.I.", 0, 0, programFont, 'c');
3198 p4 = StaticPrompt (k, "Last Name", 0, 0, programFont, 'c');
3199 p5 = StaticPrompt (k, "Sfx", 0, 0, programFont, 'c');
3200
3201 adp->stdAuthor = CreateTagListDialog (adp->stdGrp, rows, 4, spacing,
3202 author_types, std_author_widths,
3203 author_popups,
3204 StdAuthListPtrToAuthorDialog,
3205 AuthorDialogToStdAuthListPtr);
3206 adp->type = 1;
3207
3208 tlp = (TagListPtr) GetObjectExtra (adp->strAuthor);
3209 if (tlp != NULL) {
3210 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [0], (HANDLE) p1, NULL);
3211 }
3212 tlp = (TagListPtr) GetObjectExtra (adp->stdAuthor);
3213 if (tlp != NULL) {
3214 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [0], (HANDLE) p2, NULL);
3215 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [1], (HANDLE) p3, NULL);
3216 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [2], (HANDLE) p4, NULL);
3217 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [3], (HANDLE) p5, NULL);
3218 }
3219
3220 b = PushButton (p, "Insert First Author", InsertFirstAuthor);
3221 SetObjectExtra (b, adp, NULL);
3222 AlignObjects (ALIGN_CENTER, (HANDLE) list_grp, (HANDLE) b, NULL);
3223 }
3224
3225 return (DialoG) p;
3226 }
3227
3228 typedef struct affildialog {
3229 DIALOG_MESSAGE_BLOCK
3230 TexT affil;
3231 TexT div;
3232 TexT address;
3233 TexT city;
3234 TexT state;
3235 TexT zip;
3236 TexT country;
3237 TexT phone;
3238 TexT fax;
3239 TexT email;
3240 } AffilDialog, PNTR AffilDialogPtr;
3241
3242 static void AffilPtrToAffilDialog (DialoG d, Pointer data)
3243
3244 {
3245 AffilDialogPtr adp;
3246 AffilPtr ap;
3247
3248 adp = (AffilDialogPtr) GetObjectExtra (d);
3249 ap = (AffilPtr) data;
3250 if (adp != NULL) {
3251 if (ap != NULL) {
3252 SafeSetTitle (adp->affil, ap->affil);
3253 SafeSetTitle (adp->div, ap->div);
3254 SafeSetTitle (adp->address, ap->street);
3255 SafeSetTitle (adp->city, ap->city);
3256 SafeSetTitle (adp->state, ap->sub);
3257 SafeSetTitle (adp->zip, ap->postal_code);
3258 SafeSetTitle (adp->country, ap->country);
3259 SafeSetTitle (adp->phone, ap->phone);
3260 SafeSetTitle (adp->fax, ap->fax);
3261 SafeSetTitle (adp->email, ap->email);
3262 } else {
3263 SafeSetTitle (adp->affil, "");
3264 SafeSetTitle (adp->div, "");
3265 SafeSetTitle (adp->address, "");
3266 SafeSetTitle (adp->city, "");
3267 SafeSetTitle (adp->state, "");
3268 SafeSetTitle (adp->zip, "");
3269 SafeSetTitle (adp->country, "");
3270 SafeSetTitle (adp->phone, "");
3271 SafeSetTitle (adp->fax, "");
3272 SafeSetTitle (adp->email, "");
3273 }
3274 }
3275 }
3276
3277 static Pointer AffilDialogToAffilPtr (DialoG d)
3278
3279 {
3280 AffilDialogPtr adp;
3281 AffilPtr ap;
3282
3283 ap = NULL;
3284 adp = (AffilDialogPtr) GetObjectExtra (d);
3285 if (adp != NULL) {
3286 ap = AffilNew ();
3287 if (ap != NULL) {
3288 ap->affil = SaveStringFromText (adp->affil);
3289 ap->div = SaveStringFromText (adp->div);
3290 ap->street = SaveStringFromText (adp->address);
3291 ap->city = SaveStringFromText (adp->city);
3292 ap->sub = SaveStringFromText (adp->state);
3293 ap->postal_code = SaveStringFromText (adp->zip);
3294 ap->country = SaveStringFromText (adp->country);
3295 ap->phone = SaveStringFromText (adp->phone);
3296 ap->fax = SaveStringFromText (adp->fax);
3297 ap->email = SaveStringFromText (adp->email);
3298 if (ap->div == NULL && ap->street == NULL && ap->city == NULL &&
3299 ap->sub == NULL && ap->postal_code == NULL && ap->country == NULL &&
3300 ap->phone == NULL && ap->fax == NULL && ap->email == NULL) {
3301 ap->choice = 1;
3302 if (ap->affil == NULL) {
3303 ap = AffilFree (ap);
3304 }
3305 } else {
3306 ap->choice = 2;
3307 }
3308 }
3309 }
3310 return (Pointer) ap;
3311 }
3312
3313 static void AffilDialogMessage (DialoG d, Int2 mssg)
3314
3315 {
3316 AffilDialogPtr adp;
3317
3318 adp = (AffilDialogPtr) GetObjectExtra (d);
3319 if (adp != NULL) {
3320 switch (mssg) {
3321 case VIB_MSG_ENTER :
3322 Select (adp->affil);
3323 break;
3324 default :
3325 break;
3326 }
3327 }
3328 }
3329
3330 static DialoG CreateAnAffilDialog (GrouP prnt, CharPtr title,
3331 Boolean publisher,
3332 Boolean split,
3333 Boolean proceedings,
3334 GrouP PNTR grp1, GrouP PNTR grp2)
3335
3336 {
3337 AffilDialogPtr adp;
3338 GrouP g;
3339 GrouP g1, g2;
3340 GrouP j;
3341 GrouP m;
3342 GrouP p;
3343 GrouP q;
3344 GrouP s;
3345 #ifdef WIN_MAC
3346 Int2 wid = 20;
3347 Int2 zipw = 6;
3348 Int2 ewid = 8;
3349 #else
3350 Int2 wid = 30;
3351 Int2 zipw = 10;
3352 Int2 ewid = 20;
3353 #endif
3354
3355 p = HiddenGroup (prnt, 0, 0, NULL);
3356
3357 adp = (AffilDialogPtr) MemNew (sizeof (AffilDialog));
3358 if (adp != NULL) {
3359
3360 SetObjectExtra (p, adp, StdCleanupExtraProc);
3361 adp->dialog = (DialoG) p;
3362 adp->todialog = AffilPtrToAffilDialog;
3363 adp->fromdialog = AffilDialogToAffilPtr;
3364 adp->testdialog = NULL;
3365 adp->dialogmessage = AffilDialogMessage;
3366
3367 if (title != NULL && title [0] != '\0') {
3368 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
3369 } else {
3370 s = HiddenGroup (p, 0, -2, NULL);
3371 }
3372 m = HiddenGroup (s, 0, 0, NULL);
3373
3374 q = HiddenGroup (m, 2, 0, NULL);
3375 g1 = q;
3376 g2 = NULL;
3377 if (grp1 != NULL) {
3378 *grp1 = q;
3379 }
3380 if (grp2 != NULL) {
3381 *grp2 = NULL;
3382 }
3383 g = HiddenGroup (q, 0, 20, NULL);
3384 if (publisher) {
3385 StaticPrompt (g, "Publisher", 0, dialogTextHeight, programFont, 'l');
3386 } else if (proceedings) {
3387 StaticPrompt (g, "Location", 0, dialogTextHeight, programFont, 'l');
3388 } else {
3389 StaticPrompt (g, "Institution", 0, dialogTextHeight, programFont, 'l');
3390 StaticPrompt (g, "Department", 0, dialogTextHeight, programFont, 'l');
3391 }
3392 StaticPrompt (g, "Address", 0, dialogTextHeight, programFont, 'l');
3393 StaticPrompt (g, "City", 0, dialogTextHeight, programFont, 'l');
3394 StaticPrompt (g, "State/Province", 0, dialogTextHeight, programFont, 'l');
3395 StaticPrompt (g, "Country", 0, dialogTextHeight, programFont, 'l');
3396 if (! split) {
3397 if (! proceedings) {
3398 StaticPrompt (g, "", 0, stdLineHeight, programFont, 'l');
3399 StaticPrompt (g, "Phone", 0, dialogTextHeight, programFont, 'l');
3400 if (publisher) {
3401 StaticPrompt (g, "Internet Access", 0, dialogTextHeight, programFont, 'l');
3402 } else {
3403 StaticPrompt (g, "Email", 0, dialogTextHeight, programFont, 'l');
3404 }
3405 }
3406 }
3407 j = HiddenGroup (q, 0, 20, NULL);
3408 g = HiddenGroup (j, 0, 20, NULL);
3409 adp->affil = DialogText (g, "", wid, NULL);
3410 adp->div = NULL;
3411 if (! publisher && ! proceedings) {
3412 adp->div = DialogText (g, "", wid, NULL);
3413 }
3414 adp->address = DialogText (g, "", wid, NULL);
3415 adp->city = DialogText (g, "", wid, NULL);
3416 g = HiddenGroup (j, 3, 0, NULL);
3417 SetGroupSpacing (g, 20, 2);
3418 adp->state = DialogText (g, "", 10, NULL);
3419 if (! proceedings) {
3420 /* StaticPrompt (g, "Zip/Postal Code", 7 * stdCharWidth,
3421 dialogTextHeight, programFont, 'l'); */
3422 StaticPrompt (g, "Zip/Postal Code", 0, dialogTextHeight, programFont, 'l');
3423 adp->zip = DialogText (g, "", zipw, NULL);
3424 }
3425 g = HiddenGroup (j, 0, 20, NULL);
3426 adp->country = DialogText (g, "", wid, NULL);
3427 if (split) {
3428 if (! proceedings) {
3429 q = HiddenGroup (m, 2, 0, NULL);
3430 g2 = q;
3431 if (grp2 != NULL) {
3432 *grp2 = q;
3433 }
3434 g = HiddenGroup (q, 0, 20, NULL);
3435 StaticPrompt (g, "", 0, stdLineHeight, programFont, 'l');
3436 StaticPrompt (g, "Phone", 0, dialogTextHeight, programFont, 'l');
3437 if (publisher) {
3438 StaticPrompt (g, "Internet Access", 0, dialogTextHeight, programFont, 'l');
3439 } else {
3440 StaticPrompt (g, "Email", 0, dialogTextHeight, programFont, 'l');
3441 }
3442 j = HiddenGroup (q, 0, 20, NULL);
3443 }
3444 }
3445 if (! proceedings) {
3446 StaticPrompt (j, "Please include country code for non-U.S. phone numbers.",
3447 0, stdLineHeight, programFont, 'l');
3448 g = HiddenGroup (j, 3, 0, NULL);
3449 SetGroupSpacing (g, 20, 2);
3450 adp->phone = DialogText (g, "", 10, NULL);
3451 if (split) {
3452 StaticPrompt (g, "Fax", 0,
3453 dialogTextHeight, programFont, 'l');
3454 } else {
3455 StaticPrompt (g, "Fax", /* 7 * stdCharWidth */ 0,
3456 dialogTextHeight, programFont, 'l');
3457 }
3458 adp->fax = DialogText (g, "", 10, NULL);
3459 g = HiddenGroup (j, 0, 20, NULL);
3460 if (split) {
3461 adp->email = DialogText (g, "", ewid, NULL);
3462 } else {
3463 adp->email = DialogText (g, "", ewid, NULL);
3464 }
3465 }
3466
3467 if (split) {
3468 AlignObjects (ALIGN_RIGHT, (HANDLE) adp->affil,
3469 (HANDLE) adp->address, (HANDLE) adp->city,
3470 (HANDLE) adp->zip, (HANDLE) adp->country,
3471 (HANDLE) adp->div, NULL);
3472 AlignObjects (ALIGN_RIGHT, (HANDLE) adp->fax, (HANDLE) adp->email, NULL);
3473 AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) g2, NULL);
3474 Hide (g1);
3475 Hide (g2);
3476 } else {
3477 AlignObjects (ALIGN_RIGHT, (HANDLE) adp->affil,
3478 (HANDLE) adp->address, (HANDLE) adp->city,
3479 (HANDLE) adp->zip, (HANDLE) adp->country,
3480 (HANDLE) adp->fax, (HANDLE) adp->email,
3481 (HANDLE) adp->div, NULL);
3482 }
3483 }
3484
3485 return (DialoG) p;
3486 }
3487
3488 extern DialoG CreateAffilDialog (GrouP prnt, CharPtr title)
3489
3490 {
3491 return CreateAnAffilDialog (prnt, title, FALSE, FALSE, FALSE, NULL, NULL);
3492 }
3493
3494 extern DialoG CreatePublisherAffilDialog (GrouP prnt, CharPtr title)
3495
3496 {
3497 return CreateAnAffilDialog (prnt, title, TRUE, FALSE, FALSE, NULL, NULL);
3498 }
3499
3500 extern DialoG CreateProceedingsDialog (GrouP prnt, CharPtr title)
3501
3502 {
3503 return CreateAnAffilDialog (prnt, title, FALSE, FALSE, TRUE, NULL, NULL);
3504 }
3505
3506 extern DialoG CreateExtAffilDialog (GrouP prnt, CharPtr title, GrouP PNTR grp1, GrouP PNTR grp2)
3507
3508 {
3509 return CreateAnAffilDialog (prnt, title, FALSE, TRUE, FALSE, grp1, grp2);
3510 }
3511
3512 extern DialoG CreateExtPublisherAffilDialog (GrouP prnt, CharPtr title, GrouP PNTR grp1, GrouP PNTR grp2)
3513
3514 {
3515 return CreateAnAffilDialog (prnt, title, TRUE, TRUE, FALSE, grp1, grp2);
3516 }
3517
3518 extern DialoG CreateExtProceedingsDialog (GrouP prnt, CharPtr title, GrouP PNTR grp1, GrouP PNTR grp2)
3519
3520 {
3521 return CreateAnAffilDialog (prnt, title, FALSE, TRUE, TRUE, grp1, grp2);
3522 }
3523
3524 extern void DatePtrToVibrant (DatePtr dp, PopuP dateMonth, TexT dateDay, TexT dateYear)
3525
3526 {
3527 Int2 day;
3528 Char str [32];
3529 Int2 year;
3530
3531 if (dp != NULL) {
3532 if (dp->data [0] == 0) {
3533 DatePrint (dp, str);
3534 } else if (dp->data [0] == 1) {
3535 SetEnumPopup (dateMonth, months_alist, (UIEnum) dp->data [2]);
3536 day = (Int2) dp->data [3];
3537 if (day > 0 && day <= 31) {
3538 sprintf (str, "%d", (int) day);
3539 SafeSetTitle (dateDay, str);
3540 } else {
3541 SafeSetTitle (dateDay, "");
3542 }
3543 year = (Int2) dp->data [1];
3544 if (year > 0) {
3545 sprintf (str, "%d", (int) (year + 1900));
3546 SafeSetTitle (dateYear, str);
3547 } else {
3548 SafeSetTitle (dateYear, "");
3549 }
3550 } else {
3551 Message (MSG_ERROR, "Unknown date type");
3552 }
3553 } else {
3554 SafeSetValue (dateMonth, 1);
3555 SafeSetTitle (dateDay, "");
3556 SafeSetTitle (dateYear, "");
3557 }
3558 }
3559
3560 extern DatePtr VibrantToDatePtr (PopuP dateMonth, TexT dateDay, TexT dateYear)
3561
3562 {
3563 Int2 day;
3564 Int2 dateType;
3565 DatePtr dp;
3566 UIEnum month;
3567 Char str [32];
3568 Int2 year;
3569
3570 dp = DateNew ();
3571 if (dp != NULL) {
3572 dateType = 1;
3573 dp->data [0] = (Uint1) dateType;
3574 if (dateType == 0) {
3575 } else if (dateType == 1) {
3576 GetTitle (dateYear, str, sizeof (str));
3577 if (! StringHasNoText (str)) {
3578 StrToInt (str, &year);
3579 if (year >= 1900) {
3580 dp->data [1] = (Uint1) (year - 1900);
3581 } else {
3582 /* dp->data [1] = 0; */
3583 dp = DateFree (dp);
3584 return dp;
3585 }
3586 if (GetEnumPopup (dateMonth, months_alist, &month)) {
3587 dp->data [2] = (Uint1) month;
3588 }
3589 GetTitle (dateDay, str, sizeof (str));
3590 StrToInt (str, &day);
3591 dp->data [3] = (Uint1) day;
3592 } else {
3593 dp = DateFree (dp);
3594 }
3595 } else {
3596 Message (MSG_ERROR, "Unknown date type");
3597 }
3598 }
3599 return dp;
3600 }
3601
3602 static void GBQualPtrToQualsDialog (DialoG d, Pointer data)
3603
3604 {
3605 ValNodePtr head;
3606 Int2 j;
3607 size_t len;
3608 GBQualPtr list;
3609 CharPtr str;
3610 TagListPtr tlp;
3611 ValNodePtr vnp;
3612
3613 tlp = (TagListPtr) GetObjectExtra (d);
3614 list = (GBQualPtr) data;
3615 if (tlp != NULL) {
3616 head = NULL;
3617 while (list != NULL) {
3618 vnp = ValNodeNew (head);
3619 if (head == NULL) {
3620 head = vnp;
3621 }
3622 if (vnp != NULL) {
3623 if (list->qual != NULL && list->val != NULL) {
3624 len = StringLen (list->qual) + StringLen (list->val);
3625 str = MemNew (len + 4);
3626 if (str != NULL) {
3627 StringCpy (str, list->qual);
3628 StringCat (str, "\t");
3629 StringCat (str, list->val);
3630 StringCat (str, "\n");
3631 }
3632 vnp->data.ptrvalue = str;
3633 }
3634 }
3635 list = list->next;
3636 }
3637 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
3638 tlp->vnp = head;
3639 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
3640 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
3641 }
3642 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
3643 CorrectBarMax (tlp->bar, tlp->max);
3644 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
3645 }
3646 }
3647
3648 static Pointer QualsDialogToGBQualPtr (DialoG d)
3649
3650 {
3651 Char ch;
3652 GBQualPtr gbq;
3653 GBQualPtr gbqlast;
3654 GBQualPtr head;
3655 Int2 j;
3656 Int2 len;
3657 Boolean okay;
3658 CharPtr str;
3659 TagListPtr tlp;
3660 ValNodePtr vnp;
3661
3662 head = NULL;
3663 tlp = (TagListPtr) GetObjectExtra (d);
3664 if (tlp != NULL && tlp->vnp != NULL) {
3665 gbq = NULL;
3666 gbqlast = NULL;
3667 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
3668 str = (CharPtr) vnp->data.ptrvalue;
3669 okay = FALSE;
3670 len = StringLen (str);
3671 for (j = 0; j < len; j++) {
3672 ch = str [j];
3673 if (ch != ' ' && ch != '\t' && ch != '\n') {
3674 okay = TRUE;
3675 }
3676 }
3677 if (okay) {
3678 gbq = GBQualNew ();
3679 if (gbqlast == NULL) {
3680 head = gbq;
3681 } else {
3682 gbqlast->next = gbq;
3683 }
3684 gbqlast = gbq;
3685 if (gbq != NULL) {
3686 gbq->qual = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
3687 gbq->val = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
3688 }
3689 }
3690 }
3691 }
3692 return (Pointer) head;
3693 }
3694
3695 Uint2 gbqual_types [] = {
3696 TAGLIST_TEXT, TAGLIST_TEXT
3697 };
3698
3699 Uint2 gbqual_widths [] = {
3700 0, 0, 0, 0
3701 };
3702
3703 extern DialoG CreateQualsDialog (GrouP h, Uint2 rows, Int2 spacing,
3704 Int2 width1, Int2 width2);
3705 extern DialoG CreateQualsDialog (GrouP h, Uint2 rows, Int2 spacing,
3706 Int2 width1, Int2 width2)
3707
3708 {
3709 gbqual_widths [0] = width1;
3710 gbqual_widths [1] = width2;
3711 return CreateTagListDialog (h, rows, 2, spacing,
3712 gbqual_types, gbqual_widths, NULL,
3713 GBQualPtrToQualsDialog,
3714 QualsDialogToGBQualPtr);
3715 }
3716
3717 extern void CreateSeqAlignLabel (SeqAlignPtr salp, CharPtr buf, Int4 buf_size)
3718 {
3719 Int4 remaining_len, aln_pos, id_len;
3720 SeqIdPtr sip;
3721 CharPtr buf_ptr;
3722
3723 if (buf == NULL || buf_size < 1)
3724 {
3725 return;
3726 }
3727 MemSet (buf, 0, buf_size);
3728 if (salp == NULL)
3729 {
3730 return;
3731 }
3732 remaining_len = buf_size - 1;
3733 buf_ptr = buf;
3734 StringNCat (buf_ptr, "aln|", remaining_len);
3735 remaining_len -= 4;
3736
3737 if (remaining_len <= 3)
3738 {
3739 return;
3740 }
3741 buf_ptr += 4;
3742
3743 for (aln_pos = 1; aln_pos <= salp->dim && remaining_len > 2; aln_pos++)
3744 {
3745 sip = AlnMgr2GetNthSeqIdPtr(salp, aln_pos);
3746 SeqIdWrite (sip, buf_ptr, PRINTID_REPORT, remaining_len);
3747 id_len = StringLen (buf_ptr);
3748 remaining_len -= id_len;
3749 buf_ptr += id_len;
3750 /* put comma between IDs in list */
3751 if (aln_pos < salp->dim && remaining_len > 2)
3752 {
3753 StringCat (buf_ptr, ",");
3754 remaining_len -= 1;
3755 buf_ptr += 1;
3756 }
3757 }
3758
3759 /* add ellipsis to indicate unshown IDs */
3760 if (remaining_len == 0 && aln_pos < salp->dim)
3761 {
3762 buf_ptr -= 3;
3763 StringCat (buf_ptr, "...");
3764 }
3765 }
3766
3767
3768 static Boolean HasDisqualifyingUserObjects(SeqAnnotPtr sap)
3769 {
3770 AnnotDescrPtr desc;
3771 UserObjectPtr uop;
3772 ObjectIdPtr oip;
3773
3774 if (sap == NULL) {
3775 return FALSE;
3776 }
3777
3778 desc = sap->desc;
3779 while (desc != NULL) {
3780 if (desc->choice == Annot_descr_user) {
3781 uop = (UserObjectPtr) desc->data.ptrvalue;
3782 while(uop) {
3783 if(uop->type) {
3784 oip = uop->type;
3785 if(StringCmp(oip->str, "Hist Seqalign") == 0
3786 || StringCmp (oip->str, "Blast Type") == 0) {
3787 return TRUE;
3788 }
3789 }
3790 uop = uop->next;
3791 }
3792 }
3793 desc = desc->next;
3794 }
3795 return FALSE;
3796 }
3797
3798
3799 extern void GetAlignmentsInSeqEntryCallback (SeqAnnotPtr sap, Pointer userdata)
3800 {
3801 SeqAlignPtr PNTR salp_list;
3802 SeqAlignPtr salp, last_salp;
3803
3804 if (sap == NULL || sap->type != 2 || userdata == NULL || HasDisqualifyingUserObjects(sap))
3805 {
3806 return;
3807 }
3808 salp_list = (SeqAlignPtr PNTR) userdata;
3809 salp = (SeqAlignPtr) sap->data;
3810 if (salp == NULL) return;
3811 salp = SeqAlignListDup(salp);
3812 AlnMgr2IndexSeqAlign(salp);
3813 if (*salp_list == NULL)
3814 {
3815 *salp_list = salp;
3816 }
3817 else
3818 {
3819 last_salp = *salp_list;
3820 while (last_salp->next != NULL)
3821 {
3822 last_salp = last_salp->next;
3823 }
3824 last_salp->next = salp;
3825 }
3826 }
3827
3828 typedef struct intervalpage {
3829 DIALOG_MESSAGE_BLOCK
3830 DialoG ivals;
3831 ButtoN partial5;
3832 ButtoN partial3;
3833 ButtoN nullsBetween;
3834 Int2 count;
3835 SeqIdPtr PNTR sip_list;
3836 EnumFieldAssoc PNTR alist;
3837 EnumFieldAssocPtr alists [5];
3838 Int4 PNTR lengths;
3839 Boolean nucsOK;
3840 Boolean protsOK;
3841 Boolean showIdTags;
3842 FeatureFormPtr ffp;
3843 IntEdPartialProc proc;
3844
3845 Int4 strand_col; /* column for selecting strand.
3846 * 2 if nucsOK, -1 otherwise
3847 */
3848 Int4 seqid_col; /* column for entering SeqIds,
3849 * which could be in a different place
3850 * depending on nucsOK or -1 if not show_seqid
3851 */
3852 Int4 aln_col; /* column for selecting alignments,
3853 * could be in a different place if not show_seqid
3854 * or -1 if not use_aln
3855 */
3856 Boolean show_seqids; /* false when entering coordinates for an entire
3857 * alignments, true otherwise
3858 */
3859
3860 /* for editing alignment intervals */
3861 SeqAlignPtr PNTR salp_list;
3862 TaglistCallback PNTR callbacks;
3863 EnumFieldAssoc PNTR aln_alist;
3864 Int2 aln_count;
3865 Int4 PNTR aln_lengths;
3866 Boolean allow_nulls_in_list; /* some sequences may be all gap
3867 * in the specified interval -
3868 * if this value is FALSE, return
3869 * a NULL for the entire list,
3870 * otherwise allow NULLs to appear
3871 * in the list.
3872 */
3873
3874 } IntervalPage, PNTR IntervalPagePtr;
3875
3876 #define NUM_IVAL_ROWS 7
3877 #define EXTRA_HEIGHT 2
3878
3879 static void ClearBspScratch (BioseqPtr bsp, Pointer userdata)
3880
3881 {
3882 if (bsp == NULL) return;
3883 bsp->idx.scratch = NULL;
3884 }
3885
3886 static void AddToSipList (IntervalPagePtr ipp, BioseqPtr bsp)
3887
3888 {
3889 /*
3890 Int2 j;
3891 */
3892 SeqIdPtr sip;
3893
3894 if (ipp == NULL || bsp == NULL) return;
3895 if (bsp->idx.scratch != NULL) return;
3896 sip = SeqIdFindBest (bsp->id, 0);
3897 if (sip == NULL) return;
3898 /*
3899 for (j = 1; j <= ipp->count; j++) {
3900 if (SeqIdComp (sip, ipp->sip_list [j]) == SIC_YES) return;
3901 }
3902 */
3903 ipp->count++;
3904 ipp->sip_list [ipp->count] = SeqIdDup (sip);
3905 bsp->idx.scratch = (Pointer) bsp;
3906 }
3907
3908 static void FillInProducts (SeqEntryPtr sep, Pointer mydata,
3909 Int4 index, Int2 indent)
3910
3911 {
3912 BioseqPtr bsp;
3913 IntervalPagePtr ipp;
3914 SeqIdPtr sip;
3915 SeqLocPtr slp;
3916 ValNode vn;
3917
3918 if (sep != NULL && mydata != NULL && sep->choice == 1) {
3919 ipp = (IntervalPagePtr) mydata;
3920 bsp = (BioseqPtr) sep->data.ptrvalue;
3921 if (bsp != NULL) {
3922 if ((ipp->nucsOK && ISA_na (bsp->mol)) ||
3923 (ipp->protsOK && ISA_aa (bsp->mol))) {
3924 AddToSipList (ipp, bsp);
3925 }
3926 if (bsp->repr == Seq_repr_seg && bsp->seq_ext != NULL) {
3927 vn.choice = SEQLOC_MIX;
3928 vn.next = NULL;
3929 vn.data.ptrvalue = bsp->seq_ext;
3930 slp = SeqLocFindNext (&vn, NULL);
3931 while (slp != NULL) {
3932 sip = SeqLocId (slp);
3933 if (sip != NULL) {
3934 bsp = BioseqFindCore (sip);
3935 if (bsp != NULL) {
3936 AddToSipList (ipp, bsp);
3937 } else {
3938 bsp = BioseqLockById (sip);
3939 if (bsp != NULL) {
3940 AddToSipList (ipp, bsp);
3941 BioseqUnlock (bsp);
3942 }
3943 }
3944 }
3945 slp = SeqLocFindNext (&vn, slp);
3946 }
3947 }
3948 }
3949 }
3950 }
3951
3952 static Int4 SegmentedEntryList (SeqEntryPtr sep, Pointer mydata,
3953 SeqEntryFunc mycallback,
3954 Int4 index, Int2 indent)
3955
3956 {
3957 BioseqPtr bsp;
3958 BioseqSetPtr bssp;
3959 SeqLocPtr slp;
3960 ValNode vn;
3961
3962 if (sep == NULL) return index;
3963 if (IS_Bioseq (sep)) {
3964 if (mycallback != NULL)
3965 (*mycallback) (sep, mydata, index, indent);
3966 bsp = (BioseqPtr) sep->data.ptrvalue;
3967 if (bsp != NULL && bsp->repr == Seq_repr_seg && bsp->seq_ext != NULL) {
3968 vn.choice = SEQLOC_MIX;
3969 vn.next = NULL;
3970 vn.data.ptrvalue = bsp->seq_ext;
3971 slp = SeqLocFindNext (&vn, NULL);
3972 while (slp != NULL) {
3973 index++;
3974 slp = SeqLocFindNext (&vn, slp);
3975 }
3976 }
3977 return index + 1;
3978 }
3979 /*
3980 if (Bioseq_set_class (sep) == 4) return index;
3981 index++;
3982 */
3983 bssp = (BioseqSetPtr) sep->data.ptrvalue;
3984 sep = bssp->seq_set;
3985 indent++;
3986 while (sep != NULL) {
3987 index = SegmentedEntryList (sep, mydata, mycallback, index, indent);
3988 sep = sep->next;
3989 }
3990 return index;
3991 }
3992
3993 #define SegmentedEntryCount( a ) SegmentedEntryList( a ,NULL,NULL,0,0);
3994
3995 static ENUM_ALIST(strand_alist)
3996 {" ", Seq_strand_unknown}, /* 0 */
3997 {"Plus", Seq_strand_plus}, /* 1 */
3998 {"Minus", Seq_strand_minus}, /* 2 */
3999 /*
4000 {"Both", Seq_strand_both},
4001 {"Reverse", Seq_strand_both_rev},
4002 */
4003 {"Other", Seq_strand_other}, /* 255 */
4004 END_ENUM_ALIST
4005
4006 static Boolean IsSeqIdInValNodeList (SeqIdPtr sip, ValNodePtr list)
4007 {
4008 if (sip == NULL)
4009 {
4010 return FALSE;
4011 }
4012 while (list != NULL)
4013 {
4014 if (SeqIdComp (sip, list->data.ptrvalue) == SIC_YES)
4015 {
4016 return TRUE;
4017 }
4018 list = list->next;
4019 }
4020 return FALSE;
4021 }
4022
4023 static Int4 FindLastStopForSeqId (SeqLocPtr slp, SeqIdPtr sip)
4024 {
4025 Int4 last_stop = 0, new_stop;
4026 SeqLocPtr tmp_slp;
4027 SeqIdPtr tmp_sip;
4028
4029 tmp_slp = SeqLocFindNext (slp, NULL);
4030 while (tmp_slp != NULL)
4031 {
4032 tmp_sip = SeqLocId (tmp_slp);
4033 if (SeqIdComp (sip, tmp_sip) == SIC_YES)
4034 {
4035 new_stop = SeqLocStop (slp);
4036 if (new_stop > last_stop)
4037 {
4038 last_stop = new_stop;
4039 }
4040 }
4041 tmp_slp = SeqLocFindNext (slp, tmp_slp);
4042 }
4043 return last_stop;
4044 }
4045
4046 extern void UpdateTagListPopupChoices (DialoG d, Int4 column);
4047
4048 /* We need to make sure that all IDs in the location are found in the enum list
4049 * for the interval editor ID Enum */
4050 static void CorrectIntervalEditorSeqIdEnum (IntervalPagePtr ipp, SeqLocPtr slp)
4051 {
4052 SeqLocPtr tmp_slp;
4053 SeqIdPtr sip;
4054 Int4 j = 0;
4055 Boolean found;
4056 ValNodePtr missing_list = NULL, missing_vnp;
4057 Int4 new_count;
4058 SeqIdPtr PNTR new_sip_list;
4059 EnumFieldAssoc PNTR new_alist;
4060 Int4 PNTR new_lengths;
4061 BioseqPtr bsp;
4062 Char str [128];
4063 CharPtr ptr;
4064
4065 if (ipp == NULL || slp == NULL)
4066 {
4067 return;
4068 }
4069
4070 tmp_slp = SeqLocFindNext (slp, NULL);
4071 while (tmp_slp != NULL)
4072 {
4073 sip = SeqLocId (tmp_slp);
4074 if (!IsSeqIdInValNodeList (sip, missing_list))
4075 {
4076 found = FALSE;
4077 for (j = 1; j <= ipp->count && !found; j++)
4078 {
4079 if (SeqIdComp (sip, ipp->sip_list [j]) == SIC_YES)
4080 {
4081 found = TRUE;
4082 }
4083 }
4084 /* this process takes longer, so don't combine it with the above
4085 * loop
4086 */
4087 if (!found)
4088 {
4089 for (j = 1; j <= ipp->count && !found; j++)
4090 {
4091 bsp = BioseqFindCore (ipp->sip_list [j]);
4092 if (bsp == NULL) {
4093 bsp = BioseqLockById (ipp->sip_list [j]);
4094 BioseqUnlock (bsp);
4095 }
4096 if (bsp != NULL && SeqIdIn (sip, bsp->id))
4097 {
4098 found = TRUE;
4099 }
4100 }
4101 }
4102 if (!found)
4103 {
4104 ValNodeAddPointer (&missing_list, 0, sip);
4105 }
4106 }
4107
4108 tmp_slp = SeqLocFindNext (slp, tmp_slp);
4109 }
4110
4111 if (missing_list != NULL)
4112 {
4113 new_count = ipp->count + 4 + ValNodeLen (missing_list);
4114 new_sip_list = MemNew (sizeof (SeqIdPtr) * (size_t) new_count);
4115 new_alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) new_count);
4116 new_lengths = MemNew (sizeof (Int4) * (size_t) new_count);
4117 if (ipp->sip_list != NULL) {
4118 /* first one is blank, remainder are actual data */
4119 for (j = 0; j < ipp->count + 1; j++)
4120 {
4121 new_sip_list [j] = ipp->sip_list [j];
4122 ipp->sip_list [j] = NULL;
4123 new_alist [j].name = ipp->alist [j].name;
4124 ipp->alist [j].name = NULL;
4125 new_alist [j].value = ipp->alist [j].value;
4126 new_lengths [j] = ipp->lengths [j];
4127 }
4128 }
4129
4130 missing_vnp = missing_list;
4131 while (j < new_count - 1 && missing_vnp != NULL)
4132 {
4133 new_sip_list [j] = SeqIdDup (missing_vnp->data.ptrvalue);
4134 new_alist [j].value = j;
4135
4136 sip = new_sip_list [j];
4137 bsp = BioseqFindCore (sip);
4138 if (bsp == NULL) {
4139 bsp = BioseqLockById (sip);
4140 BioseqUnlock (bsp);
4141 }
4142 if (bsp != NULL)
4143 {
4144 new_lengths [j] = bsp->length;
4145 sip = SeqIdFindWorst (bsp->id);
4146 }
4147 else
4148 {
4149 new_lengths [j] = FindLastStopForSeqId (slp, sip);
4150 }
4151 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
4152 ptr = StringChr (str, '|');
4153 if (ptr == NULL) {
4154 ptr = str;
4155 } else {
4156 ptr++;
4157 }
4158 new_alist [j].name = StringSave (ptr);
4159 missing_vnp = missing_vnp->next;
4160 j++;
4161 }
4162 /* set terminator for enum list */
4163 new_alist [j].name = NULL;
4164 new_alist [j].value = (UIEnum) 0;
4165
4166 ipp->sip_list = MemFree (ipp->sip_list);
4167 ipp->sip_list = new_sip_list;
4168 ipp->alist = MemFree (ipp->alist);
4169 ipp->alist = new_alist;
4170 ipp->lengths = MemFree (ipp->lengths);
4171 ipp->lengths = new_lengths;
4172 ipp->count = j;
4173
4174 ipp->alists [ipp->seqid_col] = ipp->alist;
4175 UpdateTagListPopupChoices (ipp->ivals, ipp->seqid_col);
4176 }
4177 missing_list = ValNodeFree (missing_list);
4178 }
4179
4180 static void
4181 BuildIntervalString
4182 (IntervalPagePtr ipp,
4183 CharPtr fuzz_from_ch,
4184 Int4 start,
4185 CharPtr fuzz_to_ch,
4186 Int4 stop,
4187 Uint2 strand,
4188 Int4 seq,
4189 Int4 salp_num,
4190 Boolean isInterval,
4191 Boolean isPoint,
4192 CharPtr buf,
4193 Int4 buf_len)
4194 {
4195 CharPtr cp;
4196 Boolean need_tab = FALSE;
4197
4198 if (ipp == NULL || fuzz_from_ch == NULL || fuzz_to_ch == NULL || buf == NULL || buf_len == 0)
4199 {
4200 return;
4201 }
4202
4203 MemSet (buf, 0, buf_len);
4204
4205 if (isInterval)
4206 {
4207 sprintf (buf, "%s%ld\t%s%ld",
4208 fuzz_from_ch, (long) (start + 1),
4209 fuzz_to_ch, (long) (stop + 1));
4210 need_tab = TRUE;
4211 }
4212 else if (isPoint)
4213 {
4214 sprintf (buf, "%ld%s\t%ld%s",
4215 (long) (start + 1), fuzz_from_ch,
4216 (long) (stop + 1), fuzz_to_ch);
4217 need_tab = TRUE;
4218 }
4219
4220 cp = buf + StringLen (buf);
4221 if (ipp->strand_col > -1)
4222 {
4223 if (need_tab)
4224 {
4225 StringCat (cp, "\t");
4226 cp++;
4227 }
4228 sprintf (cp, "%d", (int) strand);
4229 need_tab = TRUE;
4230 cp += StringLen (cp);
4231 }
4232
4233 if (ipp->seqid_col > -1)
4234 {
4235 if (need_tab)
4236 {
4237 StringCat (cp, "\t");
4238 cp++;
4239 }
4240 sprintf (cp, "%d", (int) seq);
4241 need_tab = TRUE;
4242 cp += StringLen (cp);
4243 }
4244
4245 if (ipp->aln_col > -1)
4246 {
4247 if (need_tab)
4248 {
4249 StringCat (cp, "\t");
4250 cp++;
4251 }
4252 sprintf (cp, "%d", (int) salp_num);
4253 need_tab = TRUE;
4254 cp += StringLen (cp);
4255 }
4256 StringCat (cp, "\n");
4257 }
4258
4259 static void SeqLocPtrToIntervalPage (DialoG d, Pointer data)
4260
4261 {
4262 BioseqPtr bsp;
4263 SeqLocPtr firstSlp;
4264 Char fuzz_from_ch [4];
4265 Char fuzz_to_ch [4];
4266 ValNodePtr head;
4267 SeqIdPtr id;
4268 IntFuzzPtr ifp;
4269 IntervalPagePtr ipp;
4270 Boolean isInterval;
4271 Boolean isPoint;
4272 Int2 j;
4273 SeqLocPtr lastSlp;
4274 SeqLocPtr location;
4275 SeqLocPtr next;
4276 SeqEntryPtr oldscope;
4277 Boolean partial5;
4278 Boolean partial3;
4279 Int2 seq;
4280 SeqIntPtr sip;
4281 SeqLocPtr slp;
4282 SeqPntPtr spp;
4283 Int4 start;
4284 Int4 stop;
4285 Char str [255];
4286 Uint1 strand, aln_strand;
4287 TagListPtr tlp;
4288 ValNodePtr vnp;
4289 Int4 salp_num, salp_row;
4290 SeqIdPtr tmp_sip, bsp_id;
4291
4292 ipp = (IntervalPagePtr) GetObjectExtra (d);
4293 if (ipp == NULL) return;
4294 SafeSetStatus (ipp->partial5, FALSE);
4295 SafeSetStatus (ipp->partial3, FALSE);
4296 tlp = GetObjectExtra (ipp->ivals);
4297 if (tlp == NULL) return;
4298
4299 location = (SeqLocPtr) data;
4300 partial5 = FALSE;
4301 partial3 = FALSE;
4302 head = NULL;
4303
4304 if (location == NULL)
4305 {
4306 if (ipp->count == 1)
4307 {
4308 sprintf (str, "\t\t\t1\n");
4309 vnp = ValNodeNew (head);
4310 if (head == NULL) {
4311 head = vnp;
4312 }
4313 if (vnp != NULL) {
4314 vnp->data.ptrvalue = StringSave (str);
4315 }
4316 }
4317 }
4318 if (location != NULL) {
4319 CorrectIntervalEditorSeqIdEnum (ipp, location);
4320 firstSlp = NULL;
4321 lastSlp = NULL;
4322 slp = SeqLocFindNext (location, NULL);
4323 while (slp != NULL) {
4324 if (firstSlp == NULL) {
4325 firstSlp = slp;
4326 }
4327 lastSlp = slp;
4328 next = SeqLocFindNext (location, slp);
4329 if (slp->choice == SEQLOC_NULL) {
4330 SafeSetStatus (ipp->nullsBetween, TRUE);
4331 SafeShow (ipp->nullsBetween);
4332 } else {
4333 id = SeqLocId (slp);
4334 if (id != NULL) {
4335 bsp = BioseqFind (id);
4336 if (bsp == NULL) {
4337 oldscope = SeqEntrySetScope (NULL);
4338 if (oldscope != NULL) {
4339 bsp = BioseqFind (id);
4340 SeqEntrySetScope (oldscope);
4341 }
4342 }
4343 isInterval = TRUE;
4344 isPoint = FALSE;
4345 StringCpy (fuzz_from_ch, "");
4346 StringCpy (fuzz_to_ch, "");
4347 if (bsp == NULL) {
4348 start = SeqLocStart (slp);
4349 stop = SeqLocStop (slp);
4350 }
4351 else
4352 {
4353 start = GetOffsetInBioseq (slp, bsp, SEQLOC_START);
4354 stop = GetOffsetInBioseq (slp, bsp, SEQLOC_STOP);
4355 }
4356 if (start == stop && slp->choice == SEQLOC_PNT) {
4357 spp = (SeqPntPtr) slp->data.ptrvalue;
4358 if (spp != NULL) {
4359 ifp = spp->fuzz;
4360 if (ifp != NULL && ifp->choice == 4 && ifp->a == 3) {
4361 isInterval = FALSE;
4362 isPoint = TRUE;
4363 StringCpy (fuzz_from_ch, "^");
4364 /* start--; */ /* compensate for other fix */
4365 stop++; /* compensate for other fix */
4366 }
4367 }
4368 }
4369 strand = SeqLocStrand (slp);
4370 if (strand > Seq_strand_both_rev && strand != Seq_strand_other) {
4371 strand = Seq_strand_unknown;
4372 }
4373 /*
4374 if (strand == Seq_strand_unknown) {
4375 strand = Seq_strand_plus;
4376 }
4377 */
4378 if (! ipp->nucsOK) {
4379 strand = 0;
4380 }
4381 seq = 0;
4382 if (ipp->sip_list != NULL && bsp != NULL) {
4383 for (j = 1; j <= ipp->count && seq == 0; j++) {
4384 if (SeqIdComp (SeqIdFindBest (bsp->id, 0), ipp->sip_list[j]) == SIC_YES) {
4385 seq = j;
4386 }
4387 }
4388 }
4389
4390 salp_num = 0;
4391 salp_row = 0;
4392 if (seq > 0 && ipp->salp_list != NULL)
4393 {
4394 salp_num = 1;
4395 while (salp_num <= ipp->aln_count
4396 && salp_row == 0)
4397 {
4398 tmp_sip = SeqIdPtrFromSeqAlign (ipp->salp_list [salp_num]);
4399 bsp = BioseqFind (ipp->sip_list [seq]);
4400 if (bsp != NULL)
4401 {
4402 for (bsp_id = bsp->id;
4403 bsp_id != NULL && salp_row == 0;
4404 bsp_id = bsp_id->next)
4405 {
4406 salp_row = SeqIdOrderInBioseqIdList(bsp_id, tmp_sip);
4407 }
4408 }
4409 if (salp_row < 1)
4410 {
4411 salp_num++;
4412 }
4413 }
4414 if (salp_row < 1)
4415 {
4416 salp_num = 0;
4417 }
4418 else
4419 {
4420 start = AlnMgr2MapBioseqToSeqAlign(ipp->salp_list [salp_num], start, salp_row);
4421 stop = AlnMgr2MapBioseqToSeqAlign(ipp->salp_list [salp_num], stop, salp_row);
4422 aln_strand = AlnMgr2GetNthStrand (ipp->salp_list [salp_num], salp_row);
4423 /* if reverse strand in alignment, reverse strand for location */
4424 if (aln_strand == Seq_strand_minus)
4425 {
4426 if (strand == Seq_strand_minus)
4427 {
4428 strand = Seq_strand_plus;
4429 }
4430 else if (strand == Seq_strand_plus)
4431 {
4432 strand = Seq_strand_minus;
4433 }
4434 }
4435 }
4436 }
4437
4438 BuildIntervalString (ipp, fuzz_from_ch, start, fuzz_to_ch, stop,
4439 strand, seq, salp_num, isInterval, isPoint,
4440 str, sizeof (str));
4441 vnp = ValNodeNew (head);
4442 if (head == NULL) {
4443 head = vnp;
4444 }
4445 if (vnp != NULL) {
4446 vnp->data.ptrvalue = StringSave (str);
4447 }
4448 }
4449 }
4450 slp = next;
4451 }
4452 if (firstSlp != NULL) {
4453 if (firstSlp->choice == SEQLOC_INT && firstSlp->data.ptrvalue != NULL) {
4454 sip = (SeqIntPtr) firstSlp->data.ptrvalue;
4455 if (sip->strand == Seq_strand_minus || sip->strand == Seq_strand_both_rev) {
4456 ifp = sip->if_to;
4457 if (ifp != NULL && ifp->choice == 4 && ifp->a == 1) {
4458 partial5 = TRUE;
4459 }
4460 } else {
4461 ifp = sip->if_from;
4462 if (ifp != NULL && ifp->choice == 4 && ifp->a == 2) {
4463 partial5 = TRUE;
4464 }
4465 }
4466 } else if (firstSlp->choice == SEQLOC_PNT && firstSlp->data.ptrvalue != NULL) {
4467 spp = (SeqPntPtr) firstSlp->data.ptrvalue;
4468 if (spp->strand == Seq_strand_minus || spp->strand == Seq_strand_both_rev) {
4469 ifp = spp->fuzz;
4470 if (ifp != NULL && ifp->choice == 4 && ifp->a == 1) {
4471 partial5 = TRUE;
4472 }
4473 } else {
4474 ifp = spp->fuzz;
4475 if (ifp != NULL && ifp->choice == 4 && ifp->a == 2) {
4476 partial5 = TRUE;
4477 }
4478 }
4479 }
4480 }
4481 if (lastSlp != NULL) {
4482 if (lastSlp->choice == SEQLOC_INT && lastSlp->data.ptrvalue != NULL) {
4483 sip = (SeqIntPtr) lastSlp->data.ptrvalue;
4484 if (sip->strand == Seq_strand_minus || sip->strand == Seq_strand_both_rev) {
4485 ifp = sip->if_from;
4486 if (ifp != NULL && ifp->choice == 4 && ifp->a == 2) {
4487 partial3 = TRUE;
4488 }
4489 } else {
4490 ifp = sip->if_to;
4491 if (ifp != NULL && ifp->choice == 4 && ifp->a == 1) {
4492 partial3 = TRUE;
4493 }
4494 }
4495 } else if (lastSlp->choice == SEQLOC_PNT && lastSlp->data.ptrvalue != NULL) {
4496 spp = (SeqPntPtr) lastSlp->data.ptrvalue;
4497 if (spp->strand == Seq_strand_minus || spp->strand == Seq_strand_both_rev) {
4498 ifp = spp->fuzz;
4499 if (ifp != NULL && ifp->choice == 4 && ifp->a == 2) {
4500 partial3 = TRUE;
4501 }
4502 } else {
4503 ifp = spp->fuzz;
4504 if (ifp != NULL && ifp->choice == 4 && ifp->a == 1) {
4505 partial3 = TRUE;
4506 }
4507 }
4508 }
4509 }
4510 }
4511 SafeSetStatus (ipp->partial5, partial5);
4512 SafeSetStatus (ipp->partial3, partial3);
4513
4514 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
4515 tlp->vnp = head;
4516 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
4517 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
4518 }
4519 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
4520 CorrectBarMax (tlp->bar, tlp->max);
4521 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
4522 }
4523
4524 extern void SetSequenceAndStrandForIntervalPage (DialoG d)
4525 {
4526 SendMessageToDialog (d, NUM_VIB_MSG + 1);
4527 }
4528
4529 static Boolean
4530 ReadFromValueFromDialogLine
4531 (CharPtr line,
4532 Int4Ptr p_from_val,
4533 BoolPtr fuzz_after)
4534 {
4535 CharPtr txt, ptr;
4536 Int4 len;
4537 Boolean okay;
4538 Int4 val;
4539 Int4 j;
4540 Char ch;
4541
4542 if (p_from_val == NULL || fuzz_after == NULL || StringHasNoText (line))
4543 {
4544 return FALSE;
4545 }
4546
4547 txt = ExtractTagListColumn (line, 0);
4548 okay = FALSE;
4549 len = StringLen (txt);
4550 for (j = 0; j < len; j++) {
4551 ch = txt [j];
4552 if (ch != ' ' && ch != '\t' && ch != '\n') {
4553 okay = TRUE;
4554 }
4555 }
4556 if (okay) {
4557 *fuzz_after = FALSE;
4558 *p_from_val = 0;
4559
4560 ptr = StringChr (txt, '<');
4561 if (ptr != NULL) {
4562 *ptr = ' ';
4563 }
4564 ptr = StringChr (txt, '>');
4565 if (ptr != NULL) {
4566 *ptr = ' ';
4567 }
4568 ptr = StringChr (txt, '^');
4569 if (ptr != NULL) {
4570 *fuzz_after = TRUE;
4571 *ptr = ' ';
4572 }
4573 TrimSpacesAroundString (txt);
4574 if (StrToLong (txt, &val)) {
4575 *p_from_val = val;
4576 } else {
4577 okay = FALSE;
4578 }
4579 } else {
4580 okay = FALSE;
4581 }
4582 MemFree (txt);
4583 return okay;
4584 }
4585
4586 static Boolean
4587 ReadToValueFromDialogLine
4588 (CharPtr line,
4589 Int4Ptr p_to_val,
4590 Int4Ptr p_from_val,
4591 BoolPtr fuzz_after,
4592 BoolPtr isInterval,
4593 BoolPtr isPoint,
4594 Boolean partial5,
4595 Boolean partial3)
4596 {
4597 CharPtr txt, ptr;
4598 Int4 val, tmp;
4599 Boolean okay = TRUE;
4600
4601 if (p_to_val == NULL || p_from_val == NULL || fuzz_after == NULL
4602 || isInterval == NULL || isPoint == NULL)
4603 {
4604 return FALSE;
4605 }
4606
4607 *p_to_val = 0;
4608
4609 txt = ExtractTagListColumn (line, 1);
4610 if (! StringHasNoText (txt)) {
4611 ptr = StringChr (txt, '<');
4612 if (ptr != NULL) {
4613 *ptr = ' ';
4614 }
4615 ptr = StringChr (txt, '>');
4616 if (ptr != NULL) {
4617 *ptr = ' ';
4618 }
4619 ptr = StringChr (txt, '^');
4620 if (ptr != NULL) {
4621 *fuzz_after = TRUE;
4622 *ptr = ' ';
4623 }
4624 TrimSpacesAroundString (txt);
4625 if (StrToLong (txt, &val)) {
4626 *p_to_val = val;
4627 if (*fuzz_after && *p_to_val == *p_from_val + 1) {
4628 *isInterval = FALSE;
4629 *isPoint = TRUE;
4630 /* from++; */ /* this was causing point to be thrown off */
4631 } else if (*p_to_val == *p_from_val && (! partial5) && (! partial3)) {
4632 *isInterval = FALSE;
4633 *isPoint = TRUE;
4634 }
4635 } else {
4636 okay = FALSE;
4637 }
4638 } else {
4639 /*
4640 okay = FALSE;
4641 */
4642 *isInterval = FALSE;
4643 *isPoint = TRUE;
4644 *p_to_val = *p_from_val;
4645 }
4646 MemFree (txt);
4647
4648 if (okay && *isInterval) {
4649 if (*p_from_val > *p_to_val) {
4650 tmp = *p_from_val;
4651 *p_from_val = *p_to_val;
4652 *p_to_val = tmp;
4653 }
4654 }
4655
4656
4657 return okay;
4658 }
4659
4660 static Boolean
4661 ReadStrandFromDialogLine
4662 (CharPtr line,
4663 Int4 strand_col,
4664 Uint2Ptr p_strand_val,
4665 Uint2Ptr p_prev_strand_val)
4666 {
4667 CharPtr txt;
4668 Int2 val2;
4669
4670 if (p_strand_val == NULL
4671 || p_prev_strand_val == NULL)
4672 {
4673 return FALSE;
4674 }
4675
4676 *p_strand_val = Seq_strand_unknown;
4677 if (strand_col > -1) {
4678 txt = ExtractTagListColumn (line, strand_col);
4679 if (txt != NULL && StrToInt (txt, &val2)) {
4680 *p_strand_val = val2;
4681 if (*p_strand_val > Seq_strand_both_rev) {
4682 *p_strand_val = Seq_strand_other;
4683 }
4684 *p_prev_strand_val = *p_strand_val;
4685 } else {
4686 *p_strand_val = *p_prev_strand_val;
4687 }
4688 MemFree (txt);
4689 }
4690 if (*p_strand_val == Seq_strand_unknown) {
4691 *p_strand_val = Seq_strand_plus;
4692 }
4693 return TRUE;
4694 }
4695
4696 static Boolean
4697 ReadSeqIdFromDialogLine
4698 (CharPtr line,
4699 Int4 seqid_col,
4700 SeqIdPtr PNTR p_sip_val,
4701 SeqIdPtr PNTR p_prev_sip_val,
4702 SeqIdPtr PNTR sip_list,
4703 Int4 sip_count)
4704 {
4705 CharPtr txt;
4706 Int2 val2;
4707 Boolean okay = TRUE;
4708
4709 if (p_sip_val == NULL || p_prev_sip_val == NULL
4710 || sip_count == 0 || sip_list == NULL
4711 || seqid_col < 0)
4712 {
4713 return FALSE;
4714 }
4715 *p_sip_val = NULL;
4716 txt = ExtractTagListColumn (line, seqid_col);
4717 if (txt != NULL) {
4718 if (! StrToInt (txt, &val2) || val2 <= 0)
4719 {
4720 if (*p_prev_sip_val != NULL)
4721 {
4722 *p_sip_val = *p_prev_sip_val;
4723 }
4724 else
4725 {
4726 okay = FALSE;
4727 }
4728 }
4729 else if (val2 <= sip_count)
4730 {
4731 *p_sip_val = sip_list [val2];
4732 *p_prev_sip_val = *p_sip_val;
4733 } else {
4734 okay = FALSE;
4735 }
4736 }
4737 else
4738 {
4739 okay = FALSE;
4740 }
4741 MemFree (txt);
4742 return okay;
4743 }
4744
4745 static Boolean
4746 ReadSeqAlignFromDialogLine
4747 (CharPtr line,
4748 Int4 aln_col,
4749 SeqAlignPtr PNTR p_salp_val,
4750 SeqAlignPtr PNTR p_prev_salp_val,
4751 SeqAlignPtr PNTR salp_list,
4752 Int4 salp_count)
4753 {
4754 CharPtr txt;
4755 Int2 val2;
4756 Boolean okay = TRUE;
4757
4758 if (p_salp_val == NULL || p_prev_salp_val == NULL
4759 || salp_count == 0 || salp_list == NULL
4760 || aln_col < 0)
4761 {
4762 return FALSE;
4763 }
4764
4765 txt = ExtractTagListColumn (line, aln_col);
4766 if (txt != NULL) {
4767 if (! StrToInt (txt, &val2) || val2 <= 0)
4768 {
4769 if (*p_prev_salp_val != NULL)
4770 {
4771 *p_salp_val = *p_prev_salp_val;
4772 }
4773 else
4774 {
4775 okay = FALSE;
4776 }
4777 }
4778 else if (val2 <= salp_count)
4779 {
4780 *p_salp_val = salp_list [val2];
4781 *p_prev_salp_val = *p_salp_val;
4782 } else {
4783 okay = FALSE;
4784 }
4785 }
4786 else
4787 {
4788 if (*p_prev_salp_val == NULL)
4789 {
4790 okay = FALSE;
4791 }
4792 else
4793 {
4794 *p_salp_val = *p_prev_salp_val;
4795 }
4796 }
4797 MemFree (txt);
4798 return okay;
4799 }
4800
4801 static Boolean
4802 GetBioseqAlignmentRow
4803 (SeqAlignPtr salp,
4804 BioseqPtr bsp,
4805 Int4Ptr aln_row)
4806 {
4807 SeqIdPtr tmp_sip, bsp_id;
4808 if (salp == NULL || bsp == NULL || aln_row == NULL)
4809 {
4810 return FALSE;
4811 }
4812
4813 *aln_row = 0;
4814
4815 tmp_sip = SeqIdPtrFromSeqAlign (salp);
4816
4817 for (bsp_id = bsp->id;
4818 bsp_id != NULL && *aln_row == 0;
4819 bsp_id = bsp_id->next)
4820 {
4821 *aln_row = SeqIdOrderInBioseqIdList(bsp_id, tmp_sip);
4822 }
4823 if (*aln_row < 1)
4824 {
4825 return FALSE;
4826 }
4827 else
4828 {
4829 return TRUE;
4830 }
4831 }
4832
4833 static void
4834 ListAlignmentsThatContainSequence
4835 (SeqAlignPtr PNTR salp_list,
4836 Int4 salp_count,
4837 BioseqPtr bsp,
4838 SeqIdPtr sip,
4839 ValNodePtr PNTR head)
4840 {
4841 Int4 i;
4842 Char str [34];
4843 Char id_label [128];
4844 Int4 aln_row;
4845 ValNodePtr good_aln = NULL;
4846 CharPtr none_found_fmt = "%s is not found in any alignments";
4847 CharPtr one_found_fmt = "%s is found in %s";
4848 CharPtr some_found_fmt = "%s is found in the following alignments";
4849 CharPtr err_msg;
4850 CharPtr cp;
4851
4852 if (head == NULL || bsp == NULL || sip == NULL)
4853 {
4854 return;
4855 }
4856 SeqIdWrite (sip, id_label, PRINTID_REPORT, sizeof (id_label));
4857
4858 /* indent the names of the alignments */
4859 str [0] = ' ';
4860 str [1] = ' ';
4861 str [2] = ' ';
4862 str [3] = ' ';
4863 for (i = 0; i < salp_count; i++)
4864 {
4865 if (GetBioseqAlignmentRow (salp_list [i], bsp, &aln_row))
4866 {
4867 CreateSeqAlignLabel (salp_list [i], str + 4, sizeof (str) - 4);
4868 ValNodeAddPointer (&good_aln, 0, StringSave (str));
4869 }
4870 }
4871 if (good_aln == NULL)
4872 {
4873 err_msg = (CharPtr) MemNew ((StringLen (none_found_fmt) + StringLen (id_label))
4874 * sizeof (Char));
4875 if (err_msg != NULL)
4876 {
4877 sprintf (err_msg, none_found_fmt, id_label);
4878 ValNodeAddPointer (head, 0, err_msg);
4879 }
4880 }
4881 else if (good_aln->next == NULL)
4882 {
4883 err_msg = (CharPtr) MemNew ((StringLen (one_found_fmt)
4884 + StringLen (id_label)
4885 + StringLen (good_aln->data.ptrvalue))
4886 * sizeof (Char));
4887 if (err_msg != NULL)
4888 {
4889 cp = (CharPtr) good_aln->data.ptrvalue;
4890 /* skip over indented space */
4891 cp += 4;
4892 sprintf (err_msg, one_found_fmt, id_label, cp);
4893 ValNodeAddPointer (head, 0, err_msg);
4894 good_aln = ValNodeFreeData (good_aln);
4895 }
4896 }
4897 else
4898 {
4899 err_msg = (CharPtr) MemNew ((StringLen (some_found_fmt)
4900 + StringLen (id_label))
4901 * sizeof (Char));
4902 if (err_msg != NULL)
4903 {
4904 sprintf (err_msg, some_found_fmt, id_label);
4905 ValNodeAddPointer (head, 0, err_msg);
4906 ValNodeLink (head, good_aln);
4907 }
4908 }
4909 }
4910
4911 static void
4912 ListSequencesInAlignment
4913 (SeqIdPtr PNTR sip_list,
4914 Int4 sip_count,
4915 SeqAlignPtr salp,
4916 ValNodePtr PNTR head)
4917 {
4918 SeqIdPtr tmp_sip, aln_id;
4919 BioseqPtr bsp;
4920 Int4 i;
4921 Boolean found;
4922 Char id_label [128];
4923
4924 if (salp == NULL || head == NULL)
4925 {
4926 return;
4927 }
4928
4929 tmp_sip = SeqIdPtrFromSeqAlign (salp);
4930 if (tmp_sip == NULL)
4931 {
4932 ValNodeAddPointer (head, 0, StringSave ("Selected alignment contains no sequences"));
4933 return;
4934 }
4935 /* indent list of sequence IDs */
4936 id_label [0] = ' ';
4937 id_label [1] = ' ';
4938 id_label [2] = ' ';
4939 id_label [3] = ' ';
4940 ValNodeAddPointer (head, 0, StringSave ("The selected alignment contains the following sequences:"));
4941 for (aln_id = tmp_sip; aln_id != NULL; aln_id = aln_id->next)
4942 {
4943 bsp = BioseqFind (aln_id);
4944 if (bsp == NULL)
4945 {
4946 continue;
4947 }
4948 found = FALSE;
4949 for (i = 0; i < sip_count && ! found; i++)
4950 {
4951 if (SeqIdIn (sip_list [i], bsp->id))
4952 {
4953 SeqIdWrite (sip_list [i], id_label + 4, PRINTID_REPORT, sizeof (id_label) - 4);
4954 ValNodeAddPointer (head, 0, StringSave (id_label));
4955 found = TRUE;
4956 }
4957 }
4958 }
4959 }
4960
4961 extern Boolean AdjustFromForGap (Int4Ptr p_from, SeqAlignPtr salp, Int4 aln_len, Int4 aln_row)
4962 {
4963 Int4 aln_from, aln_offset = 0;
4964
4965 if (p_from == NULL || salp == NULL || aln_len == 0 || aln_row == 0
4966 || *p_from < 1)
4967 {
4968 return FALSE;
4969 }
4970
4971 aln_from = AlnMgr2MapSeqAlignToBioseq(salp, (*p_from) - 1, aln_row);
4972
4973 while (aln_from == -2 && (*p_from) + aln_offset < aln_len)
4974 {
4975 aln_offset ++;
4976 aln_from = AlnMgr2MapSeqAlignToBioseq(salp, (*p_from) + aln_offset - 1, aln_row);
4977 }
4978 if (aln_from < 0)
4979 {
4980 return FALSE;
4981 }
4982 else
4983 {
4984 *p_from = aln_from + 1;
4985 return TRUE;
4986 }
4987 }
4988
4989 extern Boolean AdjustToForGap (Int4Ptr p_to, SeqAlignPtr salp, Int4 aln_row)
4990 {
4991 Int4 aln_to, aln_offset = 0;
4992
4993 if (p_to == NULL || salp == NULL || aln_row == 0
4994 || *p_to < 1)
4995 {
4996 return FALSE;
4997 }
4998
4999 aln_to = AlnMgr2MapSeqAlignToBioseq(salp, (*p_to) - 1, aln_row);
5000 aln_offset = 0;
5001 while (aln_to == -2 && (*p_to) - 1 - aln_offset >= 0)
5002 {
5003 aln_offset ++;
5004 aln_to = AlnMgr2MapSeqAlignToBioseq(salp, (*p_to) - 1 - aln_offset, aln_row);
5005 }
5006 if (aln_to < 0)
5007 {
5008 return FALSE;
5009 }
5010 else
5011 {
5012 *p_to = aln_to + 1;
5013 return TRUE;
5014 }
5015 }
5016
5017 static Boolean AdjustStrandForAlignment (Uint2Ptr p_strand, SeqAlignPtr salp, Int4 aln_row)
5018 {
5019 Uint2 aln_strand;
5020
5021 if (p_strand == NULL || salp == NULL || aln_row < 1)
5022 {
5023 return FALSE;
5024 }
5025
5026 aln_strand = AlnMgr2GetNthStrand (salp, aln_row);
5027 if (aln_strand == Seq_strand_minus)
5028 {
5029 /* if alignment strand is minus, reverse strand of location */
5030 if (*p_strand == Seq_strand_minus)
5031 {
5032 *p_strand = Seq_strand_plus;
5033 }
5034 else if (*p_strand == Seq_strand_plus)
5035 {
5036 *p_strand = Seq_strand_minus;
5037 }
5038 }
5039 return TRUE;
5040 }
5041
5042 static Boolean CoordinatesValidForBioseq (Int4 from, Int4 to, BioseqPtr bsp)
5043 {
5044 if (bsp == NULL || from < 1 || to > bsp->length)
5045 {
5046 return FALSE;
5047 }
5048 else
5049 {
5050 return TRUE;
5051 }
5052 }
5053
5054 static ValNodePtr TestIntervalEditor (DialoG d)
5055 {
5056 IntervalPagePtr ipp;
5057 TagListPtr tlp;
5058 ValNodePtr head = NULL, vnp;
5059 Boolean from_ok, to_ok, seqid_ok, salp_ok;
5060 Boolean partial5, partial3;
5061 Int4 to, from, aln_row;
5062 Int4 interval_num;
5063 Uint2 strand, prev_strand = Seq_strand_unknown;
5064 SeqIdPtr seqid, prev_seqid = NULL;
5065 SeqAlignPtr salp, prev_salp = NULL;
5066 Char err_msg[200];
5067 BioseqPtr bsp = NULL;
5068 Int4 aln_len;
5069 Boolean isInterval, isPoint, fuzz_before, fuzz_after;
5070 Int2 fuzz_from;
5071 Int2 fuzz_to;
5072
5073 ipp = (IntervalPagePtr) GetObjectExtra (d);
5074 if (ipp == NULL)
5075 {
5076 ValNodeAddPointer (&head, 0, StringSave ("No dialog data"));
5077 return head;
5078 }
5079
5080 tlp = GetObjectExtra (ipp->ivals);
5081 if (tlp == NULL)
5082 {
5083 ValNodeAddPointer (&head, 0, StringSave ("No dialog data"));
5084 return head;
5085 }
5086
5087 if (tlp->vnp == NULL)
5088 {
5089 ValNodeAddPointer (&head, 0, StringSave ("No location intervals listed!"));
5090 }
5091
5092 partial5 = GetStatus (ipp->partial5);
5093 partial3 = GetStatus (ipp->partial3);
5094
5095 for (vnp = tlp->vnp, interval_num = 1;
5096 vnp != NULL;
5097 vnp = vnp->next, interval_num++) {
5098 isInterval = TRUE;
5099 isPoint = FALSE;
5100 fuzz_from = -1;
5101 fuzz_to = -1;
5102 fuzz_before = FALSE;
5103 fuzz_after = FALSE;
5104 from = 0;
5105 to = 0;
5106
5107 from_ok = ReadFromValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5108 &from, &fuzz_after);
5109 if (!from_ok)
5110 {
5111 /* we'll silently ignore lines that have no from value */
5112 continue;
5113 }
5114
5115 to_ok = ReadToValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5116 &to, &from, &fuzz_after, &isInterval, &isPoint,
5117 partial5, partial3);
5118 if (!to_ok)
5119 {
5120 sprintf (err_msg, "Bad to value in interval %d", interval_num);
5121 ValNodeAddPointer (&head, 0, StringSave ("err_msg"));
5122 }
5123 strand = Seq_strand_unknown;
5124 ReadStrandFromDialogLine (vnp->data.ptrvalue, ipp->strand_col,
5125 &strand, &prev_strand);
5126
5127 seqid_ok = ReadSeqIdFromDialogLine (vnp->data.ptrvalue, ipp->seqid_col,
5128 &seqid, &prev_seqid,
5129 ipp->sip_list, ipp->count);
5130 if (seqid_ok)
5131 {
5132 bsp = BioseqFind (seqid);
5133 if (bsp == NULL)
5134 {
5135 sprintf (err_msg, "Can't find bioseq for interval %d", interval_num);
5136 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5137 seqid_ok = FALSE;
5138 }
5139 }
5140 else
5141 {
5142 sprintf (err_msg, "No sequence ID in interval %d", interval_num);
5143 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5144 }
5145
5146
5147 /* get SeqAlign */
5148 salp = NULL;
5149 if (ipp->salp_list == NULL)
5150 {
5151 salp_ok = TRUE;
5152 if (bsp != NULL)
5153 {
5154 if (!CoordinatesValidForBioseq (from, to, bsp))
5155 {
5156 sprintf (err_msg, "Coordinates for interval %d are not in sequence (1-%d)",
5157 interval_num, bsp->length);
5158 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5159 }
5160 }
5161 }
5162 else
5163 {
5164 salp_ok = ReadSeqAlignFromDialogLine (vnp->data.ptrvalue,
5165 ipp->aln_col,
5166 &salp, &prev_salp,
5167 ipp->salp_list,
5168 ipp->aln_count);
5169 if (!salp_ok)
5170 {
5171 sprintf (err_msg, "No alignment for interval %d", interval_num);
5172 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5173 }
5174
5175 if (salp_ok && seqid_ok)
5176 {
5177 aln_row = 0;
5178 if (GetBioseqAlignmentRow (salp, bsp, &aln_row))
5179 {
5180 aln_len = SeqAlignLength (salp);
5181 if (from < 1 || to > aln_len)
5182 {
5183 sprintf (err_msg, "Coordinates for interval %d are not in alignment interval (%d-%d)",
5184 interval_num, 1, aln_len);
5185 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5186 }
5187 else
5188 {
5189 /* check for locations in gaps */
5190 if (!AdjustFromForGap (&from, salp, aln_len, aln_row)
5191 || ! AdjustToForGap (&to, salp, aln_row))
5192 {
5193 sprintf (err_msg, "Interval %d is completely contained in a gap in the alignment.",
5194 interval_num);
5195 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5196 }
5197 }
5198 }
5199 else
5200 {
5201 sprintf (err_msg, "Sequence for interval %d not in selected alignment", interval_num);
5202 ValNodeAddPointer (&head, 0, StringSave (err_msg));
5203 ListAlignmentsThatContainSequence (ipp->salp_list, ipp->aln_count,
5204 bsp, seqid, &head);
5205 ListSequencesInAlignment (ipp->sip_list, ipp->count, salp, &head);
5206 }
5207 }
5208 }
5209 }
5210
5211 return head;
5212 }
5213
5214
5215 static Boolean
5216 AddLocToList
5217 (SeqIdPtr seqid,
5218 Uint2 strand,
5219 Int4 from,
5220 Int4 to,
5221 Boolean add_null,
5222 Int2 fuzz_from,
5223 Int2 fuzz_to,
5224 Boolean fuzz_before,
5225 Boolean fuzz_after,
5226 Boolean partial5,
5227 Boolean partial3,
5228 SeqLocPtr PNTR pslp)
5229 {
5230 SeqLocPtr slp;
5231 SeqLocPtr tmploc1, tmploc2;
5232 Boolean isInterval;
5233 Boolean isPoint;
5234 Int4 tmp;
5235
5236 if (pslp == NULL || seqid == NULL)
5237 {
5238 return FALSE;
5239 }
5240
5241 if (add_null) {
5242 /* add NULL location between last location and this one */
5243 slp = ValNodeNew (NULL);
5244 if (slp != NULL) {
5245 slp->choice = SEQLOC_NULL;
5246 tmploc1 = *pslp;
5247 if (tmploc1 != NULL) {
5248 if (tmploc1->choice == SEQLOC_MIX) {
5249 tmploc2 = (ValNodePtr) (tmploc1->data.ptrvalue);
5250 if (tmploc2 != NULL) {
5251 while (tmploc2->next != NULL) {
5252 tmploc2 = tmploc2->next;
5253 }
5254 tmploc2->next = slp;
5255 }
5256 } else {
5257 tmploc2 = ValNodeNew (NULL);
5258 if (tmploc2 != NULL) {
5259 tmploc2->choice = SEQLOC_MIX;
5260 tmploc2->data.ptrvalue = (Pointer) tmploc1;
5261 tmploc1->next = slp;
5262 *pslp = tmploc2;
5263 }
5264 }
5265 }
5266 }
5267 }
5268
5269 isInterval = TRUE;
5270 isPoint = FALSE;
5271
5272 /* make sure from and to are in correct order */
5273 if (from > to)
5274 {
5275 tmp = from;
5276 from = to;
5277 to = tmp;
5278 }
5279
5280 if (fuzz_after && to == from + 1) {
5281 isInterval = FALSE;
5282 isPoint = TRUE;
5283 /* from++; */ /* this was causing point to be thrown off */
5284 } else if (to == from && (! partial5) && (! partial3)) {
5285 isInterval = FALSE;
5286 isPoint = TRUE;
5287 }
5288
5289 if (isInterval) {
5290 AddIntToSeqLoc (pslp, from - 1, to - 1, seqid,
5291 fuzz_from, fuzz_to, strand);
5292 } else if (isPoint) {
5293 AddSeqLocPoint (pslp, seqid, from, fuzz_before, fuzz_after, strand);
5294 }
5295 return TRUE;
5296 }
5297
5298 static void SetPartialsForOneLocation (SeqLocPtr master_slp, Boolean partial5, Boolean partial3)
5299 {
5300 SeqLocPtr firstSlp, lastSlp, tmp_slp;
5301 IntFuzzPtr ifp;
5302 SeqIntPtr sip;
5303 SeqPntPtr spp;
5304
5305 if (master_slp == NULL)
5306 {
5307 return;
5308 }
5309
5310 /* now set partials for location */
5311 firstSlp = NULL;
5312 lastSlp = NULL;
5313 tmp_slp = SeqLocFindNext (master_slp, NULL);
5314 while (tmp_slp != NULL) {
5315 if (firstSlp == NULL) {
5316 firstSlp = tmp_slp;
5317 }
5318 lastSlp = tmp_slp;
5319 tmp_slp = SeqLocFindNext (master_slp, tmp_slp);
5320 }
5321 if (firstSlp != NULL && partial5) {
5322 if (firstSlp->choice == SEQLOC_INT && firstSlp->data.ptrvalue != NULL) {
5323 sip = (SeqIntPtr) firstSlp->data.ptrvalue;
5324 ifp = IntFuzzNew ();
5325 if (ifp != NULL) {
5326 ifp->choice = 4;
5327 if (sip->strand == Seq_strand_minus || sip->strand == Seq_strand_both_rev) {
5328 sip->if_to = ifp;
5329 ifp->a = 1;
5330 } else {
5331 sip->if_from = ifp;
5332 ifp->a = 2;
5333 }
5334 }
5335 } else if (firstSlp->choice == SEQLOC_PNT && firstSlp->data.ptrvalue != NULL) {
5336 spp = (SeqPntPtr) firstSlp->data.ptrvalue;
5337 ifp = IntFuzzNew ();
5338 if (ifp != NULL) {
5339 ifp->choice = 4;
5340 if (spp->strand == Seq_strand_minus || spp->strand == Seq_strand_both_rev) {
5341 spp->fuzz = ifp;
5342 ifp->a = 1;
5343 } else {
5344 spp->fuzz = ifp;
5345 ifp->a = 2;
5346 }
5347 }
5348 }
5349 }
5350 if (lastSlp != NULL && partial3) {
5351 if (lastSlp->choice == SEQLOC_INT && lastSlp->data.ptrvalue != NULL) {
5352 sip = (SeqIntPtr) lastSlp->data.ptrvalue;
5353 ifp = IntFuzzNew ();
5354 if (ifp != NULL) {
5355 ifp->choice = 4;
5356 if (sip->strand == Seq_strand_minus || sip->strand == Seq_strand_both_rev) {
5357 sip->if_from = ifp;
5358 ifp->a = 2;
5359 } else {
5360 sip->if_to = ifp;
5361 ifp->a = 1;
5362 }
5363 }
5364 } else if (lastSlp->choice == SEQLOC_PNT && lastSlp->data.ptrvalue != NULL) {
5365 spp = (SeqPntPtr) lastSlp->data.ptrvalue;
5366 ifp = IntFuzzNew ();
5367 if (ifp != NULL) {
5368 ifp->choice = 4;
5369 if (spp->strand == Seq_strand_minus || spp->strand == Seq_strand_both_rev) {
5370 spp->fuzz = ifp;
5371 ifp->a = 2;
5372 } else {
5373 spp->fuzz = ifp;
5374 ifp->a = 1;
5375 }
5376 }
5377 }
5378 }
5379 }
5380
5381 static SeqLocPtr
5382 ReadSingleSeqLoc
5383 (TagListPtr tlp,
5384 IntervalPagePtr ipp,
5385 Boolean partial5,
5386 Boolean partial3,
5387 Boolean nullsBetween)
5388 {
5389 Int4 from, to, aln_row, aln_len;
5390 Boolean fuzz_after;
5391 Boolean fuzz_before;
5392 Int2 fuzz_from;
5393 Int2 fuzz_to;
5394 Boolean isInterval;
5395 Boolean isPoint;
5396 Boolean notFirst;
5397 Boolean okay;
5398 SeqIdPtr seqid, prev_sip;
5399 SeqLocPtr master_slp;
5400 Uint2 strand, prev_strand;
5401 ValNodePtr vnp;
5402 SeqAlignPtr salp, prev_salp;
5403 BioseqPtr bsp;
5404
5405 if (tlp == NULL)
5406 {
5407 return NULL;
5408 }
5409
5410 prev_sip = NULL;
5411 prev_salp = NULL;
5412 prev_strand = Seq_strand_unknown;
5413 master_slp = NULL;
5414
5415 notFirst = FALSE;
5416 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
5417 if (StringHasNoText (vnp->data.ptrvalue))
5418 {
5419 continue;
5420 }
5421 fuzz_from = -1;
5422 fuzz_to = -1;
5423 fuzz_before = FALSE;
5424 fuzz_after = FALSE;
5425 from = 0;
5426 to = 0;
5427 isInterval = TRUE;
5428 isPoint = FALSE;
5429 strand = Seq_strand_unknown;
5430 seqid = NULL;
5431 salp = NULL;
5432 aln_row = 0;
5433 if (!ReadFromValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5434 &from, &fuzz_after))
5435 {
5436 continue;
5437 }
5438 okay = ReadToValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5439 &to, &from, &fuzz_after,
5440 &isInterval, &isPoint,
5441 partial5, partial3)
5442 && ReadStrandFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5443 ipp->strand_col,
5444 &strand, &prev_strand)
5445 && ReadSeqIdFromDialogLine ((CharPtr) vnp->data.ptrvalue, ipp->seqid_col,
5446 &seqid, &prev_sip,
5447 ipp->sip_list, ipp->count)
5448 && (ipp->salp_list == NULL
5449 || ReadSeqAlignFromDialogLine ((CharPtr) vnp->data.ptrvalue, ipp->aln_col,
5450 &salp, &prev_salp,
5451 ipp->salp_list, ipp->aln_count))
5452 && ((bsp = BioseqFind (seqid)) != NULL)
5453 && (salp != NULL || CoordinatesValidForBioseq (from, to, bsp))
5454 && (salp == NULL ||
5455 (GetBioseqAlignmentRow (salp, bsp, &aln_row)
5456 && AdjustStrandForAlignment (&strand, salp, aln_row)
5457 && (aln_len = SeqAlignLength (salp)) > 0
5458 && AdjustFromForGap (&from, salp, aln_len, aln_row)
5459 && AdjustToForGap (&to, salp, aln_row)))
5460 && AddLocToList (seqid, strand, from, to,
5461 (nullsBetween && notFirst),
5462 fuzz_from, fuzz_to,
5463 fuzz_before, fuzz_after,
5464 partial5, partial3,
5465 &(master_slp));
5466 if (okay)
5467 {
5468 notFirst = TRUE;
5469 }
5470 else
5471 {
5472 master_slp = SeqLocFree (master_slp);
5473 return NULL;
5474 }
5475 }
5476
5477 /* now set partials for location */
5478 SetPartialsForOneLocation (master_slp, partial5, partial3);
5479 return master_slp;
5480 }
5481
5482 static SeqLocPtr PNTR FreeSeqLocArray (SeqLocPtr PNTR loc_list, Int4 num_loc)
5483 {
5484 Int4 j;
5485 if (loc_list != NULL)
5486 {
5487 for (j = 0; j < num_loc; j++)
5488 {
5489 loc_list [j] = SeqLocFree (loc_list [j]);
5490 }
5491 loc_list = MemFree (loc_list);
5492 }
5493 return loc_list;
5494 }
5495
5496 static SeqLocPtr
5497 ReadAlignedSeqLocList
5498 (TagListPtr tlp,
5499 IntervalPagePtr ipp,
5500 Boolean partial5,
5501 Boolean partial3,
5502 Boolean nullsBetween)
5503 {
5504 Int4 from, to, aln_from, aln_to, aln_row, aln_len = 0;
5505 Boolean fuzz_after;
5506 Boolean fuzz_before;
5507 Int2 fuzz_from;
5508 Int2 fuzz_to;
5509 Boolean isInterval;
5510 Boolean isPoint;
5511 Boolean notFirst;
5512 Boolean okay;
5513 SeqIdPtr seqid;
5514 SeqLocPtr master_slp, tmp_slp;
5515 Uint2 strand, prev_strand, aln_strand;
5516 ValNodePtr vnp;
5517 SeqAlignPtr salp, prev_salp;
5518 BioseqPtr bsp;
5519 SeqLocPtr PNTR loc_list;
5520 Int4 loc_num, max_locs;
5521 Boolean asked_about_repair = FALSE;
5522 MsgAnswer ans = ANS_YES;
5523
5524 if (tlp == NULL || ipp == NULL || ipp->salp_list == NULL)
5525 {
5526 return NULL;
5527 }
5528
5529 prev_salp = NULL;
5530 prev_strand = Seq_strand_unknown;
5531 master_slp = NULL;
5532
5533 max_locs = 0;
5534 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next)
5535 {
5536 if (!ReadSeqAlignFromDialogLine ((CharPtr) vnp->data.ptrvalue, ipp->aln_col,
5537 &salp, &prev_salp,
5538 ipp->salp_list, ipp->aln_count))
5539 {
5540 return NULL;
5541 }
5542 else
5543 {
5544 max_locs = MAX (max_locs, salp->dim);
5545 }
5546 }
5547 if (max_locs == 0)
5548 {
5549 return NULL;
5550 }
5551
5552 loc_list = (SeqLocPtr PNTR) MemNew (max_locs * sizeof (SeqLocPtr));
5553 if (loc_list == NULL)
5554 {
5555 return NULL;
5556 }
5557
5558 prev_salp = NULL;
5559
5560 okay = TRUE;
5561 notFirst = FALSE;
5562 for (vnp = tlp->vnp; vnp != NULL && okay; vnp = vnp->next) {
5563 if (StringHasNoText (vnp->data.ptrvalue))
5564 {
5565 continue;
5566 }
5567 fuzz_from = -1;
5568 fuzz_to = -1;
5569 fuzz_before = FALSE;
5570 fuzz_after = FALSE;
5571 from = 0;
5572 to = 0;
5573 isInterval = TRUE;
5574 isPoint = FALSE;
5575 strand = Seq_strand_unknown;
5576 seqid = NULL;
5577 salp = NULL;
5578 aln_row = 0;
5579 if (! ReadFromValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5580 &from, &fuzz_after))
5581 {
5582 continue;
5583 }
5584 okay = ReadToValueFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5585 &to, &from, &fuzz_after,
5586 &isInterval, &isPoint,
5587 partial5, partial3)
5588 && ReadStrandFromDialogLine ((CharPtr) vnp->data.ptrvalue,
5589 ipp->strand_col,
5590 &strand, &prev_strand)
5591 && ReadSeqAlignFromDialogLine ((CharPtr) vnp->data.ptrvalue, ipp->aln_col,
5592 &salp, &prev_salp,
5593 ipp->salp_list, ipp->aln_count);
5594 if (okay)
5595 {
5596 for (loc_num = 0; loc_num < salp->dim; loc_num++)
5597 {
5598 aln_row = loc_num + 1;
5599 aln_from = from;
5600 aln_to = to;
5601 aln_strand = strand;
5602 seqid = AlnMgr2GetNthSeqIdPtr (salp, aln_row);
5603 okay = ((bsp = BioseqFind (seqid)) != NULL)
5604 && AdjustStrandForAlignment (&aln_strand, salp, aln_row)
5605 && (aln_len = SeqAlignLength (salp)) > 0;
5606 if (okay)
5607 {
5608 if (ipp->allow_nulls_in_list)
5609 {
5610 if (! AdjustFromForGap (&aln_from, salp, aln_len, aln_row)
5611 || ! AdjustToForGap (&aln_to, salp, aln_row)
5612 || ! AddLocToList (seqid, aln_strand, aln_from, aln_to,
5613 (nullsBetween && notFirst),
5614 fuzz_from, fuzz_to,
5615 fuzz_before, fuzz_after,
5616 partial5, partial3,
5617 &(loc_list [loc_num])))
5618 {
5619 if (loc_list[loc_num] == NULL)
5620 {
5621 loc_list [loc_num] = ValNodeNew (NULL);
5622 loc_list [loc_num]->choice = SEQLOC_NULL;
5623 }
5624 }
5625 }
5626 else
5627 {
5628 okay = AdjustFromForGap (&aln_from, salp, aln_len, aln_row)
5629 && AdjustToForGap (&aln_to, salp, aln_row)
5630 && AddLocToList (seqid, aln_strand, aln_from, aln_to,
5631 (nullsBetween && notFirst),
5632 fuzz_from, fuzz_to,
5633 fuzz_before, fuzz_after,
5634 partial5, partial3,
5635 &(loc_list [loc_num]));
5636 }
5637 }
5638 }
5639 }
5640
5641 notFirst = TRUE;
5642 }
5643
5644 if (!okay)
5645 {
5646 loc_list = FreeSeqLocArray (loc_list, max_locs);
5647 return NULL;
5648 }
5649
5650 /* now fix intervals that are out of order and set partials for locations */
5651 for (loc_num = 0; loc_num < max_locs && loc_list [loc_num] != NULL; loc_num++)
5652 {
5653 bsp = BioseqFindFromSeqLoc (loc_list [loc_num]);
5654 if (bsp != NULL && SeqLocBadSortOrder (bsp, loc_list [loc_num]))
5655 {
5656 if (!asked_about_repair)
5657 {
5658 ans = Message (MSG_YN,
5659 "Feature location intervals are out of order. Do you want them repaired?");
5660 asked_about_repair = TRUE;
5661 }
5662 if (ans == ANS_YES) {
5663 tmp_slp = SeqLocMerge (bsp, loc_list [loc_num], NULL, FALSE, FALSE, nullsBetween);
5664 loc_list [loc_num] = SeqLocFree (loc_list [loc_num]);
5665 loc_list [loc_num] = tmp_slp;
5666 if (bsp->repr == Seq_repr_seg) {
5667 tmp_slp = SegLocToParts (bsp, loc_list [loc_num]);
5668 loc_list [loc_num] = SeqLocFree (loc_list [loc_num]);
5669 loc_list [loc_num] = tmp_slp;
5670 }
5671 FreeAllFuzz (loc_list [loc_num]);
5672 }
5673 }
5674 SetSeqLocPartial (loc_list [loc_num], partial5, partial3);
5675 }
5676
5677 /* now make chain */
5678 master_slp = loc_list [0];
5679 tmp_slp = loc_list [0];
5680 for (tmp_slp = loc_list [0], loc_num = 1;
5681 tmp_slp != NULL && loc_num < max_locs;
5682 loc_num++)
5683 {
5684 tmp_slp->next = loc_list [loc_num];
5685 tmp_slp = tmp_slp->next;
5686 }
5687
5688 loc_list = MemFree (loc_list);
5689
5690 return master_slp;
5691 }
5692
5693 static Pointer IntervalPageToSeqLocPtr (DialoG d)
5694
5695 {
5696 IntervalPagePtr ipp;
5697 Boolean nullsBetween;
5698 Boolean partial5;
5699 Boolean partial3;
5700 SeqLocPtr master_slp;
5701 TagListPtr tlp;
5702
5703 ipp = (IntervalPagePtr) GetObjectExtra (d);
5704 if (ipp == NULL) return NULL;
5705 tlp = GetObjectExtra (ipp->ivals);
5706 if (tlp == NULL) return NULL;
5707
5708
5709 nullsBetween = GetStatus (ipp->nullsBetween);
5710 partial5 = GetStatus (ipp->partial5);
5711 partial3 = GetStatus (ipp->partial3);
5712
5713 if (ipp->seqid_col > -1)
5714 {
5715 master_slp = ReadSingleSeqLoc (tlp, ipp, partial5, partial3, nullsBetween);
5716 }
5717 else
5718 {
5719 master_slp = ReadAlignedSeqLocList (tlp, ipp, partial5, partial3, nullsBetween);
5720 }
5721 return (Pointer) master_slp;
5722 }
5723
5724 static void CleanupIntervalPage (GraphiC g, VoidPtr data)
5725
5726 {
5727 IntervalPagePtr ipp;
5728 Int2 j;
5729
5730 ipp = (IntervalPagePtr) data;
5731 if (ipp != NULL) {
5732 /* free seq ID list */
5733 if (ipp->sip_list != NULL)
5734 {
5735 for (j = 0; j <= ipp->count + 1; j++) {
5736 ipp->sip_list [j] = SeqIdFree (ipp->sip_list [j]);
5737 }
5738 }
5739 MemFree (ipp->sip_list);
5740 if (ipp->alist != NULL) {
5741 for (j = 0; j <= ipp->count + 1; j++) {
5742 MemFree (ipp->alist [j].name);
5743 }
5744 }
5745 MemFree (ipp->alist);
5746 MemFree (ipp->lengths);
5747
5748 /* free list of alignments */
5749 if (ipp->salp_list != NULL)
5750 {
5751 for (j = 0; j <= ipp->aln_count + 1; j++) {
5752 ipp->salp_list [j] = SeqAlignFree (ipp->salp_list [j]);
5753 }
5754 }
5755 MemFree (ipp->salp_list);
5756 /* free alignment tags */
5757 if (ipp->aln_alist != NULL) {
5758 for (j = 0; j <= ipp->aln_count + 1; j++) {
5759 MemFree (ipp->aln_alist [j].name);
5760 }
5761 }
5762 MemFree (ipp->aln_alist);
5763 /* free alignment lengths */
5764 MemFree (ipp->aln_lengths);
5765
5766
5767 /* free callback list */
5768 MemFree (ipp->callbacks);
5769 }
5770 MemFree (data);
5771 }
5772
5773 Uint2 interval_types [] = {
5774 TAGLIST_TEXT, TAGLIST_TEXT, TAGLIST_POPUP, TAGLIST_POPUP, TAGLIST_POPUP
5775 };
5776
5777 Uint2 interval_widths [] = {
5778 5, 5, 0, 0, 0
5779 };
5780
5781 static Boolean ReadSeqLocDialog (DialoG d, CharPtr filename)
5782
5783 {
5784 AsnIoPtr aip;
5785 IntervalPagePtr ipp;
5786 SeqLocPtr slp;
5787 Char path [PATH_MAX];
5788
5789 path [0] = '\0';
5790 StringNCpy_0 (path, filename, sizeof (path));
5791 ipp = (IntervalPagePtr) GetObjectExtra (d);
5792 if (ipp != NULL) {
5793 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
5794 aip = AsnIoOpen (path, "r");
5795 if (aip != NULL) {
5796 slp = SeqLocAsnRead (aip, NULL);
5797 AsnIoClose (aip);
5798 if (slp != NULL) {
5799 SeqLocPtrToIntervalPage (ipp->dialog, slp);
5800 slp = SeqLocFree (slp);
5801 Update ();
5802 return TRUE;
5803 }
5804 }
5805 }
5806 }
5807 return FALSE;
5808 }
5809
5810 static Boolean WriteSeqLocDialog (DialoG d, CharPtr filename)
5811
5812 {
5813 AsnIoPtr aip;
5814 IntervalPagePtr ipp;
5815 SeqLocPtr slp;
5816 Char path [PATH_MAX];
5817 #ifdef WIN_MAC
5818 FILE *f;
5819 #endif
5820
5821 path [0] = '\0';
5822 StringNCpy_0 (path, filename, sizeof (path));
5823 ipp = (IntervalPagePtr) GetObjectExtra (d);
5824 if (ipp != NULL) {
5825 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
5826 #ifdef WIN_MAC
5827 f = FileOpen (path, "r");
5828 if (f != NULL) {
5829 FileClose (f);
5830 } else {
5831 FileCreate (path, "TEXT", "ttxt");
5832 }
5833 #endif
5834 aip = AsnIoOpen (path, "w");
5835 if (aip != NULL) {
5836 slp = IntervalPageToSeqLocPtr (ipp->dialog);
5837 SeqLocAsnWrite (slp, aip, NULL);
5838 AsnIoClose (aip);
5839 slp = SeqLocFree (slp);
5840 return TRUE;
5841 }
5842 }
5843 }
5844 return FALSE;
5845 }
5846
5847 static void SetOnlySequenceAndStrand (IntervalPagePtr ipp)
5848 {
5849 TagListPtr tlp;
5850 ValNodePtr vnp;
5851 CharPtr cp;
5852 CharPtr tabptr;
5853 ValNodePtr saved_list;
5854
5855 if (ipp == NULL) return;
5856 tlp = GetObjectExtra (ipp->ivals);
5857 if (tlp == NULL) return;
5858 saved_list = tlp->vnp;
5859 tlp->vnp = NULL;
5860 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
5861 tlp->vnp = saved_list;
5862 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next)
5863 {
5864 cp = vnp->data.ptrvalue;
5865 if (cp != NULL)
5866 {
5867 tabptr = StringChr (cp, '\t');
5868 if (tabptr != NULL)
5869 {
5870 tabptr = StringChr (tabptr + 1, '\t');
5871 }
5872 if (tabptr != NULL)
5873 {
5874 cp[0] = '\t';
5875 cp++;
5876 while (*tabptr != 0)
5877 {
5878 *cp = *tabptr;
5879 cp++;
5880 tabptr++;
5881 }
5882 *cp = 0;
5883 }
5884 }
5885 }
5886
5887 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
5888 }
5889
5890 static void ClearLocationPartialCheckboxes (IntervalPagePtr ipp)
5891 {
5892 if (ipp != NULL)
5893 {
5894 SetStatus (ipp->partial5, FALSE);
5895 SetStatus (ipp->partial3, FALSE);
5896 SetStatus (ipp->nullsBetween, FALSE);
5897 if (ipp->proc != NULL) {
5898 ipp->proc (ipp->ffp, FALSE, FALSE, FALSE);
5899 }
5900 }
5901 }
5902
5903 static void IntervalEditorMessage (DialoG d, Int2 mssg)
5904
5905 {
5906 IntervalPagePtr ipp;
5907
5908 ipp = (IntervalPagePtr) GetObjectExtra (d);
5909 if (ipp != NULL) {
5910 switch (mssg) {
5911 case VIB_MSG_INIT:
5912 SeqLocPtrToIntervalPage (d, NULL);
5913 break;
5914 case VIB_MSG_ENTER:
5915 SendMessageToDialog (ipp->ivals, VIB_MSG_ENTER);
5916 break;
5917 case VIB_MSG_RESET:
5918 /* do nothing */
5919 break;
5920 case NUM_VIB_MSG + 1:
5921 SetOnlySequenceAndStrand (ipp);
5922 break;
5923 case NUM_VIB_MSG + 2:
5924 ClearLocationPartialCheckboxes (ipp);
5925 break;
5926 case VIB_MSG_CUT :
5927 StdCutTextProc (NULL);
5928 break;
5929 case VIB_MSG_COPY :
5930 StdCopyTextProc (NULL);
5931 break;
5932 case VIB_MSG_PASTE :
5933 StdPasteTextProc (NULL);
5934 break;
5935 case VIB_MSG_DELETE :
5936 StdDeleteTextProc (NULL);
5937 break;
5938 }
5939 }
5940 }
5941
5942 extern void StdFeatIntEdPartialCallback (FeatureFormPtr ffp, Boolean partial5, Boolean partial3, Boolean order)
5943
5944 {
5945 if (ffp == NULL) return;
5946 SafeSetStatus (ffp->partial, (partial5 || partial3 || order));
5947 Update ();
5948 }
5949
5950 static void ChangedPartialProc (ButtoN b)
5951
5952 {
5953 IntervalPagePtr ipp;
5954
5955 ipp = (IntervalPagePtr) GetObjectExtra (b);
5956 if (ipp == NULL) return;
5957 if (ipp->proc != NULL) {
5958 ipp->proc (ipp->ffp, GetStatus (ipp->partial5),
5959 GetStatus (ipp->partial3), GetStatus (ipp->nullsBetween));
5960 }
5961 }
5962
5963
5964 static CharPtr MakeBlankLocationLine (CharPtr orig)
5965 {
5966 CharPtr cp, rval = NULL;
5967
5968 if (StringHasNoText (orig)) {
5969 return StringSave ("");
5970 }
5971 /* skip first two values, keep the rest */
5972 cp = StringChr (orig, '\t');
5973 if (cp == NULL) {
5974 return StringSave ("");
5975 }
5976 cp = StringChr (cp + 1, '\t');
5977 if (cp == NULL) {
5978 return StringSave ("");
5979 }
5980 cp++;
5981
5982 rval = (CharPtr) MemNew (sizeof (Char) * (StringLen (cp) + 3));
5983 sprintf (rval, "\t\t%s", cp);
5984 return rval;
5985 }
5986
5987
5988 static void InsertFirstLocation (ButtoN b)
5989 {
5990 DialoG ivals;
5991 TagListPtr tlp;
5992 ValNodePtr vnp;
5993 Int2 j;
5994
5995 ivals = (DialoG) GetObjectExtra (b);
5996 if (ivals == NULL) {
5997 return;
5998 }
5999 tlp = (TagListPtr) GetObjectExtra (ivals);
6000 if (tlp == NULL || tlp->vnp == NULL || StringHasNoText (tlp->vnp->data.ptrvalue)) {
6001 return;
6002 }
6003
6004 /* add blank line to current lines */
6005 vnp = ValNodeNew (NULL);
6006 vnp->data.ptrvalue = MakeBlankLocationLine (tlp->vnp->data.ptrvalue);
6007 vnp->next = tlp->vnp;
6008 /* disconnect lines from taglist, so they won't be erased by the reset */
6009 tlp->vnp = NULL;
6010
6011 /* reset the dialog */
6012 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
6013
6014 /* attach the lines to the dialog */
6015 tlp->vnp = vnp;
6016
6017 /* redraw dialog */
6018 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
6019 /* adjust scroll bars */
6020 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
6021 }
6022 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
6023 CorrectBarMax (tlp->bar, tlp->max);
6024 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
6025 SendMessageToDialog (tlp->dialog, VIB_MSG_ENTER);
6026 }
6027
6028 extern DialoG CreateTagListDialogEx (GrouP h, Uint2 rows, Uint2 cols,
6029 Int2 spacing, Uint2Ptr types,
6030 Uint2Ptr textWidths, EnumFieldAssocPtr PNTR alists,
6031 Boolean useBar, Boolean noExtend,
6032 ToDialogFunc tofunc, FromDialogFunc fromfunc);
6033
6034 extern DialoG CreateIntervalEditorDialogExEx (GrouP h, CharPtr title, Uint2 rows,
6035 Int2 spacing, SeqEntryPtr sep,
6036 Boolean nucsOK, Boolean protsOK,
6037 Boolean useBar, Boolean showPartials,
6038 Boolean allowGaps, FeatureFormPtr ffp,
6039 IntEdPartialProc proc,
6040 Boolean use_aln, Boolean show_seqid,
6041 TaglistCallback tlp_callback,
6042 Pointer callback_data,
6043 Boolean allow_nulls_in_list)
6044
6045 {
6046 BioseqPtr bsp;
6047 Int4 count;
6048 GrouP f;
6049 IntervalPagePtr ipp;
6050 Int2 j;
6051 GrouP m;
6052 GrouP p;
6053 GrouP btn_grp;
6054 PrompT p1;
6055 PrompT p2;
6056 PrompT p3;
6057 PrompT p_from, p_to;
6058 CharPtr ptr;
6059 GrouP q;
6060 GrouP s;
6061 Boolean showIdTags;
6062 SeqIdPtr sip;
6063 Char str [128];
6064 TagListPtr tlp;
6065 SeqAlignPtr salp_list = NULL, salp;
6066 Int4 num_cols;
6067 ButtoN b;
6068
6069 p = HiddenGroup (h, 1, 0, NULL);
6070 SetGroupSpacing (p, 10, 10);
6071
6072 ipp = (IntervalPagePtr) MemNew (sizeof (IntervalPage));
6073 if (ipp != NULL) {
6074
6075 SetObjectExtra (p, ipp, CleanupIntervalPage);
6076 ipp->dialog = (DialoG) p;
6077 ipp->todialog = SeqLocPtrToIntervalPage;
6078 ipp->fromdialog = IntervalPageToSeqLocPtr;
6079 ipp->dialogmessage = IntervalEditorMessage;
6080 ipp->testdialog = TestIntervalEditor;
6081 ipp->importdialog = ReadSeqLocDialog;
6082 ipp->exportdialog = WriteSeqLocDialog;
6083
6084 ipp->ffp = ffp;
6085 ipp->proc = proc;
6086
6087 ipp->allow_nulls_in_list = allow_nulls_in_list;
6088
6089 if (title != NULL && title [0] != '\0') {
6090 s = NormalGroup (p, 0, -2, title, systemFont, NULL);
6091 } else {
6092 s = HiddenGroup (p, 0, -2, NULL);
6093 }
6094 m = HiddenGroup (s, -1, 0, NULL);
6095 /*
6096 SetGroupSpacing (m, 10, 10);
6097 */
6098
6099 ipp->nucsOK = nucsOK;
6100 ipp->protsOK = protsOK;
6101 ipp->showIdTags = FALSE;
6102 ipp->count = 0;
6103
6104 if (ipp->nucsOK)
6105 {
6106 ipp->strand_col = 2;
6107 }
6108 else
6109 {
6110 ipp->strand_col = -1;
6111 }
6112
6113 ipp->aln_col = -1;
6114 if (show_seqid)
6115 {
6116 if (ipp->nucsOK)
6117 {
6118 ipp->seqid_col = 3;
6119 }
6120 else
6121 {
6122 ipp->seqid_col = 2;
6123 }
6124 if (use_aln)
6125 {
6126 ipp->aln_col = ipp->seqid_col + 1;
6127 }
6128 }
6129 else
6130 {
6131 ipp->seqid_col = -1;
6132 if (use_aln)
6133 {
6134 if (ipp->nucsOK)
6135 {
6136 ipp->aln_col = 3;
6137 }
6138 else
6139 {
6140 ipp->aln_col = 2;
6141 }
6142 }
6143 }
6144
6145 /* set up callbacks */
6146 ipp->callbacks = (TaglistCallback PNTR) MemNew (5 * sizeof (TaglistCallback));
6147 if (ipp->callbacks != NULL)
6148 {
6149 ipp->callbacks [0] = NULL;
6150 ipp->callbacks [1] = NULL;
6151 ipp->callbacks [2] = NULL;
6152 ipp->callbacks [3] = NULL;
6153 ipp->callbacks [4] = NULL;
6154
6155 if (ipp->seqid_col > -1)
6156 {
6157 ipp->callbacks [ipp->seqid_col] = tlp_callback;
6158 }
6159 if (ipp->aln_col > -1)
6160 {
6161 ipp->callbacks [ipp->aln_col] = tlp_callback;
6162 }
6163 }
6164
6165 if (sep != NULL) {
6166 if (use_aln)
6167 {
6168 VisitAnnotsInSep (sep, &salp_list, GetAlignmentsInSeqEntryCallback);
6169 count = 4;
6170 salp = salp_list;
6171 while (salp != NULL)
6172 {
6173 count++;
6174 salp = salp->next;
6175 }
6176
6177 ipp->salp_list = (SeqAlignPtr PNTR) MemNew (sizeof (SeqAlignPtr) * count);
6178 ipp->aln_alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) count);
6179 ipp->aln_lengths = MemNew (sizeof (Int4) * (size_t) count);
6180 ipp->aln_count = 0;
6181 if (ipp->salp_list != NULL && ipp->aln_alist != NULL && ipp->aln_lengths != NULL)
6182 {
6183 /* first one is NULL */
6184 ipp->salp_list [0] = NULL;
6185 ipp->aln_lengths [0] = 0;
6186 ipp->aln_alist [0].name = StringSave (" ");
6187 ipp->aln_alist [0].value = (UIEnum) 0;
6188 ipp->aln_count ++;
6189 salp = salp_list;
6190 while (salp != NULL)
6191 {
6192 ipp->salp_list [ipp->aln_count] = salp;
6193 ipp->aln_lengths [ipp->aln_count] = SeqAlignLength (ipp->salp_list [ipp->aln_count]);
6194 CreateSeqAlignLabel (ipp->salp_list [ipp->aln_count], str, 30);
6195 ipp->aln_alist [ipp->aln_count].name = StringSave (str);
6196 ipp->aln_alist [ipp->aln_count].value = (UIEnum) ipp->aln_count;
6197
6198 salp = salp->next;
6199 /* sever chain */
6200 ipp->salp_list [ipp->aln_count]->next = NULL;
6201 ipp->aln_count++;
6202 }
6203 }
6204 /* add end of list marker */
6205 ipp->aln_alist [ipp->aln_count].name = NULL;
6206 ipp->aln_alist [ipp->aln_count].value = (UIEnum) 0;
6207
6208 }
6209 else
6210 {
6211 ipp->salp_list = NULL;
6212 ipp->aln_alist = NULL;
6213 ipp->aln_lengths = NULL;
6214 ipp->aln_count = 0;
6215 }
6216 count = SegmentedEntryCount (sep);
6217 count += 4;
6218 ipp->sip_list = MemNew (sizeof (SeqIdPtr) * (size_t) count);
6219 ipp->alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) count);
6220 ipp->lengths = MemNew (sizeof (Int4) * (size_t) count);
6221 ipp->count = 0;
6222
6223 if (ipp->sip_list != NULL && ipp->alist != NULL && ipp->lengths != NULL) {
6224 VisitBioseqsInSep (sep, NULL, ClearBspScratch);
6225 SeqEntryExplore (sep, (Pointer) ipp, FillInProducts);
6226 VisitBioseqsInSep (sep, NULL, ClearBspScratch);
6227 j = 0;
6228 ipp->alist [j].name = StringSave (" ");
6229 ipp->alist [j].value = (UIEnum) 0;
6230 for (j = 1; j <= ipp->count; j++) {
6231 sip = ipp->sip_list [j];
6232 if (sip != NULL) {
6233 bsp = BioseqFindCore (sip);
6234 if (bsp == NULL) {
6235 bsp = BioseqLockById (sip);
6236 BioseqUnlock (bsp);
6237 }
6238 if (bsp != NULL)
6239 {
6240 ipp->lengths [j] = bsp->length;
6241 sip = SeqIdFindWorst (bsp->id);
6242 }
6243 SeqIdWrite (sip, str, PRINTID_REPORT, sizeof (str));
6244 ptr = StringChr (str, '|');
6245 showIdTags = FALSE;
6246 if (ptr == NULL) {
6247 ptr = str;
6248 } else if (showIdTags) {
6249 ptr = str;
6250 } else {
6251 ptr++;
6252 }
6253 ipp->alist [j].name = StringSave (ptr);
6254 ipp->alist [j].value = (UIEnum) j;
6255 }
6256 }
6257 /* add end of list marker */
6258 j = ipp->count + 1;
6259 ipp->alist [j].name = NULL;
6260 ipp->alist [j].value = (UIEnum) 0;
6261 }
6262 #ifdef WIN_MOTIF
6263 if (ipp->count > 31) {
6264 if (ipp->seqid_col > -1)
6265 {
6266 interval_types [ipp->seqid_col] = TAGLIST_LIST;
6267 }
6268 if (ipp->aln_col > -1)
6269 {
6270 interval_types [ipp->aln_col] = TAGLIST_LIST;
6271 }
6272 } else {
6273 interval_types [2] = TAGLIST_POPUP;
6274 interval_types [3] = TAGLIST_POPUP;
6275 interval_types [4] = TAGLIST_POPUP;
6276 }
6277 #endif
6278
6279 } else {
6280 ipp->alist = MemNew (sizeof (EnumFieldAssoc) * (size_t) 4);
6281 if (ipp->alist != NULL) {
6282 j = 0;
6283 ipp->alist [j].name = StringSave (" ");
6284 ipp->alist [j].value = (UIEnum) 0;
6285 j = 1;
6286 ipp->alist [j].name = NULL;
6287 ipp->alist [j].value = (UIEnum) 0;
6288
6289 }
6290 }
6291
6292 ipp->alists [0] = NULL;
6293 ipp->alists [1] = NULL;
6294 ipp->alists [2] = NULL;
6295 ipp->alists [3] = NULL;
6296 ipp->alists [4] = NULL;
6297 if (ipp->strand_col > -1)
6298 {
6299 ipp->alists [ipp->strand_col] = strand_alist;
6300 }
6301 if (ipp->seqid_col > -1)
6302 {
6303 ipp->alists [ipp->seqid_col] = ipp->alist;
6304 }
6305 if (ipp->aln_col > -1)
6306 {
6307 ipp->alists [ipp->aln_col] = ipp->aln_alist;
6308 }
6309
6310 q = NULL;
6311 if (showPartials) {
6312 q = HiddenGroup (m, 4, 0, NULL);
6313 SetGroupSpacing (q, 20, 2);
6314 if (nucsOK) {
6315 ipp->partial5 = CheckBox (q, "5' Partial", ChangedPartialProc);
6316 } else {
6317 ipp->partial5 = CheckBox (q, "NH2 Partial", ChangedPartialProc);
6318 }
6319 SetObjectExtra (ipp->partial5, ipp, NULL);
6320 if (nucsOK) {
6321 ipp->partial3 = CheckBox (q, "3' Partial", ChangedPartialProc);
6322 } else {
6323 ipp->partial3 = CheckBox (q, "CO2H Partial", ChangedPartialProc);
6324 }
6325 SetObjectExtra (ipp->partial3, ipp, NULL);
6326 }
6327
6328 f = HiddenGroup (m, 5, 0, NULL);
6329 p_from = StaticPrompt (f, "From", 5 * stdCharWidth, 0, programFont, 'c');
6330 p_to = StaticPrompt (f, "To", 5 * stdCharWidth, 0, programFont, 'c');
6331 p1 = NULL;
6332 p2 = NULL;
6333 p3 = NULL;
6334 if (ipp->strand_col > -1)
6335 {
6336 p1 = StaticPrompt (f, "Strand", 0, 0, programFont, 'c');
6337 }
6338 if (ipp->seqid_col > -1)
6339 {
6340 p2 = StaticPrompt (f, "SeqID", 0, 0, programFont, 'c');
6341 }
6342 if (ipp->aln_col > -1)
6343 {
6344 p3 = StaticPrompt (f, "Alignment", 0, 0, programFont, 'c');
6345 }
6346
6347 f = HiddenGroup (m, 0, 4, NULL);
6348 SetGroupSpacing (f, 0, 0);
6349
6350 num_cols = 2;
6351 if (ipp->strand_col > -1)
6352 {
6353 num_cols ++;
6354 }
6355 if (ipp->seqid_col > -1)
6356 {
6357 num_cols ++;
6358 }
6359 if (ipp->aln_col > -1)
6360 {
6361 num_cols ++;
6362 }
6363
6364 ipp->ivals = CreateTagListDialogEx3 (f, rows, num_cols, spacing,
6365 interval_types, interval_widths, ipp->alists,
6366 useBar, FALSE, NULL, NULL,
6367 ipp->callbacks, callback_data, FALSE, TRUE);
6368
6369 /* put back static interval_types values that may have been changed */
6370 interval_types [2] = TAGLIST_POPUP;
6371 interval_types [3] = TAGLIST_POPUP;
6372 interval_types [4] = TAGLIST_POPUP;
6373 btn_grp = HiddenGroup (m, 2, 0, NULL);
6374 SetGroupSpacing (btn_grp, 10, 10);
6375 ipp->nullsBetween = CheckBox (btn_grp, "'order' (intersperse intervals with gaps)", ChangedPartialProc);
6376 SetObjectExtra (ipp->nullsBetween, ipp, NULL);
6377 b = PushButton (btn_grp, "Insert First Location", InsertFirstLocation);
6378 SetObjectExtra (b, ipp->ivals, NULL);
6379
6380 AlignObjects (ALIGN_CENTER, (HANDLE) ipp->ivals,
6381 (HANDLE) q, (HANDLE) btn_grp, NULL);
6382 tlp = (TagListPtr) GetObjectExtra (ipp->ivals);
6383 if (tlp != NULL) {
6384 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [0], (HANDLE) p_from, NULL);
6385 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [1], (HANDLE) p_to, NULL);
6386 if (ipp->strand_col > -1)
6387 {
6388 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [ipp->strand_col], (HANDLE) p1, NULL);
6389 }
6390 if (ipp->seqid_col > -1)
6391 {
6392 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [ipp->seqid_col], (HANDLE) p2, NULL);
6393 }
6394 if (ipp->aln_col > -1)
6395 {
6396 AlignObjects (ALIGN_JUSTIFY, (HANDLE) tlp->control [ipp->aln_col], (HANDLE) p3, NULL);
6397 }
6398 }
6399 }
6400
6401 return (DialoG) p;
6402 }
6403
6404 typedef struct intervalchoice
6405 {
6406 DIALOG_MESSAGE_BLOCK
6407 GrouP seq_or_aln;
6408 DialoG aln_dlg;
6409 DialoG seq_dlg;
6410 } IntervalChoiceData, PNTR IntervalChoicePtr;
6411
6412 static void IntervalChoiceCallback (Pointer userdata)
6413 {
6414 IntervalChoicePtr dlg;
6415 SeqLocPtr slp, slp_tmp;
6416 Boolean ok_for_aln = FALSE;
6417 BioseqPtr bsp;
6418 SeqAlignPtr salp, salp_next;
6419
6420 if (userdata == NULL)
6421 {
6422 return;
6423 }
6424
6425 dlg = (IntervalChoicePtr) userdata;
6426
6427 if (GetValue (dlg->seq_or_aln) == 1)
6428 {
6429 slp = DialogToPointer (dlg->seq_dlg);
6430 if (slp != NULL)
6431 {
6432 ok_for_aln = TRUE;
6433 slp_tmp = SeqLocFindNext (slp, NULL);
6434 while (slp_tmp != NULL && ok_for_aln)
6435 {
6436 bsp = BioseqFindFromSeqLoc (slp_tmp);
6437 salp = FindAlignmentsForBioseq (bsp);
6438 if (salp == NULL)
6439 {
6440 ok_for_aln = FALSE;
6441 }
6442 else
6443 {
6444 while (salp != NULL)
6445 {
6446 salp_next = salp->next;
6447 salp->next = NULL;
6448 salp = SeqAlignFree (salp);
6449 salp = salp_next;
6450 }
6451 }
6452 slp_tmp = SeqLocFindNext (slp, slp_tmp);
6453 }
6454 }
6455 if (ok_for_aln)
6456 {
6457 Enable (dlg->seq_or_aln);
6458 }
6459 else
6460 {
6461 Disable (dlg->seq_or_aln);
6462 }
6463 }
6464 }
6465
6466 static void SeqLocToIntervalChoiceEditor (DialoG d, Pointer userdata)
6467 {
6468 IntervalChoicePtr dlg;
6469
6470 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6471 if (dlg == NULL)
6472 {
6473 return;
6474 }
6475 PointerToDialog (dlg->seq_dlg, userdata);
6476 PointerToDialog (dlg->aln_dlg, userdata);
6477 IntervalChoiceCallback (dlg);
6478 }
6479
6480 static Pointer IntervalChoiceEditorToSeqLoc (DialoG d)
6481 {
6482 IntervalChoicePtr dlg;
6483
6484 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6485 if (dlg == NULL)
6486 {
6487 return NULL;
6488 }
6489 if (GetValue (dlg->seq_or_aln) == 1)
6490 {
6491 return DialogToPointer (dlg->seq_dlg);
6492 }
6493 else
6494 {
6495 return DialogToPointer (dlg->aln_dlg);
6496 }
6497 }
6498
6499
6500 static Boolean WriteIntervalChoiceDialog (DialoG d, CharPtr filename)
6501
6502 {
6503 AsnIoPtr aip;
6504 IntervalChoicePtr dlg;
6505 SeqLocPtr slp;
6506 Char path [PATH_MAX];
6507 #ifdef WIN_MAC
6508 FILE *f;
6509 #endif
6510
6511 path [0] = '\0';
6512 StringNCpy_0 (path, filename, sizeof (path));
6513 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6514 if (dlg != NULL) {
6515 if (path [0] != '\0' || GetOutputFileName (path, sizeof (path), NULL)) {
6516 #ifdef WIN_MAC
6517 f = FileOpen (path, "r");
6518 if (f != NULL) {
6519 FileClose (f);
6520 } else {
6521 FileCreate (path, "TEXT", "ttxt");
6522 }
6523 #endif
6524 aip = AsnIoOpen (path, "w");
6525 if (aip != NULL) {
6526 slp = IntervalChoiceEditorToSeqLoc (dlg->dialog);
6527 SeqLocAsnWrite (slp, aip, NULL);
6528 AsnIoClose (aip);
6529 slp = SeqLocFree (slp);
6530 return TRUE;
6531 }
6532 }
6533 }
6534 return FALSE;
6535 }
6536
6537
6538 static Boolean ReadIntervalChoiceDialog (DialoG d, CharPtr filename)
6539
6540 {
6541 AsnIoPtr aip;
6542 IntervalChoicePtr dlg;
6543 SeqLocPtr slp;
6544 Char path [PATH_MAX];
6545
6546 path [0] = '\0';
6547 StringNCpy_0 (path, filename, sizeof (path));
6548 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6549 if (dlg != NULL) {
6550 if (path [0] != '\0' || GetInputFileName (path, sizeof (path), "", "TEXT")) {
6551 aip = AsnIoOpen (path, "r");
6552 if (aip != NULL) {
6553 slp = SeqLocAsnRead (aip, NULL);
6554 AsnIoClose (aip);
6555 if (slp != NULL) {
6556 SeqLocToIntervalChoiceEditor (dlg->dialog, slp);
6557 slp = SeqLocFree (slp);
6558 Update ();
6559 return TRUE;
6560 }
6561 }
6562 }
6563 }
6564 return FALSE;
6565 }
6566
6567
6568 static void IntervalChoiceEditorMessage (DialoG d, Int2 mssg)
6569
6570 {
6571 IntervalChoicePtr dlg;
6572
6573 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6574 if (dlg != NULL) {
6575 if (GetValue (dlg->seq_or_aln) == 1)
6576 {
6577 SendMessageToDialog (dlg->seq_dlg, mssg);
6578 }
6579 else
6580 {
6581 SendMessageToDialog (dlg->aln_dlg, mssg);
6582 }
6583 }
6584 }
6585
6586 static ValNodePtr TestIntervalChoiceEditor (DialoG d)
6587 {
6588 IntervalChoicePtr dlg;
6589
6590 dlg = (IntervalChoicePtr) GetObjectExtra (d);
6591 if (dlg == NULL)
6592 {
6593 return NULL;
6594 }
6595 else if (GetValue (dlg->seq_or_aln) == 1)
6596 {
6597 return TestDialog (dlg->seq_dlg);
6598 }
6599 else
6600 {
6601 return TestDialog (dlg->aln_dlg);
6602 }
6603 }
6604
6605 static void DisplayErrorMessagesOk (ButtoN b)
6606 {
6607 BoolPtr pdone;
6608
6609 pdone = (BoolPtr) GetObjectExtra (b);
6610 if (pdone != NULL)
6611 {
6612 *pdone = TRUE;
6613 }
6614 }
6615
6616 extern void DisplayErrorMessages (CharPtr title, ValNodePtr err_list)
6617 {
6618 WindoW w;
6619 GrouP h;
6620 DoC doc;
6621 ButtoN b;
6622 ValNodePtr vnp;
6623 Boolean done = FALSE;
6624
6625 w = MovableModalWindow(-20, -13, -10, -10, title, NULL);
6626 h = HiddenGroup (w, -1, 0, NULL);
6627 SetGroupSpacing (h, 10, 10);
6628
6629 doc = DocumentPanel (h, stdCharWidth * 27, stdLineHeight * 8);
6630 SetDocAutoAdjust (doc, TRUE);
6631 for (vnp = err_list; vnp != NULL; vnp = vnp->next)
6632 {
6633 if (!StringHasNoText (vnp->data.ptrvalue))
6634 {
6635 AppendText (doc, vnp->data.ptrvalue, NULL, NULL, programFont);
6636 }
6637 }
6638 b = PushButton (h, "OK", DisplayErrorMessagesOk);
6639 SetObjectExtra (b, &done, NULL);
6640 AlignObjects (ALIGN_CENTER, (HANDLE) doc,
6641 (HANDLE) b,
6642 NULL);
6643 Show (w);
6644 Select (w);
6645 while (!done)
6646 {
6647 ProcessExternalEvent ();
6648 Update ();
6649 }
6650 ProcessAnEvent ();
6651 Remove (w);
6652 }
6653
6654 static void ShowIntervalChoice (IntervalChoicePtr dlg)
6655 {
6656 if (dlg == NULL)
6657 {
6658 return;
6659 }
6660 if (GetValue (dlg->seq_or_aln) == 1)
6661 {
6662 Show (dlg->seq_dlg);
6663 Hide (dlg->aln_dlg);
6664 }
6665 else
6666 {
6667 Show (dlg->aln_dlg);
6668 Hide (dlg->seq_dlg);
6669 }
6670 }
6671
6672 static void ChangeIntervalChoice (GrouP g)
6673 {
6674 IntervalChoicePtr dlg;
6675 SeqLocPtr slp;
6676 ValNodePtr err_list = NULL;
6677 CharPtr title = NULL;
6678
6679 dlg = (IntervalChoicePtr) GetObjectExtra (g);
6680 if (dlg == NULL)
6681 {
6682 return;
6683 }
6684 if (GetValue (dlg->seq_or_aln) == 1)
6685 {
6686 title = "Unable to translate to sequence coordinates";
6687 err_list = TestDialog (dlg->aln_dlg);
6688 if (err_list == NULL)
6689 {
6690 slp = DialogToPointer (dlg->aln_dlg);
6691 PointerToDialog (dlg->seq_dlg, slp);
6692 slp = SeqLocFree (slp);
6693 err_list = TestDialog (dlg->seq_dlg);
6694 }
6695 if (err_list != NULL)
6696 {
6697 SetValue (dlg->seq_or_aln, 2);
6698 }
6699 }
6700 else
6701 {
6702 title = "Unable to translate to alignment coordinates";
6703 err_list = TestDialog (dlg->seq_dlg);
6704 if (err_list == NULL)
6705 {
6706 slp = DialogToPointer (dlg->seq_dlg);
6707 PointerToDialog (dlg->aln_dlg, slp);
6708 slp = SeqLocFree (slp);
6709 err_list = TestDialog (dlg->aln_dlg);
6710 }
6711 if (err_list != NULL)
6712 {
6713 SetValue (dlg->seq_or_aln, 1);
6714 }
6715 }
6716 ShowIntervalChoice (dlg);
6717 if (err_list != NULL)
6718 {
6719 DisplayErrorMessages (title, err_list);
6720 err_list = ValNodeFreeData (err_list);
6721 }
6722 }
6723
6724 static DialoG CreateIntervalEditorDialogAlnChoice (GrouP h, CharPtr title, Uint2 rows,
6725 Int2 spacing, SeqEntryPtr sep,
6726 Boolean nucsOK, Boolean protsOK,
6727 Boolean useBar, Boolean showPartials,
6728 Boolean allowGaps, FeatureFormPtr ffp,
6729 IntEdPartialProc proc)
6730 {
6731 SeqAlignPtr salp_list = NULL;
6732 GrouP p, g;
6733 IntervalChoicePtr dlg;
6734
6735 VisitAnnotsInSep (sep, &salp_list, GetAlignmentsInSeqEntryCallback);
6736 if (salp_list == NULL)
6737 {
6738 return CreateIntervalEditorDialogExEx (h, title, rows, spacing, sep,
6739 nucsOK, protsOK, useBar, showPartials,
6740 allowGaps, ffp, proc, FALSE, TRUE,
6741 NULL, NULL, FALSE);
6742 }
6743 else
6744 {
6745 dlg = (IntervalChoicePtr) MemNew (sizeof (IntervalChoiceData));
6746 if (dlg == NULL)
6747 {
6748 return NULL;
6749 }
6750
6751 p = HiddenGroup (h, -1, 0, NULL);
6752 SetGroupSpacing (p, 10, 10);
6753 SetObjectExtra (p, dlg, StdCleanupExtraProc);
6754
6755 dlg->dialog = (DialoG) p;
6756 dlg->todialog = SeqLocToIntervalChoiceEditor;
6757 dlg->fromdialog = IntervalChoiceEditorToSeqLoc;
6758 dlg->dialogmessage = IntervalChoiceEditorMessage;
6759 dlg->testdialog = TestIntervalChoiceEditor;
6760 dlg->exportdialog = WriteIntervalChoiceDialog;
6761 dlg->importdialog = ReadIntervalChoiceDialog;
6762
6763 g = HiddenGroup (p, 0, 0, NULL);
6764 dlg->seq_dlg = CreateIntervalEditorDialogExEx (g, title, rows, spacing, sep,
6765 nucsOK, protsOK, useBar, showPartials,
6766 allowGaps, ffp, proc, FALSE, TRUE,
6767 IntervalChoiceCallback, dlg, FALSE);
6768
6769 dlg->aln_dlg = CreateIntervalEditorDialogExEx (g, title, rows, spacing, sep,
6770 nucsOK, protsOK, useBar, showPartials,
6771 allowGaps, ffp, proc, TRUE, TRUE,
6772 IntervalChoiceCallback, dlg, FALSE);
6773 AlignObjects (ALIGN_CENTER, (HANDLE)dlg->seq_dlg, (HANDLE) dlg->aln_dlg, NULL);
6774 dlg->seq_or_aln = HiddenGroup (p, 2, 0, ChangeIntervalChoice);
6775 SetObjectExtra (dlg->seq_or_aln, dlg, NULL);
6776 RadioButton (dlg->seq_or_aln, "Sequence Coordinates");
6777 RadioButton (dlg->seq_or_aln, "Alignment Coordinates");
6778 SetValue (dlg->seq_or_aln, 1);
6779
6780 AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) dlg->seq_or_aln, NULL);
6781 ShowIntervalChoice (dlg);
6782 IntervalChoiceCallback (dlg);
6783 return (DialoG) p;
6784 }
6785 }
6786
6787 extern DialoG CreateIntervalEditorDialogEx (GrouP h, CharPtr title, Uint2 rows,
6788 Int2 spacing, SeqEntryPtr sep,
6789 Boolean nucsOK, Boolean protsOK,
6790 Boolean useBar, Boolean showPartials,
6791 Boolean allowGaps, FeatureFormPtr ffp,
6792 IntEdPartialProc proc)
6793 {
6794 return CreateIntervalEditorDialogAlnChoice (h, title, rows, spacing, sep,
6795 nucsOK, protsOK, useBar, showPartials,
6796 allowGaps, ffp, proc);
6797 }
6798
6799 extern DialoG CreateIntervalEditorDialog (GrouP h, CharPtr title, Uint2 rows,
6800 Int2 spacing, SeqEntryPtr sep,
6801 Boolean nucsOK, Boolean protsOK)
6802
6803 {
6804 return CreateIntervalEditorDialogEx (h, title, rows, spacing, sep,
6805 nucsOK, protsOK, TRUE, TRUE, FALSE,
6806 NULL, NULL);
6807 }
6808
6809 static void ValNodePtrToVisStringDialog (DialoG d, Pointer data)
6810
6811 {
6812 ValNodePtr head;
6813 Int2 j;
6814 ValNodePtr list;
6815 CharPtr str;
6816 TagListPtr tlp;
6817 ValNodePtr vnp;
6818
6819 tlp = (TagListPtr) GetObjectExtra (d);
6820 list = (ValNodePtr) data;
6821 if (tlp != NULL) {
6822 head = NULL;
6823 while (list != NULL) {
6824 vnp = ValNodeNew (head);
6825 if (head == NULL) {
6826 head = vnp;
6827 }
6828 if (vnp != NULL) {
6829 str = MemNew (StringLen ((CharPtr) list->data.ptrvalue) + 3);
6830 if (str != NULL) {
6831 StringCpy (str, (CharPtr) list->data.ptrvalue);
6832 StringCat (str, "\n");
6833 }
6834 vnp->data.ptrvalue = str;
6835 }
6836 list = list->next;
6837 }
6838 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
6839 tlp->vnp = head;
6840 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
6841 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
6842 }
6843 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
6844 CorrectBarMax (tlp->bar, tlp->max);
6845 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
6846 }
6847 }
6848
6849 static Pointer VisStringDialogToValNodePtr (DialoG d)
6850
6851 {
6852 Char ch;
6853 ValNodePtr head;
6854 Int2 j;
6855 Int2 len;
6856 ValNodePtr list;
6857 Boolean okay;
6858 CharPtr str;
6859 TagListPtr tlp;
6860 ValNodePtr vnp;
6861
6862 head = NULL;
6863 tlp = (TagListPtr) GetObjectExtra (d);
6864 if (tlp != NULL && tlp->vnp != NULL) {
6865 list = NULL;
6866 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
6867 str = (CharPtr) vnp->data.ptrvalue;
6868 okay = FALSE;
6869 len = StringLen (str);
6870 for (j = 0; j < len; j++) {
6871 ch = str [j];
6872 if (ch != ' ' && ch != '\t' && ch != '\n') {
6873 okay = TRUE;
6874 }
6875 }
6876 if (okay) {
6877 list = ValNodeNew (list);
6878 if (head == NULL) {
6879 head = list;
6880 }
6881 if (list != NULL) {
6882 list->choice = 0;
6883 list->data.ptrvalue = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
6884 }
6885 }
6886 }
6887 }
6888 return (Pointer) head;
6889 }
6890
6891 static void DbtagPtrToDbtagDialog (DialoG d, Pointer data, Boolean readOnly)
6892
6893 {
6894 DbtagPtr dp;
6895 ValNodePtr head;
6896 Int2 j;
6897 size_t len;
6898 ValNodePtr list;
6899 ObjectIdPtr oid;
6900 CharPtr ptr;
6901 CharPtr str;
6902 TagListPtr tlp;
6903 Char tmp [16];
6904 ValNodePtr vnp;
6905
6906 tlp = (TagListPtr) GetObjectExtra (d);
6907 list = (ValNodePtr) data;
6908 if (tlp != NULL) {
6909 head = NULL;
6910 while (list != NULL) {
6911 vnp = ValNodeNew (head);
6912 if (head == NULL) {
6913 head = vnp;
6914 }
6915 if (vnp != NULL) {
6916 dp = (DbtagPtr) list->data.ptrvalue;
6917 if (dp != NULL && dp->db != NULL && dp->tag != NULL) {
6918 oid = dp->tag;
6919 ptr = NULL;
6920 if (oid->str != NULL) {
6921 ptr = oid->str;
6922 } else {
6923 sprintf (tmp, "%ld", (long) oid->id);
6924 ptr = tmp;
6925 }
6926 len = StringLen (dp->db) + StringLen (ptr);
6927 str = MemNew (len + 4);
6928 if (str != NULL) {
6929 StringCpy (str, dp->db);
6930 StringCat (str, "\t");
6931 StringCat (str, ptr);
6932 StringCat (str, "\n");
6933 }
6934 vnp->data.ptrvalue = str;
6935 }
6936 }
6937 list = list->next;
6938 }
6939 SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
6940 tlp->vnp = head;
6941 SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
6942 for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
6943 }
6944 if (readOnly) {
6945 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows));
6946 CorrectBarMax (tlp->bar, tlp->max);
6947 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
6948 if (tlp->max > 0) {
6949 SafeShow (tlp->bar);
6950 } else {
6951 SafeHide (tlp->bar);
6952 }
6953 } else {
6954 tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
6955 CorrectBarMax (tlp->bar, tlp->max);
6956 CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
6957 }
6958 }
6959 }
6960
6961 static void DbtagPtrToRODbtagDialog (DialoG d, Pointer data)
6962
6963 {
6964 DbtagPtrToDbtagDialog (d, data, TRUE);
6965 }
6966
6967 static void DbtagPtrToRWDbtagDialog (DialoG d, Pointer data)
6968
6969 {
6970 DbtagPtrToDbtagDialog (d, data, FALSE);
6971 }
6972
6973 static Pointer DbtagDialogToDbtagPtr (DialoG d)
6974
6975 {
6976 Boolean alldigits;
6977 Char ch;
6978 DbtagPtr dp;
6979 ValNodePtr head;
6980 Int2 j;
6981 Boolean leadingzero;
6982 Int2 len;
6983 ValNodePtr list;
6984 Boolean notallzero;
6985 ObjectIdPtr oid;
6986 Boolean okay;
6987 CharPtr ptr;
6988 CharPtr str;
6989 TagListPtr tlp;
6990 CharPtr tmp;
6991 long int val;
6992 ValNodePtr vnp;
6993
6994 head = NULL;
6995 tlp = (TagListPtr) GetObjectExtra (d);
6996 if (tlp != NULL && tlp->vnp != NULL) {
6997 list = NULL;
6998 for (vnp = tlp->vnp; vnp != NULL; vnp = vnp->next) {
6999 str = (CharPtr) vnp->data.ptrvalue;
7000 okay = FALSE;
7001 len = StringLen (str);
7002 for (j = 0; j < len; j++) {
7003 ch = str [j];
7004 if (ch != ' ' && ch != '\t' && ch != '\n') {
7005 okay = TRUE;
7006 }
7007 }
7008 if (okay) {
7009 list = ValNodeNew (list);
7010 if (head == NULL) {
7011 head = list;
7012 }
7013 if (list != NULL) {
7014 list->choice = 0;
7015 dp = DbtagNew ();
7016 list->data.ptrvalue = (Pointer) dp;
7017 if (dp != NULL) {
7018 dp->db = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
7019 oid = ObjectIdNew ();
7020 dp->tag = oid;
7021 if (oid != NULL) {
7022 tmp = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
7023 TrimSpacesAroundString (tmp);
7024 if (tmp != NULL) {
7025 leadingzero = FALSE;
7026 notallzero = FALSE;
7027 alldigits = TRUE;
7028 ptr = tmp;
7029 ch = *ptr;
7030 if (ch == '0') {
7031 leadingzero = TRUE;
7032 }
7033 while (ch != '\0') {
7034 if (! (IS_DIGIT (ch))) {
7035 alldigits = FALSE;
7036 } else if ('1'<= ch && ch <='9') {
7037 notallzero = TRUE;
7038 }
7039 ptr++;
7040 ch = *ptr;
7041 }
7042 if (alldigits && (! (leadingzero && notallzero)) && sscanf (tmp, "%ld", &val) == 1) {
7043 oid->id = (Int4) val;
7044 MemFree (tmp);
7045 } else {
7046 oid->str = tmp;
7047 }
7048 } else {
7049 oid->str = StringSave ("?");
7050 }
7051 }
7052 }
7053 }
7054 }
7055 }
7056 }
7057 return (Pointer) head;
7058 }
7059
7060 Uint2 visstring_types [] = {
7061 TAGLIST_TEXT, TAGLIST_TEXT
7062 };
7063
7064 Uint2 readonlystring_types [] = {
7065 TAGLIST_PROMPT, TAGLIST_PROMPT
7066 };
7067
7068 Uint2 visstring_widths [] = {
7069 0, 0, 0, 0
7070 };
7071
7072 extern DialoG CreateVisibleStringDialog (GrouP h, Uint2 rows,
7073 Int2 spacing, Int2 width)
7074
7075 {
7076 visstring_widths [0] = width;
7077 return CreateTagListDialog (h, rows, 1, spacing,
7078 visstring_types, visstring_widths, NULL,
7079 ValNodePtrToVisStringDialog,
7080 VisStringDialogToValNodePtr);
7081 }
7082
7083 extern DialoG CreateDbtagDialog (GrouP h, Uint2 rows, Int2 spacing,
7084 Int2 width1, Int2 width2)
7085
7086 {
7087 DialoG d;
7088 TagListPtr tlp;
7089
7090 visstring_widths [0] = width1;
7091 visstring_widths [1] = width2;
7092 if (GetAppProperty ("ReadOnlyDbTags") == NULL) {
7093 return CreateTagListDialog (h, rows, 2, spacing,
7094 visstring_types, visstring_widths, NULL,
7095 DbtagPtrToRWDbtagDialog,
7096 DbtagDialogToDbtagPtr);
7097 } else {
7098 d = CreateTagListDialog (h, rows, 2, spacing,
7099 readonlystring_types, visstring_widths, NULL,
7100 DbtagPtrToRODbtagDialog,
7101 DbtagDialogToDbtagPtr);
7102 tlp = (TagListPtr) GetObjectExtra (d);
7103 if (tlp != NULL) {
7104 Hide (tlp->bar);
7105 }
7106 return d;
7107 }
7108 }
7109
7110 /* ValueList Editor */
7111 static CharPtr combine_strings (CharPtr s, CharPtr add)
7112 {
7113 CharPtr total;
7114 if (StringHasNoText (add))
7115 {
7116 return s;
7117 }
7118 if (StringHasNoText (s))
7119 {
7120 s = MemFree (s);
7121 s = StringSave (add);
7122 }
7123 else
7124 {
7125 total = (CharPtr) MemNew (sizeof (Char) * (StringLen (s) + StringLen (add) + 2));
7126 sprintf (total, "%s;%s", s, add);
7127 s = MemFree (s);
7128 s = total;
7129 }
7130 return s;
7131 }
7132
7133
7134
7135 typedef struct simpletextvalueedit {
7136 DIALOG_MESSAGE_BLOCK
7137 TaglistCallback change_notify;
7138 Pointer change_userdata;
7139 TexT text;
7140 } SimpleTextValueEditData, PNTR SimpleTextValueEditPtr;
7141
7142 static void SimpleTextValueEditChange (TexT t)
7143 {
7144 SimpleTextValueEditPtr dlg;
7145 dlg = (SimpleTextValueEditPtr) GetObjectExtra (t);
7146 if (dlg != NULL && dlg->change_notify != NULL)
7147 {
7148 (dlg->change_notify) (dlg->change_userdata);
7149 }
7150 }
7151
7152 static void StringToSimpleTextValueEditDialog (DialoG d, Pointer data)
7153 {
7154 SimpleTextValueEditPtr dlg;
7155 dlg = (SimpleTextValueEditPtr) GetObjectExtra (d);
7156
7157 if (dlg != NULL)
7158 {
7159 SetTitle (dlg->text, (CharPtr) data);
7160 if (dlg->change_notify != NULL)
7161 {
7162 (dlg->change_notify) (dlg->change_userdata);
7163 }
7164 }
7165 }
7166
7167
7168 static Pointer SimpleTextValueEditDialogToString (DialoG d)
7169 {
7170 SimpleTextValueEditPtr dlg;
7171 dlg = (SimpleTextValueEditPtr) GetObjectExtra (d);
7172
7173 if (dlg != NULL)
7174 {
7175 return SaveStringFromText (dlg->text);
7176 }
7177 else
7178 {
7179 return NULL;
7180 }
7181 }
7182
7183 static DialoG SimpleTextValueEditDialog (GrouP h, Int2 width, ValueListParentPtr parent, TaglistCallback change_notify, Pointer change_userdata)
7184 {
7185 SimpleTextValueEditPtr dlg;
7186 GrouP p;
7187
7188 p = HiddenGroup (h, -1, 0, NULL);
7189 SetGroupSpacing (p, 10, 10);
7190 dlg = (SimpleTextValueEditPtr) MemNew (sizeof(SimpleTextValueEditData));
7191
7192 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7193 dlg->dialog = (DialoG) p;
7194 dlg->todialog = StringToSimpleTextValueEditDialog;
7195 dlg->fromdialog = SimpleTextValueEditDialogToString;
7196 dlg->testdialog = NULL;
7197 dlg->dialogmessage = NULL;
7198 dlg->change_notify = change_notify;
7199 dlg->change_userdata = change_userdata;
7200
7201 dlg->text = DialogText (p, "", width, SimpleTextValueEditChange);
7202 SetObjectExtra (dlg->text, dlg, NULL);
7203 return (DialoG) p;
7204 }
7205
7206 #define STRUCTURED_VALUE_EDIT_FIELDS \
7207 DIALOG_MESSAGE_BLOCK \
7208 TaglistCallback change_notify; \
7209 Pointer change_userdata; \
7210 GrouP unparsable; \
7211 TexT text; \
7212 ValueListParentPtr parent; \
7213 DialoG dlg; \
7214 ParseOK parse_func;
7215
7216 typedef struct structuredvalueeditdlg {
7217 STRUCTURED_VALUE_EDIT_FIELDS
7218 } StructuredValueEditDlgData, PNTR StructuredValueEditDlgPtr;
7219
7220
7221 static void CopyUnparsableToNote (ButtoN b)
7222 {
7223 StructuredValueEditDlgPtr dlg;
7224 CharPtr old_note, new_note;
7225
7226 dlg = (StructuredValueEditDlgPtr) GetObjectExtra (b);
7227
7228 if (dlg != NULL && dlg->parent != NULL && dlg->parent->note != NULL)
7229 {
7230 old_note = SaveStringFromText (dlg->parent->note);
7231 new_note = SaveStringFromText (dlg->text);
7232 old_note = combine_strings (old_note, new_note);
7233 SetTitle (dlg->parent->note, old_note);
7234 new_note = MemFree (new_note);
7235 old_note = MemFree (old_note);
7236 SetTitle (dlg->text, "");
7237 Hide (dlg->unparsable);
7238 if (dlg != NULL && dlg->change_notify != NULL)
7239 {
7240 (dlg->change_notify) (dlg->change_userdata);
7241 }
7242 }
7243 }
7244
7245
7246 static void EraseUnparsable (ButtoN b)
7247 {
7248 StructuredValueEditDlgPtr dlg;
7249
7250 dlg = (StructuredValueEditDlgPtr) GetObjectExtra (b);
7251
7252 if (dlg != NULL)
7253 {
7254 SetTitle (dlg->text, "");
7255 Hide (dlg->unparsable);
7256 if (dlg != NULL && dlg->change_notify != NULL)
7257 {
7258 (dlg->change_notify) (dlg->change_userdata);
7259 }
7260 }
7261 }
7262
7263
7264 static void StringToStructuredValueEditDialog (DialoG d, Pointer data)
7265 {
7266 StructuredValueEditDlgPtr dlg;
7267 CharPtr txt;
7268
7269 dlg = (StructuredValueEditDlgPtr) GetObjectExtra (d);
7270
7271 txt = (CharPtr) data;
7272
7273 if (dlg != NULL)
7274 {
7275 if (StringHasNoText (txt) || (dlg->parse_func != NULL && (dlg->parse_func) (txt)))
7276 {
7277 PointerToDialog (dlg->dlg, txt);
7278 SetTitle (dlg->text, "");
7279 Hide (dlg->unparsable);
7280 }
7281 else
7282 {
7283 SetTitle (dlg->text, (CharPtr) data);
7284 Show (dlg->unparsable);
7285 }
7286 if (dlg->change_notify != NULL)
7287 {
7288 (dlg->change_notify) (dlg->change_userdata);
7289 }
7290 }
7291 }
7292
7293
7294 static Pointer StructuredValueEditDialogToString (DialoG d)
7295 {
7296 StructuredValueEditDlgPtr dlg;
7297 CharPtr txt = NULL, tmp;
7298
7299 dlg = (StructuredValueEditDlgPtr) GetObjectExtra (d);
7300
7301 if (dlg != NULL)
7302 {
7303 if (dlg->dlg == NULL)
7304 {
7305 txt = StringSave ("");
7306 }
7307 else
7308 {
7309 txt = DialogToPointer (dlg->dlg);
7310 }
7311
7312 if (!TextHasNoText (dlg->text))
7313 {
7314 tmp = SaveStringFromText (dlg->text);
7315 txt = combine_strings (txt, tmp);
7316 tmp = MemFree (tmp);
7317 }
7318 }
7319 return txt;
7320
7321 }
7322
7323
7324 static void StructuredValueEditChange (TexT t)
7325 {
7326 StructuredValueEditDlgPtr dlg;
7327 CharPtr txt, tmp;
7328
7329 dlg = (StructuredValueEditDlgPtr) GetObjectExtra (t);
7330
7331 if (TextHasNoText (dlg->text))
7332 {
7333 Hide (dlg->unparsable);
7334 }
7335 else if (dlg->dlg != NULL)
7336 {
7337 txt = SaveStringFromText(dlg->text);
7338 tmp = DialogToPointer (dlg->dlg);
7339 if (StringHasNoText (tmp) && dlg->parse_func != NULL && (dlg->parse_func)(txt))
7340 {
7341 PointerToDialog (dlg->dlg, txt);
7342 SetTitle (dlg->text, "");
7343 Hide (dlg->unparsable);
7344 }
7345 txt = MemFree (txt);
7346 tmp = MemFree (tmp);
7347 }
7348
7349 if (dlg != NULL && dlg->change_notify != NULL)
7350 {
7351 (dlg->change_notify) (dlg->change_userdata);
7352 }
7353 }
7354
7355
7356
7357 typedef struct truefalsevalueedit {
7358 STRUCTURED_VALUE_EDIT_FIELDS
7359 } TrueFalseValueEditData, PNTR TrueFalseValueEditPtr;
7360
7361 static DialoG TrueFalseValueEditDialog (GrouP h, Int2 width, ValueListParentPtr parent, TaglistCallback change_notify, Pointer change_userdata)
7362 {
7363 TrueFalseValueEditPtr dlg;
7364 GrouP p;
7365 ButtoN b;
7366
7367 p = HiddenGroup (h, 2, 0, NULL);
7368 SetGroupSpacing (p, 10, 10);
7369 dlg = (TrueFalseValueEditPtr) MemNew (sizeof(TrueFalseValueEditData));
7370
7371 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7372 dlg->dialog = (DialoG) p;
7373 dlg->todialog = StringToStructuredValueEditDialog;
7374 dlg->fromdialog = StructuredValueEditDialogToString;
7375 dlg->testdialog = NULL;
7376 dlg->dialogmessage = NULL;
7377 dlg->change_notify = change_notify;
7378 dlg->change_userdata = change_userdata;
7379 dlg->parent = parent;
7380
7381 StaticPrompt (p, "TRUE", 0, 0, programFont, 'c');
7382
7383 dlg->unparsable = HiddenGroup (p, 3, 0, NULL);
7384 SetGroupSpacing (dlg->unparsable, 10, 10);
7385 dlg->text = DialogText (dlg->unparsable, "", width - 15, StructuredValueEditChange);
7386 SetObjectExtra (dlg->text, dlg, NULL);
7387
7388 b = PushButton (dlg->unparsable, "Copy to Note", CopyUnparsableToNote);
7389 SetObjectExtra (b, dlg, NULL);
7390
7391 b = PushButton (dlg->unparsable, "Erase", EraseUnparsable);
7392 SetObjectExtra (b, dlg, NULL);
7393
7394 Hide (dlg->unparsable);
7395
7396 return (DialoG) p;
7397 }
7398
7399
7400 typedef struct latlondlg {
7401 DIALOG_MESSAGE_BLOCK
7402
7403 PopuP dir_ns;
7404 PopuP dir_ew;
7405 TexT deg_ns;
7406 TexT deg_ew;
7407
7408 TaglistCallback change_notify;
7409 Pointer change_userdata;
7410
7411 } LatLonDlgData, PNTR LatLonDlgPtr;
7412
7413
7414 static void ResetLatLonDlg (LatLonDlgPtr dlg)
7415 {
7416 if (dlg == NULL) return;
7417
7418 SetTitle (dlg->deg_ns, "");
7419 SetValue (dlg->dir_ns, 1);
7420 SetTitle (dlg->deg_ew, "");
7421 SetValue (dlg->dir_ew, 1);
7422 }
7423
7424
7425 static void StringToLatLonDlg (DialoG d, Pointer data)
7426 {
7427 LatLonDlgPtr dlg;
7428 CharPtr str, ns, ew, tmp;
7429 Int4 len;
7430
7431 dlg = (LatLonDlgPtr) GetObjectExtra (d);
7432 if (dlg == NULL) return;
7433
7434 str = (CharPtr) data;
7435 if (str == NULL)
7436 {
7437 ResetLatLonDlg (dlg);
7438 return;
7439 }
7440
7441 ew = str + StringLen (str) - 1;
7442 if (*ew != 'E' && *ew != 'W')
7443 {
7444 ResetLatLonDlg (dlg);
7445 return;
7446 }
7447
7448 ns = StringChr (str, 'N');
7449 if (ns == NULL)
7450 {
7451 ns = StringChr (str, 'S');
7452 }
7453 if (ns == NULL)
7454 {
7455 ResetLatLonDlg (dlg);
7456 return;
7457 }
7458
7459 len = ns - str + 1;
7460 tmp = (CharPtr) MemNew (sizeof (Char) * len);
7461 StringNCpy (tmp, str, len - 1);
7462 tmp [len - 1] = 0;
7463 TrimSpacesAroundString (tmp);
7464 SetTitle (dlg->deg_ns, tmp);
7465 tmp = MemFree (tmp);
7466 SetValue (dlg->dir_ns, *ns == 'N' ? 1 : 2);
7467
7468 len = ew - ns;
7469 tmp = (CharPtr) MemNew (sizeof (Char) * len);
7470 StringNCpy (tmp, ns + 1, len - 1);
7471 tmp [len - 1] = 0;
7472 TrimSpacesAroundString (tmp);
7473 SetTitle (dlg->deg_ew, tmp);
7474 tmp = MemFree (tmp);
7475 SetValue (dlg->dir_ew, *ew == 'E' ? 1 : 2);
7476
7477 }
7478
7479
7480 static Pointer LatLonDlgToString (DialoG d)
7481 {
7482 LatLonDlgPtr dlg;
7483 CharPtr str, ns, ew;
7484 Int4 len;
7485
7486 dlg = (LatLonDlgPtr) GetObjectExtra (d);
7487 if (dlg == NULL) return NULL;
7488
7489 if (TextHasNoText (dlg->deg_ns) && TextHasNoText (dlg->deg_ew))
7490 {
7491 return NULL;
7492 }
7493
7494 ns = SaveStringFromText (dlg->deg_ns);
7495 ew = SaveStringFromText (dlg->deg_ew);
7496 len = StringLen (ns) + StringLen (ew) + 6;
7497 str = (CharPtr) MemNew (sizeof(Char) * len);
7498 sprintf (str, "%s %c %s %c",
7499 ns == NULL ? "" : ns,
7500 GetValue (dlg->dir_ns) == 1 ? 'N' : 'S',
7501 ew == NULL ? "" : ew,
7502 GetValue (dlg->dir_ew) == 1 ? 'E' : 'W');
7503 ns = MemFree (ns);
7504 ew = MemFree (ew);
7505 return str;
7506 }
7507
7508 static void LatLonTextChange (TexT t)
7509 {
7510 LatLonDlgPtr dlg;
7511
7512 dlg = (LatLonDlgPtr) GetObjectExtra (t);
7513 if (dlg == NULL) return;
7514
7515
7516 if (dlg->change_notify != NULL)
7517 {
7518 (dlg->change_notify) (dlg->change_userdata);
7519 }
7520 }
7521
7522
7523 static void LatLonPopupChange (PopuP p)
7524 {
7525 LatLonDlgPtr dlg;
7526
7527 dlg = (LatLonDlgPtr) GetObjectExtra (p);
7528 if (dlg == NULL) return;
7529
7530
7531 if (dlg->change_notify != NULL)
7532 {
7533 (dlg->change_notify) (dlg->change_userdata);
7534 }
7535 }
7536
7537
7538 static DialoG LatLonDialog (GrouP h, TaglistCallback change_notify, Pointer change_userdata)
7539 {
7540 LatLonDlgPtr dlg;
7541 GrouP p;
7542
7543 p = HiddenGroup (h, 4, 0, NULL);
7544 SetGroupSpacing (p, 10, 10);
7545 dlg = (LatLonDlgPtr) MemNew (sizeof(LatLonDlgData));
7546
7547 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7548 dlg->dialog = (DialoG) p;
7549 dlg->todialog = StringToLatLonDlg;
7550 dlg->fromdialog = LatLonDlgToString;
7551 dlg->testdialog = NULL;
7552 dlg->dialogmessage = NULL;
7553 dlg->change_notify = change_notify;
7554 dlg->change_userdata = change_userdata;
7555
7556 dlg->deg_ns = DialogText (p, "", 3, LatLonTextChange);
7557 SetObjectExtra (dlg->deg_ns, dlg, NULL);
7558 dlg->dir_ns = PopupList (p, TRUE, LatLonPopupChange);
7559 SetObjectExtra (dlg->dir_ns, dlg, NULL);
7560 PopupItem (dlg->dir_ns, "N");
7561 PopupItem (dlg->dir_ns, "S");
7562 SetValue (dlg->dir_ns, 1);
7563
7564 dlg->deg_ew = DialogText (p, "", 3, LatLonTextChange);
7565 SetObjectExtra (dlg->deg_ew, dlg, NULL);
7566 dlg->dir_ew = PopupList (p, TRUE, LatLonPopupChange);
7567 SetObjectExtra (dlg->dir_ew, dlg, NULL);
7568 PopupItem (dlg->dir_ew, "E");
7569 PopupItem (dlg->dir_ew, "W");
7570
7571 SetValue (dlg->dir_ew, 1);
7572
7573 return (DialoG) p;
7574 }
7575
7576
7577 static Boolean ParseLatLonOk (CharPtr str)
7578 {
7579 CharPtr ns, ew, cp;
7580
7581 if (StringHasNoText (str))
7582 {
7583 return TRUE;
7584 }
7585 ew = str + StringLen (str) - 1;
7586 if (*ew != 'E' && *ew != 'W')
7587 {
7588 return FALSE;
7589 }
7590 ns = str;
7591 while (ns < ew && !isalpha (*ns))
7592 {
7593 ns++;
7594 }
7595 if (*ns != 'N' && *ns != 'S')
7596 {
7597 return FALSE;
7598 }
7599
7600 cp = ns + 1;
7601 while (cp < ew)
7602 {
7603 if (isalpha (*cp))
7604 {
7605 return FALSE;
7606 }
7607 cp++;
7608 }
7609 return TRUE;
7610 }
7611
7612
7613 static DialoG ValueListLatLonDialog (GrouP h, Int2 width, ValueListParentPtr parent, TaglistCallback change_notify, Pointer change_userdata)
7614 {
7615 StructuredValueEditDlgPtr dlg;
7616 GrouP p;
7617 ButtoN b;
7618
7619
7620 p = HiddenGroup (h, 2, 0, NULL);
7621 SetGroupSpacing (p, 10, 10);
7622 dlg = (StructuredValueEditDlgPtr) MemNew (sizeof(StructuredValueEditDlgData));
7623
7624 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7625 dlg->dialog = (DialoG) p;
7626 dlg->todialog = StringToStructuredValueEditDialog;
7627 dlg->fromdialog = StructuredValueEditDialogToString;
7628 dlg->testdialog = NULL;
7629 dlg->dialogmessage = NULL;
7630 dlg->change_notify = change_notify;
7631 dlg->change_userdata = change_userdata;
7632 dlg->parent = parent;
7633
7634 dlg->dlg = LatLonDialog (p, change_notify, change_userdata);
7635 dlg->parse_func = ParseLatLonOk;
7636
7637 dlg->unparsable = HiddenGroup (p, 3, 0, NULL);
7638 SetGroupSpacing (dlg->unparsable, 10, 10);
7639 dlg->text = DialogText (dlg->unparsable, "", width - 15, StructuredValueEditChange);
7640 SetObjectExtra (dlg->text, dlg, NULL);
7641
7642 b = PushButton (dlg->unparsable, "Copy to Note", CopyUnparsableToNote);
7643 SetObjectExtra (b, dlg, NULL);
7644
7645 b = PushButton (dlg->unparsable, "Erase", EraseUnparsable);
7646 SetObjectExtra (b, dlg, NULL);
7647
7648 Hide (dlg->unparsable);
7649
7650 return (DialoG) p;
7651 }
7652
7653
7654 typedef struct specimenvoucherdlg {
7655 DIALOG_MESSAGE_BLOCK
7656
7657 TexT institution_code;
7658 TexT collection_code;
7659 TexT free_text;
7660
7661 TaglistCallback change_notify;
7662 Pointer change_userdata;
7663
7664 } SpecimenVoucherDlgData, PNTR SpecimenVoucherDlgPtr;
7665
7666
7667 static void ResetSpecimenVoucherDlg (SpecimenVoucherDlgPtr dlg)
7668 {
7669 if (dlg == NULL) return;
7670
7671 SetTitle (dlg->institution_code, "");
7672 SetTitle (dlg->collection_code, "");
7673 SetTitle (dlg->free_text, "");
7674 }
7675
7676
7677 static void StringToSpecimenVoucherDlg (DialoG d, Pointer data)
7678 {
7679 SpecimenVoucherDlgPtr dlg;
7680 CharPtr str, ptr, cp;
7681
7682 dlg = (SpecimenVoucherDlgPtr) GetObjectExtra (d);
7683 if (dlg == NULL) return;
7684
7685 ResetSpecimenVoucherDlg (dlg);
7686 str = (CharPtr) data;
7687 if (str == NULL)
7688 {
7689 return;
7690 }
7691
7692 /* make copy so we don't worry about changing data */
7693 str = StringSave (str);
7694
7695 cp = StringChr (str, ':');
7696 if (cp == NULL)
7697 {
7698 SetTitle (dlg->free_text, str);
7699 }
7700 else
7701 {
7702 *cp = 0;
7703 SetTitle (dlg->institution_code, str);
7704 ptr = cp + 1;
7705 cp = StringChr (ptr, ':');
7706 if (cp == NULL)
7707 {
7708 SetTitle (dlg->free_text, ptr);
7709 }
7710 else
7711 {
7712 *cp = 0;
7713 SetTitle (dlg->collection_code, ptr);
7714 SetTitle (dlg->free_text, cp + 1);
7715 }
7716 }
7717 str = MemFree (str);
7718 }
7719
7720
7721 static Pointer SpecimenVoucherDlgToString (DialoG d)
7722 {
7723 SpecimenVoucherDlgPtr dlg;
7724 CharPtr str;
7725 Int4 len;
7726 CharPtr inst, coll, free_text;
7727
7728 dlg = (SpecimenVoucherDlgPtr) GetObjectExtra (d);
7729 if (dlg == NULL) return NULL;
7730
7731 if (TextHasNoText (dlg->institution_code) && TextHasNoText (dlg->collection_code) && TextHasNoText (dlg->free_text))
7732 {
7733 return NULL;
7734 }
7735
7736 inst = SaveStringFromText (dlg->institution_code);
7737 coll = SaveStringFromText (dlg->collection_code);
7738 free_text = SaveStringFromText (dlg->free_text);
7739
7740 len = StringLen (inst) + StringLen (coll) + StringLen (free_text) + 3;
7741 str = (CharPtr) MemNew (sizeof(Char) * len);
7742 if (StringHasNoText (inst) && StringHasNoText (coll))
7743 {
7744 sprintf (str, "%s", free_text);
7745 }
7746 else if (StringHasNoText (coll))
7747 {
7748 sprintf (str, "%s:%s", inst, free_text == NULL ? "" : free_text);
7749 }
7750 else
7751 {
7752 sprintf (str, "%s:%s:%s", inst == NULL ? "" : inst,
7753 coll == NULL ? "" : coll,
7754 free_text == NULL ? "" : free_text);
7755 }
7756 inst = MemFree (inst);
7757 coll = MemFree (coll);
7758 free_text = MemFree (free_text);
7759 return str;
7760 }
7761
7762 static void SpecimenVoucherTextChange (TexT t)
7763 {
7764 SpecimenVoucherDlgPtr dlg;
7765
7766 dlg = (SpecimenVoucherDlgPtr) GetObjectExtra (t);
7767 if (dlg == NULL) return;
7768
7769
7770 if (dlg->change_notify != NULL)
7771 {
7772 (dlg->change_notify) (dlg->change_userdata);
7773 }
7774 }
7775
7776
7777 static DialoG SpecimenVoucherDialog (GrouP h, Int2 width, ValueListParentPtr parent, TaglistCallback change_notify, Pointer change_userdata)
7778 {
7779 SpecimenVoucherDlgPtr dlg;
7780 GrouP p;
7781
7782 p = HiddenGroup (h, 6, 0, NULL);
7783 SetGroupSpacing (p, 10, 10);
7784 dlg = (SpecimenVoucherDlgPtr) MemNew (sizeof(SpecimenVoucherDlgData));
7785
7786 SetObjectExtra (p, dlg, StdCleanupExtraProc);
7787 dlg->dialog = (DialoG) p;
7788 dlg->todialog = StringToSpecimenVoucherDlg;
7789 dlg->fromdialog = SpecimenVoucherDlgToString;
7790 dlg->testdialog = NULL;
7791 dlg->dialogmessage = NULL;
7792 dlg->change_notify = change_notify;
7793 dlg->change_userdata = change_userdata;
7794
7795 StaticPrompt (p, "Inst", 0, 0, programFont, 'r');
7796 dlg->institution_code = DialogText (p, "", 4, SpecimenVoucherTextChange);
7797 SetObjectExtra (dlg->institution_code, dlg, NULL);
7798 StaticPrompt (p, "Coll", 0, 0, programFont, 'r');
7799 dlg->collection_code = DialogText (p, "", 4, SpecimenVoucherTextChange);
7800 SetObjectExtra (dlg->collection_code, dlg, NULL);
7801
7802 StaticPrompt (p, "SpecID/Text", 0, 0, programFont, 'r');
7803 dlg->free_text = DialogText (p, "", width - 8, SpecimenVoucherTextChange);
7804 SetObjectExtra (dlg->free_text, dlg, NULL);
7805
7806 return (DialoG) p;
7807 }
7808
7809
7810 static Boolean ParseSpecimenVoucherOk (CharPtr str)
7811 {
7812 return TRUE;
7813 }
7814
7815
7816 typedef DialoG (*MakeValueEditDialogFunc) PROTO ((GrouP, Int2, ValueListParentPtr, TaglistCallback, Pointer));
7817
7818 static MakeValueEditDialogFunc value_edit_dialog_list[] = {
7819 SimpleTextValueEditDialog,
7820 TrueFalseValueEditDialog,
7821 ValueListLatLonDialog,
7822 SpecimenVoucherDialog
7823 };
7824
7825
7826 extern NameValuePairPtr NameValuePairFree (NameValuePairPtr nvp)
7827 {
7828 if (nvp != NULL)
7829 {
7830 nvp->name_vnp = ValNodeFreeData (nvp->name_vnp);
7831 nvp->value = MemFree (nvp->value);
7832 nvp = MemFree (nvp);
7833 }
7834 return nvp;
7835 }
7836
7837
7838 extern NameValuePairPtr NameValuePairCopy (NameValuePairPtr nvp)
7839 {
7840 NameValuePairPtr cpy = NULL;
7841
7842 if (nvp != NULL)
7843 {
7844 cpy = (NameValuePairPtr) MemNew (sizeof (NameValuePairData));
7845 if (nvp->name_vnp != NULL)
7846 {
7847 cpy->name_vnp = ValNodeNew (NULL);
7848 cpy->name_vnp->choice = nvp->name_vnp->choice;
7849 cpy->name_vnp->data.ptrvalue = StringSave (nvp->name_vnp->data.ptrvalue);
7850 }
7851 cpy->value = StringSave (nvp->value);
7852 }
7853 return cpy;
7854 }
7855
7856
7857 extern ValNodePtr NameValuePairListFree (ValNodePtr vnp)
7858 {
7859 ValNodePtr vnp_next;
7860
7861 while (vnp != NULL)
7862 {
7863 vnp->data.ptrvalue = NameValuePairFree (vnp->data.ptrvalue);
7864 vnp_next = vnp->next;
7865 vnp->next= NULL;
7866 vnp = ValNodeFree (vnp);
7867 vnp = vnp_next;
7868 }
7869 return vnp;
7870 }
7871
7872
7873 typedef struct valuelistrowdialog {
7874 DIALOG_MESSAGE_BLOCK
7875
7876 TaglistCallback change_notify;
7877 Pointer change_userdata;
7878 DialoG parent_dlg;
7879 DialoG name_dlg;
7880 DialoG editors[eNumValueEditors];
7881 Int4 current_editor;
7882 } ValueListRowDialogData, PNTR ValueListRowDialogPtr;
7883
7884
7885 static void ChangeValueListRowName (Pointer data)
7886 {
7887 ValueListRowDialogPtr dlg;
7888 ValNodePtr vnp;
7889 Int4 i;
7890 CharPtr value = NULL;
7891
7892 dlg = (ValueListRowDialogPtr) data;
7893 if (dlg == NULL) return;
7894
7895 if (dlg->current_editor > -1)
7896 {
7897 value = (CharPtr) DialogToPointer (dlg->editors[dlg->current_editor]);
7898 }
7899 for (i = 0; i < eNumValueEditors; i++)
7900 {
7901 Hide (dlg->editors[i]);
7902 }
7903 vnp = (ValNodePtr) DialogToPointer (dlg->name_dlg);
7904 if (vnp != NULL && vnp->choice > 0)
7905 {
7906 dlg->current_editor = vnp->choice - 1;
7907 Show (dlg->editors[dlg->current_editor]);
7908 PointerToDialog (dlg->editors[dlg->current_editor], value);
7909 vnp = ValNodeFree (vnp);
7910 } else {
7911 dlg->current_editor = -1;
7912 }
7913 value = MemFree (value);
7914
7915 if (dlg->change_notify != NULL)
7916 {
7917 (dlg->change_notify) (dlg->change_userdata);
7918 }
7919 }
7920
7921
7922 static void NameValuePairToDialog (DialoG d, Pointer data)
7923 {
7924 ValueListRowDialogPtr dlg;
7925 NameValuePairPtr nvp;
7926 ValNode vn;
7927 Int4 i;
7928
7929 dlg = (ValueListRowDialogPtr) GetObjectExtra (d);
7930 nvp = (NameValuePairPtr) data;
7931
7932 if (dlg == NULL) return;
7933 if (nvp == NULL)
7934 {
7935 vn.next = NULL;
7936 vn.choice = 0;
7937 vn.data.ptrvalue = " ";
7938 PointerToDialog (dlg->name_dlg, &vn);
7939 for (i = 0; i < eNumValueEditors; i++)
7940 {
7941 PointerToDialog (dlg->editors[i], NULL);
7942 }
7943 ChangeValueListRowName (dlg);
7944 }
7945 else
7946 {
7947 PointerToDialog (dlg->name_dlg, nvp->name_vnp);
7948 ChangeValueListRowName (dlg);
7949 if (dlg->current_editor > -1)
7950 {
7951 PointerToDialog (dlg->editors[dlg->current_editor], nvp->value);
7952 if (dlg->change_notify != NULL)
7953 {
7954 (dlg->change_notify) (dlg->change_userdata);
7955 }
7956 }
7957 }
7958 }
7959
7960
7961 static Pointer DialogToNameValuePair (DialoG d)
7962 {
7963 ValueListRowDialogPtr dlg;
7964 NameValuePairPtr nvp;
7965 ValNodePtr name_vnp;
7966
7967 dlg = (ValueListRowDialogPtr) GetObjectExtra (d);
7968 if (dlg == NULL || dlg->current_editor < 0) return NULL;
7969
7970 name_vnp = DialogToPointer (dlg->name_dlg);
7971 if (name_vnp == NULL) return NULL;
7972
7973 nvp = (NameValuePairPtr) MemNew (sizeof (NameValuePairData));
7974 nvp->name_vnp = name_vnp;
7975 nvp->value = DialogToPointer (dlg->editors[dlg->current_editor]);
7976 return nvp;
7977 }
7978
7979
7980 static ValNodePtr CopyChoiceList (ValNodePtr orig)
7981 {
7982 ValNodePtr vnp, cpy = NULL, prev = NULL;
7983
7984 while (orig != NULL)
7985 {
7986 vnp = ValNodeNew (NULL);
7987 vnp->choice = orig->choice;
7988 vnp->data.ptrvalue = StringSave (orig->data.ptrvalue);
7989 if (prev == NULL)
7990 {
7991 cpy = vnp;
7992 }
7993 else
7994 {
7995 prev->next = vnp;
7996 }
7997 prev = vnp;
7998 orig = orig->next;
7999 }
8000 return cpy;
8001 }
8002
8003 static ValNodePtr TestValueListRowDialog (DialoG d)
8004 {
8005 ValueListRowDialogPtr dlg;
8006 ValNodePtr name_vnp, err_list = NULL;
8007 CharPtr val, err_str;
8008 CharPtr err_fmt = "No modifier type selected for data %s";
8009
8010 dlg = (ValueListRowDialogPtr) GetObjectExtra (d);
8011 if (dlg == NULL || dlg->current_editor < 0) return NULL;
8012
8013 val = DialogToPointer (dlg->editors[dlg->current_editor]);
8014 if (!StringHasNoText (val))
8015 {
8016 name_vnp = DialogToPointer (dlg->name_dlg);
8017 if (name_vnp == NULL || name_vnp->choice == 0)
8018 {
8019 err_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (err_fmt) + StringLen (val)));
8020 sprintf (err_str, err_fmt, val);
8021 err_list = ValNodeNew(NULL);
8022 err_list->choice = 0;
8023 err_list->data.ptrvalue = err_str;
8024 }
8025 name_vnp = ValNodeFree (name_vnp);
8026 }
8027 val = MemFree (val);
8028 return err_list;
8029 }
8030
8031
8032 static void ClearValueListRow (ButtoN b)
8033 {
8034 ValueListRowDialogPtr dlg;
8035
8036 dlg = (ValueListRowDialogPtr) GetObjectExtra (b);
8037
8038 if (dlg != NULL)
8039 {
8040 PointerToDialog (dlg->dialog, NULL);
8041 if (dlg->change_notify != NULL)
8042 {
8043 (dlg->change_notify) (dlg->change_userdata);
8044 }
8045 SendMessageToDialog (dlg->parent_dlg, VIB_MSG_REDRAW);
8046 }
8047 }
8048
8049
8050 static DialoG ValueListRowDialog (GrouP h, Int2 width, ValNodePtr choice_list, ValueListParentPtr parent,
8051 TaglistCallback change_notify, Pointer change_userdata, DialoG parent_dlg)
8052 {
8053 ValueListRowDialogPtr dlg;
8054 GrouP p, g;
8055 Int4 i;
8056 ValNode vn;
8057 ButtoN b;
8058
8059 p = HiddenGroup (h, 3, 0, NULL);
8060 SetGroupSpacing (p, 2, 2);
8061 dlg = (ValueListRowDialogPtr) MemNew (sizeof(ValueListRowDialogData));
8062
8063 SetObjectExtra (p, dlg, StdCleanupExtraProc);
8064 dlg->dialog = (DialoG) p;
8065 dlg->todialog = NameValuePairToDialog;
8066 dlg->fromdialog = DialogToNameValuePair;
8067 dlg->testdialog = TestValueListRowDialog;
8068 dlg->dialogmessage = NULL;
8069 dlg->change_notify = change_notify;
8070 dlg->change_userdata = change_userdata;
8071 dlg->parent_dlg = parent_dlg;
8072
8073 dlg->name_dlg = ValNodeSelectionDialog (p, CopyChoiceList(choice_list), 1,
8074 ValNodeStringName,
8075 ValNodeSimpleDataFree, ValNodeStringCopy,
8076 ValNodeStringMatch, NULL,
8077 ChangeValueListRowName, dlg, FALSE);
8078 vn.next = NULL;
8079 vn.choice = 0;
8080 vn.data.ptrvalue = " ";
8081 PointerToDialog (dlg->name_dlg, &vn);
8082
8083 g = HiddenGroup (p, 0, 0, NULL);
8084 for (i = 0; i < eNumValueEditors; i++)
8085 {
8086 dlg->editors[i] = (value_edit_dialog_list[i]) (g, width, parent, change_notify, change_userdata);
8087 }
8088
8089 b = PushButton (p, "X", ClearValueListRow);
8090 SetObjectExtra (b, dlg, NULL);
8091
8092 ChangeValueListRowName (dlg);
8093
8094 return (DialoG) p;
8095 }
8096
8097 typedef struct valuelistdialog {
8098 DIALOG_MESSAGE_BLOCK
8099 TaglistCallback change_notify;
8100 Pointer change_userdata;
8101 Int4 num_rows;
8102 DialoG * rows;
8103 BaR left_bar;
8104 BaR right_bar;
8105 ValNodePtr choice_list;
8106 ValNodePtr value_list;
8107 Int4 scroll_pos;
8108 Boolean suppress_notify;
8109 } ValueListDialogData, PNTR ValueListDialogPtr;
8110
8111
8112 static void CleanupValueListDialog (GraphiC g, VoidPtr data)
8113
8114 {
8115 ValueListDialogPtr dlg;
8116
8117 dlg = (ValueListDialogPtr) data;
8118 if (dlg != NULL)
8119 {
8120 dlg->rows = MemFree (dlg->rows);
8121 }
8122
8123 StdCleanupExtraProc (g, data);
8124 }
8125
8126
8127 static NameValuePairPtr GetNthNameValuePair (Int4 n, ValNodePtr list)
8128 {
8129 while (n > 0 && list != NULL)
8130 {
8131 n--;
8132 list = list->next;
8133 }
8134 if (list == NULL)
8135 {
8136 return NULL;
8137 }
8138 else
8139 {
8140 return (NameValuePairPtr) list->data.ptrvalue;
8141 }
8142 }
8143
8144 static void PopulateValueListRows (ValueListDialogPtr dlg)
8145 {
8146 Int4 n;
8147 ValNodePtr vnp;
8148
8149 n = dlg->scroll_pos;
8150 vnp = dlg->value_list;
8151
8152 dlg->suppress_notify = TRUE;
8153
8154 while (n > 0 && vnp != NULL)
8155 {
8156 n--;
8157 vnp = vnp->next;
8158 }
8159 for (n = 0; n < dlg->num_rows; n++)
8160 {
8161 if (vnp == NULL)
8162 {
8163 PointerToDialog (dlg->rows[n], NULL);
8164 }
8165 else
8166 {
8167 PointerToDialog (dlg->rows[n], vnp->data.ptrvalue);
8168 vnp = vnp->next;
8169 }
8170 }
8171 dlg->suppress_notify = FALSE;
8172 }
8173
8174
8175 static Boolean IsNameValuePairEmpty (NameValuePairPtr nvp)
8176 {
8177 if (nvp == NULL)
8178 {
8179 return TRUE;
8180 }
8181 else if ((nvp->name_vnp == NULL || nvp->name_vnp->choice == 0 || StringHasNoText (nvp->name_vnp->data.ptrvalue)) /* no choice */
8182 && StringHasNoText (nvp->value)) /* no value */
8183 {
8184 return TRUE;
8185 }
8186 else
8187 {
8188 return FALSE;
8189 }
8190 }
8191
8192 /* Only trim blanks from the end of the list */
8193 static void RemoveBlanks (ValNodePtr PNTR pvnp)
8194 {
8195 ValNodePtr vnp, last_non_blank = NULL;
8196
8197 if (pvnp == NULL) return;
8198
8199 vnp = *pvnp;
8200 while (vnp != NULL)
8201 {
8202 if (!IsNameValuePairEmpty ((NameValuePairPtr) vnp->data.ptrvalue))
8203 {
8204 last_non_blank = vnp;
8205 }
8206 vnp = vnp->next;
8207 }
8208 if (last_non_blank != NULL) {
8209 last_non_blank->next = NameValuePairListFree (last_non_blank->next);
8210 }
8211 }
8212
8213 static void ValueListPairToDialog (DialoG d, Pointer data)
8214 {
8215 ValueListDialogPtr dlg;
8216 Int4 num_vals;
8217
8218 dlg = (ValueListDialogPtr) GetObjectExtra (d);
8219 if (dlg == NULL) return;
8220
8221 dlg->value_list = NameValuePairListFree (dlg->value_list);
8222 dlg->value_list = (ValNodePtr) data;
8223 RemoveBlanks (&(dlg->value_list));
8224
8225 num_vals = ValNodeLen (dlg->value_list);
8226 if (num_vals >= dlg->num_rows)
8227 {
8228 SetBarMax (dlg->left_bar, num_vals + 1 - dlg->num_rows);
8229 SetBarMax (dlg->right_bar, num_vals + 1 - dlg->num_rows);
8230 }
8231 else
8232 {
8233 SetBarMax (dlg->left_bar, 0);
8234 SetBarMax (dlg->right_bar, 0);
8235 }
8236 if (GetValue (dlg->left_bar) > GetBarMax (dlg->left_bar))
8237 {
8238 CorrectBarValue (dlg->left_bar, 0);
8239 CorrectBarValue (dlg->right_bar, 0);
8240 }
8241 PopulateValueListRows (dlg);
8242 }
8243
8244
8245 static void ScrollValueListProc (BaR b, GraphiC g, Int2 _new, Int2 _old)
8246 {
8247 ValueListDialogPtr dlg;
8248
8249 dlg = (ValueListDialogPtr) GetObjectExtra (b);
8250 if (dlg == NULL) return;
8251
8252 /* synchronize left and right scroll bars */
8253 if (b == dlg->right_bar && dlg->left_bar != NULL)
8254 {
8255 CorrectBarValue (dlg->left_bar, GetBarValue (dlg->right_bar));
8256 }
8257 else if (b == dlg->left_bar && dlg->right_bar != NULL)
8258 {
8259 CorrectBarValue (dlg->right_bar, GetBarValue (dlg->left_bar));
8260 }
8261
8262 dlg->scroll_pos = _new;
8263 PopulateValueListRows (dlg);
8264 }
8265
8266
8267 static void ValueListDialogMessage (DialoG d, Int2 mssg)
8268
8269 {
8270 ValNodePtr new_value_list;
8271
8272 switch (mssg) {
8273 case VIB_MSG_REDRAW :
8274 new_value_list = DialogToPointer (d);
8275 PointerToDialog (d, new_value_list);
8276 break;
8277 default :
8278 break;
8279 }
8280 }
8281
8282
8283 static void ChangeValueRow (Pointer data)
8284 {
8285 ValueListDialogPtr dlg;
8286 NameValuePairPtr nvp;
8287 Int4 max, i;
8288 ValNodePtr vnp;
8289
8290 dlg = (ValueListDialogPtr) data;
8291
8292 if (dlg == NULL) return;
8293
8294 if (dlg->suppress_notify) return;
8295
8296 /* copy values into list */
8297 /* first, skip over rows scrolled past */
8298 vnp = dlg->value_list;
8299 i = 0;
8300 while (i < dlg->scroll_pos)
8301 {
8302 if (vnp == NULL)
8303 {
8304 vnp = ValNodeAddPointer (&dlg->value_list, 0, NULL);
8305 }
8306 vnp = vnp->next;
8307 i++;
8308 }
8309
8310 /* now copy in rows we can see */
8311 for (i = 0; i < dlg->num_rows; i++)
8312 {
8313 if (vnp == NULL)
8314 {
8315 vnp = ValNodeAddPointer (&dlg->value_list, 0, DialogToPointer (dlg->rows[i]));
8316 }
8317 else
8318 {
8319 vnp->data.ptrvalue = NameValuePairFree (vnp->data.ptrvalue);
8320 vnp->data.ptrvalue = DialogToPointer (dlg->rows[i]);
8321 }
8322 vnp = vnp->next;
8323 }
8324
8325
8326 /* if editing last row, extend scrollbar for new row */
8327 max = GetBarMax (dlg->left_bar);
8328 if (dlg->scroll_pos == max)
8329 {
8330 nvp = DialogToPointer (dlg->rows[dlg->num_rows - 1]);
8331 if (!IsNameValuePairEmpty (nvp))
8332 {
8333 SetBarMax (dlg->left_bar, max + 1);
8334 SetBarMax (dlg->right_bar, max + 1);
8335 }
8336 nvp = NameValuePairFree(nvp);
8337 }
8338
8339 if (dlg->change_notify != NULL)
8340 {
8341 (dlg->change_notify)(dlg->change_userdata);
8342 }
8343 }
8344
8345
8346 static Pointer DialogToNameValuePairList (DialoG d)
8347 {
8348 ValueListDialogPtr dlg;
8349 ValNodePtr value_list = NULL, vnp;
8350
8351 dlg = (ValueListDialogPtr) GetObjectExtra (d);
8352 if (dlg == NULL) return NULL;
8353
8354 for (vnp = dlg->value_list; vnp != NULL; vnp = vnp->next)
8355 {
8356 if (vnp->data.ptrvalue != NULL)
8357 {
8358 ValNodeAddPointer (&value_list, 0, NameValuePairCopy (vnp->data.ptrvalue));
8359 }
8360 }
8361 return (Pointer) value_list;
8362 }
8363
8364
8365 static ValNodePtr TestValueListDialog (DialoG d)
8366 {
8367 ValNodePtr err_list = NULL, value_list = NULL, vnp;
8368 NameValuePairPtr nvp;
8369 CharPtr err_fmt = "No modifier type selected for data %s";
8370 CharPtr err_str;
8371
8372 value_list = DialogToPointer (d);
8373
8374 for (vnp = value_list; vnp != NULL; vnp = vnp->next)
8375 {
8376 nvp = (NameValuePairPtr) vnp->data.ptrvalue;
8377 if (nvp != NULL
8378 && !StringHasNoText (nvp->value)
8379 && (nvp->name_vnp == NULL || StringHasNoText (nvp->name_vnp->data.ptrvalue)))
8380 {
8381 err_str = (CharPtr) MemNew (sizeof (Char) * (StringLen (err_fmt) + StringLen (nvp->value)));
8382 sprintf (err_str, err_fmt, nvp->value);
8383 ValNodeAddPointer (&err_list, 0, err_str);
8384 }
8385 }
8386 value_list = NameValuePairListFree (value_list);
8387 return err_list;
8388 }
8389
8390 extern DialoG ValueListDialog (GrouP h, Uint2 num_rows, Int2 width, ValNodePtr choice_list, ValueListParentPtr parent, TaglistCallback change_notify, Pointer change_userdata)
8391 {
8392 ValueListDialogPtr dlg;
8393 GrouP p, g;
8394 Int4 i;
8395
8396 p = HiddenGroup (h, 3, 0, NULL);
8397 SetGroupSpacing (p, 2, 2);
8398 dlg = (ValueListDialogPtr) MemNew (sizeof(ValueListDialogData));
8399
8400 SetObjectExtra (p, dlg, CleanupValueListDialog);
8401 dlg->dialog = (DialoG) p;
8402 dlg->todialog = ValueListPairToDialog;
8403 dlg->fromdialog = DialogToNameValuePairList;
8404 dlg->testdialog = TestValueListDialog;
8405 dlg->dialogmessage = ValueListDialogMessage;
8406 dlg->change_notify = change_notify;
8407 dlg->change_userdata = change_userdata;
8408
8409 dlg->num_rows = num_rows;
8410
8411 /* navigation bar on left */
8412 dlg->left_bar = ScrollBar (p, 0, dlg->num_rows, ScrollValueListProc);
8413 SetObjectExtra (dlg->left_bar, dlg, NULL);
8414 CorrectBarPage (dlg->left_bar, dlg->num_rows - 1, dlg->num_rows - 1);
8415
8416 g = HiddenGroup (p, 1, 0, NULL);
8417 dlg->rows = (DialoG *) MemNew (num_rows * sizeof (DialoG));
8418 for (i = 0; i < dlg->num_rows; i++)
8419 {
8420 dlg->rows[i] = ValueListRowDialog (g, width, choice_list, parent, ChangeValueRow, dlg, (DialoG) p);
8421
8422 }
8423
8424 /* navigation bar on right */
8425 dlg->right_bar = ScrollBar (p, 0, dlg->num_rows, ScrollValueListProc);
8426 SetObjectExtra (dlg->right_bar, dlg, NULL);
8427 CorrectBarPage (dlg->right_bar, dlg->num_rows - 1, dlg->num_rows - 1);
8428
8429 AlignObjects (ALIGN_LOWER, (HANDLE) g, (HANDLE) dlg->left_bar, (HANDLE) dlg->right_bar, NULL);
8430
8431
8432 return (DialoG) p;
8433 }
8434
8435
8436 typedef struct modifierlistdlg {
8437 VALUE_LIST_PARENT_FIELDS
8438
8439 DialoG dlg;
8440 ButtoN type_strain;
8441 TexT taxname;
8442
8443 EnumFieldAssocPtr al;
8444 } ModifierListDlgData, PNTR ModifierListDlgPtr;
8445
8446
8447 static ValNodePtr TestModifierListDlg (DialoG d)
8448 {
8449 ModifierListDlgPtr dlg = (ModifierListDlgPtr) GetObjectExtra (d);
8450 if (dlg == NULL) return NULL;
8451 return TestDialog (dlg->dlg);
8452 }
8453
8454
8455
8456 static ValNodePtr SubSourceListToNameValueList (SubSourcePtr ssp)
8457 {
8458 ValNodePtr val_list = NULL;
8459 NameValuePairPtr nvp;
8460
8461 while (ssp != NULL)
8462 {
8463 if (ssp->subtype != SUBSRC_other)
8464 {
8465 nvp = (NameValuePairPtr) MemNew (sizeof (NameValuePairData));
8466 nvp->name_vnp = ValNodeNew(NULL);
8467 nvp->name_vnp->choice = 1;
8468 nvp->name_vnp->data.ptrvalue = StringSave (GetSubsourceQualName (ssp->subtype));
8469 nvp->value = StringSave (ssp->name);
8470 ValNodeAddPointer (&val_list, 0, nvp);
8471 }
8472 ssp = ssp->next;
8473 }
8474 return val_list;
8475
8476 }
8477
8478
8479 static void SubSourceListToDialog (DialoG d, Pointer data)
8480 {
8481 ModifierListDlgPtr dlg;
8482 SubSourcePtr ssp;
8483 ValNodePtr vnp;
8484 CharPtr note_txt = NULL;
8485
8486 dlg = (ModifierListDlgPtr) GetObjectExtra (d);
8487
8488 if (dlg == NULL) return;
8489
8490 ssp = (SubSourcePtr) data;
8491
8492 vnp = SubSourceListToNameValueList (ssp);
8493 PointerToDialog (dlg->dlg, vnp);
8494
8495 while (ssp != NULL)
8496 {
8497 if (ssp->subtype == SUBSRC_other)
8498 {
8499 note_txt = combine_strings (note_txt, ssp->name);
8500 }
8501 ssp = ssp->next;
8502 }
8503 SetTitle (dlg->note, note_txt);
8504
8505 }
8506
8507
8508 static Pointer DialogToSubSourceList (DialoG d)
8509 {
8510 ModifierListDlgPtr dlg;
8511 ValNodePtr val_list, vnp;
8512 NameValuePairPtr nvp;
8513 SubSourcePtr ssp_list = NULL, ssp_prev = NULL, ssp_new;
8514 Uint1 subtype;
8515 CharPtr comment_str;
8516
8517 dlg = (ModifierListDlgPtr) GetObjectExtra (d);
8518
8519 if (dlg == NULL) return NULL;
8520
8521 val_list = (ValNodePtr) DialogToPointer (dlg->dlg);
8522 for (vnp = val_list; vnp != NULL; vnp = vnp->next)
8523 {
8524 if (vnp->data.ptrvalue != NULL)
8525 {
8526 nvp = (NameValuePairPtr) vnp->data.ptrvalue;
8527 if (nvp != NULL && nvp->name_vnp != NULL)
8528 {
8529 subtype = EquivalentSubSourceEx (nvp->name_vnp->data.ptrvalue, TRUE);
8530 if (subtype != 0)
8531 {
8532 ssp_new = SubSourceNew ();
8533 ssp_new->subtype = subtype;
8534 ssp_new->name = StringSave (nvp->value == NULL ? "" : nvp->value);
8535 if (ssp_prev == NULL)
8536 {
8537 ssp_list = ssp_new;
8538 }
8539 else
8540 {
8541 ssp_prev->next = ssp_new;
8542 }
8543 ssp_prev = ssp_new;
8544 }
8545 }
8546 }
8547 }
8548 val_list = NameValuePairListFree (val_list);
8549
8550 /* add comment */
8551 comment_str = SaveStringFromText (dlg->note);
8552 if (!StringHasNoText (comment_str))
8553 {
8554 ssp_new = SubSourceNew();
8555 ssp_new->subtype = SUBSRC_other;
8556 ssp_new->name = StringSave (comment_str);
8557 if (ssp_prev == NULL)
8558 {
8559 ssp_list = ssp_new;
8560 }
8561 else
8562 {
8563 ssp_prev->next = ssp_new;
8564 }
8565 ssp_prev = ssp_new;
8566 }
8567
8568 return ssp_list;
8569 }
8570
8571
8572 static ValNodePtr GetSubSourceChoicesForValueList (EnumFieldAssocPtr al)
8573 {
8574 ValNodePtr choice_list = NULL;
8575 EnumFieldAssocPtr efap;
8576
8577 efap = al;
8578 while (efap->name != NULL)
8579 {
8580 if (StringHasNoText (efap->name))
8581 {
8582 ValNodeAddStr (&choice_list, eValueEditSimpleText + 1, StringSave (efap->name));
8583 }
8584 else if (efap->value == SUBSRC_lat_lon)
8585 {
8586 ValNodeAddStr (&choice_list, eValueEditLatLon + 1, StringSave (efap->name));
8587 }
8588 else if (IsNonTextModifier (efap->name))
8589 {
8590 ValNodeAddStr (&choice_list, eValueEditTrueFalse + 1, StringSave (efap->name));
8591 }
8592 else
8593 {
8594 ValNodeAddStr (&choice_list, eValueEditSimpleText + 1, StringSave (efap->name));
8595 }
8596 efap ++;
8597 }
8598 return choice_list;
8599 }
8600
8601
8602 static CharPtr subsource_extra_prompts [] = {
8603 "Additional", "Source", "Information", NULL
8604 };
8605
8606 extern DialoG CreateSubSourceDialog (GrouP h, EnumFieldAssocPtr al)
8607 {
8608 ModifierListDlgPtr dlg;
8609 GrouP p, g, x;
8610 ValNodePtr choice_list;
8611 Int2 max;
8612
8613
8614 p = HiddenGroup (h, -1, 0, NULL);
8615 SetGroupSpacing (p, 10, 10);
8616 dlg = (ModifierListDlgPtr) MemNew (sizeof(ModifierListDlgData));
8617
8618 SetObjectExtra (p, dlg, StdCleanupExtraProc);
8619 dlg->dialog = (DialoG) p;
8620 dlg->todialog = SubSourceListToDialog;
8621 dlg->fromdialog = DialogToSubSourceList;
8622 dlg->testdialog = TestModifierListDlg;
8623 dlg->dialogmessage = NULL;
8624
8625 choice_list = GetSubSourceChoicesForValueList (al);
8626 dlg->dlg = ValueListDialog (p, 3, 23, choice_list, (ValueListParentPtr) dlg, NULL, NULL);
8627 choice_list = ValNodeFreeData (choice_list);
8628
8629 g = HiddenGroup (p, 2, 0, NULL);
8630 SelectFont (programFont);
8631 max = MaxStringWidths (subsource_extra_prompts) + 2;
8632 x = MultiLinePrompt (g, "Additional Source Information", max, programFont);
8633 dlg->note = ScrollText (g, 20, 3, programFont, TRUE, NULL);
8634 AlignObjects (ALIGN_MIDDLE, (HANDLE) x, (HANDLE) dlg->note, NULL);
8635
8636 AlignObjects (ALIGN_CENTER, (HANDLE) dlg->dlg, (HANDLE) g, NULL);
8637
8638 return (DialoG) p;
8639 }
8640
8641
8642 static ValNodePtr OrgModListToNameValueList (OrgModPtr mod)
8643 {
8644 ValNodePtr val_list = NULL;
8645 NameValuePairPtr nvp;
8646
8647 while (mod != NULL)
8648 {
8649 if (mod->subtype != ORGMOD_gb_acronym
8650 && mod->subtype != ORGMOD_gb_anamorph
8651 && mod->subtype != ORGMOD_gb_synonym
8652 && mod->subtype != ORGMOD_other)
8653 {
8654 nvp = (NameValuePairPtr) MemNew (sizeof (NameValuePairData));
8655 nvp->name_vnp = ValNodeNew(NULL);
8656 nvp->name_vnp->choice = 1;
8657 nvp->name_vnp->data.ptrvalue = StringSave (GetOrgModQualName (mod->subtype));
8658 nvp->value = StringSave (mod->subname);
8659 ValNodeAddPointer (&val_list, 0, nvp);
8660 }
8661 mod = mod->next;
8662 }
8663 return val_list;
8664
8665 }
8666
8667
8668 static void OrgModListToDialog (DialoG d, Pointer data)
8669 {
8670 ModifierListDlgPtr dlg;
8671 OrgModPtr mod;
8672 ValNodePtr vnp;
8673 CharPtr note_txt = NULL;
8674
8675 dlg = (ModifierListDlgPtr) GetObjectExtra (d);
8676
8677 if (dlg == NULL) return;
8678
8679 mod = (OrgModPtr) data;
8680
8681 vnp = OrgModListToNameValueList (mod);
8682 PointerToDialog (dlg->dlg, vnp);
8683
8684 while (mod != NULL)
8685 {
8686 if (mod->subtype == ORGMOD_other)
8687 {
8688 note_txt = combine_strings (note_txt, mod->subname);
8689 }
8690 mod = mod->next;
8691 }
8692 SetTitle (dlg->note, note_txt);
8693
8694 }
8695
8696
8697 static Pointer DialogToOrgModList (DialoG d)
8698 {
8699 ModifierListDlgPtr dlg;
8700 ValNodePtr val_list, vnp;
8701 NameValuePairPtr nvp;
8702 OrgModPtr mod_list = NULL, mod_prev = NULL, mod_new;
8703 Uint1 subtype;
8704 CharPtr comment_str;
8705
8706 dlg = (ModifierListDlgPtr) GetObjectExtra (d);
8707
8708 if (dlg == NULL) return NULL;
8709
8710 val_list = (ValNodePtr) DialogToPointer (dlg->dlg);
8711 for (vnp = val_list; vnp != NULL; vnp = vnp->next)
8712 {
8713 if (vnp->data.ptrvalue != NULL)
8714 {
8715 nvp = (NameValuePairPtr) vnp->data.ptrvalue;
8716 if (nvp != NULL && nvp->name_vnp != NULL)
8717 {
8718 subtype = EquivalentOrgModEx (nvp->name_vnp->data.ptrvalue, TRUE);
8719 if (subtype != 0)
8720 {
8721 mod_new = OrgModNew ();
8722 mod_new->subtype = subtype;
8723 mod_new->subname = StringSave (nvp->value == NULL ? "" : nvp->value);
8724 if (mod_prev == NULL)
8725 {
8726 mod_list = mod_new;
8727 }
8728 else
8729 {
8730 mod_prev->next = mod_new;
8731 }
8732 mod_prev = mod_new;
8733 }
8734 }
8735 }
8736 }
8737 val_list = NameValuePairListFree (val_list);
8738
8739 /* add comment */
8740 comment_str = SaveStringFromText (dlg->note);
8741 if (!StringHasNoText (comment_str))
8742 {
8743 mod_new = OrgModNew();
8744 mod_new->subtype = ORGMOD_other;
8745 mod_new->subname = StringSave (comment_str);
8746 if (mod_prev == NULL)
8747 {
8748 mod_list = mod_new;
8749 }
8750 else
8751 {
8752 mod_prev->next = mod_new;
8753 }
8754 mod_prev = mod_new;
8755 }
8756
8757 return mod_list;
8758 }
8759
8760
8761 extern Boolean IsNonTextModifier (CharPtr mod_name)
8762 {
8763 if (StringICmp (mod_name, "transgenic") == 0
8764 || StringICmp (mod_name, "germline") == 0
8765 || StringICmp (mod_name, "metagenomic") == 0
8766 || StringICmp (mod_name, "environmental-sample") ==0
8767 || StringICmp (mod_name, "rearranged") == 0)
8768 {
8769 return TRUE;
8770 }
8771 else
8772 {
8773 return FALSE;
8774 }
8775 }
8776
8777
8778 static ValNodePtr GetOrgModChoicesForValueList (EnumFieldAssocPtr al)
8779 {
8780 ValNodePtr choice_list = NULL;
8781 EnumFieldAssocPtr efap;
8782
8783 efap = al;
8784 while (efap->name != NULL)
8785 {
8786 if (StringHasNoText (efap->name))
8787 {
8788 ValNodeAddStr (&choice_list, eValueEditSimpleText + 1, StringSave (efap->name));
8789 }
8790 else if (IsNonTextModifier (efap->name))
8791 {
8792 ValNodeAddStr (&choice_list, eValueEditTrueFalse + 1, StringSave (efap->name));
8793 }
8794 else if (efap->value == ORGMOD_specimen_voucher || efap->value == ORGMOD_culture_collection || efap->value == ORGMOD_bio_material)
8795 {
8796 ValNodeAddStr (&choice_list, eValueEditSpecimenVoucher + 1, StringSave (efap->name));
8797 }
8798 else
8799 {
8800 ValNodeAddStr (&choice_list, eValueEditSimpleText + 1, StringSave (efap->name));
8801 }
8802 efap ++;
8803 }
8804 return choice_list;
8805 }
8806
8807
8808 static CharPtr orgmod_extra_prompts [] = {
8809 "Additional", "Organism", "Information", NULL
8810 };
8811
8812 static void ChangeOrgmodComment (TexT t)
8813 {
8814 ModifierListDlgPtr dlg;
8815 CharPtr str;
8816
8817 dlg = (ModifierListDlgPtr) GetObjectExtra (t);
8818 if (dlg == NULL) return;
8819
8820 str = SaveStringFromText (t);
8821 if ( StringStr (str, "type strain of ")) {
8822 Disable (dlg->type_strain);
8823 }
8824
8825 }
8826
8827
8828 static void AddTypeStrainProc (ButtoN b)
8829 {
8830 ModifierListDlgPtr dlg;
8831 CharPtr old_orgcomment;
8832 Int4 old_orgcomment_len;
8833 CharPtr org_name;
8834 Int4 org_name_len;
8835 const CharPtr ts = "type strain of ";
8836 const CharPtr sep = "; ";
8837 CharPtr new_orgcomment;
8838
8839 dlg = (ModifierListDlgPtr) GetObjectExtra (b);
8840 if (dlg == NULL) return;
8841
8842 old_orgcomment_len = TextLength (dlg->note) + 1;
8843 old_orgcomment = MemNew (old_orgcomment_len + 1);
8844 if (old_orgcomment == NULL) return;
8845 org_name_len = TextLength (dlg->taxname) + 1;
8846 org_name = MemNew (org_name_len + 1);
8847 if (org_name == NULL)
8848 {
8849 MemFree (old_orgcomment);
8850 return;
8851 }
8852 new_orgcomment = MemNew (old_orgcomment_len
8853 + StringLen (sep)
8854 + StringLen (ts)
8855 + org_name_len
8856 + 1);
8857 if (new_orgcomment == NULL)
8858 {
8859 MemFree (old_orgcomment);
8860 MemFree (org_name);
8861 }
8862
8863 GetTitle (dlg->note, old_orgcomment, old_orgcomment_len);
8864 TrimSpacesAroundString (old_orgcomment);
8865 GetTitle (dlg->taxname, org_name, org_name_len);
8866 TrimSpacesAroundString (org_name);
8867 if (old_orgcomment[0] != 0)
8868 {
8869 StringCpy(new_orgcomment, old_orgcomment);
8870 StringCat(new_orgcomment, sep);