NCBI C Toolkit Cross Reference

C/desktop/import.c


  1 /*   import.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:  import.c
 27 *
 28 * Author:  Jonathan Kans
 29 *
 30 * Version Creation Date:   6/18/95
 31 *
 32 * $Revision: 6.74 $
 33 *
 34 * File Description: 
 35 *
 36 * Modifications:  
 37 * --------------------------------------------------------------------------
 38 * Date     Name        Description of modification
 39 * -------  ----------  -----------------------------------------------------
 40 *
 41 *
 42 * ==========================================================================
 43 */
 44 
 45 #include <import.h>
 46 #include <objfdef.h>
 47 #include <gbfeat.h>
 48 #include <gbftdef.h>
 49 #include <gather.h>
 50 #include <subutil.h>    /* TOPOLOGY_xxx definitions */
 51 #include <explore.h>
 52 #include <toasn3.h>
 53 
 54 #define IMPORT_PAGE      0
 55 #define ENUM_PAGE        0
 56 #define REGION_PAGE      0
 57 #define COMMON_PAGE      1
 58 #define LOCATION_PAGE    2
 59 
 60 #define NUM_PAGES  8
 61 
 62 typedef struct imprtform {
 63   FEATURE_FORM_BLOCK
 64   SeqEntryPtr   sep;
 65   GrouP         pages [NUM_PAGES];
 66   DialoG        foldertabs;
 67   Int2          currentPage;
 68 } ImprtForm, PNTR ImprtFormPtr;
 69 
 70 typedef struct importpage {
 71   DIALOG_MESSAGE_BLOCK
 72   ImprtFormPtr       ifp;
 73   Handle             key;
 74   TexT               loc;
 75   EnumFieldAssoc     PNTR alist;
 76 } ImportPage, PNTR ImportPagePtr;
 77 
 78 extern EnumFieldAssocPtr import_featdef_alist (Boolean notJustImpFeats, Boolean allowPeptideFeats, Boolean allowRnaImpFeats)
 79 
 80 {
 81   EnumFieldAssocPtr  alist;
 82   EnumFieldAssocPtr  ap;
 83   FeatDefPtr         curr;
 84   Int2               fdn;
 85   Int2               i;
 86   Uint1              key;
 87   CharPtr            label = NULL;
 88   CharPtr            str;
 89   Uint2              subtype;
 90 
 91   fdn = FeatDefNum ();
 92   alist = MemNew (sizeof (EnumFieldAssoc) * (fdn + 2));
 93   if (alist == NULL) {
 94     Message (MSG_ERROR, "in import_featdef_alist: no room");
 95   } else {
 96     i = 0;
 97     ap = alist;
 98     ap->name = StringSave ("     ");
 99     ap->value = (UIEnum) 0;
100     ap++;
101     i++;
102     curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
103     while (curr != NULL) {
104       if (key != FEATDEF_BAD) {
105         if (notJustImpFeats || curr->seqfeat_key == SEQFEAT_IMP) {
106           subtype = curr->featdef_key;
107           if (subtype != FEATDEF_IMP &&
108               subtype != FEATDEF_Imp_CDS &&
109               subtype != FEATDEF_source &&
110               subtype != FEATDEF_virion &&
111               subtype != FEATDEF_mutation &&
112               subtype != FEATDEF_allele &&
113               subtype != FEATDEF_site_ref &&
114               subtype != FEATDEF_gap &&
115               subtype != FEATDEF_misc_RNA &&
116               subtype != FEATDEF_satellite &&
117               subtype != FEATDEF_repeat_unit) {
118             if (allowPeptideFeats ||
119                 (subtype != FEATDEF_mat_peptide &&
120                  subtype != FEATDEF_sig_peptide &&
121                  subtype != FEATDEF_transit_peptide)) {
122               if (allowRnaImpFeats ||
123                 (subtype != FEATDEF_misc_RNA &&
124                  subtype != FEATDEF_precursor_RNA)) {
125                 if (StringCmp (curr->typelabel, "RNA") == 0) {
126                   str = StringSave ("misc_RNA");
127                 } else {
128                   str = StringSave (curr->typelabel);
129                 }
130                 if (*str == '-') {
131                   *str = '~';
132                 }
133                 ap->name = str;
134                 ap->value = key;
135                 ap++;
136                 i++;
137               }
138             }
139           }
140         }
141       }
142       curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
143     }
144     ap->name = NULL;
145   }
146   return alist;
147 }
148 
149 static EnumFieldAssocPtr gap_featdef_alist (void)
150 
151 {
152   EnumFieldAssocPtr  alist;
153   EnumFieldAssocPtr  ap;
154 
155   alist = MemNew (sizeof (EnumFieldAssoc) * (4));
156   if (alist == NULL) {
157     Message (MSG_ERROR, "in gap_featdef_alist: no room");
158   } else {
159     ap = alist;
160     ap->name = StringSave ("     ");
161     ap->value = (UIEnum) 0;
162     ap++;
163     ap->name = StringSave ("gap");
164     ap->value = (UIEnum) FEATDEF_gap;
165     ap++;
166     ap->name = NULL;
167   }
168   return alist;
169 }
170 
171 static void ImpFeatPtrToImportPage (DialoG d, Pointer data)
172 
173 {
174   EnumFieldAssocPtr  ap;
175   Int2               i;
176   ImportPagePtr      ipp;
177   ImpFeatPtr         ifp;
178 
179   ipp = (ImportPagePtr) GetObjectExtra (d);
180   ifp = (ImpFeatPtr) data;
181   if (ipp != NULL) {
182     if (ifp != NULL) {
183       for (i = 1, ap = ipp->alist; ap->name != NULL; i++, ap++) {
184         if (StringCmp (ap->name, ifp->key) == 0) {
185           SetValue (ipp->key, i);
186           SetTitle (ipp->loc, ifp->loc);
187           return;
188         }
189       }
190     }
191     SetValue (ipp->key, 1);
192     SetTitle (ipp->loc, "");
193   }
194 }
195 
196 static Pointer ImportPageToImpFeatPtr (DialoG d)
197 
198 {
199   EnumFieldAssocPtr  ap;
200   Int2               i;
201   ImportPagePtr      ipp;
202   ImpFeatPtr         ifp;
203   UIEnum             val;
204 
205   ifp = NULL;
206   ipp = (ImportPagePtr) GetObjectExtra (d);
207   if (ipp != NULL) {
208     ifp = ImpFeatNew ();
209     if (ifp != NULL) {
210       ifp->loc = SaveStringFromText (ipp->loc);
211       val = GetValue (ipp->key);
212       if (val > 1) {
213         for (i = 1, ap = ipp->alist; ap->name != NULL; i++, ap++) {
214           if (i == val) {
215             ifp->key = StringSave (ap->name);
216             return (Pointer) ifp;
217           }
218         }
219       } else {
220         ifp->key = StringSave ("misc_feature");
221       }
222     }
223   }
224   return (Pointer) ifp;
225 }
226 
227 static void CleanupImportPage (GraphiC g, VoidPtr data)
228 
229 {
230   ImportPagePtr  ipp;
231   Int2           j;
232 
233   ipp = (ImportPagePtr) data;
234   if (ipp != NULL) {
235     if (ipp->alist != NULL) {
236       for (j = 0; ipp->alist [j].name != NULL; j++) {
237         MemFree (ipp->alist [j].name);
238       }
239     }
240     MemFree (ipp->alist);
241   }
242   MemFree (data);
243 }
244 
245 
246 static void ChangeKey (Handle obj)
247 
248 {
249   Char             ch;
250   Int2             expev;
251   Int2             geneval;
252   HelpMessageFunc  helpfunc;
253   ImprtFormPtr     ifp;
254   ImpFeatPtr       imp;
255   ImprtFormPtr     newifp;
256   ObjMgrPtr        omp;
257   ObjMgrTypePtr    omtp;
258   CharPtr          ptr;
259   SeqEntryPtr      sep;
260   SeqFeatPtr       sfp;
261   Char             title [128];
262   WindoW           w;
263 
264   ifp = (ImprtFormPtr) GetObjectExtra (obj);
265   if (ifp != NULL) {
266     sfp = SeqFeatNew ();
267     if (sfp != NULL) {
268       sfp->data.choice = FindFeatFromFeatDefType (ifp->this_subtype);
269       sfp->data.value.ptrvalue = DialogToPointer (ifp->data);
270       sfp->comment = SaveStringFromText (ifp->comment);
271       ptr = sfp->comment;
272       if (ptr != NULL) {
273         ch = *ptr;
274         while (ch != '\0') {
275           if (ch < ' ' || ch > '~') {
276             *ptr = '~';
277           }
278           ptr++;
279           ch = *ptr;
280         }
281       }
282       expev = GetValue (ifp->evidence);
283       if (expev > 0 && expev <= 3) {
284         sfp->exp_ev = expev - 1;
285       } else {
286         sfp->exp_ev = 0;
287       }
288       sfp->partial = GetStatus (ifp->partial);
289       sfp->excpt = GetStatus (ifp->exception);
290       sfp->title = NULL;
291       sfp->product = DialogToPointer (ifp->product);
292       sfp->location = DialogToPointer (ifp->location);
293       sfp->cit = DialogToPointer (ifp->featcits);
294       sfp->dbxref = DialogToPointer (ifp->dbxrefs);
295       sfp->qual = DialogToPointer (ifp->gbquals);
296       CleanupEvidenceGBQuals (&(sfp->qual));
297       VisStringDialogToGbquals (sfp, ifp->experiment, "experiment");
298       InferenceDialogToGBQuals (ifp->inference, sfp, TRUE);
299       geneval = GetValue (ifp->gene);
300       sep = GetTopSeqEntryForEntityID (ifp->input_entityID);
301       StringCpy (title, "Feature");
302       if (sfp != NULL && sfp->data.value.ptrvalue != NULL) {
303         imp = (ImpFeatPtr) sfp->data.value.ptrvalue;
304         StringNCpy_0 (title, imp->key, sizeof (title));
305         if (StringHasNoText (title)) {
306           StringCpy (title, "Feature");
307         }
308       }
309       w = (WindoW) CreateImportForm (-50, -33, title, sfp, sep,
310                                      StdFeatFormActnProc);
311       newifp = (ImprtFormPtr) GetObjectExtra (w);
312       if (newifp != NULL) {
313         newifp->input_entityID = ifp->input_entityID;
314         newifp->input_itemID = ifp->input_itemID;
315         newifp->input_itemtype = ifp->input_itemtype;
316         newifp->this_itemtype = ifp->this_itemtype;
317         newifp->this_subtype = ifp->this_subtype;
318         if (sfp != NULL) {
319           omp = ObjMgrGet ();
320           if (omp != NULL) {
321             omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
322             if (omtp != NULL && omtp->subtypefunc != NULL) {
323               newifp->this_subtype = (*(omtp->subtypefunc)) (sfp);
324             }
325           }
326         }
327         SendMessageToForm (newifp->form, VIB_MSG_INIT);
328         SetValue (newifp->gene, geneval);
329         if (sfp != NULL) {
330           PointerToForm (newifp->form, (Pointer) sfp);
331         }
332       }
333       Remove (ifp->form);
334       Show (w);
335       Select (w);
336       helpfunc = (HelpMessageFunc) GetAppProperty ("HelpMessageProc");
337       if (helpfunc != NULL) {
338         helpfunc ("Features", title);
339       }
340     }
341     SeqFeatFree (sfp);
342     Update ();
343   }
344 }
345 
346 static DialoG CreateImportDialog (GrouP h, CharPtr title, ImprtFormPtr ifp,
347                                   Boolean allowPeptideFeats, SeqFeatPtr sfp, Boolean is_gap)
348 
349 {
350   EnumFieldAssocPtr  ap;
351   GrouP              f;
352   ImportPagePtr      ipp;
353   GrouP              m;
354   GrouP              p;
355   PrompT             ppt;
356   GrouP              s;
357   CharPtr            str;
358   Boolean            usePopup;
359   PrompT             x;
360 
361   p = HiddenGroup (h, 1, 0, NULL);
362   SetGroupSpacing (p, 10, 10);
363 
364   ipp = (ImportPagePtr) MemNew (sizeof (ImportPage));
365   if (ipp != NULL) {
366 
367     SetObjectExtra (p, ipp, CleanupImportPage);
368     ipp->dialog = (DialoG) p;
369     ipp->todialog = ImpFeatPtrToImportPage;
370     ipp->fromdialog = ImportPageToImpFeatPtr;
371     ipp->testdialog = NULL;
372 
373     if (title != NULL && title [0] != '\0') {
374       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
375     } else {
376       s = HiddenGroup (p, 0, -2, NULL);
377     }
378     m = HiddenGroup (s, -1, 0, NULL);
379     /*
380     SetGroupSpacing (m, 10, 10);
381     */
382 
383     ipp->ifp = ifp;
384     if (is_gap) {
385       ipp->alist = gap_featdef_alist ();
386     } else {
387       ipp->alist = import_featdef_alist (FALSE, allowPeptideFeats, FALSE);
388     }
389 
390     ppt = StaticPrompt (m, "Changing feature key will recreate the window.",
391                         0, 0, programFont, 'c');
392     f = HiddenGroup (m, -2, 0, NULL);
393 
394 #ifdef WIN_MOTIF
395     usePopup = FALSE;
396 #else
397     usePopup = TRUE;
398 #endif
399 
400     x = NULL;
401 #ifndef WIN_MOTIF
402     x = StaticPrompt (f, "Key", 0, 0, programFont, 'l');
403 #endif
404     if (usePopup) {
405       if (is_gap) {
406         ipp->key = (Handle) PopupList (f, TRUE, (PupActnProc) ChangeKey);
407       } else {
408         ipp->key = (Handle) PopupList (f, TRUE, (PupActnProc) ChangeKey);
409       }
410       SetObjectExtra (ipp->key, ifp, NULL);
411       InitEnumPopup ((PopuP) ipp->key, ipp->alist, NULL);
412       SetEnumPopup ((PopuP) ipp->key, ipp->alist, (UIEnum) 0);
413     } else {
414       ipp->key = (Handle) SingleList (f, 12, 3, (LstActnProc) ChangeKey);
415       SetObjectExtra (ipp->key, ifp, NULL);
416       for (ap = ipp->alist; ap->name != NULL; ap++) {
417         ListItem ((LisT) ipp->key, ap->name);
418       }
419       SetValue (ipp->key, 0);
420     }
421     if (Nlm_GetAppProperty ("SequinUseImpFeatLocField") != NULL) {
422       StaticPrompt (f, "Loc", 0, dialogTextHeight, programFont, 'l');
423       ipp->loc = DialogText (f, "", 15, NULL);
424     }
425     AlignObjects (ALIGN_VERTICAL, (HANDLE) ipp->key, (HANDLE) x, NULL);
426     for (ap = ipp->alist; ap->name != NULL; ap++) {
427       str = ap->name;
428       if (*str == '~') {
429         *str = '-';
430       }
431     }
432     AlignObjects (ALIGN_CENTER, (HANDLE) ppt, (HANDLE) f, NULL);
433   }
434 
435   return (DialoG) p;
436 }
437 
438 static void SetImportImportExportItems (ImprtFormPtr ifp)
439 
440 {
441   IteM  exportItm;
442   IteM  importItm;
443 
444   if (ifp != NULL) {
445     importItm = FindFormMenuItem ((BaseFormPtr) ifp, VIB_MSG_IMPORT);
446     exportItm = FindFormMenuItem ((BaseFormPtr) ifp, VIB_MSG_EXPORT);
447     switch (ifp->currentPage) {
448       case IMPORT_PAGE :
449         SafeSetTitle (importItm, "Import...");
450         SafeSetTitle (exportItm, "Export...");
451         SafeDisable (importItm);
452         SafeDisable (exportItm);
453         break;
454       case COMMON_PAGE :
455         SafeSetTitle (importItm, "Import...");
456         SafeSetTitle (exportItm, "Export...");
457         SafeDisable (importItm);
458         SafeDisable (exportItm);
459         break;
460       case LOCATION_PAGE :
461         SafeSetTitle (importItm, "Import SeqLoc...");
462         SafeSetTitle (exportItm, "Export SeqLoc...");
463         SafeEnable (importItm);
464         SafeEnable (exportItm);
465         break;
466       default :
467         break;
468     }
469   }
470 }
471 
472 static void ChangeImportPage (VoidPtr data, Int2 newval, Int2 oldval)
473 
474 {
475   ImprtFormPtr  ifp;
476 
477   ifp = (ImprtFormPtr) data;
478   if (ifp != NULL) {
479     ifp->currentPage = newval;
480     SafeHide (ifp->pages [oldval]);
481     SafeShow (ifp->pages [newval]);
482     switch (newval) {
483       case IMPORT_PAGE :
484         SendMessageToDialog (ifp->data, VIB_MSG_ENTER);
485         break;
486       case COMMON_PAGE :
487         break;
488       case LOCATION_PAGE :
489         SendMessageToDialog (ifp->location, VIB_MSG_ENTER);
490         break;
491       default :
492         break;
493     }
494     SetImportImportExportItems (ifp);
495     Update ();
496   }
497 }
498 
499 static Boolean ImportImportForm (ForM f, CharPtr filename)
500 
501 {
502   ImprtFormPtr  ifp;
503 
504   ifp = (ImprtFormPtr) GetObjectExtra (f);
505   if (ifp != NULL) {
506     switch (ifp->currentPage) {
507       case LOCATION_PAGE :
508         return ImportDialog (ifp->location, filename);
509       default :
510         break;
511     }
512   }
513   return FALSE;
514 }
515 
516 static Boolean ExportImportForm (ForM f, CharPtr filename)
517 
518 {
519   ImprtFormPtr  ifp;
520 
521   ifp = (ImprtFormPtr) GetObjectExtra (f);
522   if (ifp != NULL) {
523     switch (ifp->currentPage) {
524       case LOCATION_PAGE :
525         return ExportDialog (ifp->location, filename);
526       default :
527         break;
528     }
529   }
530   return FALSE;
531 }
532 
533 static CharPtr  importFormTabs [] = {
534   NULL, "Properties", "Location", NULL
535 };
536 
537 extern DialoG CreateQualsDialog (GrouP h, Uint2 rows, Int2 spacing,
538                                  Int2 width1, Int2 width2);
539 
540 static void ImportFormMessage (ForM f, Int2 mssg)
541 
542 {
543   ImprtFormPtr  ifp;
544 
545   ifp = (ImprtFormPtr) GetObjectExtra (f);
546   if (ifp != NULL) {
547     switch (mssg) {
548       case VIB_MSG_INIT :
549         StdInitFeatFormProc (f);
550         break;
551       case VIB_MSG_IMPORT :
552         ImportImportForm (f, NULL);
553         break;
554       case VIB_MSG_EXPORT :
555         ExportImportForm (f, NULL);
556         break;
557       case VIB_MSG_CLOSE :
558         Remove (f);
559         break;
560       case VIB_MSG_CUT :
561         StdCutTextProc (NULL);
562         break;
563       case VIB_MSG_COPY :
564         StdCopyTextProc (NULL);
565         break;
566       case VIB_MSG_PASTE :
567         StdPasteTextProc (NULL);
568         break;
569       case VIB_MSG_DELETE :
570         if (ifp->currentPage == LOCATION_PAGE) {
571           PointerToDialog (ifp->location, NULL);
572         } else {
573           StdDeleteTextProc (NULL);
574         }
575         break;
576       default :
577         if (ifp->appmessage != NULL) {
578           ifp->appmessage (f, mssg);
579         }
580         break;
581     }
582   }
583 }
584 
585 static void ImportFormActivate (WindoW w)
586 
587 {
588   ImprtFormPtr  ifp;
589 
590   ifp = (ImprtFormPtr) GetObjectExtra (w);
591   if (ifp != NULL) {
592     if (ifp->activate != NULL) {
593       ifp->activate (w);
594     }
595     SetImportImportExportItems (ifp);
596   }
597 }
598 
599 extern DialoG NewCreateImportFields (GrouP h, CharPtr name, SeqFeatPtr sfp, Boolean allowProductGBQual);
600 
601 extern ForM CreateImportForm (Int2 left, Int2 top, CharPtr title,
602                               SeqFeatPtr sfp, SeqEntryPtr sep,
603                               FormActnFunc actproc)
604 
605 {
606   Boolean            allowPeptideFeats;
607   Boolean            allowProductGBQual;
608   ButtoN             b;
609   GrouP              c;
610   GrouP              g;
611   GrouP              h;
612   Boolean            hasGeneControl;
613   ImprtFormPtr       ifp;
614   ImpFeatPtr         imp;
615   Boolean            is_gap = FALSE;
616   GrouP              s;
617   StdEditorProcsPtr  sepp;
618   WindoW             w;
619   GrouP              x;
620   GrouP              z;
621 
622   w = NULL;
623   ifp = (ImprtFormPtr) MemNew (sizeof (ImprtForm));
624   if (ifp != NULL) {
625     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
626     SetObjectExtra (w, ifp, StdFeatFormCleanupProc);
627     ifp->form = (ForM) w;
628     ifp->actproc = actproc;
629     ifp->toform = StdSeqFeatPtrToFeatFormProc;
630     ifp->fromform = NULL;
631     ifp->formmessage = ImportFormMessage;
632     ifp->testform = NULL;
633     ifp->importform = ImportImportForm;
634     ifp->exportform = ExportImportForm;
635 
636 #ifndef WIN_MAC
637     CreateStdEditorFormMenus (w);
638 #endif
639 
640     ifp->activate = NULL;
641     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
642     if (sepp != NULL) {
643       ifp->activate = sepp->activateForm;
644       ifp->appmessage = sepp->handleMessages;
645     }
646     SetActivate (w, ImportFormActivate);
647 
648     g = HiddenGroup (w, -1, 0, NULL);
649     SetGroupSpacing (g, 3, 10);
650 
651     if (sfp != NULL && sfp->data.choice == SEQFEAT_IMP) {
652       imp = (ImpFeatPtr) sfp->data.value.ptrvalue;
653       if (imp != NULL && StringICmp (imp->key, "gap") == 0) {
654         is_gap = TRUE;
655       }
656     }
657 
658     ifp->sep = sep;
659     importFormTabs [0] = NULL;
660     if (title == NULL || *title == '\0') {
661       title = "misc_feature";
662     }
663     importFormTabs [0] = title;
664     ifp->foldertabs = CreateFolderTabs (g, importFormTabs, IMPORT_PAGE,
665                                         0, 0, SYSTEM_FOLDER_TAB,
666                                         ChangeImportPage, (Pointer) ifp);
667     ifp->currentPage = IMPORT_PAGE;
668 
669     h = HiddenGroup (g, 0, 0, NULL);
670 
671     s = HiddenGroup (h, -1, 0, NULL);
672     SetGroupSpacing (s, 3, 10);
673     allowPeptideFeats = FALSE;
674     allowProductGBQual = FALSE;
675     if (StringICmp (title, "mat_peptide") == 0 ||
676         StringICmp (title, "sig_peptide") == 0 ||
677         StringICmp (title, "transit_peptide") == 0) {
678       allowPeptideFeats = TRUE;
679       allowProductGBQual = TRUE;
680     } else if (StringICmp (title, "misc_RNA") == 0 ||
681         StringICmp (title, "C_region") == 0 ||
682         StringICmp (title, "D_segment") == 0 ||
683         StringICmp (title, "exon") == 0 ||
684         StringICmp (title, "J_segment") == 0 ||
685         StringICmp (title, "misc_feature") == 0 ||
686         StringICmp (title, "N_region") == 0 ||
687         StringICmp (title, "S_region") == 0 ||
688         StringICmp (title, "V_region") == 0 ||
689         StringICmp (title, "V_segment") == 0 ||
690         StringICmp (title, "variation") == 0) {
691       allowProductGBQual = TRUE;
692     }
693     ifp->data = CreateImportDialog (s, NULL, ifp, allowPeptideFeats, sfp, is_gap);
694     x = HiddenGroup (s, -1, 0, NULL);
695     if (StringICmp (importFormTabs [0], "source") == 0) {
696       z = HiddenGroup (x, -4, 0, NULL);
697       SetGroupSpacing (z, -1, 0);
698       StaticPrompt (z, "Qualifier", 7 * stdCharWidth, 0, programFont, 'c');
699       StaticPrompt (z, "Value", 10 * stdCharWidth, 0, programFont, 'c');
700       ifp->gbquals = CreateQualsDialog (x, 5, -1, 7, 10);
701     } else {
702       ifp->gbquals = NewCreateImportFields (x, importFormTabs [0], sfp, allowProductGBQual);
703 /* old version: ifp->gbquals = CreateImportFields (x, importFormTabs [0], sfp, allowProductGBQual); */
704     }
705     AlignObjects (ALIGN_CENTER, (HANDLE) ifp->data, (HANDLE) x, NULL);
706     ifp->pages [IMPORT_PAGE] = s;
707     Hide (ifp->pages [IMPORT_PAGE]);
708     importFormTabs [0] = NULL;
709 
710     s = HiddenGroup (h, -1, 0, NULL);
711     hasGeneControl = TRUE;
712     if (StringICmp (title, "operon") == 0) {
713       hasGeneControl = FALSE;
714     }
715     CreateCommonFeatureGroup (s, (FeatureFormPtr) ifp, sfp, hasGeneControl, TRUE);
716     ifp->pages [COMMON_PAGE] = s;
717     Hide (ifp->pages [COMMON_PAGE]);
718 
719     s = HiddenGroup (h, -1, 0, NULL);
720     ifp->location = CreateIntervalEditorDialogEx (s, NULL, 4, 2, sep, TRUE, FALSE,
721                                                   TRUE, TRUE, FALSE,
722                                                   (FeatureFormPtr) ifp,
723                                                   StdFeatIntEdPartialCallback);
724     ifp->pages [LOCATION_PAGE] = s;
725     Hide (ifp->pages [LOCATION_PAGE]);
726 
727     AlignObjects (ALIGN_CENTER, (HANDLE) ifp->pages [IMPORT_PAGE],
728                   (HANDLE) ifp->pages [COMMON_PAGE], (HANDLE) ifp->pages [LOCATION_PAGE],
729                   NULL);
730     AlignObjects (ALIGN_CENTER, (HANDLE) ifp->foldertabs, (HANDLE) h, NULL);
731 
732     c = HiddenGroup (w, 2, 0, NULL);
733     b = PushButton (c, "Accept", StdFeatFormAcceptButtonProc);
734     SetObjectExtra (b, ifp, NULL);
735     PushButton (c, "Cancel", StdCancelButtonProc);
736     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
737     RealizeWindow (w);
738 
739     SendMessageToDialog (ifp->data, VIB_MSG_INIT);
740     SendMessageToDialog (ifp->location, VIB_MSG_INIT);
741     Show (ifp->pages [ifp->currentPage]);
742     SendMessageToDialog (ifp->data, VIB_MSG_ENTER);
743     Update ();
744   }
745   return (ForM) w;
746 }
747 
748 extern Int2 LIBCALLBACK ImportGenFunc (Pointer data)
749 
750 {
751   EnumFieldAssocPtr  ap;
752   FeatDefPtr         curr;
753   HelpMessageFunc    helpfunc;
754   Int2               i;
755   ImprtFormPtr       ifp;
756   ImpFeatPtr         imp;
757   ImportPagePtr      ipp;
758   Uint1              key;
759   CharPtr            label = NULL;
760   ObjMgrPtr          omp;
761   OMProcControlPtr   ompcp;
762   ObjMgrTypePtr      omtp;
763   OMUserDataPtr      omudp;
764   ObjMgrProcPtr      proc;
765   SeqEntryPtr        sep;
766   SeqFeatPtr         sfp;
767   Uint2              subtype;
768   Char               title [64];
769   WindoW             w;
770 
771   ompcp = (OMProcControlPtr) data;
772   sfp = NULL;
773   sep = NULL;
774   imp = NULL;
775   subtype = FEATDEF_IMP;
776   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
777   proc = ompcp->proc;
778   switch (ompcp->input_itemtype) {
779     case OBJ_SEQFEAT :
780       sfp = (SeqFeatPtr) ompcp->input_data;
781       if (sfp != NULL && sfp->data.choice != SEQFEAT_IMP) {
782         return OM_MSG_RET_ERROR;
783       }
784       break;
785     case OBJ_BIOSEQ :
786       break;
787     case OBJ_BIOSEQSET :
788       break;
789     case 0 :
790       break;
791     default :
792       return OM_MSG_RET_ERROR;
793   }
794   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
795                                 ompcp->input_itemtype, ompcp->proc->procid);
796   if (omudp != NULL) {
797     ifp = (ImprtFormPtr) omudp->userdata.ptrvalue;
798     if (ifp != NULL) {
799       Select (ifp->form);
800     }
801     return OM_MSG_RET_DONE;
802   }
803   sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
804   StringCpy (title, "Feature");
805   if (sfp != NULL && sfp->data.value.ptrvalue != NULL) {
806     imp = (ImpFeatPtr) sfp->data.value.ptrvalue;
807     StringNCpy_0 (title, imp->key, sizeof (title));
808     if (StringHasNoText (title)) {
809       StringCpy (title, "Feature");
810     }
811   } else if (proc->subinputtype > 0) {
812     subtype = proc->subinputtype;
813     curr = FeatDefFindNext (NULL, &key, &label, FEATDEF_ANY, TRUE);
814     while (curr != NULL) {
815       if (key != FEATDEF_BAD && curr->seqfeat_key == SEQFEAT_IMP) {
816         if (subtype == curr->featdef_key) {
817           StringNCpy_0 (title, curr->typelabel, sizeof (title));
818           break;
819         }
820       }
821       curr = FeatDefFindNext (curr, &key, &label, FEATDEF_ANY, TRUE);
822     }
823   }
824   w = (WindoW) CreateImportForm (-50, -33, title, sfp, sep,
825                                  StdFeatFormActnProc);
826   ifp = (ImprtFormPtr) GetObjectExtra (w);
827   if (ifp != NULL) {
828     ifp->input_entityID = ompcp->input_entityID;
829     ifp->input_itemID = ompcp->input_itemID;
830     ifp->input_itemtype = ompcp->input_itemtype;
831     ifp->this_itemtype = OBJ_SEQFEAT;
832     ifp->this_subtype = subtype;
833     ifp->procid = ompcp->proc->procid;
834     ifp->proctype = ompcp->proc->proctype;
835     ifp->userkey = OMGetNextUserKey ();
836     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
837                                    OMPROC_EDIT, ifp->userkey);
838     if (omudp != NULL) {
839       omudp->userdata.ptrvalue = (Pointer) ifp;
840       omudp->messagefunc = StdVibrantEditorMsgFunc;
841     }
842     if (sfp != NULL) {
843       omp = ObjMgrGet ();
844       if (omp != NULL) {
845         omtp = ObjMgrTypeFind (omp, OBJ_SEQFEAT, NULL, NULL);
846         if (omtp != NULL && omtp->subtypefunc != NULL) {
847           ifp->this_subtype = (*(omtp->subtypefunc)) (sfp);
848         }
849       }
850     }
851     SendMessageToForm (ifp->form, VIB_MSG_INIT);
852     if (sfp != NULL) {
853       PointerToForm (ifp->form, (Pointer) sfp);
854       SetClosestParentIfDuplicating ((BaseFormPtr) ifp);
855     } else {
856       ipp = (ImportPagePtr) GetObjectExtra (ifp->data);
857       if (ipp != NULL) {
858         for (i = 1, ap = ipp->alist; ap->name != NULL; i++, ap++) {
859           if (StringCmp (ap->name, title) == 0) {
860             SetValue (ipp->key, i);
861             SetTitle (ipp->loc, "");
862             break;
863           }
864         }
865       }
866       SetNewFeatureDefaultInterval ((FeatureFormPtr) ifp);
867     }
868   }
869   Show (w);
870   Select (w);
871   helpfunc = (HelpMessageFunc) GetAppProperty ("HelpMessageProc");
872   if (helpfunc != NULL) {
873     helpfunc ("Features", title);
874   }
875   return OM_MSG_RET_DONE;
876 }
877 
878 
879 typedef struct enumpage {
880   DIALOG_MESSAGE_BLOCK
881   PopuP              key;
882   EnumFieldAssocPtr  alist;
883 } EnumPage, PNTR EnumPagePtr;
884 
885 typedef struct enumform {
886   FEATURE_FORM_BLOCK
887   SeqEntryPtr   sep;
888   GrouP         pages [NUM_PAGES];
889   DialoG        foldertabs;
890   Int2          currentPage;
891 } EnumForm, PNTR EnumFormPtr;
892 
893 extern EnumFieldAssoc  enum_bond_alist [];
894 ENUM_ALIST(enum_bond_alist)
895   {"Disulfide",              1},
896   {"Thioester",              2},
897   {"Crosslink",              3},
898   {"Thioether",              4},
899   {"Other",                255},
900 END_ENUM_ALIST
901 
902 extern EnumFieldAssoc  enum_site_alist [];
903 ENUM_ALIST(enum_site_alist)
904   {"Active",                       1},
905   {"Binding",                      2},
906   {"Cleavage",                     3},
907   {"Inhibit",                      4},
908   {"Modified",                     5},
909   {"Glycosylation",                6},
910   {"Myristoylation",               7},
911   {"Mutagenized",                  8},
912   {"Metal-binding",                9},
913   {"Phosphorylation",             10},
914   {"Acetylation",                 11},
915   {"Amidation",                   12},
916   {"Methylation",                 13},
917   {"Hydroxylation",               14},
918   {"Sulfatation",                 15},
919   {"Oxidative-deamination",       16},
920   {"Pyrrolidone-carboxylic-acid", 17},
921   {"Gamma-carboxyglutamic-acid",  18},
922   {"Blocked",                     19},
923   {"Lipid-binding",               20},
924   {"np-binding",                  21},
925   {"DNA-binding",                 22},
926   {"Signal-peptide",              23},
927   {"Transit-peptide",             24},
928   {"Transmembrane-region",        25},
929   {"Nitrosylation",               26},
930   {"Other",                      255},
931 END_ENUM_ALIST
932 
933 static ENUM_ALIST(enum_psec_alist)
934   {"Helix",                  1},
935   {"Sheet",                  2},
936   {"Turn",                   3},
937  END_ENUM_ALIST
938 
939 static void EnumFeatPtrToEnumPage (DialoG d, Pointer data)
940 
941 {
942   EnumPagePtr  epp;
943   Int4Ptr      intptr;
944   Int4         val;
945 
946   epp = (EnumPagePtr) GetObjectExtra (d);
947   intptr = (Int4Ptr) data;
948   if (epp != NULL) {
949     val = *intptr;
950     SetEnumPopup (epp->key, epp->alist, (UIEnum) val);
951   }
952 }
953 
954 static Pointer EnumPageToEnumFeatPtr (DialoG d)
955 
956 {
957   EnumPagePtr  epp;
958   Int4Ptr      intptr;
959   UIEnum       val;
960 
961   intptr = NULL;
962   epp = (EnumPagePtr) GetObjectExtra (d);
963   if (epp != NULL) {
964     if (GetEnumPopup (epp->key, epp->alist, &val)) {
965       epp->intvalue = (Int4) val;
966       intptr = (&epp->intvalue);
967     }
968   }
969   return (Pointer) intptr;
970 }
971 
972 static DialoG CreateEnumDialog (GrouP h, CharPtr title, Uint2 subtype)
973 
974 {
975   EnumPagePtr  epp;
976   GrouP        f;
977   GrouP        m;
978   GrouP        p;
979   GrouP        s;
980 
981   p = HiddenGroup (h, 1, 0, NULL);
982   SetGroupSpacing (p, 10, 10);
983 
984   epp = (EnumPagePtr) MemNew (sizeof (EnumPage));
985   if (epp != NULL) {
986 
987     SetObjectExtra (p, epp, StdCleanupExtraProc);
988     epp->dialog = (DialoG) p;
989     epp->todialog = EnumFeatPtrToEnumPage;
990     epp->fromdialog = EnumPageToEnumFeatPtr;
991     epp->testdialog = NULL;
992 
993     if (title != NULL && title [0] != '\0') {
994       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
995     } else {
996       s = HiddenGroup (p, 0, -2, NULL);
997     }
998     m = HiddenGroup (s, -1, 0, NULL);
999     /*
1000     SetGroupSpacing (m, 10, 10);
1001     */
1002 
1003     switch (subtype) {
1004       case FEATDEF_BOND :
1005         epp->alist = enum_bond_alist;
1006         break;
1007       case FEATDEF_SITE :
1008         epp->alist = enum_site_alist;
1009         break;
1010       case FEATDEF_PSEC_STR :
1011         epp->alist = enum_psec_alist;
1012         break;
1013       default :
1014         Message (MSG_FATAL, "Unknown enumerated feature type");
1015         return NULL;
1016     }
1017 
1018     f = HiddenGroup (m, -2, 0, NULL);
1019     StaticPrompt (f, "Type", 0, popupMenuHeight, programFont, 'l');
1020     epp->key = PopupList (f, TRUE, NULL);
1021     SetObjectExtra (epp->key, epp, NULL);
1022     InitEnumPopup (epp->key, epp->alist, NULL);
1023     /*
1024     SetEnumPopup (epp->key, epp->alist, (UIEnum) 0);
1025     */
1026   }
1027 
1028   return (DialoG) p;
1029 }
1030 
1031 static void SetEnumImportExportItems (EnumFormPtr efp)
1032 
1033 {
1034   IteM  exportItm;
1035   IteM  importItm;
1036 
1037   if (efp != NULL) {
1038     importItm = FindFormMenuItem ((BaseFormPtr) efp, VIB_MSG_IMPORT);
1039     exportItm = FindFormMenuItem ((BaseFormPtr) efp, VIB_MSG_EXPORT);
1040     switch (efp->currentPage) {
1041       case ENUM_PAGE :
1042         SafeSetTitle (importItm, "Import...");
1043         SafeSetTitle (exportItm, "Export...");
1044         SafeDisable (importItm);
1045         SafeDisable (exportItm);
1046         break;
1047       case COMMON_PAGE :
1048         SafeSetTitle (importItm, "Import...");
1049         SafeSetTitle (exportItm, "Export...");
1050         SafeDisable (importItm);
1051         SafeDisable (exportItm);
1052         break;
1053       case LOCATION_PAGE :
1054         SafeSetTitle (importItm, "Import SeqLoc...");
1055         SafeSetTitle (exportItm, "Export SeqLoc...");
1056         SafeEnable (importItm);
1057         SafeEnable (exportItm);
1058         break;
1059       default :
1060         break;
1061     }
1062   }
1063 }
1064 
1065 static void ChangeEnumPage (VoidPtr data, Int2 newval, Int2 oldval)
1066 
1067 {
1068   EnumFormPtr  efp;
1069 
1070   efp = (EnumFormPtr) data;
1071   if (efp != NULL) {
1072     efp->currentPage = newval;
1073     SafeHide (efp->pages [oldval]);
1074     SafeShow (efp->pages [newval]);
1075     switch (newval) {
1076       case ENUM_PAGE :
1077         SendMessageToDialog (efp->data, VIB_MSG_ENTER);
1078         break;
1079       case COMMON_PAGE :
1080         break;
1081       case LOCATION_PAGE :
1082         SendMessageToDialog (efp->location, VIB_MSG_ENTER);
1083         break;
1084       default :
1085         break;
1086     }
1087     SetEnumImportExportItems (efp);
1088     Update ();
1089   }
1090 }
1091 
1092 static Boolean ImportEnumForm (ForM f, CharPtr filename)
1093 
1094 {
1095   EnumFormPtr  efp;
1096 
1097   efp = (EnumFormPtr) GetObjectExtra (f);
1098   if (efp != NULL) {
1099     switch (efp->currentPage) {
1100       case LOCATION_PAGE :
1101         return ImportDialog (efp->location, filename);
1102       default :
1103         break;
1104     }
1105   }
1106   return FALSE;
1107 }
1108 
1109 static Boolean ExportEnumForm (ForM f, CharPtr filename)
1110 
1111 {
1112   EnumFormPtr  efp;
1113 
1114   efp = (EnumFormPtr) GetObjectExtra (f);
1115   if (efp != NULL) {
1116     switch (efp->currentPage) {
1117       case LOCATION_PAGE :
1118         return ExportDialog (efp->location, filename);
1119       default :
1120         break;
1121     }
1122   }
1123   return FALSE;
1124 }
1125 
1126 static CharPtr  enumFormTabs [] = {
1127   NULL, "Properties", "Location", NULL
1128 };
1129 
1130 static void EnumFormMessage (ForM f, Int2 mssg)
1131 
1132 {
1133   EnumFormPtr  efp;
1134 
1135   efp = (EnumFormPtr) GetObjectExtra (f);
1136   if (efp != NULL) {
1137     switch (mssg) {
1138       case VIB_MSG_INIT :
1139         StdInitFeatFormProc (f);
1140         break;
1141       case VIB_MSG_IMPORT :
1142         ImportEnumForm (f, NULL);
1143         break;
1144       case VIB_MSG_EXPORT :
1145         ExportEnumForm (f, NULL);
1146         break;
1147       case VIB_MSG_CLOSE :
1148         Remove (f);
1149         break;
1150       case VIB_MSG_CUT :
1151         StdCutTextProc (NULL);
1152         break;
1153       case VIB_MSG_COPY :
1154         StdCopyTextProc (NULL);
1155         break;
1156       case VIB_MSG_PASTE :
1157         StdPasteTextProc (NULL);
1158         break;
1159       case VIB_MSG_DELETE :
1160         if (efp->currentPage == LOCATION_PAGE) {
1161           PointerToDialog (efp->location, NULL);
1162         } else {
1163           StdDeleteTextProc (NULL);
1164         }
1165         break;
1166       default :
1167         if (efp->appmessage != NULL) {
1168           efp->appmessage (f, mssg);
1169         }
1170         break;
1171     }
1172   }
1173 }
1174 
1175 static void EnumFormActivate (WindoW w)
1176 
1177 {
1178   EnumFormPtr  efp;
1179 
1180   efp = (EnumFormPtr) GetObjectExtra (w);
1181   if (efp != NULL) {
1182     if (efp->activate != NULL) {
1183       efp->activate (w);
1184     }
1185     SetEnumImportExportItems (efp);
1186   }
1187 }
1188 
1189 extern DialoG CreateBondEditorDialog (GrouP h, CharPtr title, SeqEntryPtr sep);
1190 
1191 extern ForM CreateEnumForm (Int2 left, Int2 top, CharPtr title,
1192                             SeqFeatPtr sfp, SeqEntryPtr sep,
1193                             Uint2 subtype, FormActnFunc actproc)
1194 
1195 {
1196   ButtoN             b;
1197   GrouP              c;
1198   EnumFormPtr        efp;
1199   GrouP              g;
1200   GrouP              h;
1201   GrouP              s;
1202   StdEditorProcsPtr  sepp;
1203   WindoW             w;
1204 
1205   w = NULL;
1206   efp = (EnumFormPtr) MemNew (sizeof (EnumForm));
1207   if (efp != NULL) {
1208     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
1209     SetObjectExtra (w, efp, StdFeatFormCleanupProc);
1210     efp->form = (ForM) w;
1211     efp->actproc = actproc;
1212     efp->toform = StdSeqFeatPtrToFeatFormProc;
1213     efp->fromform = NULL;
1214     efp->formmessage = EnumFormMessage;
1215     efp->testform = NULL;
1216     efp->importform = ImportEnumForm;
1217     efp->exportform = ExportEnumForm;
1218 
1219 #ifndef WIN_MAC
1220     CreateStdEditorFormMenus (w);
1221 #endif
1222 
1223     efp->activate = NULL;
1224     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1225     if (sepp != NULL) {
1226       efp->activate = sepp->activateForm;
1227       efp->appmessage = sepp->handleMessages;
1228     }
1229     SetActivate (w, EnumFormActivate);
1230 
1231     g = HiddenGroup (w, -1, 0, NULL);
1232     SetGroupSpacing (g, 3, 10);
1233 
1234     efp->sep = sep;
1235     enumFormTabs [0] = NULL;
1236     if (title != NULL && *title != '\0') {
1237       enumFormTabs [0] = title;
1238     } else if (subtype == FEATDEF_BOND) {
1239       enumFormTabs [0] = "Bond";
1240     } else if (subtype == FEATDEF_SITE) {
1241       enumFormTabs [0] = "Site";
1242     } else if (subtype == FEATDEF_PSEC_STR) {
1243       enumFormTabs [0] = "Secondary Structure";
1244     }
1245     efp->foldertabs = CreateFolderTabs (g, enumFormTabs, ENUM_PAGE,
1246                                         0, 0, SYSTEM_FOLDER_TAB,
1247                                         ChangeEnumPage, (Pointer) efp);
1248     efp->currentPage = ENUM_PAGE;
1249 
1250     h = HiddenGroup (g, 0, 0, NULL);
1251 
1252     s = HiddenGroup (h, -1, 0, NULL);
1253     SetGroupSpacing (s, 3, 10);
1254     efp->data = CreateEnumDialog (s, NULL, subtype);
1255     efp->pages [ENUM_PAGE] = s;
1256     Hide (efp->pages [ENUM_PAGE]);
1257     enumFormTabs [0] = NULL;
1258 
1259     s = HiddenGroup (h, -1, 0, NULL);
1260     CreateCommonFeatureGroup (s, (FeatureFormPtr) efp, sfp, TRUE, TRUE);
1261     efp->pages [COMMON_PAGE] = s;
1262     Hide (efp->pages [COMMON_PAGE]);
1263 
1264     s = HiddenGroup (h, -1, 0, NULL);
1265     if (subtype == FEATDEF_BOND) {
1266       efp->location = CreateBondEditorDialog (s, NULL, sep);
1267     } else {
1268       efp->location = CreateIntervalEditorDialogEx (s, NULL, 4, 2, sep, TRUE, TRUE,
1269                                                     TRUE, TRUE, FALSE,
1270                                                     (FeatureFormPtr) efp,
1271                                                     StdFeatIntEdPartialCallback);
1272     }
1273     efp->pages [LOCATION_PAGE] = s;
1274     Hide (efp->pages [LOCATION_PAGE]);
1275 
1276     AlignObjects (ALIGN_CENTER, (HANDLE) efp->pages [ENUM_PAGE],
1277                   (HANDLE) efp->pages [COMMON_PAGE], (HANDLE) efp->pages [LOCATION_PAGE],
1278                   NULL);
1279     AlignObjects (ALIGN_CENTER, (HANDLE) efp->foldertabs, (HANDLE) h, NULL);
1280 
1281     c = HiddenGroup (w, 2, 0, NULL);
1282     b = PushButton (c, "Accept", StdFeatFormAcceptButtonProc);
1283     SetObjectExtra (b, efp, NULL);
1284     PushButton (c, "Cancel", StdCancelButtonProc);
1285     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
1286     RealizeWindow (w);
1287 
1288     SendMessageToDialog (efp->data, VIB_MSG_INIT);
1289     SendMessageToDialog (efp->location, VIB_MSG_INIT);
1290     Show (efp->pages [efp->currentPage]);
1291     SendMessageToDialog (efp->data, VIB_MSG_ENTER);
1292     Update ();
1293   }
1294   return (ForM) w;
1295 }
1296 
1297 extern Int2 LIBCALLBACK EnumGenFunc (Pointer data)
1298 
1299 {
1300   EnumFormPtr       efp;
1301   HelpMessageFunc   helpfunc;
1302   OMProcControlPtr  ompcp;
1303   OMUserDataPtr     omudp;
1304   ObjMgrProcPtr     proc;
1305   SeqEntryPtr       sep;
1306   SeqFeatPtr        sfp;
1307   Uint2             subtype;
1308   WindoW            w;
1309 
1310   ompcp = (OMProcControlPtr) data;
1311   w = NULL;
1312   sfp = NULL;
1313   sep = NULL;
1314   subtype = 0;
1315   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1316   proc = ompcp->proc;
1317   switch (ompcp->input_itemtype)
1318   {
1319     case OBJ_SEQFEAT :
1320       sfp = (SeqFeatPtr) ompcp->input_data;
1321       if (sfp != NULL &&
1322          (sfp->data.choice != SEQFEAT_BOND &&
1323           sfp->data.choice != SEQFEAT_SITE &&
1324           sfp->data.choice != SEQFEAT_PSEC_STR)) {
1325         return OM_MSG_RET_ERROR;
1326       }
1327       if (sfp->data.choice == SEQFEAT_BOND) {
1328         subtype = FEATDEF_BOND;
1329       } else if (sfp->data.choice == SEQFEAT_SITE) {
1330         subtype = FEATDEF_SITE;
1331       } else if (sfp->data.choice == SEQFEAT_PSEC_STR) {
1332         subtype = FEATDEF_PSEC_STR;
1333       } else {
1334         return OM_MSG_RET_ERROR;
1335       }
1336       break;
1337     case OBJ_BIOSEQ :
1338       break;
1339     case OBJ_BIOSEQSET :
1340       break;
1341     case 0 :
1342       break;
1343     default :
1344       return OM_MSG_RET_ERROR;
1345   }
1346   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
1347                                 ompcp->input_itemtype, ompcp->proc->procid);
1348   if (omudp != NULL) {
1349     efp = (EnumFormPtr) omudp->userdata.ptrvalue;
1350     if (efp != NULL) {
1351       Select (efp->form);
1352     }
1353     return OM_MSG_RET_DONE;
1354   }
1355   sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1356   if (sfp == NULL) {
1357     subtype = proc->subinputtype;
1358   }
1359   if (subtype == FEATDEF_BOND) {
1360     w = (WindoW) CreateEnumForm (-50, -33, "Bond",
1361                                  sfp, sep, subtype,
1362                                  StdFeatFormActnProc);
1363   } else if (subtype == FEATDEF_SITE) {
1364     w = (WindoW) CreateEnumForm (-50, -33, "Site",
1365                                  sfp, sep, subtype,
1366                                  StdFeatFormActnProc);
1367   } else if (subtype == FEATDEF_PSEC_STR) {
1368     w = (WindoW) CreateEnumForm (-50, -33, "Secondary Structure",
1369                                  sfp, sep, subtype,
1370                                  StdFeatFormActnProc);
1371   } else {
1372     return OM_MSG_RET_ERROR;
1373   }
1374   efp = (EnumFormPtr) GetObjectExtra (w);
1375   if (efp != NULL) {
1376     efp->input_entityID = ompcp->input_entityID;
1377     efp->input_itemID = ompcp->input_itemID;
1378     efp->input_itemtype = ompcp->input_itemtype;
1379     efp->this_itemtype = OBJ_SEQFEAT;
1380     efp->this_subtype = subtype;
1381     efp->procid = ompcp->proc->procid;
1382     efp->proctype = ompcp->proc->proctype;
1383     efp->userkey = OMGetNextUserKey ();
1384     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
1385                                    OMPROC_EDIT, efp->userkey);
1386     if (omudp != NULL) {
1387       omudp->userdata.ptrvalue = (Pointer) efp;
1388       omudp->messagefunc = StdVibrantEditorMsgFunc;
1389     }
1390 
1391     SendMessageToForm (efp->form, VIB_MSG_INIT);
1392     if (sfp != NULL) {
1393       PointerToForm (efp->form, (Pointer) sfp);
1394       SetClosestParentIfDuplicating ((BaseFormPtr) efp);
1395     } else {
1396       SetNewFeatureDefaultInterval ((FeatureFormPtr) efp);
1397     }
1398   }
1399   Show (w);
1400   Select (w);
1401   helpfunc = (HelpMessageFunc) GetAppProperty ("HelpMessageProc");
1402   if (helpfunc != NULL) {
1403     if (subtype == FEATDEF_BOND) {
1404       helpfunc ("Features", "Bond");
1405     } else if (subtype == FEATDEF_SITE) {
1406       helpfunc ("Features", "Site");
1407     } else if (subtype == FEATDEF_PSEC_STR) {
1408       helpfunc ("Features", "Secondary Structure");
1409     }
1410   }
1411   return OM_MSG_RET_DONE;
1412 }
1413 
1414 
1415 typedef struct regionform {
1416   FEATURE_FORM_BLOCK
1417   SeqEntryPtr   sep;
1418   GrouP         pages [NUM_PAGES];
1419   DialoG        foldertabs;
1420   Int2          currentPage;
1421 } RegionForm, PNTR RegionFormPtr;
1422 
1423 typedef struct regionpage {
1424   DIALOG_MESSAGE_BLOCK
1425   TexT           region;
1426   ButtoN         convertToMiscFeat;
1427   RegionFormPtr  rfp;
1428 } RegionPage, PNTR RegionPagePtr;
1429 
1430 static void CharPtrToRegionPage (DialoG d, Pointer data)
1431 
1432 {
1433   RegionFormPtr  rfp;
1434   RegionPagePtr  rpp;
1435   CharPtr        str;
1436 
1437   rpp = (RegionPagePtr) GetObjectExtra (d);
1438   str = (CharPtr) data;
1439   if (rpp != NULL) {
1440     rfp = rpp->rfp;
1441     if (rfp->this_subtype == FEATDEF_COMMENT) return;
1442     if (rfp->this_subtype == FEATDEF_misc_feature) return;
1443     if (str != NULL) {
1444       SafeSetTitle (rpp->region, str);
1445     } else {
1446       SafeSetTitle (rpp->region, "");
1447     }
1448   }
1449 }
1450 
1451 static Pointer RegionPageToCharPtr (DialoG d)
1452 
1453 {
1454   ImpFeatPtr     ifp;
1455   RegionFormPtr  rfp;
1456   RegionPagePtr  rpp;
1457   CharPtr        str;
1458 
1459   str = NULL;
1460   rpp = (RegionPagePtr) GetObjectExtra (d);
1461   if (rpp != NULL) {
1462     rfp = rpp->rfp;
1463     if (rfp->this_subtype == FEATDEF_misc_feature) {
1464       if (GetStatus (rpp->convertToMiscFeat)) {
1465         ifp = ImpFeatNew ();
1466         if (ifp != NULL) {
1467           ifp->key = StringSave ("misc_feature");
1468         }
1469         return (Pointer) ifp;
1470       } else {
1471         return NULL;
1472       }
1473     }
1474     if (rfp->this_subtype == FEATDEF_COMMENT) return NULL;
1475     str = SaveStringFromText (rpp->region);
1476     if (str == NULL) {
1477       str = StringSave ("");
1478     }
1479   }
1480   return (Pointer) str;
1481 }
1482 
1483 static DialoG CreateRegionDialog (GrouP h, CharPtr title, CharPtr str,
1484                                   Uint2 subtype, RegionFormPtr rfp)
1485 
1486 {
1487   GrouP          m;
1488   GrouP          p;
1489   RegionPagePtr  rpp;
1490   GrouP          s;
1491 
1492   p = HiddenGroup (h, 1, 0, NULL);
1493   SetGroupSpacing (p, 10, 10);
1494 
1495   rpp = (RegionPagePtr) MemNew (sizeof (RegionPage));
1496   if (rpp != NULL) {
1497 
1498     SetObjectExtra (p, rpp, StdCleanupExtraProc);
1499     rpp->dialog = (DialoG) p;
1500     rpp->todialog = CharPtrToRegionPage;
1501     rpp->fromdialog = RegionPageToCharPtr;
1502     rpp->testdialog = NULL;
1503 
1504     rpp->rfp = rfp;
1505 
1506     if (title != NULL && title [0] != '\0') {
1507       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
1508     } else {
1509       s = HiddenGroup (p, 0, -2, NULL);
1510     }
1511     m = HiddenGroup (s, 2, 0, NULL);
1512 
1513     if (subtype == FEATDEF_REGION) {
1514       StaticPrompt (m, "Name", 0, dialogTextHeight, programFont, 'c');
1515       rpp->region = DialogText (m, "", 20, NULL);
1516     } else if (subtype == FEATDEF_COMMENT) {
1517       StaticPrompt (m, "Enter comment in Properties page", 0, 0, programFont, 'c');
1518     }
1519     if (GetAppProperty ("InternalNcbiSequin") != NULL) {
1520       rpp->convertToMiscFeat = CheckBox (p, "Convert to misc_feat", NULL);
1521       AlignObjects (ALIGN_CENTER, (HANDLE) s, (HANDLE) rpp->convertToMiscFeat, NULL);
1522     }
1523   }
1524 
1525   return (DialoG) p;
1526 }
1527 
1528 static void SetRegionImportExportItems (RegionFormPtr rfp)
1529 
1530 {
1531   IteM  exportItm;
1532   IteM  importItm;
1533 
1534   if (rfp != NULL) {
1535     importItm = FindFormMenuItem ((BaseFormPtr) rfp, VIB_MSG_IMPORT);
1536     exportItm = FindFormMenuItem ((BaseFormPtr) rfp, VIB_MSG_EXPORT);
1537     switch (rfp->currentPage) {
1538       case REGION_PAGE :
1539         SafeSetTitle (importItm, "Import...");
1540         SafeSetTitle (exportItm, "Export...");
1541         SafeDisable (importItm);
1542         SafeDisable (exportItm);
1543         break;
1544       case COMMON_PAGE :
1545         SafeSetTitle (importItm, "Import...");
1546         SafeSetTitle (exportItm, "Export...");
1547         SafeDisable (importItm);
1548         SafeDisable (exportItm);
1549         break;
1550       case LOCATION_PAGE :
1551         SafeSetTitle (importItm, "Import SeqLoc...");
1552         SafeSetTitle (exportItm, "Export SeqLoc...");
1553         SafeEnable (importItm);
1554         SafeEnable (exportItm);
1555         break;
1556       default :
1557         break;
1558     }
1559   }
1560 }
1561 
1562 static void ChangeRegionPage (VoidPtr data, Int2 newval, Int2 oldval)
1563 
1564 {
1565   RegionFormPtr  rfp;
1566 
1567   rfp = (RegionFormPtr) data;
1568   if (rfp != NULL) {
1569     rfp->currentPage = newval;
1570     SafeHide (rfp->pages [oldval]);
1571     SafeShow (rfp->pages [newval]);
1572     switch (newval) {
1573       case REGION_PAGE :
1574         break;
1575       case COMMON_PAGE :
1576         break;
1577       case LOCATION_PAGE :
1578         SendMessageToDialog (rfp->location, VIB_MSG_ENTER);
1579         break;
1580       default :
1581         break;
1582     }
1583     SetRegionImportExportItems (rfp);
1584     Update ();
1585   }
1586 }
1587 
1588 static Boolean ImportRegionForm (ForM f, CharPtr filename)
1589 
1590 {
1591   RegionFormPtr  rfp;
1592 
1593   rfp = (RegionFormPtr) GetObjectExtra (f);
1594   if (rfp != NULL) {
1595     switch (rfp->currentPage) {
1596       case LOCATION_PAGE :
1597         return ImportDialog (rfp->location, filename);
1598       default :
1599         break;
1600     }
1601   }
1602   return FALSE;
1603 }
1604 
1605 static Boolean ExportRegionForm (ForM f, CharPtr filename)
1606 
1607 {
1608   RegionFormPtr  rfp;
1609 
1610   rfp = (RegionFormPtr) GetObjectExtra (f);
1611   if (rfp != NULL) {
1612     switch (rfp->currentPage) {
1613       case LOCATION_PAGE :
1614         return ExportDialog (rfp->location, filename);
1615       default :
1616         break;
1617     }
1618   }
1619   return FALSE;
1620 }
1621 
1622 static CharPtr  regionFormTabs [] = {
1623   "Region", "Properties", "Location", NULL
1624 };
1625 
1626 static CharPtr  commentFormTabs [] = {
1627   "Comment", "Properties", "Location", NULL
1628 };
1629 
1630 static void RegionFormMessage (ForM f, Int2 mssg)
1631 
1632 {
1633   RegionFormPtr  rfp;
1634 
1635   rfp = (RegionFormPtr) GetObjectExtra (f);
1636   if (rfp != NULL) {
1637     switch (mssg) {
1638       case VIB_MSG_INIT :
1639         StdInitFeatFormProc (f);
1640         break;
1641       case VIB_MSG_IMPORT :
1642         ImportRegionForm (f, NULL);
1643         break;
1644       case VIB_MSG_EXPORT :
1645         ExportRegionForm (f, NULL);
1646         break;
1647       case VIB_MSG_CLOSE :
1648         Remove (f);
1649         break;
1650       case VIB_MSG_CUT :
1651         StdCutTextProc (NULL);
1652         break;
1653       case VIB_MSG_COPY :
1654         StdCopyTextProc (NULL);
1655         break;
1656       case VIB_MSG_PASTE :
1657         StdPasteTextProc (NULL);
1658         break;
1659       case VIB_MSG_DELETE :
1660         if (rfp->currentPage == LOCATION_PAGE) {
1661           PointerToDialog (rfp->location, NULL);
1662         } else {
1663           StdDeleteTextProc (NULL);
1664         }
1665         break;
1666       default :
1667         if (rfp->appmessage != NULL) {
1668           rfp->appmessage (f, mssg);
1669         }
1670         break;
1671     }
1672   }
1673 }
1674 
1675 static void RegionFormActivate (WindoW w)
1676 
1677 {
1678   RegionFormPtr  rfp;
1679 
1680   rfp = (RegionFormPtr) GetObjectExtra (w);
1681   if (rfp != NULL) {
1682     if (rfp->activate != NULL) {
1683       rfp->activate (w);
1684     }
1685     SetRegionImportExportItems (rfp);
1686   }
1687 }
1688 
1689 extern ForM CreateRegionOrCommentForm (Int2 left, Int2 top, CharPtr title,
1690                                        SeqFeatPtr sfp, SeqEntryPtr sep,
1691                                        Uint2 subtype, FormActnFunc actproc)
1692 
1693 {
1694   ButtoN             b;
1695   GrouP              c;
1696   GrouP              g;
1697   GrouP              h;
1698   RegionFormPtr      rfp;
1699   GrouP              s;
1700   StdEditorProcsPtr  sepp;
1701   CharPtr            str;
1702   WindoW             w;
1703 
1704   w = NULL;
1705   rfp = (RegionFormPtr) MemNew (sizeof (RegionForm));
1706   if (rfp != NULL) {
1707     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
1708     SetObjectExtra (w, rfp, StdFeatFormCleanupProc);
1709     rfp->form = (ForM) w;
1710     rfp->actproc = actproc;
1711     rfp->toform = StdSeqFeatPtrToFeatFormProc;
1712     rfp->fromform = NULL;
1713     rfp->formmessage = RegionFormMessage;
1714     rfp->testform = NULL;
1715     rfp->importform = ImportRegionForm;
1716     rfp->exportform = ExportRegionForm;
1717 
1718 #ifndef WIN_MAC
1719     CreateStdEditorFormMenus (w);
1720 #endif
1721 
1722     rfp->activate = NULL;
1723     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
1724     if (sepp != NULL) {
1725       rfp->activate = sepp->activateForm;
1726       rfp->appmessage = sepp->handleMessages;
1727     }
1728     SetActivate (w, RegionFormActivate);
1729 
1730     g = HiddenGroup (w, -1, 0, NULL);
1731     SetGroupSpacing (g, 3, 10);
1732 
1733     rfp->sep = sep;
1734     if (subtype == FEATDEF_REGION) {
1735       rfp->foldertabs = CreateFolderTabs (g, regionFormTabs, REGION_PAGE,
1736                                           0, 0, SYSTEM_FOLDER_TAB,
1737                                           ChangeRegionPage, (Pointer) rfp);
1738     } else if (subtype == FEATDEF_COMMENT) {
1739       rfp->foldertabs = CreateFolderTabs (g, commentFormTabs, REGION_PAGE,
1740                                           0, 0, SYSTEM_FOLDER_TAB,
1741                                           ChangeRegionPage, (Pointer) rfp);
1742     } else {
1743       Message (MSG_FATAL, "Region or Comment Feature error");
1744     }
1745     rfp->currentPage = REGION_PAGE;
1746 
1747     h = HiddenGroup (g, 0, 0, NULL);
1748 
1749     s = HiddenGroup (h, -1, 0, NULL);
1750     str = NULL;
1751     if (sfp != NULL && sfp->data.choice == SEQFEAT_REGION) {
1752       str = sfp->data.value.ptrvalue;
1753     }
1754     rfp->data = CreateRegionDialog (s, NULL, str, subtype, rfp);
1755     /*
1756     if (subtype == FEATDEF_COMMENT) {
1757       rfp->data = NULL;
1758     }
1759     */
1760     rfp->pages [REGION_PAGE] = s;
1761     Hide (rfp->pages [REGION_PAGE]);
1762 
1763     s = HiddenGroup (h, -1, 0, NULL);
1764     CreateCommonFeatureGroup (s, (FeatureFormPtr) rfp, sfp, TRUE, TRUE);
1765     rfp->pages [COMMON_PAGE] = s;
1766     Hide (rfp->pages [COMMON_PAGE]);
1767 
1768     s = HiddenGroup (h, -1, 0, NULL);
1769     rfp->location = CreateIntervalEditorDialogEx (s, NULL, 4, 2, sep, TRUE, TRUE,
1770                                                   TRUE, TRUE, FALSE,
1771                                                   (FeatureFormPtr) rfp,
1772                                                   StdFeatIntEdPartialCallback);
1773     rfp->pages [LOCATION_PAGE] = s;
1774     Hide (rfp->pages [LOCATION_PAGE]);
1775 
1776     AlignObjects (ALIGN_CENTER, (HANDLE) rfp->pages [REGION_PAGE],
1777                   (HANDLE) rfp->pages [COMMON_PAGE], (HANDLE) rfp->pages [LOCATION_PAGE],
1778                   NULL);
1779     AlignObjects (ALIGN_CENTER, (HANDLE) rfp->foldertabs, (HANDLE) h, NULL);
1780 
1781     c = HiddenGroup (w, 2, 0, NULL);
1782     b = PushButton (c, "Accept", StdFeatFormAcceptButtonProc);
1783     SetObjectExtra (b, rfp, NULL);
1784     PushButton (c, "Cancel", StdCancelButtonProc);
1785     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
1786     RealizeWindow (w);
1787 
1788     SendMessageToDialog (rfp->data, VIB_MSG_INIT);
1789     SendMessageToDialog (rfp->location, VIB_MSG_INIT);
1790     Show (rfp->pages [rfp->currentPage]);
1791     SendMessageToDialog (rfp->data, VIB_MSG_ENTER);
1792     Update ();
1793   }
1794   return (ForM) w;
1795 }
1796 
1797 static void CopyRegionNameToComment (RegionPagePtr rpp, RegionFormPtr rfp)
1798 {
1799   CharPtr        old_comment = NULL;
1800   CharPtr        region_name = NULL;
1801   CharPtr        new_comment = NULL;
1802   Int4           new_comment_len;
1803 
1804   if (rpp == NULL || rfp == NULL) 
1805   {
1806     return;
1807   }
1808   
1809   region_name = SaveStringFromText (rpp->region);
1810   if (StringHasNoText (region_name))
1811   {
1812     region_name = MemFree (region_name);
1813   }
1814   else
1815   {
1816     old_comment = SaveStringFromText (rfp->comment);
1817     if (StringHasNoText (old_comment))
1818     {
1819       SetTitle (rfp->comment, region_name);
1820     }
1821     else
1822     {
1823       new_comment_len = StringLen (region_name) + StringLen (old_comment) + 3;
1824       new_comment = (CharPtr) MemNew (new_comment_len * sizeof (Char));
1825       if (new_comment != NULL)
1826       {
1827         StringCpy (new_comment, region_name);
1828         StringCat (new_comment, "; ");
1829         StringCat (new_comment, old_comment);
1830         SetTitle (rfp->comment, new_comment);
1831       }
1832       region_name = MemFree (region_name);
1833     }
1834     old_comment = MemFree (old_comment);
1835   }
1836 }
1837 
1838 static void MoveToNucSequence (RegionFormPtr rfp)
1839 {
1840   SeqLocPtr  slp;
1841   BioseqPtr  bsp;
1842   ValNodePtr prods, vnp;
1843   SeqFeatPtr cds = NULL;
1844   SeqLocPtr  new_location;
1845   
1846   if (rfp == NULL) return;
1847   
1848   slp = DialogToPointer (rfp->location);
1849   bsp = BioseqFindFromSeqLoc (slp);
1850   if (bsp != NULL && ISA_aa (bsp->mol))
1851   {
1852         prods = SeqMgrGetSfpProductList (bsp);
1853           for (vnp = prods; vnp != NULL && cds == NULL; vnp = vnp->next) 
1854           {
1855       cds = (SeqFeatPtr) vnp->data.ptrvalue;
1856       if (cds == NULL) continue;
1857       if (cds->data.choice != SEQFEAT_CDREGION)
1858       {
1859         cds = NULL;
1860       }
1861           }
1862           if (cds != NULL)
1863           {
1864             new_location = aaLoc_to_dnaLoc (cds, slp); 
1865       PointerToDialog (rfp->location, new_location);
1866       SeqLocFree (new_location);
1867           }
1868   }
1869   SeqLocFree (slp);
1870 }
1871 
1872 static void RegionOrCommentFeatFormActnProc (ForM f)
1873 
1874 {
1875   RegionFormPtr  rfp;
1876   RegionPagePtr  rpp;
1877 
1878   rfp = (RegionFormPtr) GetObjectExtra (f);
1879   if (rfp != NULL) {
1880     rpp = (RegionPagePtr) GetObjectExtra (rfp->data);
1881     if (rpp != NULL && GetStatus (rpp->convertToMiscFeat)) {
1882       rfp->this_subtype = FEATDEF_misc_feature;
1883       CopyRegionNameToComment (rpp, rfp);
1884       /* move feature to nucleotide sequence if on protein sequence */
1885       MoveToNucSequence (rfp);
1886     }
1887   }
1888   if (FeatFormReplaceWithoutUpdateProc (f)) {
1889     if (rfp != NULL) {
1890       GetRidOfEmptyFeatsDescStrings (rfp->input_entityID, NULL);
1891       if (GetAppProperty ("InternalNcbiSequin") != NULL) {
1892         ExtendGeneFeatIfOnMRNA (rfp->input_entityID, NULL);
1893       }
1894       ObjMgrSendMsg (OM_MSG_UPDATE, rfp->input_entityID,
1895                      rfp->input_itemID, rfp->input_itemtype);
1896     }
1897   }
1898 }
1899 
1900 extern Int2 LIBCALLBACK RegionOrCommentGenFunc (Pointer data)
1901 
1902 {
1903   OMProcControlPtr  ompcp;
1904   OMUserDataPtr     omudp;
1905   ObjMgrProcPtr     proc;
1906   RegionFormPtr     rfp;
1907   SeqEntryPtr       sep;
1908   SeqFeatPtr        sfp;
1909   Uint2             subtype;
1910   CharPtr           title;
1911   WindoW            w;
1912 
1913   ompcp = (OMProcControlPtr) data;
1914   sfp = NULL;
1915   sep = NULL;
1916   subtype = 0;
1917   title = NULL;
1918   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
1919   proc = ompcp->proc;
1920   switch (ompcp->input_itemtype) {
1921     case OBJ_SEQFEAT :
1922       sfp = (SeqFeatPtr) ompcp->input_data;
1923       if (sfp != NULL &&
1924           (sfp->data.choice != SEQFEAT_REGION &&
1925            sfp->data.choice != SEQFEAT_COMMENT)) {
1926         return OM_MSG_RET_ERROR;
1927       }
1928       break;
1929     case OBJ_BIOSEQ :
1930       break;
1931     case OBJ_BIOSEQSET :
1932       break;
1933     case 0 :
1934       break;
1935     default :
1936       return OM_MSG_RET_ERROR;
1937   }
1938   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
1939                                 ompcp->input_itemtype, ompcp->proc->procid);
1940   if (omudp != NULL) {
1941     rfp = (RegionFormPtr) omudp->userdata.ptrvalue;
1942     if (rfp != NULL) {
1943       Select (rfp->form);
1944     }
1945     return OM_MSG_RET_DONE;
1946   }
1947   if (sfp != NULL) {
1948     if (sfp->data.choice == SEQFEAT_REGION) {
1949       subtype = FEATDEF_REGION;
1950     } else if (sfp->data.choice == SEQFEAT_COMMENT) {
1951       subtype = FEATDEF_COMMENT;
1952     }
1953   } else if (proc->subinputtype > 0) {
1954     subtype = proc->subinputtype;
1955   }
1956   if (subtype == FEATDEF_REGION) {
1957     title = "Region";
1958   } else if (subtype == FEATDEF_COMMENT) {
1959     title = "Comment";
1960   } else {
1961     return OM_MSG_RET_ERROR;
1962   }
1963   sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
1964   w = (WindoW) CreateRegionOrCommentForm (-50, -33, title, sfp, sep,
1965                                           subtype, RegionOrCommentFeatFormActnProc);
1966   rfp = (RegionFormPtr) GetObjectExtra (w);
1967   if (rfp != NULL) {
1968     rfp->input_entityID = ompcp->input_entityID;
1969     rfp->input_itemID = ompcp->input_itemID;
1970     rfp->input_itemtype = ompcp->input_itemtype;
1971     rfp->this_itemtype = OBJ_SEQFEAT;
1972     rfp->this_subtype = subtype;
1973     rfp->procid = ompcp->proc->procid;
1974     rfp->proctype = ompcp->proc->proctype;
1975     rfp->userkey = OMGetNextUserKey ();
1976     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
1977                                    OMPROC_EDIT, rfp->userkey);
1978     if (omudp != NULL) {
1979       omudp->userdata.ptrvalue = (Pointer) rfp;
1980       omudp->messagefunc = StdVibrantEditorMsgFunc;
1981     }
1982     SendMessageToForm (rfp->form, VIB_MSG_INIT);
1983     if (sfp != NULL) {
1984       PointerToForm (rfp->form, (Pointer) sfp);
1985       SetClosestParentIfDuplicating ((BaseFormPtr) rfp);
1986     } else {
1987       SetNewFeatureDefaultInterval ((FeatureFormPtr) rfp);
1988     }
1989   }
1990   Show (w);
1991   Select (w);
1992   return OM_MSG_RET_DONE;
1993 }
1994 
1995 
1996 typedef struct molinfopage {
1997   DIALOG_MESSAGE_BLOCK
1998   PopuP           moltype;
1999   PopuP           technique;
2000   PopuP           complete;
2001   GrouP           expGrp;
2002   TexT            explain;
2003   EnumFieldAssoc  PNTR moltypeAlist;
2004   EnumFieldAssoc  PNTR techniqueAlist;
2005   EnumFieldAssoc  PNTR completeAlist;
2006 } MolInfoPage, PNTR MolInfoPagePtr;
2007 
2008 typedef struct molinfoform {
2009   DESCRIPTOR_FORM_BLOCK
2010   PopuP           molPopup;
2011   PopuP           topologyPopup;
2012   PopuP           strandPopup;
2013 } MolInfoForm, PNTR MolInfoFormPtr;
2014 
2015 static ENUM_ALIST(molinfo_biomol_alist)
2016   {" ",                       0},
2017   {"Genomic DNA or RNA",      1},
2018   {"Precursor RNA",           2},
2019   {"mRNA [cDNA]",             3},
2020   {"Ribosomal RNA",           4},
2021   {"Transfer RNA",            5},
2022   {"Small nuclear RNA",       6},
2023   {"Small cytoplasmic RNA",   7},
2024   {"Peptide",                 8},
2025   {"Other-Genetic",           9},
2026   {"Genomic-mRNA",           10},
2027   {"cRNA",                   11},
2028   {"Small nucleolar RNA",    12},
2029   {"Transcribed RNA",        13},
2030   {"Non-coding  RNA",        14},
2031   {"Transfer-messenger RNA", 15},
2032   {"Other",                 255},
2033 END_ENUM_ALIST
2034 
2035 extern CharPtr GetMoleculeTypeName (Uint1 mol_val)
2036 {
2037   Int4 i;
2038   for (i = 0; i < sizeof (molinfo_biomol_alist) / sizeof (EnumFieldAssoc); i++) {
2039     if (molinfo_biomol_alist[i].value == mol_val) {
2040       return molinfo_biomol_alist[i].name;
2041     }
2042   }
2043   return NULL;
2044 }
2045 
2046 
2047 static ENUM_ALIST(molinfo_biomol_nuc_alist)
2048   {" ",                       0},
2049   {"Genomic DNA or RNA",      1},
2050   {"Precursor RNA",           2},
2051   {"mRNA [cDNA]",             3},
2052   {"Ribosomal RNA",           4},
2053   {"Transfer RNA",            5},
2054   {"Small nuclear RNA",       6},
2055   {"Small cytoplasmic RNA",   7},
2056   {"Other-Genetic",           9},
2057   {"Genomic-mRNA",           10},
2058   {"cRNA",                   11},
2059   {"Small nucleolar RNA",    12},
2060   {"Transcribed RNA",        13},
2061   {"Non-coding  RNA",        14},
2062   {"Transfer-messenger RNA", 15},
2063   {"Other",                 255},
2064 END_ENUM_ALIST
2065 
2066 static ENUM_ALIST(molinfo_biomol_nucX_alist)
2067   {" ",                       0},
2068   {"Genomic DNA",           253},
2069   {"Genomic RNA",           254},
2070   {"Precursor RNA",           2},
2071   {"mRNA [cDNA]",             3},
2072   {"Ribosomal RNA",           4},
2073   {"Transfer RNA",            5},
2074   {"Small nuclear RNA",       6},
2075   {"Small cytoplasmic RNA",   7},
2076   {"Other-Genetic",           9},
2077   {"Genomic-mRNA",           10},
2078   {"cRNA",                   11},
2079   {"Small nucleolar RNA",    12},
2080   {"Transcribed RNA",        13},
2081   {"Non-coding  RNA",        14},
2082   {"Transfer-messenger RNA", 15},
2083   {"Other",                 255},
2084 END_ENUM_ALIST
2085 
2086 static ENUM_ALIST(molinfo_biomol_prot_alist)
2087   {" ",                      0},
2088   {"Peptide",                8},
2089   {"Other",                255},
2090 END_ENUM_ALIST
2091 
2092 static ENUM_ALIST(molinfo_tech_alist)
2093   {" ",                   0},
2094   {"Standard",            1},
2095   {"EST",                 2},
2096   {"STS",                 3},
2097   {"Survey",              4},
2098   {"Genetic Map",         5},
2099   {"Physical Map",        6},
2100   {"Derived",             7},
2101   {"Concept-Trans",       8},
2102   {"Seq-Pept",            9},
2103   {"Both",               10},
2104   {"Seq-Pept-Overlap",   11},
2105   {"Seq-Pept-Homol",     12},
2106   {"Concept-Trans-A",    13},
2107   {"HTGS 0",             18},
2108   {"HTGS 1",             14},
2109   {"HTGS 2",             15},
2110   {"HTGS 3",             16},
2111   {"FLI_cDNA",           17},
2112   {"HTC",                19},
2113   {"WGS",                20},
2114   {"Barcode",            21},
2115   {"Composite-WGS-HTGS", 22},
2116   {"TSA",                23},
2117   {"Other:",            255},
2118 END_ENUM_ALIST
2119 
2120 static ENUM_ALIST(molinfo_tech_nuc_alist)
2121   {" ",                   0},
2122   {"Standard",            1},
2123   {"EST",                 2},
2124   {"STS",                 3},
2125   {"Survey",              4},
2126   {"Genetic Map",         5},
2127   {"Physical Map",        6},
2128   {"Derived",             7},
2129   {"HTGS 0",             18},
2130   {"HTGS 1",             14},
2131   {"HTGS 2",             15},
2132   {"HTGS 3",             16},
2133   {"FLI_cDNA",           17},
2134   {"HTC",                19},
2135   {"WGS",                20},
2136   {"Barcode",            21},
2137   {"Composite-WGS-HTGS", 22},
2138   {"TSA",                23},
2139   {"Other:",            255},
2140 END_ENUM_ALIST
2141 
2142 static ENUM_ALIST(molinfo_tech_prot_alist)
2143   {" ",                  0},
2144   {"Concept-Trans",      8},
2145   {"Seq-Pept",           9},
2146   {"Both",              10},
2147   {"Seq-Pept-Overlap",  11},
2148   {"Seq-Pept-Homol",    12},
2149   {"Concept-Trans-A",   13},
2150   {"Other:",           255},
2151 END_ENUM_ALIST
2152 
2153 static ENUM_ALIST(molinfo_complete_alist)
2154   {" ",         0},
2155   {"Complete",  1},
2156   {"Partial",   2},
2157   {"No Left",   3},
2158   {"No Right",  4},
2159   {"No Ends",   5},
2160   {"Has Left",  6},
2161   {"Has Right", 7},
2162   {"Other",   255},
2163 END_ENUM_ALIST
2164 
2165 static ENUM_ALIST(molinfo_complete_nuc_alist)
2166   {" ",         0},
2167   {"Complete",  1},
2168   {"Partial",   2},
2169   {"No 5'",     3},
2170   {"No 3'",     4},
2171   {"No Ends",   5},
2172   {"Has 5'",    6},
2173   {"Has 3'",    7},
2174   {"Other",   255},
2175 END_ENUM_ALIST
2176 
2177 static ENUM_ALIST(molinfo_complete_prot_alist)
2178   {" ",         0},
2179   {"Complete",  1},
2180   {"Partial",   2},
2181   {"No NH3",    3},
2182   {"No CO2",    4},
2183   {"No Ends",   5},
2184   {"Has NH3",   6},
2185   {"Has CO2",   7},
2186   {"Other",   255},
2187 END_ENUM_ALIST
2188 
2189 static Uint1 check_biomol (Uint1 biomol)
2190 
2191 {
2192   if (biomol > MOLECULE_TYPE_TMRNA && biomol < 253) return 0;
2193   return biomol;
2194 }
2195 
2196 static Uint1 check_technique (Uint1 tech)
2197 
2198 {
2199   if (tech > MI_TECH_tsa && tech != MI_TECH_other) return 0;
2200   return tech;
2201 }
2202 
2203 static Uint1 check_complete (Uint1 completeness)
2204 
2205 {
2206   if (completeness > 7 && completeness != 255) return 0;
2207   return completeness;
2208 }
2209 
2210 static void MolInfoPtrToMolInfoPage (DialoG d, Pointer data)
2211 
2212 {
2213   MolInfoPtr      mip;
2214   MolInfoPagePtr  mpp;
2215 
2216   mpp = (MolInfoPagePtr) GetObjectExtra (d);
2217   mip = (MolInfoPtr) data;
2218   if (mpp != NULL) {
2219     SetEnumPopup (mpp->moltype, mpp->moltypeAlist,
2220                   (UIEnum) check_biomol (mip->biomol));
2221     SetEnumPopup (mpp->technique, mpp->techniqueAlist,
2222                   (UIEnum) check_technique (mip->tech));
2223     SetEnumPopup (mpp->complete, mpp->completeAlist,
2224                   (UIEnum) check_complete (mip->completeness));
2225     SetTitle (mpp->explain, mip->techexp);
2226     if (mip->tech == 255) {
2227       SafeShow (mpp->expGrp);
2228     } else {
2229       SafeHide (mpp->expGrp);
2230     }
2231   }
2232 }
2233 
2234 static Pointer MolInfoPageToMolInfoPtr (DialoG d)
2235 
2236 {
2237   MolInfoPtr      mip;
2238   MolInfoPagePtr  mpp;
2239   UIEnum          val;
2240 
2241   mip = NULL;
2242   mpp = (MolInfoPagePtr) GetObjectExtra (d);
2243   if (mpp != NULL) {
2244     mip = MolInfoNew ();
2245     if (mip != NULL) {
2246       if (GetEnumPopup (mpp->moltype, mpp->moltypeAlist, &val)) {
2247         mip->biomol = (Uint1) val;
2248       }
2249       if (GetEnumPopup (mpp->technique, mpp->techniqueAlist, &val)) {
2250         mip->tech = (Uint1) val;
2251       }
2252       if (GetEnumPopup (mpp->complete, mpp->completeAlist, &val)) {
2253         mip->completeness = (Uint1) val;
2254       }
2255       if (mip->tech == 255) {
2256         mip->techexp = SaveStringFromText (mpp->explain);
2257       }
2258     }
2259   }
2260   return (Pointer) mip;
2261 }
2262 
2263 static void ChangeTech (PopuP p)
2264 
2265 {
2266   MolInfoPagePtr  mpp;
2267   UIEnum          val;
2268 
2269   mpp = (MolInfoPagePtr) GetObjectExtra (p);
2270   if (mpp != NULL) {
2271     if (GetEnumPopup (mpp->technique, mpp->techniqueAlist, &val)) {
2272       if (val == 255) {
2273         SafeShow (mpp->expGrp);
2274       } else {
2275         SafeHide (mpp->expGrp);
2276       }
2277     }
2278   }
2279 }
2280 
2281 static CharPtr  labels [] = {
2282   "Molecule", "Technique", NULL
2283 };
2284 
2285 extern DialoG CreateMolInfoDialog (GrouP h, CharPtr title, Uint1 biomol, Uint1 tech,
2286                                    Boolean showComplete, Boolean nucsOK, Boolean protsOK,
2287                                    Boolean separateGenomicDNAandRNA)
2288 
2289 {
2290   GrouP           f;
2291   GrouP           m;
2292   MolInfoPagePtr  mpp;
2293   GrouP           p;
2294   GrouP           s;
2295   Int2            wid;
2296   GrouP           x;
2297 
2298   p = HiddenGroup (h, 1, 0, NULL);
2299   SetGroupSpacing (p, 10, 10);
2300 
2301   mpp = (MolInfoPagePtr) MemNew (sizeof (MolInfoPage));
2302   if (mpp != NULL) {
2303 
2304     SetObjectExtra (p, mpp, StdCleanupExtraProc);
2305     mpp->dialog = (DialoG) p;
2306     mpp->todialog = MolInfoPtrToMolInfoPage;
2307     mpp->fromdialog = MolInfoPageToMolInfoPtr;
2308     mpp->testdialog = NULL;
2309 
2310     if (title != NULL && title [0] != '\0') {
2311       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
2312     } else {
2313       s = HiddenGroup (p, 0, -2, NULL);
2314     }
2315     m = HiddenGroup (s, -1, 0, NULL);
2316     /*
2317     SetGroupSpacing (m, 10, 10);
2318     */
2319 
2320     if (showComplete) {
2321       f = HiddenGroup (m, -3, 0, NULL);
2322     } else {
2323       f = HiddenGroup (m, -2, 0, NULL);
2324     }
2325 
2326     SelectFont (programFont);
2327     wid = MaxStringWidths (labels);
2328 
2329     if (nucsOK && protsOK) {
2330       mpp->moltypeAlist = molinfo_biomol_alist;
2331       mpp->techniqueAlist = molinfo_tech_alist;
2332       mpp->completeAlist = molinfo_complete_alist;
2333     } else if (nucsOK) {
2334       if (separateGenomicDNAandRNA) {
2335         mpp->moltypeAlist = molinfo_biomol_nucX_alist;
2336         mpp->techniqueAlist = molinfo_tech_nuc_alist;
2337         mpp->completeAlist = molinfo_complete_nuc_alist;
2338       } else {
2339         mpp->moltypeAlist = molinfo_biomol_nuc_alist;
2340         mpp->techniqueAlist = molinfo_tech_nuc_alist;
2341         mpp->completeAlist = molinfo_complete_nuc_alist;
2342       }
2343     } else if (protsOK) {
2344       mpp->moltypeAlist = molinfo_biomol_prot_alist;
2345       mpp->techniqueAlist = molinfo_tech_prot_alist;
2346       mpp->completeAlist = molinfo_complete_prot_alist;
2347     } else {
2348       mpp->moltypeAlist = molinfo_biomol_alist;
2349       mpp->techniqueAlist = molinfo_tech_alist;
2350       mpp->completeAlist = molinfo_complete_alist;
2351     }
2352 
2353     StaticPrompt (f, "Molecule",
2354                   wid, popupMenuHeight, programFont, 'l');
2355     mpp->moltype = PopupList (f, TRUE, NULL);
2356     SetObjectExtra (mpp->moltype, mpp, NULL);
2357     InitEnumPopup (mpp->moltype, mpp->moltypeAlist, NULL);
2358     SetEnumPopup (mpp->moltype, mpp->moltypeAlist, biomol);
2359 
2360     x = NULL;
2361     if (showComplete) {
2362       x = HiddenGroup (f, 2, 0, NULL);
2363       StaticPrompt (x, "Completedness",
2364                     0, popupMenuHeight, programFont, 'l');
2365       mpp->complete = PopupList (x, TRUE, NULL);
2366       SetObjectExtra (mpp->complete, mpp, NULL);
2367       InitEnumPopup (mpp->complete, mpp->completeAlist, NULL);
2368       SetEnumPopup (mpp->complete, mpp->completeAlist, 0);
2369     }
2370 
2371     StaticPrompt (f, "Technique",
2372                   wid, popupMenuHeight, programFont, 'l');
2373     mpp->technique = PopupList (f, TRUE, ChangeTech);
2374     SetObjectExtra (mpp->technique, mpp, NULL);
2375     InitEnumPopup (mpp->technique, mpp->techniqueAlist, NULL);
2376     SetEnumPopup (mpp->technique, mpp->techniqueAlist, 0);
2377     SetEnumPopup (mpp->technique, mpp->techniqueAlist, tech);
2378 
2379     mpp->expGrp = HiddenGroup (f, -2, 0, NULL);
2380     SetGroupSpacing (mpp->expGrp, 0, 0);
2381     /*
2382     StaticPrompt (mpp->expGrp, "Explanation",
2383                   0, dialogTextHeight, programFont, 'l');
2384     */
2385     mpp->explain = DialogText (mpp->expGrp, "", 10, NULL);
2386     SetObjectExtra (mpp->explain, mpp, NULL);
2387     if (showComplete) {
2388       AlignObjects (ALIGN_LEFT, (HANDLE) mpp->explain,
2389                     (HANDLE) x, NULL);
2390       AlignObjects (ALIGN_RIGHT, (HANDLE) mpp->explain,
2391                     (HANDLE) mpp->complete, NULL);
2392       AlignObjects (ALIGN_RIGHT, (HANDLE) mpp->explain,
2393                     (HANDLE) x, NULL);
2394     } else {
2395       AlignObjects (ALIGN_RIGHT, (HANDLE) mpp->technique,
2396                     (HANDLE) mpp->explain, NULL);
2397       AlignObjects (ALIGN_LEFT, (HANDLE) mpp->technique,
2398                     (HANDLE) mpp->explain, NULL);
2399     }
2400     Hide (mpp->expGrp);
2401   }
2402 
2403   return (DialoG) p;
2404 }
2405 
2406 /************ Bioseq field editors ************/
2407 
2408 static ENUM_ALIST(mol_alist)
2409 {" ",               0},             /* Unknown? */
2410 {"DNA",             Seq_mol_dna},   /* 1 */
2411 {"RNA",             Seq_mol_rna},   /* 2 */
2412 {"Protein",         Seq_mol_aa},    /* 3 */
2413 {"Nucleotide",      Seq_mol_na},    /* 4 */
2414 {"Other",           Seq_mol_other}, /* 255 */
2415 END_ENUM_ALIST
2416 
2417 extern CharPtr GetMoleculeClassName (Uint1 mol_val)
2418 {
2419   Int4 i;
2420   for (i = 0; i < sizeof (mol_alist) / sizeof (EnumFieldAssoc); i++) {
2421     if (mol_alist[i].value == mol_val) {
2422       return mol_alist[i].name;
2423     }
2424   }
2425   return NULL;
2426 }
2427 
2428 static ENUM_ALIST(topology_alist)
2429 {" ",               0},                 /* Unknown? */
2430 {"Linear",          TOPOLOGY_LINEAR},   /* 1 */
2431 {"Circular",        TOPOLOGY_CIRCULAR}, /* 2 */
2432 {"Tandem",          TOPOLOGY_TANDEM},   /* 3 */
2433 {"Other",           255},               /* Other? */
2434 END_ENUM_ALIST
2435 
2436 static ENUM_ALIST(strand_alist)
2437 {" ",               Seq_strand_unknown},  /* 0 */
2438 {"Single",          Seq_strand_plus},     /* 1 */
2439 {"Double",          Seq_strand_minus},    /* 2 */
2440 {"Mixed",           Seq_strand_both},     /* 3 */
2441 {"Mixed Rev",       Seq_strand_both_rev}, /* 4 */
2442 {"Other",           Seq_strand_other},    /* 255 */
2443 END_ENUM_ALIST
2444 
2445 static Uint1 check_mol (Uint1 mol)
2446 {
2447   if (mol > Seq_mol_na && mol != Seq_mol_other) return 0;
2448   return mol;
2449 }
2450 
2451 static Uint1 check_topology (Uint1 topology)
2452 {
2453   if (topology > TOPOLOGY_TANDEM && topology != 255) return 0;
2454   return topology;
2455 }
2456 
2457 static Uint1 check_strand (Uint1 strand)
2458 {
2459   /* if (strand == Seq_strand_both_rev) return Seq_strand_other; ??? */
2460   if (strand > Seq_strand_both_rev && strand != Seq_strand_other)
2461     return Seq_strand_unknown;
2462   return strand;
2463 }
2464 
2465 static Boolean UpdateSeqInstGatherFunc (GatherContextPtr gcp)
2466 
2467 {
2468   BioseqPtr       bsp;
2469   MolInfoFormPtr  mfp;
2470   UIEnum          val;
2471   
2472   if (gcp == NULL) return TRUE;
2473   mfp = (MolInfoFormPtr) gcp->userdata;
2474   if (mfp == NULL) return TRUE;
2475   if (gcp->thistype == OBJ_BIOSEQ && gcp->thisitem != NULL) {
2476     bsp = (BioseqPtr) gcp->thisitem;
2477     if (GetEnumPopup (mfp->molPopup, mol_alist, &val)) {
2478       /* also convert data if switching from na to aa or aa to na */
2479       if (ISA_na (bsp->mol) && ISA_aa (val)) {
2480         BioseqConvert (bsp, Seq_code_ncbieaa);
2481       }
2482       else if (ISA_aa (bsp->mol) && ISA_na (val)) {
2483         BioseqConvert (bsp, Seq_code_ncbi2na);
2484       }
2485       bsp->mol = (Uint1) val;
2486     }
2487     if (GetEnumPopup (mfp->strandPopup, strand_alist, &val)) {
2488       bsp->strand = (Uint1) val;
2489     }
2490     if (GetEnumPopup (mfp->topologyPopup, topology_alist, &val)) {
2491       bsp->topology = (Uint1) val;
2492     }
2493   }
2494   return TRUE;
2495 }
2496 
2497 static Boolean UpdateSeqInstFlags (GatherContextPtr gcp)
2498 
2499 {
2500   GatherScope     gs;
2501   MolInfoFormPtr  mfp;
2502   SeqEntryPtr     sep;
2503 
2504   if (gcp == NULL || gcp->userdata == NULL) return TRUE;
2505   mfp = (MolInfoFormPtr) gcp->userdata;
2506   if (gcp->parenttype == OBJ_BIOSEQ || gcp->parenttype == OBJ_BIOSEQSET) {
2507     sep = SeqMgrGetSeqEntryForData (gcp->parentitem);
2508     if (sep != NULL) {
2509       MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
2510       gs.seglevels = 1;
2511       gs.scope = sep;
2512       MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
2513       gs.ignore[OBJ_BIOSEQ] = FALSE;
2514       gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
2515       gs.ignore[OBJ_SEQANNOT] = FALSE;
2516       gs.ignore[OBJ_SEQDESC] = FALSE;
2517       GatherEntity (mfp->input_entityID, (Pointer) mfp, UpdateSeqInstGatherFunc, &gs);
2518     }
2519   }
2520   return TRUE;
2521 }
2522 
2523 static Boolean CollectSeqInstGatherFunc (GatherContextPtr gcp)
2524 
2525 {
2526   BioseqPtr       bsp;
2527   MolInfoFormPtr  mfp;
2528   
2529   if (gcp == NULL) return TRUE;
2530   mfp = (MolInfoFormPtr) gcp->userdata;
2531   if (mfp == NULL) return TRUE;
2532   if (gcp->thistype == OBJ_BIOSEQ && gcp->thisitem != NULL) {
2533     bsp = (BioseqPtr) gcp->thisitem;
2534     SetEnumPopup (mfp->molPopup, mol_alist,
2535                   (UIEnum) check_mol (bsp->mol));
2536     SetEnumPopup (mfp->strandPopup, strand_alist,
2537                   (UIEnum) check_strand (bsp->strand));
2538     SetEnumPopup (mfp->topologyPopup, topology_alist,
2539                   (UIEnum) check_topology (bsp->topology));
2540   }
2541   return TRUE;
2542 }
2543 
2544 static Boolean CollectSeqInstFlags (GatherContextPtr gcp)
2545 
2546 {
2547   GatherScope     gs;
2548   MolInfoFormPtr  mfp;
2549   SeqEntryPtr     sep;
2550 
2551   if (gcp == NULL || gcp->userdata == NULL) return TRUE;
2552   mfp = (MolInfoFormPtr) gcp->userdata;
2553   if (gcp->parenttype == OBJ_BIOSEQ || gcp->parenttype == OBJ_BIOSEQSET) {
2554     sep = SeqMgrGetSeqEntryForData (gcp->parentitem);
2555     if (sep != NULL) {
2556       MemSet ((Pointer) (&gs), 0, sizeof (GatherScope));
2557       gs.seglevels = 1;
2558       gs.scope = sep;
2559       MemSet((Pointer)(gs.ignore), (int)(TRUE), (size_t)(OBJ_MAX * sizeof(Boolean)));
2560       gs.ignore[OBJ_BIOSEQ] = FALSE;
2561       gs.ignore[OBJ_BIOSEQ_SEG] = FALSE;
2562       gs.ignore[OBJ_SEQANNOT] = FALSE;
2563       gs.ignore[OBJ_SEQDESC] = FALSE;
2564       GatherEntity (mfp->input_entityID, (Pointer) mfp, CollectSeqInstGatherFunc, &gs);
2565     }
2566   }
2567   return TRUE;
2568 }
2569 
2570 static void MolInfoDescFormActnProc (ForM f)
2571 
2572 {
2573   MolInfoFormPtr  mfp;
2574 
2575   mfp = (MolInfoFormPtr) GetObjectExtra (f);
2576   if (mfp != NULL) {
2577     DescFormReplaceWithoutUpdateProc (f);
2578     if (mfp->input_itemtype == OBJ_SEQDESC) {
2579       GatherItem (mfp->input_entityID, mfp->input_itemID, mfp->input_itemtype,
2580                   (Pointer) mfp, UpdateSeqInstFlags);
2581     }
2582     GetRidOfEmptyFeatsDescStrings (mfp->input_entityID, NULL);
2583     if (GetAppProperty ("InternalNcbiSequin") != NULL) {
2584       ExtendGeneFeatIfOnMRNA (mfp->input_entityID, NULL);
2585     }
2586     ObjMgrSendMsg (OM_MSG_UPDATE, mfp->input_entityID,
2587                    mfp->input_itemID, mfp->input_itemtype);
2588   }
2589 }
2590 
2591 static void MolInfoFormMessage (ForM f, Int2 mssg)
2592 
2593 {
2594   MolInfoFormPtr  mfp;
2595 
2596   mfp = (MolInfoFormPtr) GetObjectExtra (f);
2597   if (mfp != NULL) {
2598     switch (mssg) {
2599       case VIB_MSG_CLOSE :
2600         Remove (f);
2601         break;
2602       case VIB_MSG_CUT :
2603         StdCutTextProc (NULL);
2604         break;
2605       case VIB_MSG_COPY :
2606         StdCopyTextProc (NULL);
2607         break;
2608       case VIB_MSG_PASTE :
2609         StdPasteTextProc (NULL);
2610         break;
2611       case VIB_MSG_DELETE :
2612         StdDeleteTextProc (NULL);
2613         break;
2614       default :
2615         if (mfp->appmessage != NULL) {
2616           mfp->appmessage (f, mssg);
2617         }
2618         break;
2619     }
2620   }
2621 }
2622 
2623 extern ForM CreateMolInfoForm (Int2 left, Int2 top, Int2 width, Int2 height,
2624                                CharPtr title, Uint1 biomol, Uint1 tech,
2625                                Boolean nucsOK, Boolean protsOK, FormActnFunc actproc)
2626 
2627 {
2628   ButtoN             b;
2629   GrouP              c;
2630   GrouP              g;
2631   MolInfoFormPtr     mfp;
2632   PrompT             p;
2633   GrouP              q;
2634   StdEditorProcsPtr  sepp;
2635   WindoW             w;
2636 
2637   w = NULL;
2638   mfp = (MolInfoFormPtr) MemNew (sizeof (MolInfoForm));
2639   if (mfp != NULL) {
2640     w = FixedWindow (left, top, width, height, title, StdCloseWindowProc);
2641     SetObjectExtra (w, mfp, StdDescFormCleanupProc);
2642     mfp->form = (ForM) w;
2643     mfp->actproc = actproc;
2644     mfp->formmessage = MolInfoFormMessage;
2645 
2646 #ifndef WIN_MAC
2647     CreateStdEditorFormMenus (w);
2648 #endif
2649     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
2650     if (sepp != NULL) {
2651       SetActivate (w, sepp->activateForm);
2652       mfp->appmessage = sepp->handleMessages;
2653     }
2654 
2655     g = HiddenGroup (w, -1, 0, NULL);
2656     mfp->data = CreateMolInfoDialog (g, NULL, biomol, tech, TRUE, nucsOK, protsOK, FALSE);
2657 
2658     p = StaticPrompt (w, "Biological characteristics of sequences:",
2659                       0, stdLineHeight, programFont, 'c');
2660 
2661     q = HiddenGroup (w, 6, 0, NULL);
2662     StaticPrompt (q, "Class", 0, popupMenuHeight, programFont, 'c');
2663     mfp->molPopup = PopupList (q, TRUE, NULL);
2664     InitEnumPopup (mfp->molPopup, mol_alist, NULL);
2665     StaticPrompt (q, "Topology", 0, popupMenuHeight, programFont, 'c');
2666     mfp->topologyPopup = PopupList (q, TRUE, NULL);
2667     InitEnumPopup (mfp->topologyPopup, topology_alist, NULL);
2668     StaticPrompt (q, "Strand", 0, popupMenuHeight, programFont, 'c');
2669     mfp->strandPopup = PopupList (q, TRUE, NULL);
2670     InitEnumPopup (mfp->strandPopup, strand_alist, NULL);
2671 
2672     SetGroupSpacing (q, 15, 2);
2673     c = HiddenGroup (w, 2, 0, NULL);
2674     b = PushButton (c, "Accept", StdAcceptFormButtonProc);
2675     SetObjectExtra (b, mfp, NULL);
2676     PushButton (c, "Cancel", StdCancelButtonProc);
2677     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) p, (HANDLE) q, (HANDLE) c, NULL);
2678     RealizeWindow (w);
2679   }
2680   return (ForM) w;
2681 }
2682 
2683 extern Int2 LIBCALLBACK MolInfoGenFunc (Pointer data)
2684 
2685 {
2686   MolInfoFormPtr    mfp;
2687   OMProcControlPtr  ompcp;
2688   OMUserDataPtr     omudp;
2689   ValNodePtr        sdp;
2690   WindoW            w;
2691 
2692   ompcp = (OMProcControlPtr) data;
2693   sdp = NULL;
2694   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
2695   switch (ompcp->input_itemtype) {
2696     case OBJ_SEQDESC :
2697       sdp = (ValNodePtr) ompcp->input_data;
2698       if (sdp != NULL && sdp->choice != Seq_descr_molinfo) {
2699         return OM_MSG_RET_ERROR;
2700       }
2701       break;
2702     case OBJ_BIOSEQ :
2703       break;
2704     case OBJ_BIOSEQSET :
2705       break;
2706     case 0 :
2707       break;
2708     default :
2709       return OM_MSG_RET_ERROR;
2710   }
2711   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
2712                                 ompcp->input_itemtype, ompcp->proc->procid);
2713   if (omudp != NULL) {
2714     mfp = (MolInfoFormPtr) omudp->userdata.ptrvalue;
2715     if (mfp != NULL) {
2716       Select (mfp->form);
2717     }
2718     return OM_MSG_RET_DONE;
2719   }
2720   w = (WindoW) CreateMolInfoForm (-50, -33, -10, -10,
2721                                   "Molecule Information", 0, 0, TRUE, TRUE,
2722                                   MolInfoDescFormActnProc);
2723   mfp = (MolInfoFormPtr) GetObjectExtra (w);
2724   if (mfp != NULL) {
2725     mfp->input_entityID = ompcp->input_entityID;
2726     mfp->input_itemID = ompcp->input_itemID;
2727     mfp->input_itemtype = ompcp->input_itemtype;
2728     mfp->this_itemtype = OBJ_SEQDESC;
2729     mfp->this_subtype = Seq_descr_molinfo;
2730     mfp->procid = ompcp->proc->procid;
2731     mfp->proctype = ompcp->proc->proctype;
2732     mfp->userkey = OMGetNextUserKey ();
2733     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
2734                                    OMPROC_EDIT, mfp->userkey);
2735     if (omudp != NULL) {
2736       omudp->userdata.ptrvalue = (Pointer) mfp;
2737       omudp->messagefunc = StdVibrantEditorMsgFunc;
2738     }
2739     SendMessageToDialog (mfp->data, VIB_MSG_INIT);
2740     if (sdp != NULL) {
2741       PointerToDialog (mfp->data, (Pointer) sdp->data.ptrvalue);
2742       if (mfp->input_itemtype == OBJ_SEQDESC) {
2743         GatherItem (mfp->input_entityID, mfp->input_itemID, mfp->input_itemtype,
2744                     (Pointer) mfp, CollectSeqInstFlags);
2745       }
2746       SetClosestParentIfDuplicating ((BaseFormPtr) mfp);
2747     }
2748   }
2749   Show (w);
2750   Select (w);
2751   return OM_MSG_RET_DONE;
2752 }
2753 
2754 
2755 typedef struct gbblockpage {
2756   DIALOG_MESSAGE_BLOCK
2757   TexT          source;
2758   TexT          origin;
2759   TexT          date;
2760   TexT          div;
2761   TexT          taxonomy;
2762   ButtoN        htgsDraft;
2763   ButtoN        htgsFulltop;
2764   ButtoN        htgsActivefin;
2765   ButtoN        htgsCancelled;
2766   ButtoN        tpaExperimental;
2767   ButtoN        tpaInferential;
2768   ButtoN        tpaReassembly;
2769   ButtoN        barCode;
2770   DialoG        kywds;
2771   DialoG        xaccns;
2772   DialoG        entryDate;
2773 } GenBankPage, PNTR GenBankPagePtr;
2774 
2775 typedef struct gbblockform {
2776   DESCRIPTOR_FORM_BLOCK
2777   DialoG        gbppxaccns;
2778   ButtoN        xaccnstohistory;
2779   ButtoN        xleaveoldhistory;
2780 } GenBankForm, PNTR GenBankFormPtr;
2781 
2782 static void GBBlockPtrToGenBankPage (DialoG d, Pointer data)
2783 
2784 {
2785   GBBlockPtr      gbp;
2786   GenBankPagePtr  gpp;
2787   ValNodePtr      head;
2788   Boolean         isActivefin = FALSE;
2789   Boolean         isCancelled = FALSE;
2790   Boolean         isDraft = FALSE;
2791   Boolean         isFulltop = FALSE;
2792   Boolean         isExperimental = FALSE;
2793   Boolean         isInferential = FALSE;
2794   Boolean         isReassembly = FALSE;
2795   Boolean         isBarcode = FALSE;
2796   CharPtr         str;
2797   ValNodePtr      vnp;
2798 
2799   gpp = (GenBankPagePtr) GetObjectExtra (d);
2800   gbp = (GBBlockPtr) data;
2801   if (gpp != NULL) {
2802     SetTitle (gpp->source, gbp->source);
2803     SetTitle (gpp->origin, gbp->origin);
2804     SetTitle (gpp->date, gbp->date);
2805     SetTitle (gpp->div, gbp->div);
2806     SetTitle (gpp->taxonomy, gbp->taxonomy);
2807     for (head = NULL, vnp = gbp->keywords; vnp != NULL; vnp = vnp->next) {
2808       str = (CharPtr) vnp->data.ptrvalue;
2809       if (StringICmp (str, "HTGS_DRAFT") != 0 &&
2810           StringICmp (str, "HTGS_FULLTOP") != 0 &&
2811           StringICmp (str, "HTGS_ACTIVEFIN") != 0 &&
2812           StringICmp (str, "HTGS_CANCELLED") != 0 &&
2813           StringICmp (str, "TPA:EXPERIMENTAL") != 0 &&
2814           StringICmp (str, "TPA:INFERENTIAL") != 0 &&
2815           StringICmp (str, "TPA:REASSEMBLY") != 0 &&
2816           StringICmp (str, "BARCODE") != 0) {
2817         ValNodeCopyStr (&head, 0, str);
2818       }
2819     }
2820     PointerToDialog (gpp->kywds, head);
2821     ValNodeFreeData (head);
2822     PointerToDialog (gpp->xaccns, gbp->extra_accessions);
2823     PointerToDialog (gpp->entryDate, gbp->entry_date);
2824     isDraft = FALSE;
2825     for (vnp = gbp->keywords; vnp != NULL; vnp = vnp->next) {
2826       if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_DRAFT") == 0) {
2827         isDraft = TRUE;
2828       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_FULLTOP") == 0) {
2829         isFulltop = TRUE;
2830       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_ACTIVEFIN") == 0) {
2831         isActivefin = TRUE;
2832       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_CANCELLED") == 0) {
2833         isCancelled = TRUE;
2834       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:EXPERIMENTAL") == 0 ||
2835                  StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA_EXPERIMENTAL") == 0) {
2836         isExperimental = TRUE;
2837       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:INFERENTIAL") == 0 ||
2838                  StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA_INFERENTIAL") == 0) {
2839         isInferential = TRUE;
2840       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:REASSEMBLY") == 0 ||
2841                  StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA_REASSEMBLY") == 0) {
2842         isReassembly = TRUE;
2843       } else if (StringICmp ((CharPtr) vnp->data.ptrvalue, "BARCODE") == 0) {
2844         isBarcode = TRUE;
2845       }
2846     }
2847     SafeSetStatus (gpp->htgsDraft, isDraft);
2848     SafeSetStatus (gpp->htgsFulltop, isFulltop);
2849     SafeSetStatus (gpp->htgsActivefin, isActivefin);
2850     SafeSetStatus (gpp->htgsCancelled, isCancelled);
2851     SafeSetStatus (gpp->tpaExperimental, isExperimental);
2852     SafeSetStatus (gpp->tpaInferential, isInferential);
2853     SafeSetStatus (gpp->tpaReassembly, isReassembly);
2854     SafeSetStatus (gpp->barCode, isBarcode);
2855   }
2856 }
2857 
2858 static Pointer GenBankPageToGBBlockPtr (DialoG d)
2859 
2860 {
2861   GBBlockPtr      gbp;
2862   GenBankPagePtr  gpp;
2863   Boolean         noActivefin;
2864   Boolean         noCancelled;
2865   Boolean         noDraft;
2866   Boolean         noFulltop;
2867   Boolean         noExperimental;
2868   Boolean         noInferential;
2869   Boolean         noReassembly;
2870   Boolean         noBarcode;
2871   ValNodePtr      keywords1 = NULL;
2872   ValNodePtr      keywords2 = NULL;
2873   ValNodePtr      vnp;
2874 
2875   gbp = NULL;
2876   gpp = (GenBankPagePtr) GetObjectExtra (d);
2877   if (gpp != NULL) {
2878     gbp = GBBlockNew ();
2879     if (gbp != NULL) {
2880       gbp->source = SaveStringFromText (gpp->source);
2881       gbp->origin = SaveStringFromText (gpp->origin);
2882       gbp->date = SaveStringFromText (gpp->date);
2883       gbp->div = SaveStringFromText (gpp->div);
2884       gbp->taxonomy = SaveStringFromTextAndStripNewlines (gpp->taxonomy);
2885       keywords1 = DialogToPointer (gpp->kywds);
2886       gbp->extra_accessions = DialogToPointer (gpp->xaccns);
2887       gbp->entry_date = DialogToPointer (gpp->entryDate);
2888       if (GetStatus (gpp->htgsDraft)) {
2889         noDraft = TRUE;
2890         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2891           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_DRAFT") == 0) {
2892             noDraft = FALSE;
2893           }
2894         }
2895         if (noDraft) {
2896           ValNodeCopyStr (&keywords2, 0, "HTGS_DRAFT");
2897         }
2898       }
2899       if (GetStatus (gpp->htgsFulltop)) {
2900         noFulltop = TRUE;
2901         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2902           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_FULLTOP") == 0) {
2903             noFulltop = FALSE;
2904           }
2905         }
2906         if (noFulltop) {
2907           ValNodeCopyStr (&keywords2, 0, "HTGS_FULLTOP");
2908         }
2909       }
2910       if (GetStatus (gpp->htgsActivefin)) {
2911         noActivefin = TRUE;
2912         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2913           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_ACTIVEFIN") == 0) {
2914             noActivefin = FALSE;
2915           }
2916         }
2917         if (noActivefin) {
2918           ValNodeCopyStr (&keywords2, 0, "HTGS_ACTIVEFIN");
2919         }
2920       }
2921       if (GetStatus (gpp->htgsCancelled)) {
2922         noCancelled = TRUE;
2923         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2924           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_CANCELLED") == 0) {
2925             noCancelled = FALSE;
2926           }
2927         }
2928         if (noCancelled) {
2929           ValNodeCopyStr (&keywords2, 0, "HTGS_CANCELLED");
2930         }
2931       }
2932       if (GetStatus (gpp->tpaExperimental)) {
2933         noExperimental = TRUE;
2934         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2935           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:EXPERIMENTAL") == 0) {
2936             noExperimental = FALSE;
2937           }
2938         }
2939         if (noExperimental) {
2940           ValNodeCopyStr (&keywords2, 0, "TPA:experimental");
2941         }
2942       }
2943       if (GetStatus (gpp->tpaInferential)) {
2944         noInferential = TRUE;
2945         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2946           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:INFERENTIAL") == 0) {
2947             noInferential = FALSE;
2948           }
2949         }
2950         if (noInferential) {
2951           ValNodeCopyStr (&keywords2, 0, "TPA:inferential");
2952         }
2953       }
2954       if (GetStatus (gpp->tpaReassembly)) {
2955         noReassembly = TRUE;
2956         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2957           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:REASSEMBLY") == 0) {
2958             noReassembly = FALSE;
2959           }
2960         }
2961         if (noReassembly) {
2962           ValNodeCopyStr (&keywords2, 0, "TPA:reassembly");
2963         }
2964       }
2965       if (GetStatus (gpp->barCode)) {
2966         noBarcode = TRUE;
2967         for (vnp = keywords1; vnp != NULL; vnp = vnp->next) {
2968           if (StringICmp ((CharPtr) vnp->data.ptrvalue, "BARCODE") == 0) {
2969             noBarcode = FALSE;
2970           }
2971         }
2972         if (noBarcode) {
2973           ValNodeCopyStr (&keywords2, 0, "BARCODE");
2974         }
2975       }
2976       gbp->keywords = ValNodeLink (&keywords2, keywords1);
2977     }
2978   }
2979   return (Pointer) gbp;
2980 }
2981 
2982 static void DeleteKeywordProc (ButtoN b)
2983 
2984 {
2985   GenBankPagePtr  gpp;
2986 
2987   gpp = (GenBankPagePtr) GetObjectExtra (b);
2988   if (gpp != NULL) {
2989     PointerToDialog (gpp->kywds, NULL);
2990     SafeSetStatus (gpp->htgsDraft, FALSE);
2991     SafeSetStatus (gpp->htgsFulltop, FALSE);
2992     SafeSetStatus (gpp->htgsActivefin, FALSE);
2993     SafeSetStatus (gpp->htgsCancelled, FALSE);
2994     SafeSetStatus (gpp->tpaExperimental, FALSE);
2995     SafeSetStatus (gpp->tpaInferential, FALSE);
2996     SafeSetStatus (gpp->tpaReassembly, FALSE);
2997     SafeSetStatus (gpp->barCode, FALSE);
2998   }
2999 }
3000 
3001 static DialoG CreateGenBankDialog (GrouP h, CharPtr title, ValNodePtr sdp, GenBankFormPtr gfp)
3002 
3003 {
3004   ButtoN          b;
3005   GrouP           f1, f2, f3, f4, f5;
3006   GBBlockPtr      gbp;
3007   Boolean         genome;
3008   GenBankPagePtr  gpp;
3009   Boolean         internal;
3010   GrouP           m;
3011   GrouP           p;
3012   GrouP           s;
3013   Boolean         showKeywords;
3014   ValNodePtr      vnp;
3015 
3016   p = HiddenGroup (h, 1, 0, NULL);
3017   SetGroupSpacing (p, 10, 10);
3018 
3019   gpp = (GenBankPagePtr) MemNew (sizeof (GenBankPage));
3020   if (gpp) {
3021 
3022     SetObjectExtra (p, gpp, StdCleanupExtraProc);
3023     gpp->dialog = (DialoG) p;
3024     gpp->todialog = GBBlockPtrToGenBankPage;
3025     gpp->fromdialog = GenBankPageToGBBlockPtr;
3026     gpp->testdialog = NULL;
3027 
3028     if (title != NULL && title [0] != '\0') {
3029       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
3030     } else {
3031       s = HiddenGroup (p, 0, -2, NULL);
3032     }
3033     m = HiddenGroup (s, -1, 0, NULL);
3034     /*
3035     SetGroupSpacing (m, 10, 10);
3036     */
3037 
3038     gbp = NULL;
3039     if (sdp != NULL && sdp->choice == Seq_descr_genbank && sdp->data.ptrvalue != NULL) {
3040       gbp = (GBBlockPtr) sdp->data.ptrvalue;
3041     }
3042     internal = (Boolean) (GetAppProperty ("InternalNcbiSequin") != NULL);
3043     genome = (Boolean) (GetAppProperty ("GenomeCenterSequin") != NULL);
3044 
3045     f1 = HiddenGroup (m, 1, 0, NULL);
3046 
3047     if ((! genome) || (gbp != NULL && gbp->div != NULL)) {
3048       StaticPrompt (f1, "Division", 0, 0, programFont, 'c');
3049       gpp->div = DialogText (f1, "", 15, NULL);
3050     }
3051 
3052     if (internal || (gbp != NULL && gbp->origin != NULL)) {
3053       StaticPrompt (f1, "Origin", 0, 0, programFont, 'c');
3054       gpp->origin = DialogText (f1, "", 15, NULL);
3055     }
3056 
3057     if (internal || (gbp != NULL && gbp->date != NULL)) {
3058       StaticPrompt (f1, "(Old Date)", 0, 0, programFont, 'c');
3059       gpp->date = DialogText (f1, "", 15, NULL);
3060     }
3061 
3062     if (internal || (gbp != NULL && gbp->source != NULL)) {
3063       StaticPrompt (f1, "Source", 0, 0, programFont, 'c');
3064       gpp->source = DialogText (f1, "", 15, NULL);
3065     }
3066 
3067     if (internal || (gbp != NULL && gbp->taxonomy != NULL)) {
3068       StaticPrompt (f1, "Taxonomy", 0, 0, programFont, 'c');
3069       gpp->taxonomy = ScrollText (f1, 15, 5, programFont, TRUE, NULL);
3070     }
3071 
3072     f3 = HiddenGroup (m, 0, 5, NULL);
3073     if (internal || genome || (gbp != NULL && gbp->extra_accessions != NULL)) {
3074       StaticPrompt (f3, "Secondary Accessions", 0, 0, programFont, 'c');
3075       gpp->xaccns = CreateVisibleStringDialog (f3, 3, -1, 15);
3076       if (internal || genome) {
3077         gfp->gbppxaccns = gpp->xaccns;
3078         gfp->xaccnstohistory = CheckBox (f3, "Copy to Bioseq-history.replaces", NULL);
3079         if (! internal) {
3080           SetStatus (gfp->xaccnstohistory, TRUE);
3081           Hide (gfp->xaccnstohistory);
3082         }
3083         gfp->xleaveoldhistory = CheckBox (f3, "Retain old Bioseq-history.replaces", NULL);
3084       }
3085     }
3086 
3087     b = NULL;
3088     f2 = HiddenGroup (m, 0, 3, NULL);
3089     showKeywords = FALSE;
3090     if (gbp != NULL && gbp->keywords != NULL) {
3091       vnp = gbp->keywords;
3092       if (vnp->next != NULL ||
3093           StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_DRAFT") != 0 ||
3094           StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_FULLTOP") != 0 ||
3095           StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_ACTIVEFIN") != 0 ||
3096           StringICmp ((CharPtr) vnp->data.ptrvalue, "HTGS_CANCELLED") != 0 ||
3097           StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:EXPERIMENTAL") != 0 ||
3098           StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:INFERENTIAL") != 0 ||
3099           StringICmp ((CharPtr) vnp->data.ptrvalue, "TPA:REASSEMBLY") != 0 ||
3100           StringICmp ((CharPtr) vnp->data.ptrvalue, "BARCODE") != 0) {
3101         showKeywords = TRUE;
3102       }
3103     }
3104     if (internal || showKeywords) {
3105       StaticPrompt (f2, "Keywords", 0, 0, programFont, 'c');
3106       gpp->kywds = CreateVisibleStringDialog (f2, 3, -1, 15);
3107     }
3108     if (internal || genome || (gbp != NULL && gbp->keywords != NULL)) {
3109       f5 = HiddenGroup (f2, 2, 0, NULL);
3110       gpp->htgsDraft = CheckBox (f5, "HTGS_DRAFT", NULL);
3111       gpp->htgsFulltop = CheckBox (f5, "HTGS_FULLTOP", NULL);
3112       gpp->htgsActivefin = CheckBox (f5, "HTGS_ACTIVEFIN", NULL);
3113       gpp->htgsCancelled = CheckBox (f5, "HTGS_CANCELLED", NULL);
3114       gpp->tpaExperimental = CheckBox (f5, "TPA:EXPERIMENTAL", NULL);
3115       gpp->tpaInferential = CheckBox (f5, "TPA:INFERENTIAL", NULL);
3116       gpp->tpaReassembly = CheckBox (f5, "TPA:REASSEMBLY", NULL);
3117       gpp->barCode = CheckBox (f5, "BARCODE", NULL);
3118     }
3119     if (internal) {
3120       b = PushButton (m, "Delete All Keywords", DeleteKeywordProc);
3121       SetObjectExtra (b, gpp, NULL);
3122     }
3123 
3124     f4 = HiddenGroup (m, 2, 0, NULL);
3125     if (internal || (gbp != NULL && gbp->entry_date != NULL)) {
3126       gpp->entryDate = CreateDateDialog (f4, "");
3127     }
3128 
3129     AlignObjects (ALIGN_CENTER, (HANDLE) f1, (HANDLE) f2, (HANDLE) f3,
3130                   (HANDLE) f4, (HANDLE) b, NULL);
3131   }
3132 
3133   return (DialoG) p;
3134 }
3135 
3136 static void GenBankFormMessage (ForM f, Int2 mssg)
3137 
3138 {
3139   GenBankFormPtr  gfp;
3140 
3141   gfp = (GenBankFormPtr) GetObjectExtra (f);
3142   if (gfp != NULL) {
3143     switch (mssg) {
3144       case VIB_MSG_CLOSE :
3145         Remove (f);
3146         break;
3147       case VIB_MSG_CUT :
3148         StdCutTextProc (NULL);
3149         break;
3150       case VIB_MSG_COPY :
3151         StdCopyTextProc (NULL);
3152         break;
3153       case VIB_MSG_PASTE :
3154         StdPasteTextProc (NULL);
3155         break;
3156       case VIB_MSG_DELETE :
3157         StdDeleteTextProc (NULL);
3158         break;
3159       default :
3160         if (gfp->appmessage != NULL) {
3161           gfp->appmessage (f, mssg);
3162         }
3163         break;
3164     }
3165   }
3166 }
3167 
3168 extern ForM CreateGenBankForm (Int2 left, Int2 top, CharPtr title,
3169                                ValNodePtr sdp, SeqEntryPtr sep,
3170                                FormActnFunc actproc)
3171 
3172 {
3173   ButtoN             b;
3174   GrouP              c;
3175   GrouP              g;
3176   GenBankFormPtr     gfp;
3177   StdEditorProcsPtr  sepp;
3178   WindoW             w;
3179 
3180   w = NULL;
3181   gfp = (GenBankFormPtr) MemNew (sizeof (GenBankForm));
3182   if (gfp != NULL) {
3183     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
3184     SetObjectExtra (w, gfp, StdDescFormCleanupProc);
3185     gfp->form = (ForM) w;
3186     gfp->actproc = actproc;
3187     gfp->formmessage = GenBankFormMessage;
3188 
3189 #ifndef WIN_MAC
3190     CreateStdEditorFormMenus (w);
3191 #endif
3192 
3193     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3194     if (sepp != NULL) {
3195       SetActivate (w, sepp->activateForm);
3196       gfp->appmessage = sepp->handleMessages;
3197     }
3198 
3199     g = HiddenGroup (w, -1, 0, NULL);
3200     gfp->xaccnstohistory = NULL;
3201     gfp->xleaveoldhistory = NULL;
3202     gfp->gbppxaccns = NULL;
3203     gfp->data = CreateGenBankDialog (g, NULL, sdp, gfp);
3204 
3205     c = HiddenGroup (w, 2, 0, NULL);
3206     b = PushButton (c, "Accept", StdAcceptFormButtonProc);
3207     SetObjectExtra (b, gfp, NULL);
3208     PushButton (c, "Cancel", StdCancelButtonProc);
3209     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
3210     RealizeWindow (w);
3211   }
3212   return (ForM) w;
3213 }
3214 
3215 static Boolean GetLowestStackSeqEntryForGBB (GatherContextPtr gcp)
3216 
3217 {
3218   BaseFormPtr  bfp;
3219   Int2         i;
3220 
3221   if (gcp == NULL) return TRUE;
3222   bfp = (BaseFormPtr) gcp->userdata;
3223   if (bfp == NULL) return TRUE;
3224   if (gcp->gatherstack != NULL && gcp->numstack > 0) {
3225     for (i = 0; i < gcp->numstack; i++) {
3226       if (gcp->gatherstack [i].itemtype == OBJ_BIOSEQ ||
3227           gcp->gatherstack [i].itemtype == OBJ_BIOSEQSET) {
3228         bfp->input_itemID = gcp->gatherstack [i].itemID;
3229         bfp->input_itemtype = gcp->gatherstack [i].itemtype;
3230       }
3231     }
3232   }
3233   return FALSE;
3234 }
3235 
3236 static Boolean ParseSecAccessionRange (
3237   CharPtr accn,
3238   CharPtr prefix,
3239   Int4Ptr startp,
3240   Int4Ptr stopp,
3241   Int2Ptr digitsp
3242 )
3243 
3244 {
3245   Char      ch;
3246   Int2      digits;
3247   CharPtr   ptr, tmp;
3248   Int4      start, stop;
3249   long int  val;
3250 
3251   if (StringHasNoText (accn)) return FALSE;
3252   if (prefix == NULL || startp == NULL || stopp == NULL || digitsp == NULL) return FALSE;
3253 
3254   ptr = accn;
3255   ch = *ptr;
3256   while (IS_ALPHA (ch)) {
3257     *prefix = ch;
3258     prefix++;
3259     ptr++;
3260     ch = *ptr;
3261   }
3262   *prefix = '\0';
3263 
3264   tmp = StringChr (ptr, '-');
3265   if (tmp == NULL) return FALSE;
3266   *tmp = '\0';
3267   tmp++;
3268 
3269   if (sscanf (ptr, "%ld", &val) != 1 || val < 1) return FALSE;
3270   start = (Int4) val;
3271 
3272   digits = 0;
3273   while (IS_DIGIT (ch)) {
3274     digits++;
3275     ptr++;
3276     ch = *ptr;
3277   }
3278 
3279   ptr = tmp;
3280   ch = *ptr;
3281   while (IS_ALPHA (ch)) {
3282     ptr++;
3283     ch = *ptr;
3284   }
3285 
3286   if (sscanf (ptr, "%ld", &val) != 1 || val < 1) return FALSE;
3287   stop = (Int4) val;
3288 
3289   *startp = start;
3290   *stopp = stop;
3291   *digitsp = digits;
3292 
3293   return TRUE;
3294 }
3295 
3296 static void ExpandSecondaries (SeqDescrPtr sdp, Pointer userdata)
3297 
3298 {
3299   CharPtr     accn;
3300   ValNodePtr  curr, last, next, vnp;
3301   Int2        digits, j;
3302   GBBlockPtr  gbp;
3303   Int4        idx;
3304   Char        numbers [32];
3305   Char        prefix [16];
3306   Int4        start, stop;
3307   Char        tmp [64];
3308 
3309   if (sdp == NULL || sdp->choice != Seq_descr_genbank) return;
3310   gbp = (GBBlockPtr) sdp->data.ptrvalue;
3311   if (gbp == NULL) return;
3312 
3313   vnp = gbp->extra_accessions;
3314   while (vnp != NULL) {
3315     next = vnp->next;
3316     last = vnp;
3317     accn = (CharPtr) vnp->data.ptrvalue;
3318     if (StringChr (accn, '-') != NULL) {
3319       if (ParseSecAccessionRange (accn, prefix, &start, &stop, &digits)) {
3320         for (idx = start; idx <= stop; idx++) {
3321           sprintf (numbers, "%*ld", digits, (long) idx);
3322           for (j = 0; j < digits && numbers [j] != '\0'; j++) {
3323             if (numbers [j] == ' ') {
3324               numbers [j] = '0';
3325             }
3326           }
3327           StringCpy (tmp, prefix);
3328           StringCat (tmp, numbers);
3329           if (idx == start) {
3330             vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
3331             vnp->data.ptrvalue = StringSave (tmp);
3332           } else {
3333             curr = ValNodeCopyStr (NULL, 0, tmp);
3334             if (curr != NULL) {
3335               curr->next = last->next;
3336               last->next = curr;
3337               last = curr;
3338             }
3339           }
3340         }
3341       }
3342     }
3343     vnp = next;
3344   }
3345 }
3346 
3347 static void GenBankFormActnProc (ForM f)
3348 
3349 {
3350   BioseqPtr       bsp;
3351   Boolean         changehist;
3352   GenBankFormPtr  gfp;
3353   SeqHistPtr      hist;
3354   Char            prefix [20];
3355   SeqEntryPtr     sep;
3356   SeqIdPtr        sip;
3357   TextSeqIdPtr    tsip;
3358   ValNodePtr      tmp;
3359   ValNodePtr      vnp;
3360   Uint4           whichdb;
3361 
3362   gfp = (GenBankFormPtr) GetObjectExtra (f);
3363   if (gfp != NULL) {
3364     vnp = NULL;
3365     changehist = (Boolean) (gfp->xaccnstohistory != NULL &&
3366                             GetStatus (gfp->xaccnstohistory));
3367     if (changehist) {
3368       vnp = DialogToPointer (gfp->gbppxaccns);
3369     }
3370     if (DescFormReplaceWithoutUpdateProc (f)) {
3371       GetRidOfEmptyFeatsDescStrings (gfp->input_entityID, NULL);
3372       if (GetAppProperty ("InternalNcbiSequin") != NULL) {
3373         ExtendGeneFeatIfOnMRNA (gfp->input_entityID, NULL);
3374       }
3375       if (changehist) {
3376         GatherItem (gfp->input_entityID, gfp->input_itemID, gfp->input_itemtype,
3377                     (Pointer) gfp, GetLowestStackSeqEntryForGBB);
3378         bsp = GetBioseqGivenIDs (gfp->input_entityID, gfp->input_itemID, gfp->input_itemtype);
3379         if (bsp != NULL) {
3380           hist = bsp->hist;
3381           if (hist != NULL) {
3382             if (! GetStatus (gfp->xleaveoldhistory)) {
3383               hist->replace_ids = SeqIdSetFree (hist->replace_ids);
3384             }
3385           } else {
3386             hist = SeqHistNew ();
3387             bsp->hist = hist;
3388           }
3389           if (hist != NULL && vnp != NULL) {
3390             for (tmp = vnp; tmp != NULL; tmp = tmp->next) {
3391               sip = ValNodeNew (hist->replace_ids);
3392               if (hist->replace_ids == NULL) {
3393                 hist->replace_ids = sip;
3394               }
3395               if (sip != NULL) {
3396                 tsip = TextSeqIdNew ();
3397                 StringNCpy_0 (prefix, (CharPtr) tmp->data.ptrvalue, sizeof (prefix));
3398                 /*
3399                 ptr = &(prefix [0]);
3400                 ch = *ptr;
3401                 while (ch != '\0' && IS_ALPHA (ch)) {
3402                   ptr++;
3403                   ch = *ptr;
3404                 }
3405                 *ptr = '\0';
3406                 */
3407                 whichdb = WHICH_db_accession (prefix);
3408                 if (ACCN_IS_EMBL (whichdb)) {
3409                   sip->choice = SEQID_EMBL;
3410                 } else if (ACCN_IS_DDBJ (whichdb)) {
3411                   sip->choice = SEQID_DDBJ;
3412                 } else {
3413                   sip->choice = SEQID_GENBANK;
3414                 }
3415                 sip->data.ptrvalue = (Pointer) tsip;
3416                 if (tsip != NULL) {
3417                   tsip->accession = StringSave (tmp->data.ptrvalue);
3418                 }
3419               }
3420             }
3421           }
3422           if (hist != NULL) {
3423             if (hist->assembly == NULL && hist->replace_date == NULL &&
3424                 hist->replace_ids == NULL && hist->replaced_by_date == NULL &&
3425                 hist->replaced_by_ids == NULL && hist->deleted_date == NULL &&
3426                 (! hist->deleted)) {
3427               bsp->hist = SeqHistFree (bsp->hist);
3428             }
3429           }
3430         }
3431         ValNodeFreeData (vnp);
3432       }
3433       sep = GetTopSeqEntryForEntityID (gfp->input_entityID);
3434       VisitDescriptorsInSep (sep, NULL, ExpandSecondaries);
3435       ObjMgrSendMsg (OM_MSG_UPDATE, gfp->input_entityID,
3436                      gfp->input_itemID, gfp->input_itemtype);
3437     }
3438   }
3439 }
3440 
3441 extern Int2 LIBCALLBACK GenBankGenFunc (Pointer data)
3442 
3443 {
3444   BioseqPtr         bsp;
3445   GenBankFormPtr    gfp;
3446   OMProcControlPtr  ompcp;
3447   OMUserDataPtr     omudp;
3448   ValNodePtr        sdp;
3449   SeqEntryPtr       sep;
3450   WindoW            w;
3451 
3452   ompcp = (OMProcControlPtr) data;
3453   sdp = NULL;
3454   sep = NULL;
3455   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
3456   switch (ompcp->input_itemtype) {
3457     case OBJ_SEQDESC :
3458       sdp = (ValNodePtr) ompcp->input_data;
3459       if (sdp != NULL && sdp->choice != Seq_descr_genbank) {
3460         return OM_MSG_RET_ERROR;
3461       }
3462       break;
3463     case OBJ_BIOSEQ :
3464       break;
3465     case OBJ_BIOSEQSET :
3466       break;
3467     case 0 :
3468       break;
3469     default :
3470       return OM_MSG_RET_ERROR;
3471   }
3472   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
3473                                 ompcp->input_itemtype, ompcp->proc->procid);
3474   if (omudp != NULL) {
3475     gfp = (GenBankFormPtr) omudp->userdata.ptrvalue;
3476     if (gfp != NULL) {
3477       Select (gfp->form);
3478     }
3479     return OM_MSG_RET_DONE;
3480   }
3481   sep = GetTopSeqEntryForEntityID (ompcp->input_entityID);
3482   w = (WindoW) CreateGenBankForm (-50, -33, "GenBank Block", sdp, sep,
3483                                   GenBankFormActnProc);
3484   gfp = (GenBankFormPtr) GetObjectExtra (w);
3485   if (gfp != NULL) {
3486     gfp->input_entityID = ompcp->input_entityID;
3487     gfp->input_itemID = ompcp->input_itemID;
3488     gfp->input_itemtype = ompcp->input_itemtype;
3489     gfp->this_itemtype = OBJ_SEQDESC;
3490     gfp->this_subtype = Seq_descr_genbank;
3491     gfp->procid = ompcp->proc->procid;
3492     gfp->proctype = ompcp->proc->proctype;
3493     gfp->userkey = OMGetNextUserKey ();
3494 
3495     /* Don't allow history update for proteins */
3496 
3497     bsp = GetBioseqGivenIDs (gfp->input_entityID,
3498                              gfp->input_itemID,
3499                              gfp->input_itemtype);
3500     if (bsp != NULL && ISA_aa (bsp->mol)) {
3501       SetStatus (gfp->xaccnstohistory, FALSE);
3502       SafeDisable (gfp->xaccnstohistory);
3503     }
3504   
3505     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
3506                                    OMPROC_EDIT, gfp->userkey);
3507     if (omudp != NULL) {
3508       omudp->userdata.ptrvalue = (Pointer) gfp;
3509       omudp->messagefunc = StdVibrantEditorMsgFunc;
3510     }
3511     SendMessageToDialog (gfp->data, VIB_MSG_INIT);
3512     if (sdp != NULL) {
3513       PointerToDialog (gfp->data, (Pointer) sdp->data.ptrvalue);
3514       SetClosestParentIfDuplicating ((BaseFormPtr) gfp);
3515     }
3516   }
3517   Show (w);
3518   Select (w);
3519   return OM_MSG_RET_DONE;
3520 }
3521 
3522 
3523 typedef struct visstrpage {
3524   DIALOG_MESSAGE_BLOCK
3525   TexT          title;
3526 } VisStrPage, PNTR VisStrPagePtr;
3527 
3528 typedef struct visstrform {
3529   DESCRIPTOR_FORM_BLOCK
3530   Uint1         subtype;
3531 } VisStrForm, PNTR VisStrFormPtr;
3532 
3533 static void CharPtrToVisStrPage (DialoG d, Pointer data)
3534 
3535 {
3536   CharPtr        title;
3537   VisStrPagePtr  vpp;
3538 
3539   vpp = (VisStrPagePtr) GetObjectExtra (d);
3540   title = (CharPtr) data;
3541   if (vpp != NULL) {
3542     SetTitle (vpp->title, title);
3543   }
3544 }
3545 
3546 static Pointer VisStrPageToCharPtr (DialoG d)
3547 
3548 {
3549   CharPtr        title;
3550   VisStrPagePtr  vpp;
3551   ValNodePtr     find_list = NULL;
3552 
3553   title = NULL;
3554   vpp = (VisStrPagePtr) GetObjectExtra (d);
3555   if (vpp != NULL) {
3556     title = SaveStringFromText (vpp->title);
3557     title = StripNewlines (title);
3558     SpecialCharFindWithContext (&title, &find_list, NULL, NULL);
3559     FixSpecialCharactersForStringsInList (find_list, "Special characters are not permitted.", TRUE);      
3560     if (find_list != NULL) {
3561       PointerToDialog (d, title);
3562       find_list = FreeContextList (find_list);
3563     }
3564   }
3565   return (Pointer) title;
3566 }
3567 
3568 static void VisStrDialogMessage (DialoG d, Int2 mssg)
3569 
3570 {
3571   VisStrPagePtr  vpp;
3572 
3573   vpp = (VisStrPagePtr) GetObjectExtra (d);
3574   if (vpp != NULL) {
3575     switch (mssg) {
3576       case VIB_MSG_ENTER :
3577         Select (vpp->title);
3578         break;
3579       default :
3580         break;
3581     }
3582   }
3583 }
3584 
3585 static DialoG CreateVisStrDialog (GrouP h, CharPtr title, Uint2 subtype)
3586 
3587 {
3588   GrouP          f;
3589   CharPtr        label;
3590   GrouP          m;
3591   GrouP          p;
3592   GrouP          s;
3593   VisStrPagePtr  vpp;
3594 
3595   p = HiddenGroup (h, 1, 0, NULL);
3596   SetGroupSpacing (p, 10, 10);
3597 
3598   vpp = (VisStrPagePtr) MemNew (sizeof (VisStrPage));
3599   if (vpp) {
3600 
3601     SetObjectExtra (p, vpp, StdCleanupExtraProc);
3602     vpp->dialog = (DialoG) p;
3603     vpp->todialog = CharPtrToVisStrPage;
3604     vpp->fromdialog = VisStrPageToCharPtr;
3605     vpp->testdialog = NULL;
3606     vpp->dialogmessage = VisStrDialogMessage;
3607 
3608     if (title != NULL && title [0] != '\0') {
3609       s = NormalGroup (p, 0, -2, title, systemFont, NULL);
3610     } else {
3611       s = HiddenGroup (p, 0, -2, NULL);
3612     }
3613     m = HiddenGroup (s, -1, 0, NULL);
3614     /*
3615     SetGroupSpacing (m, 10, 10);
3616     */
3617 
3618     f = HiddenGroup (m, 0, 2, NULL);
3619     if (subtype == Seq_descr_title) {
3620       label = "Title";
3621     } else if (subtype == Seq_descr_comment) {
3622       label = "Comment";
3623     } else if (subtype == Seq_descr_name) {
3624       label = "Name";
3625     } else if (subtype == Seq_descr_region) {
3626       label = "Region";
3627     } else {
3628       label = "Title";
3629     }
3630     StaticPrompt (f, label, 0, 0, programFont, 'c');
3631     vpp->title = ScrollText (f, 25, 15, programFont, TRUE, NULL);
3632   }
3633 
3634   return (DialoG) p;
3635 }
3636 
3637 static void VisStrFormMessage (ForM f, Int2 mssg)
3638 
3639 {
3640   VisStrFormPtr  vfp;
3641 
3642   vfp = (VisStrFormPtr) GetObjectExtra (f);
3643   if (vfp != NULL) {
3644     switch (mssg) {
3645       case VIB_MSG_ENTER :
3646         SendMessageToDialog (vfp->data, VIB_MSG_ENTER);
3647         break;
3648       case VIB_MSG_CLOSE :
3649         Remove (f);
3650         break;
3651       case VIB_MSG_CUT :
3652         StdCutTextProc (NULL);
3653         break;
3654       case VIB_MSG_COPY :
3655         StdCopyTextProc (NULL);
3656         break;
3657       case VIB_MSG_PASTE :
3658         StdPasteTextProc (NULL);
3659         break;
3660       case VIB_MSG_DELETE :
3661         StdDeleteTextProc (NULL);
3662         break;
3663       default :
3664         if (vfp->appmessage != NULL) {
3665           vfp->appmessage (f, mssg);
3666         }
3667         break;
3668     }
3669   }
3670 }
3671 
3672 
3673 static CharPtr citInCommentMsg =
3674 "This comment looks like it has citation references in [#] form.\n\
3675 You should put comments about references in the REMARK section by\n\
3676 double clicking on the reference and launching its editor.\n\
3677 Continue saving this comment?";
3678 
3679 
3680 typedef struct replacevisstr {
3681   Uint1       subtype;
3682   CharPtr     deleteThis;
3683   CharPtr     replaceWith;
3684   Boolean     replace_all;
3685 } ReplaceVisStrData, PNTR ReplaceVisStrPtr;
3686 
3687 static void ReplaceAllCallback (SeqDescrPtr sdp, Pointer data)
3688 
3689 {
3690   ReplaceVisStrPtr   rp;
3691 
3692   if ((rp = (ReplaceVisStrPtr) data) == NULL || sdp == NULL || sdp->choice != rp->subtype) {
3693     return;
3694   }
3695 
3696   if (StringCmp (sdp->data.ptrvalue, rp->deleteThis) == 0) {
3697     sdp->data.ptrvalue = MemFree (sdp->data.ptrvalue);
3698     sdp->data.ptrvalue = StringSave (rp->replaceWith);
3699   }
3700 }
3701 
3702 
3703 static void ReplaceAllVisibleStringsButtonProc (ButtoN b)
3704 {
3705   VisStrFormPtr vfp;
3706   Boolean       suspicious = FALSE;
3707   SeqEntryPtr   sep;
3708   ReplaceVisStrData rd; 
3709   SeqDescrPtr       sdp_orig;
3710   SeqMgrDescContext context;
3711 
3712   vfp = (VisStrFormPtr) GetObjectExtra (b);
3713   if (vfp == NULL) {
3714     return;
3715   }
3716 
3717   sep = GetTopSeqEntryForEntityID (vfp->input_entityID);
3718 
3719   rd.subtype = vfp->subtype;
3720   rd.replaceWith = DialogToPointer (vfp->data);
3721   if (rd.replaceWith == NULL || StringHasNoText (rd.replaceWith)) {
3722     Message (MSG_ERROR, "Must supply text!");
3723     rd.replaceWith = MemFree (rd.replaceWith);
3724     return;
3725   }
3726 
3727   sdp_orig = SeqMgrGetDesiredDescriptor (vfp->input_entityID, NULL, vfp->input_itemID, 0, NULL, &context);
3728   if (sdp_orig == NULL || sdp_orig->choice != vfp->subtype) {
3729     Message (MSG_ERROR, "Unable to find original descriptor!");
3730     Remove (vfp->form);
3731     rd.replaceWith = MemFree (rd.replaceWith);
3732     return;
3733   }
3734   rd.deleteThis = StringSave (sdp_orig->data.ptrvalue);
3735 
3736   if (vfp->subtype == Seq_descr_comment) {
3737     suspicious = SerialNumberInString (rd.replaceWith);
3738   }
3739   if (suspicious) {
3740     if (Message (MSG_OKC, "%s", citInCommentMsg) == ANS_CANCEL) {
3741       rd.deleteThis = MemFree (rd.deleteThis);
3742       rd.replaceWith = MemFree (rd.replaceWith);
3743       return;
3744     }
3745   }
3746 
3747   VisitDescriptorsInSep (sep, &rd, ReplaceAllCallback);
3748   
3749   GetRidOfEmptyFeatsDescStrings (vfp->input_entityID, NULL);
3750   ObjMgrSetDirtyFlag (vfp->input_entityID, TRUE);
3751   ObjMgrSendMsg (OM_MSG_UPDATE, vfp->input_entityID,
3752                   vfp->input_itemID, vfp->input_itemtype);
3753   Remove (vfp->form);
3754 }
3755 
3756 
3757 extern ForM CreateVisStrForm (Int2 left, Int2 top, CharPtr title,
3758                               Uint2 subtype, FormActnFunc actproc, SeqDescrPtr sdp)
3759 
3760 {
3761   ButtoN             b;
3762   GrouP              c;
3763   GrouP              g;
3764   StdEditorProcsPtr  sepp;
3765   VisStrFormPtr      vfp;
3766   WindoW             w;
3767 
3768   w = NULL;
3769   vfp = (VisStrFormPtr) MemNew (sizeof (VisStrForm));
3770   if (vfp != NULL) {
3771     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
3772     SetObjectExtra (w, vfp, StdDescFormCleanupProc);
3773     vfp->form = (ForM) w;
3774     vfp->actproc = actproc;
3775     vfp->formmessage = VisStrFormMessage;
3776     vfp->subtype = (Uint1)subtype;
3777 
3778 #ifndef WIN_MAC
3779     CreateStdEditorFormMenus (w);
3780 #endif
3781 
3782     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
3783     if (sepp != NULL) {
3784       SetActivate (w, sepp->activateForm);
3785       vfp->appmessage = sepp->handleMessages;
3786     }
3787 
3788     g = HiddenGroup (w, -1, 0, NULL);
3789     vfp->data = CreateVisStrDialog (g, NULL, subtype);
3790 
3791     c = HiddenGroup (w, 3, 0, NULL);
3792 
3793     if (sdp == NULL) {
3794       b = PushButton (c, "Accept", StdAcceptFormButtonProc);
3795       SetObjectExtra (b, vfp, NULL);
3796     } else {
3797       b = PushButton (c, "Replace All", ReplaceAllVisibleStringsButtonProc);
3798       SetObjectExtra (b, vfp, NULL);
3799       b = PushButton (c, "Replace This", StdAcceptFormButtonProc);
3800       SetObjectExtra (b, vfp, NULL);
3801     }
3802 
3803     PushButton (c, "Cancel", StdCancelButtonProc);
3804     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
3805     RealizeWindow (w);
3806   }
3807   return (ForM) w;
3808 }
3809 
3810 static void VisStrDescFormActnProc (ForM f)
3811 
3812 {
3813   OMProcControl  ompc;
3814   CharPtr        str;
3815   Boolean        suspicious;
3816   VisStrFormPtr  vfp;
3817 
3818   vfp = (VisStrFormPtr) GetObjectExtra (f);
3819   if (vfp != NULL) {
3820     str = DialogToPointer (vfp->data);
3821     if (str == NULL || StringHasNoText (str)) {
3822       MemSet ((Pointer) &ompc, 0, sizeof (OMProcControl));
3823       ompc.do_not_reload_from_cache = TRUE;
3824       ompc.input_entityID = vfp->input_entityID;
3825       ompc.input_itemID = vfp->input_itemID;
3826       ompc.input_itemtype = vfp->input_itemtype;
3827       if (! DetachDataForProc (&ompc, FALSE)) {
3828         Message (MSG_ERROR, "DetachDataForProc failed");
3829       }
3830       GetRidOfEmptyFeatsDescStrings (vfp->input_entityID, NULL);
3831       ObjMgrSetDirtyFlag (vfp->input_entityID, TRUE);
3832       ObjMgrSendMsg (OM_MSG_UPDATE, vfp->input_entityID,
3833                      vfp->input_itemID, vfp->input_itemtype);
3834       MemFree (str);
3835       return;
3836     }
3837     suspicious = FALSE;
3838     if (vfp->subtype == Seq_descr_comment) {
3839       suspicious = SerialNumberInString (str);
3840     }
3841     MemFree (str);
3842     if (suspicious) {
3843       if (Message (MSG_OKC, "%s", citInCommentMsg) == ANS_CANCEL) {
3844         Remove (f);
3845         return;
3846       }
3847     }
3848     if (DescFormReplaceWithoutUpdateProc (f)) {
3849       GetRidOfEmptyFeatsDescStrings (vfp->input_entityID, NULL);
3850       if (GetAppProperty ("InternalNcbiSequin") != NULL) {
3851         ExtendGeneFeatIfOnMRNA (vfp->input_entityID, NULL);
3852       }
3853       ObjMgrSetDirtyFlag (vfp->input_entityID, TRUE);
3854       ObjMgrSendMsg (OM_MSG_UPDATE, vfp->input_entityID,
3855                      vfp->input_itemID, vfp->input_itemtype);
3856     }
3857   }
3858 }
3859 
3860 extern Int2 LIBCALLBACK VisStrGenFunc (Pointer data)
3861 
3862 {
3863   OMProcControlPtr  ompcp;
3864   OMUserDataPtr     omudp;
3865   ObjMgrProcPtr     proc;
3866   ValNodePtr        sdp;
3867   Uint2             subtype;
3868   VisStrFormPtr     vfp;
3869   WindoW            w;
3870 
3871   ompcp = (OMProcControlPtr) data;
3872   sdp = NULL;
3873   subtype = 0;
3874   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
3875   proc = ompcp->proc;
3876   switch (ompcp->input_itemtype) {
3877     case OBJ_SEQDESC :
3878       sdp = (ValNodePtr) ompcp->input_data;
3879       if (sdp != NULL &&
3880          (sdp->choice != Seq_descr_title &&
3881           sdp->choice != Seq_descr_comment &&
3882           sdp->choice != Seq_descr_name &&
3883           sdp->choice != Seq_descr_region)) {
3884         return OM_MSG_RET_ERROR;
3885       }
3886       subtype = sdp->choice;
3887       break;
3888     case OBJ_BIOSEQ :
3889       break;
3890     case OBJ_BIOSEQSET :
3891       break;
3892     case 0 :
3893       break;
3894     default :
3895       return OM_MSG_RET_ERROR;
3896   }
3897   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
3898                                 ompcp->input_itemtype, ompcp->proc->procid);
3899   if (omudp != NULL) {
3900     vfp = (VisStrFormPtr) omudp->userdata.ptrvalue;
3901     if (vfp != NULL) {
3902       Select (vfp->form);
3903     }
3904     return OM_MSG_RET_DONE;
3905   }
3906   if (sdp == NULL) {
3907     subtype = proc->subinputtype;
3908   }
3909   if (subtype == Seq_descr_title) {
3910       w = (WindoW) CreateVisStrForm (-50, -33, "Title",
3911                                      subtype, VisStrDescFormActnProc, sdp);
3912   } else if (subtype == Seq_descr_comment) {
3913       w = (WindoW) CreateVisStrForm (-50, -33, "Comment",
3914                                      subtype, VisStrDescFormActnProc, sdp);
3915   } else if (subtype == Seq_descr_name) {
3916       w = (WindoW) CreateVisStrForm (-50, -33, "Name",
3917                                      subtype, VisStrDescFormActnProc, sdp);
3918   } else if (subtype == Seq_descr_region) {
3919       w = (WindoW) CreateVisStrForm (-50, -33, "Region",
3920                                      subtype, VisStrDescFormActnProc, sdp);
3921   } else {
3922     return OM_MSG_RET_ERROR;
3923   }
3924   vfp = (VisStrFormPtr) GetObjectExtra (w);
3925   if (vfp != NULL) {
3926     vfp->input_entityID = ompcp->input_entityID;
3927     vfp->input_itemID = ompcp->input_itemID;
3928     vfp->input_itemtype = ompcp->input_itemtype;
3929     vfp->this_itemtype = OBJ_SEQDESC;
3930     vfp->this_subtype = subtype;
3931     vfp->procid = ompcp->proc->procid;
3932     vfp->proctype = ompcp->proc->proctype;
3933     vfp->userkey = OMGetNextUserKey ();
3934     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
3935                                    OMPROC_EDIT, vfp->userkey);
3936     if (omudp != NULL) {
3937       omudp->userdata.ptrvalue = (Pointer) vfp;
3938       omudp->messagefunc = StdVibrantEditorMsgFunc;
3939     }
3940     SendMessageToDialog (vfp->data, VIB_MSG_INIT);
3941     if (sdp != NULL) {
3942       PointerToDialog (vfp->data, (Pointer) sdp->data.ptrvalue);
3943       SetClosestParentIfDuplicating ((BaseFormPtr) vfp);
3944     }
3945   }
3946   Show (w);
3947   Select (w);
3948   return OM_MSG_RET_DONE;
3949 }
3950 
3951 #ifdef OS_UNIX_DARWIN
3952 /* avoid a namespace conflict with Carbon's DateTimeUtils.h */
3953 # define DateForm nlm_DateForm
3954 #endif
3955 
3956 typedef struct dateform {
3957   DESCRIPTOR_FORM_BLOCK
3958 } DateForm, PNTR DateFormPtr;
3959 
3960 static void DateFormMessage (ForM f, Int2 mssg)
3961 
3962 {
3963   DateFormPtr  dfp;
3964 
3965   dfp = (DateFormPtr) GetObjectExtra (f);
3966   if (dfp != NULL) {
3967     switch (mssg) {
3968       case VIB_MSG_CLOSE :
3969         Remove (f);
3970         break;
3971       case VIB_MSG_CUT :
3972         StdCutTextProc (NULL);
3973         break;
3974       case VIB_MSG_COPY :
3975         StdCopyTextProc (NULL);
3976         break;
3977       case VIB_MSG_PASTE :
3978         StdPasteTextProc (NULL);
3979         break;
3980       case VIB_MSG_DELETE :
3981         StdDeleteTextProc (NULL);
3982         break;
3983       default :
3984         if (dfp->appmessage != NULL) {
3985           dfp->appmessage (f, mssg);
3986         }
3987         break;
3988     }
3989   }
3990 }
3991 
3992 extern ForM CreateDateForm (Int2 left, Int2 top, CharPtr title,
3993                             FormActnFunc actproc)
3994 
3995 {
3996   ButtoN             b;
3997   GrouP              c;
3998   DateFormPtr        dfp;
3999   GrouP              g;
4000   StdEditorProcsPtr  sepp;
4001   WindoW             w;
4002 
4003   w = NULL;
4004   dfp = (DateFormPtr) MemNew (sizeof (DateForm));
4005   if (dfp != NULL) {
4006     w = FixedWindow (left, top, -10, -10, title, StdCloseWindowProc);
4007     SetObjectExtra (w, dfp, StdDescFormCleanupProc);
4008     dfp->form = (ForM) w;
4009     dfp->actproc = actproc;
4010     dfp->formmessage = DateFormMessage;
4011 
4012 #ifndef WIN_MAC
4013     CreateStdEditorFormMenus (w);
4014 #endif
4015 
4016     sepp = (StdEditorProcsPtr) GetAppProperty ("StdEditorForm");
4017     if (sepp != NULL) {
4018       SetActivate (w, sepp->activateForm);
4019       dfp->appmessage = sepp->handleMessages;
4020     }
4021 
4022     g = HiddenGroup (w, -1, 0, NULL);
4023     dfp->data = CreateDateDialog (g, NULL);
4024 
4025     c = HiddenGroup (w, 2, 0, NULL);
4026     b = PushButton (c, "Accept", StdAcceptFormButtonProc);
4027     SetObjectExtra (b, dfp, NULL);
4028     PushButton (c, "Cancel", StdCancelButtonProc);
4029     AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) c, NULL);
4030     RealizeWindow (w);
4031   }
4032   return (ForM) w;
4033 }
4034 
4035 extern Int2 LIBCALLBACK DateGenFunc (Pointer data)
4036 
4037 {
4038   DateFormPtr       dfp;
4039   Uint2             itemtype;
4040   OMProcControlPtr  ompcp;
4041   OMUserDataPtr     omudp;
4042   ObjMgrProcPtr     proc;
4043   ValNodePtr        sdp;
4044   CharPtr           title;
4045   Uint2             subtype;
4046   WindoW            w;
4047 
4048   ompcp = (OMProcControlPtr) data;
4049   sdp = NULL;
4050   itemtype = 0;
4051   subtype = 0;
4052   if (ompcp == NULL || ompcp->proc == NULL) return OM_MSG_RET_ERROR;
4053   title = "Date";
4054   proc = ompcp->proc;
4055   switch (ompcp->input_itemtype) {
4056     case OBJ_SEQDESC :
4057       sdp = (ValNodePtr) ompcp->input_data;
4058       if (sdp != NULL &&
4059           (sdp->choice != Seq_descr_create_date &&
4060           sdp->choice != Seq_descr_update_date)) {
4061         return OM_MSG_RET_ERROR;
4062       }
4063       itemtype = OBJ_SEQDESC;
4064       subtype = sdp->choice;
4065       break;
4066     case OBJ_BIOSEQ :
4067       break;
4068     case OBJ_BIOSEQSET :
4069       break;
4070     case 0 :
4071       break;
4072     default :
4073       return OM_MSG_RET_ERROR;
4074   }
4075   omudp = ItemAlreadyHasEditor (ompcp->input_entityID, ompcp->input_itemID,
4076                                 ompcp->input_itemtype, ompcp->proc->procid);
4077   if (omudp != NULL) {
4078     dfp = (DateFormPtr) omudp->userdata.ptrvalue;
4079     if (dfp != NULL) {
4080       Select (dfp->form);
4081     }
4082     return OM_MSG_RET_DONE;
4083   }
4084   if (sdp != NULL) {
4085     if (sdp->choice == Seq_descr_create_date) {
4086       title = "Create Date";
4087     } else {
4088       title = "Update Date";
4089     }
4090   } else {
4091     itemtype = proc->inputtype;
4092     subtype = proc->subinputtype;
4093     if (itemtype == OBJ_SEQDESC && subtype == Seq_descr_create_date) {
4094       title = "Create Date";
4095     } else if (itemtype == OBJ_SEQDESC && subtype == Seq_descr_update_date) {
4096       title = "Update Date";
4097     } else {
4098       return OM_MSG_RET_ERROR;
4099     }
4100   }
4101   w = (WindoW) CreateDateForm (-50, -33, title, StdDescFormActnProc);
4102   dfp = (DateFormPtr) GetObjectExtra (w);
4103   if (dfp != NULL) {
4104     dfp->input_entityID = ompcp->input_entityID;
4105     dfp->input_itemID = ompcp->input_itemID;
4106     dfp->input_itemtype = ompcp->input_itemtype;
4107     dfp->this_itemtype = itemtype;
4108     dfp->this_subtype = subtype;
4109     dfp->procid = ompcp->proc->procid;
4110     dfp->proctype = ompcp->proc->proctype;
4111     dfp->userkey = OMGetNextUserKey ();
4112     omudp = ObjMgrAddUserData (ompcp->input_entityID, ompcp->proc->procid,
4113                                    OMPROC_EDIT, dfp->userkey);
4114     if (omudp != NULL) {
4115       omudp->userdata.ptrvalue = (Pointer) dfp;
4116       omudp->messagefunc = StdVibrantEditorMsgFunc;
4117     }
4118     SendMessageToDialog (dfp->data, VIB_MSG_INIT);
4119     if (sdp != NULL) {
4120       PointerToDialog (dfp->data, (Pointer) sdp->data.ptrvalue);
4121       SetClosestParentIfDuplicating ((BaseFormPtr) dfp);
4122     }
4123   }
4124   Show (w);
4125   Select (w);
4126   return OM_MSG_RET_DONE;
4127 }
4128 
4129 
4130 
4131 
4132 
4133 
4134 
4135 
4136 
4137 
4138 
4139 
4140 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.