~ubuntu-branches/debian/experimental/ncbi-tools6/experimental

« back to all changes in this revision

Viewing changes to desktop/dlgutil2.c

  • Committer: Bazaar Package Importer
  • Author(s): Aaron M. Ucko
  • Date: 2008-07-14 19:43:15 UTC
  • mfrom: (2.1.12 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080714194315-ed44u9ek7txva2rz
Tags: 6.1.20080302-3
tools/readdb.c: enable madvise()-based code on all glibc (hence all
Debian) systems, not just Linux.  (Closes: #490437.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
*
30
30
* Version Creation Date:   1/22/95
31
31
*
32
 
* $Revision: 6.112 $
 
32
* $Revision: 6.186 $
33
33
*
34
34
* File Description: 
35
35
*
53
53
#include <objfeat.h>
54
54
#include <objseq.h>
55
55
#include <toasn3.h>
 
56
#include <explore.h>
 
57
#include <findrepl.h>
56
58
#ifdef WIN_MOTIF
57
59
#include <netscape.h>
58
60
#endif
99
101
  }
100
102
}
101
103
 
 
104
 
 
105
extern CharPtr StripNewlines (CharPtr str)
 
106
 
 
107
{
 
108
  Char     ch;
 
109
  size_t   len;
 
110
  CharPtr  ptr;
 
111
 
 
112
  if (str == NULL) return str;
 
113
  len = StringLen (str);
 
114
  if (len > 0) {
 
115
    ptr = str;
 
116
    ch = *ptr;
 
117
    while (ch != '\0') {
 
118
      if (ch < ' ') {
 
119
        *ptr = ' ';
 
120
      }
 
121
      ptr++;
 
122
      ch = *ptr;
 
123
    }
 
124
    TrimSpacesAroundString (str);
 
125
    if (StringHasNoText (str)) {
 
126
      str = MemFree (str);
 
127
    }
 
128
  } else {
 
129
    str = MemFree (str);
 
130
  }
 
131
  return str;
 
132
}
 
133
 
 
134
 
 
135
extern void NewlinesToTildes (CharPtr str)
 
136
 
 
137
{
 
138
  Uchar    ch;
 
139
  CharPtr  ptr;
 
140
 
 
141
  if (StringHasNoText (str)) return;
 
142
  ptr = str;
 
143
  ch = *ptr;
 
144
  while (ch != '\0') {
 
145
    if (ch < ' ') {
 
146
      *ptr = '~';
 
147
    }
 
148
    ptr++;
 
149
    ch = *ptr;
 
150
  }
 
151
}
 
152
 
 
153
 
102
154
static void DatePtrToDatePage (DialoG d, Pointer data)
103
155
 
104
156
{
999
1051
  ButtoN             PNTR boxes;
1000
1052
} FieldPage, PNTR FieldPagePtr;
1001
1053
 
1002
 
static Boolean ShouldBeAGBQual (SeqFeatPtr sfp, Int2 qual, Boolean allowProductGBQual)
 
1054
 
 
1055
static Boolean ShouldSuppressGBQual(Uint1 subtype, CharPtr qual_name)
 
1056
{
 
1057
  if (StringHasNoText (qual_name)) {
 
1058
    return FALSE;
 
1059
  }
 
1060
 
 
1061
  /* always suppress experiment and inference quals */
 
1062
  if (StringCmp (qual_name, "experiment") == 0 || StringCmp (qual_name, "inference") == 0) {
 
1063
    return TRUE;
 
1064
  }
 
1065
  
 
1066
  if (subtype == FEATDEF_ncRNA) {
 
1067
    if (StringCmp (qual_name, "product") == 0
 
1068
        || StringCmp (qual_name, "ncRNA_class") == 0) {
 
1069
      return TRUE;
 
1070
    }
 
1071
  } else if (subtype == FEATDEF_tmRNA) {
 
1072
    if (StringCmp (qual_name, "product") == 0
 
1073
        || StringCmp (qual_name, "tag_peptide") == 0) {
 
1074
      return TRUE;
 
1075
    }
 
1076
  } else if (subtype == FEATDEF_otherRNA) {
 
1077
    if (StringCmp (qual_name, "product") == 0) {
 
1078
      return TRUE;
 
1079
    }
 
1080
  }
 
1081
  return FALSE;
 
1082
}
 
1083
    
 
1084
 
 
1085
static Boolean ShouldBeAGBQual (Uint1 subtype, Int2 qual, Boolean allowProductGBQual)
1003
1086
 
1004
1087
{
1005
1088
  if (qual < 0) return FALSE;
1009
1092
      qual == GBQUAL_evidence ||
1010
1093
      qual == GBQUAL_exception ||
1011
1094
      qual == GBQUAL_gene ||
 
1095
      qual == GBQUAL_insertion_seq ||
1012
1096
      qual == GBQUAL_label ||
1013
1097
      qual == GBQUAL_locus_tag ||
1014
1098
      qual == GBQUAL_note ||
1016
1100
      qual == GBQUAL_product ||
1017
1101
      qual == GBQUAL_pseudo ||
1018
1102
      qual == GBQUAL_rpt_unit ||
 
1103
      qual == GBQUAL_transposon ||
1019
1104
      qual == GBQUAL_experiment ||
 
1105
      qual == GBQUAL_trans_splicing ||
 
1106
      qual == GBQUAL_ribosomal_slippage ||
1020
1107
      qual == GBQUAL_inference) {
1021
1108
    return FALSE;
1022
1109
  }
1023
 
  if (qual == GBQUAL_map && (sfp == NULL ||
1024
 
      (sfp->idx.subtype != FEATDEF_repeat_region && sfp->idx.subtype != FEATDEF_gap))) return FALSE;
1025
 
  if (qual == GBQUAL_operon && (sfp == NULL || sfp->idx.subtype != FEATDEF_operon)) return FALSE;
 
1110
  if (qual == GBQUAL_map && subtype != FEATDEF_ANY && subtype != FEATDEF_repeat_region && subtype != FEATDEF_gap) return FALSE;
 
1111
  if (qual == GBQUAL_operon && subtype != FEATDEF_ANY && subtype != FEATDEF_operon) return FALSE;
1026
1112
  if (Nlm_GetAppProperty ("SequinUseEMBLFeatures") == NULL) {
1027
1113
    if (qual == GBQUAL_usedin) {
1028
1114
      return FALSE;
1029
1115
    }
1030
1116
  }
 
1117
 
 
1118
  if (qual > -1 && ShouldSuppressGBQual (subtype, ParFlat_GBQual_names [qual].name)) {
 
1119
    return FALSE;
 
1120
  }
 
1121
 
1031
1122
  return TRUE;
1032
1123
}
1033
1124
 
1308
1399
 
1309
1400
        for (i = 0; i < sefp->mand_num; i++) {
1310
1401
          qual = sefp->mand_qual [i];
1311
 
          if (qual > -1 && ShouldBeAGBQual (sfp, qual, allowProductGBQual)) {
 
1402
          if (qual > -1 && ShouldBeAGBQual (sfp == NULL ? FEATDEF_ANY : sfp->idx.subtype, qual, allowProductGBQual)) {
1312
1403
            seen [qual] = LEGAL_FEATURE;
1313
1404
          }
1314
1405
        }
1320
1411
        }
1321
1412
        for (i = 0; i < sefp->opt_num; i++) {
1322
1413
          qual = sefp->opt_qual [i];
1323
 
          if (qual > -1 && ShouldBeAGBQual (sfp, qual, allowProductGBQual)) {
 
1414
          if (qual > -1 && ShouldBeAGBQual (sfp == NULL ? FEATDEF_ANY : sfp->idx.subtype, qual, allowProductGBQual)) {
1324
1415
            seen [qual] = LEGAL_FEATURE;
1325
1416
          }
1326
1417
        }
1515
1606
static DialoG NewCreateInferenceDialog (GrouP prnt);
1516
1607
extern void Nlm_LaunchGeneFeatEd (ButtoN b);
1517
1608
 
 
1609
 
 
1610
static CharPtr GetNameForFeature (SeqFeatPtr sfp)
 
1611
{
 
1612
  FeatDefPtr curr;
 
1613
  Uint1      key;
 
1614
  CharPtr    label = NULL;
 
1615
  CharPtr    featname = NULL;
 
1616
  CharPtr    ptr;
 
1617
  Char       ch;
 
1618
 
 
1619
  if (sfp != NULL) {
 
1620
    curr = FeatDefFindNext (NULL, &key, &label, sfp->idx.subtype, TRUE);
 
1621
    if (curr != NULL) {
 
1622
      featname = StringSave (label);
 
1623
      ptr = featname;
 
1624
      ch = *ptr;
 
1625
      while (ch != '\0') {
 
1626
        if (IS_UPPER (ch)) {
 
1627
          *ptr = TO_LOWER (ch);
 
1628
        }
 
1629
        ptr++;
 
1630
        ch = *ptr;
 
1631
      }
 
1632
    }
 
1633
  }
 
1634
  return featname;
 
1635
}
 
1636
 
 
1637
 
1518
1638
extern GrouP CreateCommonFeatureGroupEx (GrouP h, FeatureFormPtr ffp,
1519
1639
                                         SeqFeatPtr sfp, Boolean hasGeneControl,
1520
1640
                                         Boolean hasCitationTab, Boolean hasGeneSuppress)
1542
1662
  GrouP      v;
1543
1663
  GrouP      x;
1544
1664
  GrouP      y;
 
1665
  CharPtr    featname;
1545
1666
 
1546
1667
  c = NULL;
1547
1668
  if (ffp != NULL) {
1548
1669
    hasQuals = FALSE;
1549
1670
    cdsQuals = FALSE;
1550
1671
    if (ffp->gbquals == NULL && sfp != NULL && sfp->qual != NULL) {
1551
 
      for (gbq = sfp->qual; gbq != NULL; gbq = gbq->next) {
1552
 
        if (StringCmp (gbq->qual, "experiment") != 0 && StringCmp (gbq->qual, "inference") != 0) {
 
1672
      for (gbq = sfp->qual; gbq != NULL && !hasQuals; gbq = gbq->next) {
 
1673
        if (!ShouldSuppressGBQual(sfp->idx.subtype, gbq->qual)) {
1553
1674
          hasQuals = TRUE;
1554
1675
        }
1555
1676
      }
1580
1701
    }
1581
1702
    commonRadioFormTabs [6] = NULL;
1582
1703
    commonNoCitFormTabs [5] = NULL;
 
1704
 
1583
1705
    p = HiddenGroup (m, 0, 0, NULL);
1584
1706
 
1585
1707
    c = HiddenGroup (p, -1, 0, NULL);
1596
1718
      ffp->pseudo = CheckBox (r, "Pseudo", NULL);
1597
1719
      pseudo = ffp->pseudo; /* allows pseudo control on earlier feature-specific page */
1598
1720
    }
1599
 
    StaticPrompt (r, "Evidence", 0, popupMenuHeight, programFont, 'l');
1600
 
    ffp->evidence = PopupList (r, TRUE, NULL);
1601
 
    PopupItem (ffp->evidence, " ");
1602
 
    PopupItem (ffp->evidence, "Experimental");
1603
 
    PopupItem (ffp->evidence, "Non-Experimental");
 
1721
    if (indexerVersion) {
 
1722
      StaticPrompt (r, "Evidence", 0, popupMenuHeight, programFont, 'l');
 
1723
      ffp->evidence = PopupList (r, TRUE, NULL);
 
1724
      PopupItem (ffp->evidence, " ");
 
1725
      PopupItem (ffp->evidence, "Experimental");
 
1726
      PopupItem (ffp->evidence, "Non-Experimental");
 
1727
    }
1604
1728
    AlignObjects (ALIGN_MIDDLE, (HANDLE) ffp->partial,
1605
 
                  (HANDLE) ffp->evidence, (HANDLE) pseudo, NULL);
 
1729
                  (HANDLE) pseudo, (HANDLE) ffp->evidence, NULL);
1606
1730
    r = HiddenGroup (f, -3, 0, NULL);
1607
1731
    ffp->exception = CheckBox (r, "Exception", NULL);
1608
1732
    StaticPrompt (r, "Explanation", 0, dialogTextHeight, programFont, 'l');
1801
1925
    Hide (ffp->commonSubGrp [page]);
1802
1926
    page++;
1803
1927
 
 
1928
 
1804
1929
    c = HiddenGroup (p, -1, 0, NULL);
1805
1930
    SetGroupSpacing (c, 10, 10);
1806
1931
    x = NULL;
1807
 
    /* z = NULL; */
1808
1932
    if (hasQuals && ffp->gbquals == NULL) {
1809
1933
      x = HiddenGroup (c, -1, 0, NULL);
1810
 
      /*
1811
 
      z = HiddenGroup (x, -4, 0, NULL);
1812
 
      SetGroupSpacing (z, -1, 0);
1813
 
      StaticPrompt (z, "Qualifier", 7 * stdCharWidth, 0, programFont, 'c');
1814
 
      StaticPrompt (z, "Value", 10 * stdCharWidth, 0, programFont, 'c');
1815
 
      ffp->gbquals = CreateQualsDialog (x, 5, -1, 7, 10);
1816
 
      */
1817
 
      ffp->gbquals = CreateImportFields (x, NULL, sfp, FALSE);
 
1934
      featname = GetNameForFeature (sfp);
 
1935
      ffp->gbquals = NewCreateImportFields (x, featname, sfp, FALSE);
 
1936
      featname = MemFree (featname);
1818
1937
    }
1819
1938
    ffp->commonSubGrp [page] = c;
1820
1939
    Hide (ffp->commonSubGrp [page]);
1821
1940
    page++;
1822
1941
 
 
1942
 
1823
1943
    AlignObjects (ALIGN_CENTER, (HANDLE) ffp->commonRadio, (HANDLE) ffp->commonSubGrp [0],
1824
1944
                  (HANDLE) ffp->commonSubGrp [1], (HANDLE) ffp->commonSubGrp [2],
1825
1945
                  (HANDLE) ffp->commonSubGrp [3], (HANDLE) ffp->commonSubGrp [4],
1826
1946
                  (HANDLE) ffp->commonSubGrp [5], (HANDLE) ffp->commonSubGrp [6],
1827
 
                  (HANDLE) ffp->gbquals, NULL);
 
1947
                  (HANDLE) ffp->commonSubGrp [7], NULL);
1828
1948
  }
1829
1949
  return c;
1830
1950
}
2218
2338
  Int2             first;
2219
2339
  FILE             *fp;
2220
2340
  Char             lastch;
2221
 
  Int4             line;
 
2341
  Int4             line = 0;
2222
2342
  ValNodePtr       matches;
2223
2343
  Int2             next;
2224
2344
  Int2             offset = 0;
4406
4526
  }
4407
4527
  else
4408
4528
  {
4409
 
    if (num_choices < 20 && ! force_list)
 
4529
    if ((num_choices < 20 && ! force_list) || list_height == 1)
4410
4530
    {
4411
4531
      dlg->popup_ctrl = PopupList (p, TRUE, SelectionDialogPopupChanged);
4412
4532
      SetObjectExtra (dlg->popup_ctrl, dlg, NULL);
4951
5071
}
4952
5072
 
4953
5073
 
4954
 
extern DialoG SequenceSelectionDialog 
 
5074
extern DialoG SequenceSelectionDialogEx 
4955
5075
(GrouP h,
4956
5076
 Nlm_ChangeNotifyProc     change_notify,
4957
5077
 Pointer                  change_userdata,
4958
5078
 Boolean                  allow_multi,
 
5079
 Boolean                  allow_none,
4959
5080
 Boolean                  show_nucs,
4960
5081
 Boolean                  show_prots,
4961
 
 Uint2                    entityID)
 
5082
 Uint2                    entityID,
 
5083
 Int4                     list_height)
4962
5084
 
4963
5085
{
4964
5086
  SequenceSelectionPtr  dlg;
4995
5117
  dlg->dialogmessage = SequenceSelectionDialogMessage;
4996
5118
  dlg->testdialog = TestSequenceSelectionDialog;
4997
5119
 
4998
 
  dlg->sequence_choice_list = NULL;
 
5120
  if (allow_none) {
 
5121
    dlg->sequence_choice_list = ValNodeNew (NULL);
 
5122
    dlg->sequence_choice_list->choice = 0;
 
5123
    dlg->sequence_choice_list->data.ptrvalue = NULL;
 
5124
  } else {
 
5125
    dlg->sequence_choice_list = NULL;
 
5126
  }
4999
5127
  GetSequenceChoiceList (sep, &dlg->sequence_choice_list, show_nucs, show_prots);
5000
5128
  
5001
5129
  
5002
5130
  for (vnp = dlg->sequence_choice_list; vnp != NULL; vnp = vnp->next) {
5003
5131
    sip = SeqIdFindWorst ((SeqIdPtr) vnp->data.ptrvalue);
5004
 
    SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
 
5132
    if (sip == NULL) {
 
5133
      sprintf (tmp, " ");
 
5134
    } else {
 
5135
      SeqIdWrite (sip, tmp, PRINTID_REPORT, sizeof (tmp));
 
5136
    }
5005
5137
    ValNodeAddPointer (&choice_name_list, 0, StringSave (tmp));
5006
5138
  }
5007
5139
 
5008
5140
  dlg->sequence_list_dlg = SelectionDialog (p, change_notify, change_userdata,
5009
5141
                                            allow_multi, "sequence",
5010
 
                                            choice_name_list, TALL_SELECTION_LIST);
 
5142
                                            choice_name_list, list_height);
5011
5143
  ValNodeFreeData (choice_name_list); 
5012
5144
  return (DialoG) p;
5013
5145
}
5014
5146
 
 
5147
 
 
5148
extern DialoG SequenceSelectionDialog 
 
5149
(GrouP h,
 
5150
 Nlm_ChangeNotifyProc     change_notify,
 
5151
 Pointer                  change_userdata,
 
5152
 Boolean                  allow_multi,
 
5153
 Boolean                  show_nucs,
 
5154
 Boolean                  show_prots,
 
5155
 Uint2                    entityID)
 
5156
{
 
5157
  return SequenceSelectionDialogEx (h, change_notify, change_userdata, allow_multi, FALSE, show_nucs, show_prots, entityID, TALL_SELECTION_LIST);
 
5158
}
 
5159
 
 
5160
 
 
5161
extern DialoG SubSourceTypeDialog 
 
5162
(GrouP                    h,
 
5163
 Int2                     list_height,
 
5164
 Nlm_ChangeNotifyProc     change_notify,
 
5165
 Pointer                  change_userdata,
 
5166
 Boolean                  allow_multi,
 
5167
 Boolean                  force_list,
 
5168
 Boolean                  include_note)
 
5169
{
 
5170
  ValNodePtr subsource_list = NULL;
 
5171
  Int4       i;
 
5172
 
 
5173
  for (i = 0; current_subsource_subtype_alist[i].name != NULL; i++) {
 
5174
    ValNodeAddPointer (&subsource_list, current_subsource_subtype_alist[i].value, StringSave (current_subsource_subtype_alist[i].name));
 
5175
  }
 
5176
  if (include_note) {
 
5177
    ValNodeAddPointer (&subsource_list, SUBSRC_other, StringSave ("Note"));
 
5178
  }
 
5179
  
 
5180
  return ValNodeSelectionDialogEx (h, subsource_list, list_height, 
 
5181
                                   ValNodeStringName,
 
5182
                                   ValNodeSimpleDataFree, 
 
5183
                                   ValNodeStringCopy,
 
5184
                                   ValNodeChoiceMatch, "subsource list", 
 
5185
                                   change_notify, change_userdata, allow_multi, force_list, NULL);
 
5186
}
 
5187
 
 
5188
 
 
5189
extern DialoG OrgModTypeDialog 
 
5190
(GrouP                    h,
 
5191
 Int2                     list_height,
 
5192
 Nlm_ChangeNotifyProc     change_notify,
 
5193
 Pointer                  change_userdata,
 
5194
 Boolean                  allow_multi,
 
5195
 Boolean                  force_list,
 
5196
 Boolean                  include_note)
 
5197
{
 
5198
  ValNodePtr orgmod_list = NULL;
 
5199
  Int4       i;
 
5200
 
 
5201
  for (i = 0; current_orgmod_subtype_alist[i].name != NULL; i++) {
 
5202
    ValNodeAddPointer (&orgmod_list, current_orgmod_subtype_alist[i].value, StringSave (current_orgmod_subtype_alist[i].name));
 
5203
  }
 
5204
  if (include_note) {
 
5205
    ValNodeAddPointer (&orgmod_list, ORGMOD_other, StringSave ("Note"));
 
5206
  }
 
5207
  
 
5208
  return ValNodeSelectionDialogEx (h, orgmod_list, list_height, 
 
5209
                                   ValNodeStringName,
 
5210
                                   ValNodeSimpleDataFree, 
 
5211
                                   ValNodeStringCopy,
 
5212
                                   ValNodeChoiceMatch, "orgmod list", 
 
5213
                                   change_notify, change_userdata, allow_multi, force_list, NULL);
 
5214
}
 
5215
 
 
5216
 
5015
5217
/*
5016
5218
static CharPtr inferencePrefix [] = {
5017
5219
  "",
5249
5451
 
5250
5452
/* inference dialog controls, utility functions */
5251
5453
 
 
5454
Uint2 accessionlist_types [] = {
 
5455
  TAGLIST_POPUP, TAGLIST_TEXT
 
5456
};
 
5457
 
 
5458
Uint2 accessionlist_widths [] = {
 
5459
  0, 10
 
5460
};
 
5461
 
 
5462
ENUM_ALIST(accn_type_alist)
 
5463
  { " ",       0 },
 
5464
  { "GenBank", 1 },
 
5465
  { "EMBL",    2 },
 
5466
  { "DDBJ",    3 },
 
5467
  { "INSD",    4 },
 
5468
  { "RefSeq",  5 },
 
5469
  { "UniProt", 6 },
 
5470
  { "Other",   7 },
 
5471
END_ENUM_ALIST
 
5472
 
 
5473
static EnumFieldAssocPtr accessionlist_popups [] = {
 
5474
  accn_type_alist, NULL
 
5475
};
 
5476
 
 
5477
static CharPtr accnTypePrefix [] = {
 
5478
  "",
 
5479
  "GenBank",
 
5480
  "EMBL",
 
5481
  "DDBJ",
 
5482
  "INSD",
 
5483
  "RefSeq",
 
5484
  "UniProt",
 
5485
  "?",
 
5486
  NULL
 
5487
};
 
5488
 
 
5489
const Int4 numAccnTypePrefixes = sizeof (accnTypePrefix) / sizeof (CharPtr);
 
5490
 
 
5491
static Int4 GetAccnTypeNum (CharPtr str)
 
5492
{
 
5493
  Int4 i;
 
5494
 
 
5495
  if (StringHasNoText (str)) return 0;
 
5496
 
 
5497
  for (i = 1; i < numAccnTypePrefixes; i++)
 
5498
  {
 
5499
    if (StringCmp (accnTypePrefix[i], str) == 0)
 
5500
    {
 
5501
      return i;
 
5502
    }
 
5503
  }
 
5504
  return 0;
 
5505
}
 
5506
 
 
5507
 
 
5508
static CharPtr ValForOneAccession (CharPtr str)
 
5509
{
 
5510
  CharPtr cp, val_buf = NULL;
 
5511
  CharPtr val_fmt = "%d\t%s";
 
5512
  Int4    db;
 
5513
 
 
5514
  if (!StringHasNoText (str))
 
5515
  {
 
5516
    cp = StringChr (str, '|');
 
5517
    if (cp == NULL)
 
5518
    {
 
5519
      if ((db = GetAccnTypeNum(str)) > 0)
 
5520
      {
 
5521
        val_buf = MemNew (sizeof (Char) * StringLen (val_fmt));
 
5522
        sprintf (val_buf, val_fmt, db, " ");
 
5523
      }
 
5524
      else
 
5525
      {
 
5526
        val_buf = MemNew (sizeof (Char) * (StringLen (val_fmt) + StringLen (str)));
 
5527
        sprintf (val_buf, val_fmt, 0, str);
 
5528
      }
 
5529
    }
 
5530
    else
 
5531
    {
 
5532
      *cp = 0;
 
5533
      db = GetAccnTypeNum (str);
 
5534
      val_buf = MemNew (sizeof (Char) * (StringLen (val_fmt) + StringLen (cp + 1)));
 
5535
      sprintf (val_buf, val_fmt, db, cp + 1);
 
5536
      *cp = '|';
 
5537
    }
 
5538
  }
 
5539
  return val_buf;
 
5540
}
 
5541
 
 
5542
static void AccessionListDataToDialog (DialoG d, Pointer data)
 
5543
{
 
5544
  TagListPtr    tlp;
 
5545
  CharPtr       str, cp, val_buf;
 
5546
  ValNodePtr    new_list = NULL, vnp;
 
5547
  Int4          j;
 
5548
  Int2          scroll_pos;
 
5549
 
 
5550
  tlp = (TagListPtr) GetObjectExtra (d);
 
5551
  
 
5552
  if (tlp == NULL) return;
 
5553
  str = (CharPtr) data;
 
5554
  
 
5555
  cp = StringChr (str, ',');
 
5556
  while (cp != NULL)
 
5557
  {
 
5558
    *cp = 0;
 
5559
    val_buf = ValForOneAccession (str);
 
5560
    if (val_buf != NULL)
 
5561
    {
 
5562
      ValNodeAddPointer (&new_list, 0, val_buf);
 
5563
    }
 
5564
    *cp = ',';
 
5565
    str = cp + 1;
 
5566
    cp = StringChr (str, ',');
 
5567
  }
 
5568
  val_buf = ValForOneAccession (str);
 
5569
  if (val_buf != NULL)
 
5570
  {
 
5571
    ValNodeAddPointer (&new_list, 0, val_buf);
 
5572
  }
 
5573
 
 
5574
  scroll_pos = 0;
 
5575
  if (tlp->bar != NULL) 
 
5576
  {
 
5577
    scroll_pos = GetBarValue (tlp->bar);
 
5578
  }
 
5579
  else if (tlp->left_bar != NULL)
 
5580
  {
 
5581
    scroll_pos = GetBarValue (tlp->left_bar);
 
5582
  }
 
5583
 
 
5584
  SendMessageToDialog (tlp->dialog, VIB_MSG_RESET);
 
5585
  tlp->vnp = new_list;
 
5586
  for (j = 0, vnp = tlp->vnp; vnp != NULL; j++, vnp = vnp->next) {
 
5587
  }
 
5588
  tlp->max = MAX ((Int2) 0, (Int2) (j - tlp->rows + 1));
 
5589
  CorrectBarMax (tlp->bar, tlp->max);
 
5590
  CorrectBarPage (tlp->bar, (Int2) (tlp->rows-1), (Int2) (tlp->rows-1));   
 
5591
 
 
5592
  /* retain scroll position */
 
5593
  if (scroll_pos > tlp->max) {
 
5594
    scroll_pos = tlp->max;
 
5595
  }
 
5596
  
 
5597
  if (tlp->bar != NULL)
 
5598
  {
 
5599
    CorrectBarValue (tlp->bar, scroll_pos);      
 
5600
  }
 
5601
  if (tlp->left_bar != NULL)
 
5602
  {
 
5603
    CorrectBarValue (tlp->left_bar, scroll_pos);      
 
5604
  }
 
5605
    
 
5606
  SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
 
5607
  Update ();
 
5608
 
 
5609
}
 
5610
 
 
5611
 
 
5612
static Pointer AccessionListDialogToData (DialoG d)
 
5613
{
 
5614
  TagListPtr    tlp;
 
5615
  ValNodePtr    vnp;
 
5616
  Int4          result_len = 0, db;
 
5617
  CharPtr       str, acc_str, result_str = NULL;
 
5618
  Boolean       first_item = TRUE;
 
5619
  
 
5620
  tlp = (TagListPtr) GetObjectExtra (d);
 
5621
  
 
5622
  if (tlp == NULL) return NULL;
 
5623
  
 
5624
  for (vnp = tlp->vnp;
 
5625
       vnp != NULL;
 
5626
       vnp = vnp->next)
 
5627
  {
 
5628
    acc_str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
 
5629
    str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
 
5630
    if (!StringHasNoText (acc_str) || !StringHasNoText (str))
 
5631
    {
 
5632
      result_len += StringLen (acc_str);
 
5633
      result_len += 1; /* comma */
 
5634
      db = atoi (str);
 
5635
      if (db >= 0 && db < numAccnTypePrefixes)
 
5636
      {
 
5637
        result_len += MAX (StringLen (accnTypePrefix[db]), 1);
 
5638
      }
 
5639
      else
 
5640
      {
 
5641
        result_len ++; /* will represent with ? */
 
5642
      }
 
5643
      result_len ++; /* for db/accession separator */
 
5644
    }
 
5645
    acc_str = MemFree (acc_str);
 
5646
    str = MemFree (str);
 
5647
  }
 
5648
  
 
5649
  if (result_len > 0) 
 
5650
  {
 
5651
    result_str = (CharPtr) MemNew (sizeof (Char) * (result_len + 1));
 
5652
    for (vnp = tlp->vnp;
 
5653
        vnp != NULL;
 
5654
        vnp = vnp->next)
 
5655
    {
 
5656
      acc_str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 1);
 
5657
      str = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, 0);
 
5658
      db = (str == NULL ? 0 : atoi (str));
 
5659
      str = MemFree (str);
 
5660
      if (!StringHasNoText (acc_str) || db > 0)
 
5661
      {
 
5662
        if (first_item)
 
5663
        {
 
5664
          first_item = FALSE;
 
5665
        }
 
5666
        else
 
5667
        {
 
5668
          StringCat (result_str, ",");
 
5669
        }
 
5670
 
 
5671
        if (db > 0 && db < numAccnTypePrefixes)
 
5672
        {
 
5673
          StringCat (result_str, accnTypePrefix[db]);
 
5674
        }
 
5675
        else
 
5676
        {
 
5677
          StringCat (result_str, "?");
 
5678
        }
 
5679
        StringCat (result_str, "|");
 
5680
        if (!StringHasNoText (result_str)) {
 
5681
          StringCat (result_str, acc_str);
 
5682
        }
 
5683
      }
 
5684
      acc_str = MemFree (acc_str);
 
5685
    }
 
5686
    result_str[result_len] = 0;
 
5687
  }
 
5688
 
 
5689
  return result_str;
 
5690
}
 
5691
 
 
5692
 
 
5693
static void RemoveEmptyAccessionStrings (CharPtr acc_list)
 
5694
{
 
5695
  CharPtr cp_prev_end = NULL, cp_src, cp_dst;
 
5696
 
 
5697
  if (acc_list == NULL) return;
 
5698
  
 
5699
  cp_src = acc_list;
 
5700
  cp_dst = acc_list;
 
5701
  cp_prev_end = acc_list;
 
5702
  while (*cp_src != 0)
 
5703
  {
 
5704
    if (*cp_src == '|' && (*(cp_src + 1) == ',' || *(cp_src + 1) == 0))
 
5705
    {
 
5706
      cp_dst = cp_prev_end;
 
5707
      cp_prev_end = cp_dst;
 
5708
      cp_src++;
 
5709
    }
 
5710
    else
 
5711
    {
 
5712
      *cp_dst = *cp_src;      
 
5713
      if (*cp_src == ',')
 
5714
      {
 
5715
        cp_prev_end = cp_dst;
 
5716
      }
 
5717
      cp_dst++;
 
5718
      cp_src++;
 
5719
    }
 
5720
  }
 
5721
  *cp_dst = 0;
 
5722
}
 
5723
 
 
5724
 
 
5725
static CharPtr insdmessage =
 
5726
"GenBank, EMBL, and DDBJ records are part of the International Nucleotide " \
 
5727
"Sequence Database collaboration.\nThe database prefix for the /inference " \
 
5728
"qualifier in these cases is INSD by collaboration policy.";
 
5729
 
 
5730
 
 
5731
static Boolean ReplaceDatabaseStrings (CharPtr PNTR str)
 
5732
{
 
5733
  Boolean changed_db = FALSE;
 
5734
 
 
5735
  if (str == NULL || *str == NULL) return FALSE;
 
5736
 
 
5737
  if (StringSearch (*str, "GenBank|") != NULL)
 
5738
  {
 
5739
    changed_db = TRUE;
 
5740
    FindReplaceString (str, "GenBank|", "INSD|", TRUE, FALSE);
 
5741
  }
 
5742
  if (StringSearch (*str, "EMBL|") != NULL)
 
5743
  {
 
5744
    changed_db = TRUE;
 
5745
    FindReplaceString (str, "EMBL|", "INSD|", TRUE, FALSE);
 
5746
  }
 
5747
  if (StringSearch (*str, "DDBJ|") != NULL)
 
5748
  {
 
5749
    changed_db = TRUE;
 
5750
    FindReplaceString (str, "DDBJ|", "INSD|", TRUE, FALSE);
 
5751
  }
 
5752
 
 
5753
  if (changed_db)
 
5754
  {
 
5755
    if (GetAppProperty ("InternalNcbiSequin") == NULL) {
 
5756
      Message (MSG_OK, "%s", insdmessage);
 
5757
    }
 
5758
  }
 
5759
 
 
5760
  return changed_db;
 
5761
}
 
5762
 
 
5763
 
 
5764
static void ChangeInferAccessionList (Pointer data); 
 
5765
static TaglistCallback AccessionListCallbacks[] = 
 
5766
{ ChangeInferAccessionList, ChangeInferAccessionList };
 
5767
 
5252
5768
typedef struct inferevid {
5253
5769
  CharPtr  prefix;     /* from inferencePrefix     */
5254
5770
  Boolean  species;    /* optional (same species)  */
5260
5776
  CharPtr  version;    /* program version          */
5261
5777
  CharPtr  basis1;     /* profile or motif         */
5262
5778
  CharPtr  basis2;     /*  evidence_basis texts    */
 
5779
  CharPtr  accession_list; /* accession list for alignment */
5263
5780
} InferEvid, PNTR InferEvidPtr;
5264
5781
 
5265
5782
typedef struct inferdialog {
5278
5795
  TexT          version;
5279
5796
  TexT          basis1;
5280
5797
  TexT          basis2;
 
5798
  PrompT        inf_free_program_prompt;
 
5799
  PrompT        inf_free_version_prompt;
 
5800
  PrompT        accession_list_program_prompt;
 
5801
  PrompT        accession_list_version_prompt;
 
5802
  PrompT        accession_list_prompt;
 
5803
  DialoG        accession_list;
5281
5804
 
5282
5805
  GrouP         inf_accn_group;
5283
5806
  GrouP         other_db_group;
5317
5840
  MemFree (iep->version);
5318
5841
  MemFree (iep->basis1);
5319
5842
  MemFree (iep->basis2);
 
5843
  MemFree (iep->accession_list);
5320
5844
 
5321
5845
  return MemFree (iep);
5322
5846
}
5375
5899
  "nucleotide motif",
5376
5900
  "protein motif",
5377
5901
  "ab initio prediction",
 
5902
  "alignment",
5378
5903
  NULL
5379
5904
};
5380
5905
 
5391
5916
  { "nucleotide motif",      9 },
5392
5917
  { "protein motif",        10 },
5393
5918
  { "ab initio prediction", 11 },
5394
 
END_ENUM_ALIST
5395
 
 
5396
 
static CharPtr accnTypePrefix [] = {
5397
 
  "",
5398
 
  "GenBank",
5399
 
  "EMBL",
5400
 
  "DDBJ",
5401
 
  "INSD",
5402
 
  "RefSeq",
5403
 
  "UniProt",
5404
 
  "?",
5405
 
  NULL
5406
 
};
5407
 
 
5408
 
ENUM_ALIST(accn_type_alist)
5409
 
  { " ",       0 },
5410
 
  { "GenBank", 1 },
5411
 
  { "EMBL",    2 },
5412
 
  { "DDBJ",    3 },
5413
 
  { "INSD",    4 },
5414
 
  { "RefSeq",  5 },
5415
 
  { "UniProt", 6 },
5416
 
  { "Other",   7 },
 
5919
  { "alignment",            12 },
5417
5920
END_ENUM_ALIST
5418
5921
 
5419
5922
static CharPtr programPrefix [] = {
5450
5953
 
5451
5954
  len = StringLen (iep->prefix) + StringLen (iep->database) + StringLen (iep->db_other) + StringLen (iep->accession) +
5452
5955
        StringLen (iep->program) + StringLen (iep->pr_other) + StringLen (iep->version) + StringLen (iep->basis1) +
5453
 
        StringLen (iep->basis2) + 50;
 
5956
        StringLen (iep->basis2) + StringLen (iep->accession_list) + 50;
5454
5957
  buf = MemNew (len);
5455
5958
  if (buf == NULL) return NULL;
5456
5959
 
5497
6000
    if (StringDoesHaveText (iep->basis2)) {
5498
6001
      StringCat (buf, ":");
5499
6002
      StringCat (buf, iep->basis2);
 
6003
      if (StringCmp (iep->prefix, "alignment") == 0 && 
 
6004
          StringDoesHaveText (iep->accession_list)) {
 
6005
        StringCat (buf, ":");
 
6006
        StringCat (buf, iep->accession_list);
 
6007
      }
5500
6008
    }
5501
6009
  } else {
5502
6010
    StringCat (buf, " ");
5533
6041
      SafeHide (idp->species);
5534
6042
      SafeHide (idp->inf_prog_group);
5535
6043
      SafeShow (idp->inf_free_group);
 
6044
      SafeHide (idp->accession_list);
 
6045
      SafeShow (idp->inf_free_program_prompt);
 
6046
      SafeShow (idp->inf_free_version_prompt);
 
6047
      SafeHide (idp->accession_list_program_prompt);
 
6048
      SafeHide (idp->accession_list_version_prompt);
 
6049
      SafeHide (idp->accession_list_prompt);
5536
6050
    } else if (val == 11) {
5537
6051
      SafeHide (idp->inf_accn_group);
5538
6052
      SafeHide (idp->species);
5545
6059
        SafeHide (idp->other_pr_group);
5546
6060
      }
5547
6061
      MemFree (str);
 
6062
    } else if (val == 12) {
 
6063
      SafeHide (idp->inf_accn_group);
 
6064
      SafeHide (idp->species);
 
6065
      SafeHide (idp->inf_prog_group);
 
6066
      SafeShow (idp->inf_free_group);
 
6067
      SafeShow (idp->accession_list);
 
6068
      SafeHide (idp->inf_free_program_prompt);
 
6069
      SafeHide (idp->inf_free_version_prompt);
 
6070
      SafeShow (idp->accession_list_program_prompt);
 
6071
      SafeShow (idp->accession_list_version_prompt);
 
6072
      SafeShow (idp->accession_list_prompt);
5548
6073
    } else {
5549
6074
      SafeHide (idp->inf_accn_group);
5550
6075
      SafeHide (idp->species);
5610
6135
    SafeSetTitle (idp->basis1, iep->basis1);
5611
6136
    SafeSetTitle (idp->basis2, iep->basis2);
5612
6137
 
 
6138
    ReplaceDatabaseStrings (&(iep->accession_list));
 
6139
    PointerToDialog (idp->accession_list, iep->accession_list);
 
6140
 
5613
6141
    ShowInferenceGroup (idp);
5614
6142
  }
5615
6143
 
5686
6214
  CheckExtendInferTable (idp);
5687
6215
}
5688
6216
 
5689
 
static CharPtr insdmessage =
5690
 
"GenBank, EMBL, and DDBJ records are part of the International Nucleotide " \
5691
 
"Sequence Database collaboration.\nThe database prefix for the /inference " \
5692
 
"qualifier in these cases is INSD by collaboration policy.";
5693
 
 
5694
6217
static void ChangeInferDatabase (
5695
6218
  PopuP p
5696
6219
)
5905
6428
  CheckExtendInferTable (idp);
5906
6429
}
5907
6430
 
 
6431
 
 
6432
static void ChangeInferAccessionList (Pointer data)
 
6433
{
 
6434
  InferDialogPtr  idp;
 
6435
  InferEvidPtr    iep;
 
6436
 
 
6437
  idp = (InferDialogPtr) data;
 
6438
  if (idp == NULL) return;
 
6439
  iep = GetInferEvid (idp, idp->currItem);
 
6440
  if (iep == NULL) return;
 
6441
 
 
6442
  iep->accession_list = MemFree (iep->accession_list);
 
6443
  iep->accession_list = DialogToPointer (idp->accession_list);
 
6444
  
 
6445
  if (ReplaceDatabaseStrings (&(iep->accession_list)))
 
6446
  {
 
6447
    PointerToDialog (idp->accession_list, iep->accession_list);
 
6448
  }
 
6449
 
 
6450
  ShowInferenceGroup (idp);
 
6451
 
 
6452
  UpdateDocument (idp->inferdoc, idp->currItem, idp->currItem);
 
6453
  Update ();
 
6454
 
 
6455
  CheckExtendInferTable (idp);
 
6456
}
 
6457
 
 
6458
 
5908
6459
static Boolean StringInList (CharPtr str, CharPtr PNTR list)
5909
6460
 
5910
6461
{
5931
6482
  size_t          len;
5932
6483
  CharPtr         rest;
5933
6484
  CharPtr         str;
5934
 
  CharPtr         tmp;
 
6485
  CharPtr         tmp, tmp2;
5935
6486
 
5936
6487
  idp = (InferDialogPtr) GetObjectExtra (d);
5937
6488
  if (idp == NULL) return;
6056
6607
      } else {
6057
6608
        iep->basis1 = MemFree (iep->basis1);
6058
6609
        iep->basis1 = StringSaveNoNull (str);
 
6610
        tmp2 = NULL;
 
6611
        if (StringCmp (iep->prefix, "alignment") == 0)
 
6612
        {
 
6613
          tmp2 = StringChr (tmp, ':');
 
6614
          if (tmp2 != NULL) {
 
6615
            *tmp2 = 0;
 
6616
            tmp2++;
 
6617
          }
 
6618
        }
6059
6619
        iep->basis2 = MemFree (iep->basis2);
6060
6620
        iep->basis2 = StringSaveNoNull (tmp);
 
6621
        iep->accession_list = MemFree (iep->accession_list);
 
6622
        iep->accession_list = StringSaveNoNull (tmp2);
6061
6623
      }
6062
6624
 
6063
6625
    } else {
6108
6670
extern void InferenceDialogToGBQuals (DialoG d, SeqFeatPtr sfp, Boolean convertBadToNote)
6109
6671
 
6110
6672
{
6111
 
  CharPtr         first = NULL, second = NULL;
 
6673
  CharPtr         first = NULL, second = NULL, accession_list = NULL;
6112
6674
  GBQualPtr       gbq, lastgbq;
6113
6675
  InferDialogPtr  idp;
6114
6676
  InferEvidPtr    iep;
6139
6701
    gbq->qual = StringSave ("inference");
6140
6702
 
6141
6703
    if (WhereInEnumPopup (inference_alist, iep->prefix, &val)) {
6142
 
      if (val > 0 && val <= 11) {
 
6704
      if (val > 0 && val <= 12) {
6143
6705
        prefix = inferencePrefix [(int) val];
6144
6706
      }
6145
6707
    }
6170
6732
      if (StringDoesHaveText (iep->basis1)) {
6171
6733
        first = iep->basis1;
6172
6734
        second = iep->basis2;
 
6735
        if (StringCmp (iep->prefix, "alignment") == 0) {
 
6736
          accession_list = iep->accession_list;
 
6737
          RemoveEmptyAccessionStrings (accession_list);
 
6738
          ReplaceDatabaseStrings (&accession_list);
 
6739
        }
6173
6740
      }
6174
6741
    }
6175
6742
 
6176
 
    len = StringLen (prefix) + StringLen (speciesies) + StringLen (first) + StringLen (second);
6177
 
    str = MemNew (len + 5);
 
6743
    len = StringLen (prefix) + StringLen (speciesies) + StringLen (first) + StringLen (second) + StringLen (accession_list);
 
6744
    str = MemNew (len + 6);
6178
6745
    if (str != NULL) {
6179
6746
      StringCpy (str, prefix);
6180
6747
      StringCat (str, speciesies);
6182
6749
      StringCat (str, first);
6183
6750
      StringCat (str, ":");
6184
6751
      StringCat (str, second);
 
6752
      if (StringCmp (prefix, "alignment") == 0 && accession_list != NULL) {
 
6753
        StringCat (str, ":");
 
6754
        StringCat (str, accession_list);
 
6755
      }
6185
6756
      gbq->val = StringSave (str);
6186
6757
      MemFree (str);
6187
6758
    } else {
6221
6792
      lastgbq->next = gbq;
6222
6793
    }
6223
6794
    lastgbq = gbq;
 
6795
    accession_list = NULL;
6224
6796
  }
6225
6797
}
6226
6798
 
6247
6819
)
6248
6820
 
6249
6821
{
6250
 
  GrouP           cts, tbl, g0, g1, g2, g3, g4, g5, p;
 
6822
  GrouP           cts, tbl, g0, g1, g2, g3, g4, g5, p, prompt_grp;
6251
6823
  FonT            fnt;
6252
6824
  Int2            i, hgt, wid;
6253
6825
  InferDialogPtr  idp;
6359
6931
  g5 = HiddenGroup (g2, 2, 0, NULL);
6360
6932
  SetGroupSpacing (g5, 5, 5);
6361
6933
 
6362
 
  StaticPrompt (g5, "Program or Database", 0, dialogTextHeight, programFont, 'l');
 
6934
  prompt_grp = HiddenGroup (g5, 0, 0, NULL);
 
6935
  idp->inf_free_program_prompt = StaticPrompt (prompt_grp, "Program or Database", 0, dialogTextHeight, programFont, 'l');
 
6936
  idp->accession_list_program_prompt = StaticPrompt (prompt_grp, "Program", 0, dialogTextHeight, programFont, 'l');
6363
6937
  idp->basis1 = DialogText (g5, "", 10, ChangeInferBasis1);
6364
6938
  SetObjectExtra (idp->basis1, idp, NULL);
6365
6939
 
6366
 
  StaticPrompt (g5, "Version or Accession", 0, dialogTextHeight, programFont, 'l');
 
6940
  prompt_grp = HiddenGroup (g5, 0, 0, NULL);
 
6941
  idp->inf_free_version_prompt = StaticPrompt (prompt_grp, "Version or Accession", 0, dialogTextHeight, programFont, 'l');
 
6942
  idp->accession_list_version_prompt = StaticPrompt (prompt_grp, "Version", 0, dialogTextHeight, programFont, 'l');
 
6943
 
6367
6944
  idp->basis2 = DialogText (g5, "", 10, ChangeInferBasis2);
6368
6945
  SetObjectExtra (idp->basis2, idp, NULL);
6369
6946
 
 
6947
  idp->accession_list_prompt = StaticPrompt (g5, "Accessions", 0, dialogTextHeight, programFont, 'l');
 
6948
  idp->accession_list = CreateTagListDialogEx3 (g5, 3, 2, 2,
 
6949
                              accessionlist_types, accessionlist_widths,
 
6950
                              accessionlist_popups, TRUE, FALSE, AccessionListDataToDialog, AccessionListDialogToData,
 
6951
                              AccessionListCallbacks, idp,
 
6952
                              FALSE, FALSE);
 
6953
 
6370
6954
  idp->inf_free_group = g5;
6371
6955
  Hide (idp->inf_free_group);
6372
6956
 
6379
6963
  return (DialoG) p;
6380
6964
}
6381
6965
 
 
6966
 
 
6967
/* ExistingText handling dialog and structures */
 
6968
typedef struct existingtextdlg 
 
6969
{
 
6970
  GrouP pre_app_grp;
 
6971
  GrouP delim_grp;
 
6972
} ExistingTextDlgData, PNTR ExistingTextDlgPtr;
 
6973
 
 
6974
static void ChangePreAppIgnoreChoice (GrouP g)
 
6975
{
 
6976
  ExistingTextDlgPtr etdp;
 
6977
  Int4               handle_choice;
 
6978
  
 
6979
  etdp = (ExistingTextDlgPtr) GetObjectExtra (g);
 
6980
  if (etdp == NULL)
 
6981
  {
 
6982
    return;
 
6983
  }
 
6984
  
 
6985
  handle_choice = GetValue (etdp->pre_app_grp);
 
6986
  if (handle_choice == 1 || handle_choice == 2)
 
6987
  {
 
6988
    Enable (etdp->delim_grp);
 
6989
  }
 
6990
  else
 
6991
  {
 
6992
    Disable (etdp->delim_grp);
 
6993
  }
 
6994
}
 
6995
 
 
6996
extern ExistingTextPtr GetExistingTextHandlerInfo (Int4 num_found, Boolean non_text)
 
6997
{
 
6998
  WindoW                w;
 
6999
  GrouP                 h, c;
 
7000
  ExistingTextDlgData   etdd;
 
7001
  ButtoN                b;
 
7002
  ModalAcceptCancelData acd;
 
7003
  ExistingTextPtr       etp;
 
7004
  Char                  txt [128];
 
7005
  MsgAnswer             ans;
 
7006
  PrompT                ppt;
 
7007
  Int4                  handle_choice;
 
7008
 
 
7009
  if (num_found <= 0)
 
7010
  {
 
7011
    return NULL;
 
7012
  }
 
7013
  
 
7014
  sprintf (txt, "%d affected fields already contain a value.  Do you wish to overwrite existing text?",
 
7015
           num_found);
 
7016
  ans = Message (MSG_YNC, txt, 0, dialogTextHeight, systemFont, 'l');
 
7017
  if (ans == ANS_CANCEL)
 
7018
  {
 
7019
    etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
 
7020
    etp->existing_text_choice = eExistingTextChoiceCancel;
 
7021
    return etp;
 
7022
  }
 
7023
  else if (ans == ANS_YES)
 
7024
  {
 
7025
    etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
 
7026
    etp->existing_text_choice = eExistingTextChoiceReplaceOld;
 
7027
    return etp;
 
7028
  }
 
7029
    
 
7030
  w = MovableModalWindow(-20, -13, -10, -10, "How to Add New Text", NULL);
 
7031
  h = HiddenGroup (w, -1, 0, NULL);
 
7032
  SetGroupSpacing (h, 10, 10);
 
7033
  etdd.pre_app_grp = HiddenGroup (h, 0, 3, ChangePreAppIgnoreChoice);
 
7034
  SetGroupSpacing (etdd.pre_app_grp, 10, 10);
 
7035
  RadioButton (etdd.pre_app_grp, "Append");
 
7036
  RadioButton (etdd.pre_app_grp, "Prefix");
 
7037
  RadioButton (etdd.pre_app_grp, "Ignore new text");
 
7038
  SetValue (etdd.pre_app_grp, 1);
 
7039
  SetObjectExtra (etdd.pre_app_grp, &etdd, NULL);
 
7040
  
 
7041
  ppt = StaticPrompt (h, "Separate new text and old text with", 
 
7042
                      0, dialogTextHeight, programFont, 'c');
 
7043
  etdd.delim_grp = HiddenGroup (h, 0, 4, NULL);
 
7044
  SetGroupSpacing (etdd.delim_grp, 10, 10);
 
7045
  RadioButton (etdd.delim_grp, "Semicolon");
 
7046
  RadioButton (etdd.delim_grp, "Space");
 
7047
  RadioButton (etdd.delim_grp, "Colon");
 
7048
  RadioButton (etdd.delim_grp, "Do not separate");
 
7049
  SetValue (etdd.delim_grp, 1);
 
7050
  
 
7051
  c = HiddenGroup (h, 2, 0, NULL);
 
7052
  SetGroupSpacing (c, 10, 10);
 
7053
  b = PushButton (c, "Accept", ModalAcceptButton);
 
7054
  SetObjectExtra (b, &acd, NULL);
 
7055
  b = PushButton (c, "Cancel", ModalCancelButton);
 
7056
  SetObjectExtra (b, &acd, NULL);
 
7057
  AlignObjects (ALIGN_CENTER, (HANDLE) etdd.pre_app_grp,
 
7058
                              (HANDLE) ppt, 
 
7059
                              (HANDLE) etdd.delim_grp, 
 
7060
                              (HANDLE) c, 
 
7061
                              NULL);
 
7062
  Show (w);
 
7063
  Select (w);
 
7064
  acd.accepted = FALSE;
 
7065
  acd.cancelled = FALSE;
 
7066
  while (!acd.accepted && ! acd.cancelled)
 
7067
  {
 
7068
    ProcessExternalEvent ();
 
7069
    Update ();
 
7070
  }
 
7071
  ProcessAnEvent ();
 
7072
  etp = (ExistingTextPtr) MemNew (sizeof (ExistingTextData));
 
7073
  if (acd.cancelled)
 
7074
  {
 
7075
    etp->existing_text_choice = eExistingTextChoiceCancel;
 
7076
  }
 
7077
  else
 
7078
  {
 
7079
    handle_choice = GetValue (etdd.pre_app_grp);
 
7080
    if (handle_choice == 1)
 
7081
    {
 
7082
      switch (GetValue (etdd.delim_grp))
 
7083
      {
 
7084
        case 1:
 
7085
          etp->existing_text_choice = eExistingTextChoiceAppendSemi;
 
7086
          break;
 
7087
        case 2:
 
7088
          etp->existing_text_choice = eExistingTextChoiceAppendSpace;
 
7089
          break;
 
7090
        case 3:
 
7091
          etp->existing_text_choice = eExistingTextChoiceAppendColon;
 
7092
          break;
 
7093
        case 4:
 
7094
          etp->existing_text_choice = eExistingTextChoiceAppendNone;
 
7095
          break;
 
7096
      }
 
7097
    }
 
7098
    else if (handle_choice == 2)
 
7099
    {
 
7100
      switch (GetValue (etdd.delim_grp))
 
7101
      {
 
7102
        case 1:
 
7103
          etp->existing_text_choice = eExistingTextChoicePrefixSemi;
 
7104
          break;
 
7105
        case 2:
 
7106
          etp->existing_text_choice = eExistingTextChoicePrefixSpace;
 
7107
          break;
 
7108
        case 3:
 
7109
          etp->existing_text_choice = eExistingTextChoicePrefixColon;
 
7110
          break;
 
7111
        case 4:
 
7112
          etp->existing_text_choice = eExistingTextChoicePrefixNone;
 
7113
          break;
 
7114
      }
 
7115
    }
 
7116
    else
 
7117
    {
 
7118
      etp->existing_text_choice = eExistingTextChoiceLeaveOld;
 
7119
    }
 
7120
  }
 
7121
  Remove (w);
 
7122
  return etp;
 
7123
}
 
7124
 
 
7125
extern CharPtr HandleExistingText (CharPtr existing_text, CharPtr new_text, ExistingTextPtr etp)
 
7126
{
 
7127
  CharPtr rstring = NULL;
 
7128
  Int4    len;
 
7129
  
 
7130
  if (StringHasNoText (existing_text) || etp == NULL)
 
7131
  {
 
7132
    MemFree (existing_text);
 
7133
    return new_text;
 
7134
  }
 
7135
  switch (etp->existing_text_choice)
 
7136
  {
 
7137
    case eExistingTextChoiceReplaceOld:
 
7138
      /* replace current text with new text */
 
7139
      MemFree (existing_text);
 
7140
      rstring = new_text;
 
7141
      break;
 
7142
    case eExistingTextChoiceLeaveOld:
 
7143
      /* do not change current text */
 
7144
      MemFree (new_text);
 
7145
      rstring = existing_text;
 
7146
      break;
 
7147
    case eExistingTextChoiceAppendSemi:
 
7148
      /* Append new text to current text, separated by semicolon */
 
7149
      len = StringLen (new_text) + StringLen (existing_text) + 4;
 
7150
      rstring = MemNew (len);
 
7151
      if (rstring != NULL) {
 
7152
        StringCpy (rstring, existing_text);
 
7153
        StringCat (rstring, "; ");
 
7154
        StringCat (rstring, new_text);
 
7155
        MemFree (new_text);
 
7156
        MemFree (existing_text);
 
7157
      }
 
7158
      break;
 
7159
    case eExistingTextChoiceAppendSpace:
 
7160
      /* Append new text to current text, separated by space */
 
7161
      len = StringLen (new_text) + StringLen (existing_text) + 3;
 
7162
      rstring = MemNew (len);
 
7163
      if (rstring != NULL) {
 
7164
        StringCpy (rstring, existing_text);
 
7165
        StringCat (rstring, " ");
 
7166
        StringCat (rstring, new_text);
 
7167
        MemFree (new_text);
 
7168
        MemFree (existing_text);
 
7169
      }
 
7170
      break;
 
7171
    case eExistingTextChoiceAppendColon:
 
7172
      /* Append new text to current text, separated by colon */
 
7173
      len = StringLen (new_text) + StringLen (existing_text) + 4;
 
7174
      rstring = MemNew (len);
 
7175
      if (rstring != NULL) {
 
7176
        StringCpy (rstring, existing_text);
 
7177
        StringCat (rstring, ": ");
 
7178
        StringCat (rstring, new_text);
 
7179
        MemFree (new_text);
 
7180
        MemFree (existing_text);
 
7181
      }
 
7182
      break;
 
7183
    case eExistingTextChoiceAppendNone:
 
7184
      /* Append new text to current text, no delimiter */
 
7185
      len = StringLen (new_text) + StringLen (existing_text) + 1;
 
7186
      rstring = MemNew (len);
 
7187
      if (rstring != NULL) {
 
7188
        StringCpy (rstring, existing_text);
 
7189
        StringCat (rstring, new_text);
 
7190
        MemFree (new_text);
 
7191
        MemFree (existing_text);
 
7192
      }
 
7193
      break;
 
7194
    case eExistingTextChoicePrefixSemi:
 
7195
      /* Prepend new text to current text, separated by semicolon */
 
7196
      len = StringLen (new_text) + StringLen (existing_text) + 4;
 
7197
      rstring = MemNew (len);
 
7198
      if (rstring != NULL) {
 
7199
        StringCpy (rstring, new_text);
 
7200
        StringCat (rstring, "; ");
 
7201
        StringCat (rstring, existing_text);
 
7202
        MemFree (new_text);
 
7203
        MemFree (existing_text);
 
7204
      }
 
7205
      break;
 
7206
    case eExistingTextChoicePrefixSpace:
 
7207
      /* Prepend new text to current text, separated by space */
 
7208
      len = StringLen (new_text) + StringLen (existing_text) + 3;
 
7209
      rstring = MemNew (len);
 
7210
      if (rstring != NULL) {
 
7211
        StringCpy (rstring, new_text);
 
7212
        StringCat (rstring, " ");
 
7213
        StringCat (rstring, existing_text);
 
7214
        MemFree (new_text);
 
7215
        MemFree (existing_text);
 
7216
      }
 
7217
      break;
 
7218
    case eExistingTextChoicePrefixColon:
 
7219
      /* Prepend new text to current text, separated by colon */
 
7220
      len = StringLen (new_text) + StringLen (existing_text) + 4;
 
7221
      rstring = MemNew (len);
 
7222
      if (rstring != NULL) {
 
7223
        StringCpy (rstring, new_text);
 
7224
        StringCat (rstring, ": ");
 
7225
        StringCat (rstring, existing_text);
 
7226
        MemFree (new_text);
 
7227
        MemFree (existing_text);
 
7228
      }
 
7229
      break;
 
7230
    case eExistingTextChoicePrefixNone:
 
7231
      /* prefix current text with new text */
 
7232
      len = StringLen (new_text) + StringLen (existing_text) + 1;
 
7233
      rstring = MemNew (len);
 
7234
      if (rstring != NULL) {
 
7235
        StringCpy (rstring, new_text);
 
7236
        StringCat (rstring, existing_text);
 
7237
        MemFree (new_text);
 
7238
        MemFree (existing_text);
 
7239
      }
 
7240
      break;    
 
7241
  }
 
7242
  return rstring;
 
7243
}
 
7244
 
 
7245
 
 
7246
/* Move EditApply data and dialog here */
 
7247
extern EditApplyPtr EditApplyFree (EditApplyPtr eap)
 
7248
{
 
7249
  if (eap != NULL)
 
7250
  {
 
7251
    eap->find_txt = MemFree (eap->find_txt);
 
7252
    eap->repl_txt = MemFree (eap->repl_txt);
 
7253
    eap->apply_txt = MemFree (eap->apply_txt);
 
7254
    eap = MemFree (eap);
 
7255
  }
 
7256
  return eap;
 
7257
}
 
7258
 
 
7259
 
 
7260
extern EditApplyPtr EditApplyNew (void)
 
7261
{
 
7262
  EditApplyPtr eap;
 
7263
 
 
7264
  eap = (EditApplyPtr) MemNew (sizeof (EditApplyData));
 
7265
  eap->find_location = EditApplyFindLocation_anywhere;
 
7266
  return eap;
 
7267
}
 
7268
 
 
7269
 
 
7270
typedef struct EditApplydlg
 
7271
{
 
7272
  DIALOG_MESSAGE_BLOCK
 
7273
  TexT           find_txt;
 
7274
  TexT           repl_txt;
 
7275
  TexT           apply_txt;
 
7276
 
 
7277
  DialoG         find_dlg;
 
7278
  DialoG         repl_dlg;
 
7279
  DialoG         apply_dlg;
 
7280
 
 
7281
  Int4           action_choice;
 
7282
  GrouP          location_choice;
 
7283
  Nlm_ChangeNotifyProc     change_notify;
 
7284
  Pointer                  change_userdata;
 
7285
} EditApplyDlgData, PNTR EditApplyDlgPtr;
 
7286
 
 
7287
static void ResetEditApplyDlg (EditApplyDlgPtr dlg)
 
7288
{
 
7289
  if (dlg != NULL)
 
7290
  {
 
7291
    if (dlg->find_txt != NULL)
 
7292
    {
 
7293
      SetTitle (dlg->find_txt, "");
 
7294
    }
 
7295
    if (dlg->repl_txt != NULL)
 
7296
    {
 
7297
      SetTitle (dlg->repl_txt, "");
 
7298
    }
 
7299
    if (dlg->apply_txt != NULL)
 
7300
    {
 
7301
      SetTitle (dlg->apply_txt, "");
 
7302
    }
 
7303
    if (dlg->location_choice != NULL) {
 
7304
      SetValue (dlg->location_choice, EditApplyFindLocation_anywhere);
 
7305
    }
 
7306
 
 
7307
    PointerToDialog (dlg->find_dlg, NULL);
 
7308
    PointerToDialog (dlg->repl_dlg, NULL);
 
7309
    PointerToDialog (dlg->apply_dlg, NULL);
 
7310
 
 
7311
  }
 
7312
}
 
7313
 
 
7314
static void EditApplyDialogChangeText (TexT t)
 
7315
{
 
7316
  EditApplyDlgPtr dlg;
 
7317
 
 
7318
  dlg = (EditApplyDlgPtr) GetObjectExtra (t);
 
7319
  if (dlg != NULL && dlg->change_notify != NULL)
 
7320
  {
 
7321
    (dlg->change_notify)(dlg->change_userdata);
 
7322
  }
 
7323
}
 
7324
 
 
7325
static void EditApplyToDialog (DialoG d, Pointer userdata)
 
7326
{
 
7327
  EditApplyDlgPtr dlg;
 
7328
  EditApplyPtr    data;
 
7329
  ValNode         vn;
 
7330
  
 
7331
  dlg = (EditApplyDlgPtr) GetObjectExtra (d);
 
7332
  if (dlg == NULL)
 
7333
  {
 
7334
    return;
 
7335
  }
 
7336
  
 
7337
  ResetEditApplyDlg (dlg);
 
7338
  data = (EditApplyPtr) userdata;
 
7339
 
 
7340
  vn.next = NULL;
 
7341
  vn.choice = 0;
 
7342
 
 
7343
  if (data != NULL)
 
7344
  {
 
7345
    if (!StringHasNoText (data->find_txt))
 
7346
    {
 
7347
      if (dlg->find_txt != NULL)
 
7348
      {
 
7349
        SetTitle (dlg->find_txt, data->find_txt);
 
7350
      }
 
7351
      else if (dlg->find_dlg != NULL)
 
7352
      {
 
7353
        vn.data.ptrvalue = data->find_txt;
 
7354
        PointerToDialog (dlg->find_dlg, &vn);
 
7355
      }
 
7356
    }
 
7357
 
 
7358
    if (!StringHasNoText (data->repl_txt))
 
7359
    {
 
7360
      if (dlg->repl_txt != NULL) 
 
7361
      {
 
7362
        SetTitle (dlg->repl_txt, data->repl_txt);
 
7363
      }
 
7364
      else if (dlg->repl_dlg != NULL)
 
7365
      {
 
7366
        vn.data.ptrvalue = data->repl_txt;
 
7367
        PointerToDialog (dlg->repl_dlg, &vn);
 
7368
      }
 
7369
    }
 
7370
 
 
7371
    if (!StringHasNoText (data->apply_txt))
 
7372
    {
 
7373
      if (dlg->apply_txt != NULL)
 
7374
      {
 
7375
        SetTitle (dlg->apply_txt, data->apply_txt);
 
7376
      }
 
7377
      else if (dlg->apply_dlg != NULL)
 
7378
      {
 
7379
        vn.data.ptrvalue = data->apply_txt;
 
7380
        PointerToDialog (dlg->apply_dlg, &vn);
 
7381
      }
 
7382
    }
 
7383
 
 
7384
    if (dlg->location_choice != NULL) {
 
7385
      SetValue (dlg->location_choice, data->find_location);
 
7386
    }
 
7387
  }
 
7388
}
 
7389
 
 
7390
static Pointer DialogToEditApply (DialoG d)
 
7391
{
 
7392
  EditApplyDlgPtr dlg;
 
7393
  EditApplyPtr    data;
 
7394
  ValNodePtr      vnp;
 
7395
  
 
7396
  dlg = (EditApplyDlgPtr) GetObjectExtra (d);
 
7397
  if (dlg == NULL)
 
7398
  {
 
7399
    return NULL;
 
7400
  }
 
7401
  
 
7402
  data = (EditApplyPtr) MemNew (sizeof (EditApplyData));
 
7403
  if (data != NULL)
 
7404
  {
 
7405
    if (dlg->find_txt != NULL)
 
7406
    {
 
7407
      data->find_txt = JustSaveStringFromText (dlg->find_txt);
 
7408
    }
 
7409
    else if (dlg->find_dlg != NULL)
 
7410
    {
 
7411
      vnp = (ValNodePtr) DialogToPointer (dlg->find_dlg);
 
7412
      if (vnp != NULL)
 
7413
      {
 
7414
        data->find_txt = StringSave (vnp->data.ptrvalue);
 
7415
      }
 
7416
      vnp = ValNodeFreeData (vnp);
 
7417
    }
 
7418
 
 
7419
    if (dlg->repl_txt != NULL)
 
7420
    {
 
7421
      data->repl_txt = JustSaveStringFromText (dlg->repl_txt);
 
7422
    }
 
7423
    else if (dlg->repl_dlg != NULL)
 
7424
    {
 
7425
      vnp = (ValNodePtr) DialogToPointer (dlg->repl_dlg);
 
7426
      if (vnp != NULL)
 
7427
      {
 
7428
        data->repl_txt = StringSave (vnp->data.ptrvalue);
 
7429
      }
 
7430
      vnp = ValNodeFreeData (vnp);
 
7431
    }
 
7432
 
 
7433
    if (dlg->apply_txt != NULL)
 
7434
    {
 
7435
      data->apply_txt = JustSaveStringFromText (dlg->apply_txt);
 
7436
    }
 
7437
    else if (dlg->apply_dlg != NULL)
 
7438
    {
 
7439
      vnp = (ValNodePtr) DialogToPointer (dlg->apply_dlg);
 
7440
      if (vnp != NULL)
 
7441
      {
 
7442
        data->apply_txt = StringSave (vnp->data.ptrvalue);
 
7443
      }
 
7444
      vnp = ValNodeFreeData (vnp);
 
7445
    }
 
7446
 
 
7447
    if (dlg->location_choice != NULL) {
 
7448
      data->find_location = (EditApplyFindLocation) GetValue (dlg->location_choice);
 
7449
    } else {
 
7450
      data->find_location = EditApplyFindLocation_anywhere;
 
7451
    }
 
7452
  }
 
7453
  return data;
 
7454
}
 
7455
 
 
7456
 
 
7457
static void EditApplyMessage (DialoG d, Int2 mssg)
 
7458
 
 
7459
{
 
7460
  EditApplyDlgPtr  dlg;
 
7461
 
 
7462
  dlg = (EditApplyDlgPtr) GetObjectExtra (d);
 
7463
  if (dlg != NULL) {
 
7464
    switch (mssg) 
 
7465
    {
 
7466
      case VIB_MSG_INIT :
 
7467
        /* reset list */
 
7468
        ResetEditApplyDlg (dlg);
 
7469
        break;
 
7470
      case VIB_MSG_ENTER :
 
7471
        if (dlg->find_txt != NULL)
 
7472
        {
 
7473
          Select (dlg->find_txt);
 
7474
        }
 
7475
        else if (dlg->apply_txt != NULL)
 
7476
        {
 
7477
          Select (dlg->apply_txt);
 
7478
        }
 
7479
        else if (dlg->find_dlg != NULL)
 
7480
        {
 
7481
          Select (dlg->find_dlg);
 
7482
        }
 
7483
        else if (dlg->apply_dlg != NULL)
 
7484
        {
 
7485
          Select (dlg->apply_dlg);
 
7486
        }
 
7487
        break;
 
7488
      default :
 
7489
        break;
 
7490
    }
 
7491
  }
 
7492
}
 
7493
 
 
7494
static ValNodePtr TestEditApply (DialoG d)
 
7495
{
 
7496
  EditApplyDlgPtr dlg;
 
7497
  ValNodePtr      total_err_list = NULL, err_list;
 
7498
  
 
7499
  dlg = (EditApplyDlgPtr) GetObjectExtra (d);
 
7500
  if (dlg == NULL)
 
7501
  {
 
7502
    return FALSE;
 
7503
  }
 
7504
 
 
7505
  if (dlg->action_choice == eEditApplyChoice_Apply)
 
7506
  {
 
7507
    if (dlg->apply_dlg == NULL) 
 
7508
    {
 
7509
      if (TextHasNoText (dlg->apply_txt))
 
7510
      {
 
7511
        ValNodeAddPointer (&total_err_list, 0, StringSave ("apply text"));
 
7512
      }
 
7513
    }
 
7514
    else
 
7515
    {
 
7516
      total_err_list = TestDialog (dlg->apply_dlg);
 
7517
    }
 
7518
  }
 
7519
  else if (dlg->action_choice == eEditApplyChoice_Edit)
 
7520
  {
 
7521
    if (dlg->find_dlg == NULL)
 
7522
    {
 
7523
      if (TextHasNoText (dlg->find_txt))
 
7524
      {
 
7525
        ValNodeAddPointer (&total_err_list, 0, StringSave ("find text"));
 
7526
      }
 
7527
    }
 
7528
    else 
 
7529
    {
 
7530
      total_err_list = TestDialog (dlg->find_dlg);
 
7531
      err_list = TestDialog (dlg->repl_dlg);
 
7532
      ValNodeLink (&total_err_list, err_list);
 
7533
    }
 
7534
  }
 
7535
  return total_err_list;
 
7536
}
 
7537
 
 
7538
static void EditApplyDialogCopy (ButtoN b)
 
7539
{
 
7540
  EditApplyDlgPtr dlg;
 
7541
  CharPtr         str = NULL;
 
7542
 
 
7543
  dlg = (EditApplyDlgPtr) GetObjectExtra (b);
 
7544
  if (dlg == NULL)
 
7545
  {
 
7546
    return;
 
7547
  }
 
7548
  str = JustSaveStringFromText (dlg->find_txt);
 
7549
  SetTitle (dlg->repl_txt, str);
 
7550
  str = MemFree (str);
 
7551
}
 
7552
 
 
7553
extern DialoG EditApplyDialog 
 
7554
(GrouP                    h,
 
7555
 Int4                     action_choice, 
 
7556
 CharPtr                  apply_label,
 
7557
 ValNodePtr               choice_list,
 
7558
 Nlm_ChangeNotifyProc     change_notify,
 
7559
 Pointer                  change_userdata)
 
7560
{
 
7561
  EditApplyDlgPtr dlg;
 
7562
  GrouP           p, p1;
 
7563
  ButtoN          b;
 
7564
  ValNodePtr      cpy;
 
7565
  
 
7566
  dlg = (EditApplyDlgPtr) MemNew (sizeof (EditApplyDlgData));
 
7567
  if (dlg == NULL)
 
7568
  {
 
7569
    return NULL;
 
7570
  }
 
7571
 
 
7572
  p = HiddenGroup (h, -1, 0, NULL);
 
7573
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
7574
  SetGroupSpacing (p, 10, 10);
 
7575
 
 
7576
  dlg->dialog = (DialoG) p;
 
7577
  dlg->todialog = EditApplyToDialog;
 
7578
  dlg->fromdialog = DialogToEditApply;
 
7579
  dlg->dialogmessage = EditApplyMessage;
 
7580
  dlg->testdialog = TestEditApply;
 
7581
  dlg->action_choice = action_choice;
 
7582
  dlg->change_notify = change_notify;
 
7583
  dlg->change_userdata = change_userdata;
 
7584
 
 
7585
  if (choice_list == NULL)
 
7586
  {
 
7587
    p1 = HiddenGroup (p, 3, 0, NULL);
 
7588
    SetGroupSpacing (p1, 10, 10);
 
7589
 
 
7590
    if (action_choice == eEditApplyChoice_Apply)
 
7591
    {
 
7592
      StaticPrompt (p1, apply_label, 0, dialogTextHeight, systemFont, 'r');
 
7593
      dlg->apply_txt = DialogText (p1, "", 20, EditApplyDialogChangeText);
 
7594
      SetObjectExtra (dlg->apply_txt, dlg, NULL);
 
7595
      dlg->location_choice = NULL;
 
7596
    }
 
7597
    else if (action_choice == eEditApplyChoice_Edit)
 
7598
    {
 
7599
      StaticPrompt (p1, "Find", 0, dialogTextHeight, systemFont, 'r');
 
7600
      dlg->find_txt = DialogText (p1, "", 18, EditApplyDialogChangeText);
 
7601
      SetObjectExtra (dlg->find_txt, dlg, NULL);
 
7602
      b = PushButton (p1, "Copy", EditApplyDialogCopy);
 
7603
      SetObjectExtra (b, dlg, NULL);
 
7604
      Hide (b);
 
7605
      StaticPrompt (p1, "Replace", 0, dialogTextHeight, systemFont, 'r');
 
7606
      dlg->repl_txt = DialogText (p1, "", 18, EditApplyDialogChangeText);
 
7607
      SetObjectExtra (dlg->repl_txt, dlg, NULL);
 
7608
      b = PushButton (p1, "Copy", EditApplyDialogCopy);
 
7609
      SetObjectExtra (b, dlg, NULL);
 
7610
 
 
7611
      dlg->location_choice = HiddenGroup (p, 3, 0, NULL);
 
7612
      RadioButton (dlg->location_choice, "Anywhere in field");
 
7613
      RadioButton (dlg->location_choice, "At the beginning of the field");
 
7614
      RadioButton (dlg->location_choice, "At the end of the field");
 
7615
      SetValue (dlg->location_choice, EditApplyFindLocation_anywhere);
 
7616
    }
 
7617
  }
 
7618
  else
 
7619
  {
 
7620
    if (action_choice == eEditApplyChoice_Apply)
 
7621
    {
 
7622
      p1 = HiddenGroup (p, 1, 0, NULL);
 
7623
      SetGroupSpacing (p1, 10, 10);
 
7624
      if (!StringHasNoText (apply_label))
 
7625
      {
 
7626
        StaticPrompt (p1, apply_label, 0, dialogTextHeight, systemFont, 'r');
 
7627
      }
 
7628
      cpy = ValNodeDupStringList (choice_list);
 
7629
      dlg->apply_dlg = ValNodeSelectionDialog (p1, cpy, 6,
 
7630
                                               ValNodeStringName,
 
7631
                                               ValNodeSimpleDataFree,
 
7632
                                               ValNodeStringCopy,
 
7633
                                               ValNodeStringMatch,
 
7634
                                               apply_label,
 
7635
                                               dlg->change_notify, dlg->change_userdata, FALSE);
 
7636
    }
 
7637
    else if (action_choice == eEditApplyChoice_Edit)
 
7638
    {
 
7639
      p1 = HiddenGroup (p, 2, 0, NULL);
 
7640
      SetGroupSpacing (p1, 10, 10);
 
7641
      StaticPrompt (p1, "From", 0, dialogTextHeight, systemFont, 'r');
 
7642
      StaticPrompt (p1, "To", 0, dialogTextHeight, systemFont, 'r');
 
7643
 
 
7644
      cpy = ValNodeDupStringList (choice_list);
 
7645
      dlg->find_dlg = ValNodeSelectionDialog (p1, cpy, 6,
 
7646
                                               ValNodeStringName,
 
7647
                                               ValNodeSimpleDataFree,
 
7648
                                               ValNodeStringCopy,
 
7649
                                               ValNodeStringMatch,
 
7650
                                               "Original",
 
7651
                                               dlg->change_notify, dlg->change_userdata, FALSE);
 
7652
      cpy = ValNodeDupStringList (choice_list);
 
7653
      dlg->repl_dlg = ValNodeSelectionDialog (p1, cpy, 6,
 
7654
                                               ValNodeStringName,
 
7655
                                               ValNodeSimpleDataFree,
 
7656
                                               ValNodeStringCopy,
 
7657
                                               ValNodeStringMatch,
 
7658
                                               "New",
 
7659
                                               dlg->change_notify, dlg->change_userdata, FALSE);
 
7660
 
 
7661
    }
 
7662
    dlg->location_choice = NULL;
 
7663
  }
 
7664
  AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) dlg->location_choice, NULL);
 
7665
 
 
7666
  return (DialoG) p;
 
7667
}
 
7668
 
 
7669
 
 
7670
/* Global Inference Editor Dialog */
 
7671
 
 
7672
extern InferenceParsePtr ParseInferenceText (CharPtr inference)
 
7673
{
 
7674
  CharPtr cp1, cp2;
 
7675
  Int4    len;
 
7676
  InferenceParsePtr ipp;
 
7677
 
 
7678
  if (StringHasNoText (inference))
 
7679
  {
 
7680
    return NULL;
 
7681
  }
 
7682
 
 
7683
  cp1 = StringChr (inference, ':');
 
7684
  if (cp1 == NULL)  
 
7685
  {
 
7686
    return NULL;
 
7687
  }
 
7688
  cp2 = StringChr (cp1 + 1, ':');
 
7689
  if (cp2 == NULL)
 
7690
  {
 
7691
    return NULL;
 
7692
  }
 
7693
 
 
7694
  ipp = (InferenceParsePtr) MemNew (sizeof (InferenceParseData));
 
7695
  ipp->second_field = StringSave (cp2 + 1);
 
7696
 
 
7697
  len = cp2 - cp1;
 
7698
  ipp->first_field = (CharPtr) MemNew (sizeof (Char) * len);
 
7699
  StringNCpy (ipp->first_field, cp1 + 1, len - 1);
 
7700
  ipp->first_field[len - 1] = 0;
 
7701
 
 
7702
  /* look for same species */
 
7703
  cp2 = StringISearch (inference, "(same species)");
 
7704
  if (cp2 != NULL && cp2 < cp1)
 
7705
  {
 
7706
    ipp->same_species = TRUE;
 
7707
    cp1 = cp2;
 
7708
  } 
 
7709
  else
 
7710
  {
 
7711
    ipp->same_species = FALSE;
 
7712
  }
 
7713
  len = cp1 - inference + 1;
 
7714
  ipp->category = (CharPtr) MemNew (sizeof (Char) * len);
 
7715
  StringNCpy (ipp->category, inference, len - 1);
 
7716
  ipp->category[len - 1] = 0;
 
7717
  TrimSpacesAroundString (ipp->category);
 
7718
  TrimSpacesAroundString (ipp->first_field);
 
7719
  TrimSpacesAroundString (ipp->second_field);
 
7720
 
 
7721
  return ipp;  
 
7722
}
 
7723
 
 
7724
 
 
7725
extern CharPtr InferenceTextFromStruct (InferenceParsePtr ipp)
 
7726
{
 
7727
  Int4 len;
 
7728
  CharPtr inference = NULL;
 
7729
  CharPtr same_sp = " (same species)";
 
7730
 
 
7731
  if (ipp == NULL) return NULL;
 
7732
 
 
7733
  len = StringLen (ipp->category) + StringLen (ipp->first_field) + StringLen (ipp->second_field)
 
7734
        + 3;
 
7735
  if (ipp->same_species)
 
7736
  {
 
7737
    len += StringLen (same_sp);
 
7738
  }
 
7739
 
 
7740
  inference = (CharPtr) MemNew (sizeof (Char) * len);
 
7741
  sprintf (inference, "%s%s:%s:%s", ipp->category == NULL ? "" : ipp->category,
 
7742
                                    ipp->same_species ? same_sp : "",
 
7743
                                    ipp->first_field == NULL ? "" : ipp->first_field,
 
7744
                                    ipp->second_field == NULL ? "" : ipp->second_field);
 
7745
  return inference;
 
7746
}
 
7747
 
 
7748
 
 
7749
typedef enum {
 
7750
  eInferenceCategorySimilarTo = 0,
 
7751
  eInferenceCategoryProgram,
 
7752
  eInferenceCategoryAbInitio,
 
7753
  eNumInferenceCategories } EInferenceCategoryType;
 
7754
 
 
7755
 
 
7756
static Int4 GetCategoryTypeFromNum (Int4 num)
 
7757
{
 
7758
  if (num > 0 && num < 8) 
 
7759
  {
 
7760
    return eInferenceCategorySimilarTo;
 
7761
  }
 
7762
  else if (num > 7 && num < 11)
 
7763
  {
 
7764
    return eInferenceCategoryProgram;
 
7765
  }
 
7766
  else if (num == 11)
 
7767
  {
 
7768
    return eInferenceCategoryAbInitio;
 
7769
  }
 
7770
  else
 
7771
  {
 
7772
    return -1;
 
7773
  }
 
7774
}
 
7775
 
 
7776
 
 
7777
static Int4 GetCategoryNumFromName (CharPtr category)
 
7778
{
 
7779
  Int4 i;
 
7780
 
 
7781
  if (StringHasNoText (category)) 
 
7782
  {
 
7783
    return -1;
 
7784
  }
 
7785
 
 
7786
  for (i = 0; inference_alist[i].name != NULL; i++)
 
7787
  {
 
7788
    if (StringICmp (inference_alist[i].name, category) == 0)
 
7789
    {
 
7790
      return i;
 
7791
    }
 
7792
  }
 
7793
  return -1;
 
7794
}
 
7795
 
 
7796
 
 
7797
extern InferenceFieldEditPtr InferenceFieldEditFree (InferenceFieldEditPtr ifep)
 
7798
{
 
7799
  if (ifep != NULL)
 
7800
  {
 
7801
    ifep->edit_apply = EditApplyFree (ifep->edit_apply);
 
7802
    ifep = MemFree (ifep);
 
7803
  }
 
7804
  return ifep;
 
7805
}
 
7806
 
 
7807
extern InferenceEditPtr InferenceEditFree (InferenceEditPtr iep)
 
7808
{
 
7809
  if (iep != NULL)
 
7810
  {
 
7811
    iep->field_edit = InferenceFieldEditFree (iep->field_edit);
 
7812
    iep = MemFree (iep);
 
7813
  }
 
7814
  return iep;
 
7815
}
 
7816
 
 
7817
typedef struct inferencefieldeditdialog
 
7818
{
 
7819
  DIALOG_MESSAGE_BLOCK
 
7820
 
 
7821
  PopuP  field_category;
 
7822
  PopuP  field_list[eNumInferenceCategories];
 
7823
  DialoG field_editors[eNumInferenceCategories * 2];
 
7824
  Nlm_ChangeNotifyProc     change_notify;
 
7825
  Pointer                  change_userdata;
 
7826
 
 
7827
} InferenceFieldEditDialogData, PNTR InferenceFieldEditDialogPtr;
 
7828
 
 
7829
 
 
7830
static Pointer InferenceFieldEditDataFromDialog (DialoG d)
 
7831
{
 
7832
  InferenceFieldEditDialogPtr dlg;
 
7833
  UIEnum                      val;
 
7834
  Int4                        i, j;
 
7835
  InferenceFieldEditPtr       data = NULL;
 
7836
 
 
7837
  dlg = (InferenceFieldEditDialogPtr) GetObjectExtra (d);
 
7838
  if (dlg == NULL) return NULL;
 
7839
 
 
7840
  if (GetEnumPopup (dlg->field_category, inference_alist, &val)
 
7841
      && val > 0
 
7842
      && (i = GetCategoryTypeFromNum (val)) > -1
 
7843
      && (j = GetValue (dlg->field_list[i])) > 0
 
7844
      && j < 3)
 
7845
  {
 
7846
    data = (InferenceFieldEditPtr) MemNew (sizeof (InferenceFieldEditData));
 
7847
    data->field_category = inferencePrefix[val];
 
7848
    data->field_choice = j - 1;
 
7849
    data->edit_apply = DialogToPointer (dlg->field_editors[2 * i + j - 1]);
 
7850
  }
 
7851
  return data;
 
7852
}
 
7853
 
 
7854
 
 
7855
static void ChangeInferenceFieldChoice (PopuP p)
 
7856
{
 
7857
  InferenceFieldEditDialogPtr dlg;
 
7858
  UIEnum                      val;
 
7859
  Int4                        i, j;
 
7860
 
 
7861
  dlg = (InferenceFieldEditDialogPtr) GetObjectExtra (p);
 
7862
  if (dlg == NULL) return;
 
7863
 
 
7864
  for (i = eInferenceCategorySimilarTo;
 
7865
       i <= eInferenceCategoryAbInitio;
 
7866
       i++)
 
7867
  {
 
7868
    Hide (dlg->field_list[i]);
 
7869
    Hide (dlg->field_editors[2 * i]);
 
7870
    Hide (dlg->field_editors[2 * i + 1]);
 
7871
  }
 
7872
 
 
7873
  if (GetEnumPopup (dlg->field_category, inference_alist, &val)
 
7874
      && val > 0
 
7875
      && (i = GetCategoryTypeFromNum (val)) > -1)
 
7876
  {
 
7877
    Show (dlg->field_list[i]);
 
7878
    j = GetValue (dlg->field_list[i]);
 
7879
    if (j > 0 && j < 3)
 
7880
    {
 
7881
      Show (dlg->field_editors[2 * i + j - 1]);
 
7882
    }
 
7883
  }
 
7884
 
 
7885
  if (dlg->change_notify != NULL) 
 
7886
  {
 
7887
    (dlg->change_notify)(dlg->change_userdata);
 
7888
  }
 
7889
}
 
7890
 
 
7891
static ValNodePtr MakeValNodeListFromEnum ( EnumFieldAssocPtr al)
 
7892
{
 
7893
  EnumFieldAssocPtr efap;
 
7894
  ValNodePtr        list;
 
7895
 
 
7896
  efap = al;
 
7897
  list = NULL;
 
7898
  while (efap->name != NULL)
 
7899
  {
 
7900
    ValNodeAddStr (&list, efap->value, StringSave (efap->name));
 
7901
    efap ++;
 
7902
  }
 
7903
  return list;
 
7904
}
 
7905
 
 
7906
 
 
7907
static DialoG 
 
7908
CreateInferenceFieldEditApplyDialog 
 
7909
(GrouP                h,
 
7910
 Int4                 action_choice,
 
7911
 Nlm_ChangeNotifyProc change_notify,
 
7912
 Pointer              change_userdata)
 
7913
{
 
7914
  InferenceFieldEditDialogPtr dlg;
 
7915
  GrouP                       p, k;
 
7916
  Int4                        i;
 
7917
  ValNodePtr                  choice_list;
 
7918
 
 
7919
  dlg = (InferenceFieldEditDialogPtr) MemNew (sizeof (InferenceFieldEditDialogData));
 
7920
  if (dlg == NULL)
 
7921
  {
 
7922
    return NULL;
 
7923
  }
 
7924
  p = HiddenGroup (h, 3, 0, NULL);
 
7925
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
7926
  SetGroupSpacing (p, 10, 10);
 
7927
  
 
7928
  dlg->dialog = (DialoG) p;
 
7929
  dlg->todialog = NULL;
 
7930
  dlg->fromdialog = InferenceFieldEditDataFromDialog;
 
7931
  dlg->dialogmessage = NULL;
 
7932
  dlg->testdialog = NULL;
 
7933
  
 
7934
  dlg->change_notify = change_notify;
 
7935
  dlg->change_userdata = change_userdata;
 
7936
 
 
7937
  StaticPrompt (p, "Category", 0, popupMenuHeight, programFont, 'c');
 
7938
  StaticPrompt (p, "Field", 0, popupMenuHeight, programFont, 'c');
 
7939
  if (action_choice == eEditApplyChoice_Apply) 
 
7940
  {
 
7941
    StaticPrompt (p, "New Value", 0, popupMenuHeight, programFont, 'c');
 
7942
  }
 
7943
  else
 
7944
  {
 
7945
    StaticPrompt (p, "Convert", 0, popupMenuHeight, programFont, 'c');
 
7946
  }
 
7947
 
 
7948
  dlg->field_category = PopupList (p, TRUE, ChangeInferenceFieldChoice);
 
7949
  SetObjectExtra (dlg->field_category, dlg, NULL);
 
7950
  InitEnumPopup (dlg->field_category, inference_alist, NULL);
 
7951
 
 
7952
 
 
7953
  k = HiddenGroup (p, 0, 0, NULL);
 
7954
  dlg->field_list[eInferenceCategorySimilarTo] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
 
7955
  SetObjectExtra (dlg->field_list[eInferenceCategorySimilarTo], dlg, NULL);
 
7956
  PopupItem (dlg->field_list[eInferenceCategorySimilarTo], "Database");
 
7957
  PopupItem (dlg->field_list[eInferenceCategorySimilarTo], "Accession");
 
7958
  
 
7959
  dlg->field_list[eInferenceCategoryProgram] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
 
7960
  SetObjectExtra (dlg->field_list[eInferenceCategoryProgram], dlg, NULL);
 
7961
  PopupItem (dlg->field_list[eInferenceCategoryProgram], "Program or Database");
 
7962
  PopupItem (dlg->field_list[eInferenceCategoryProgram], "Version or Accession");
 
7963
  
 
7964
  dlg->field_list[eInferenceCategoryAbInitio] = PopupList (k, TRUE, ChangeInferenceFieldChoice);
 
7965
  SetObjectExtra (dlg->field_list[eInferenceCategoryAbInitio], dlg, NULL);
 
7966
  PopupItem (dlg->field_list[eInferenceCategoryAbInitio], "Program");
 
7967
  PopupItem (dlg->field_list[eInferenceCategoryAbInitio], "Program Version");
 
7968
 
 
7969
  k = HiddenGroup (p, 0, 0, NULL);
 
7970
  i = 0;
 
7971
  choice_list = MakeValNodeListFromEnum (accn_type_alist);
 
7972
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", choice_list, change_notify, change_userdata);
 
7973
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
 
7974
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
 
7975
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
 
7976
  choice_list = MakeValNodeListFromEnum (program_alist);
 
7977
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", choice_list, change_notify, change_userdata);
 
7978
  dlg->field_editors[i++] = EditApplyDialog (k, action_choice, "", NULL, change_notify, change_userdata);
 
7979
 
 
7980
  ChangeInferenceFieldChoice (dlg->field_category);
 
7981
  return (DialoG) p;
 
7982
}
 
7983
 
 
7984
 
 
7985
typedef struct inferenceeditdialog {
 
7986
  DIALOG_MESSAGE_BLOCK
 
7987
  PopuP action;
 
7988
  GrouP action_pages[eNumInferenceEditActions];
 
7989
  PopuP category_from;
 
7990
  PopuP category_to;
 
7991
  
 
7992
  DialoG apply_field;
 
7993
  DialoG edit_field;
 
7994
 
 
7995
  Nlm_ChangeNotifyProc change_notify;
 
7996
  Pointer              change_userdata;
 
7997
 
 
7998
} InferenceEditDialogData, PNTR InferenceEditDialogPtr;
 
7999
 
 
8000
 
 
8001
static Pointer InferenceEditDataFromDialog (DialoG d)
 
8002
{
 
8003
  InferenceEditDialogPtr dlg;
 
8004
  InferenceEditPtr       data;
 
8005
  Int4                   i;
 
8006
 
 
8007
  dlg = (InferenceEditDialogPtr) GetObjectExtra (d);
 
8008
  if (dlg == NULL) return NULL;
 
8009
 
 
8010
  data = (InferenceEditPtr) MemNew (sizeof (InferenceEditData));
 
8011
  if (data == NULL) return NULL;
 
8012
 
 
8013
  data->action = (EInferenceEditAction) (GetValue (dlg->action) - 1);
 
8014
 
 
8015
  switch (data->action)
 
8016
  {
 
8017
    case eInferenceRemove:
 
8018
      /* no other data needed */
 
8019
      break;
 
8020
    case eInferenceEditCategory:
 
8021
      i = GetValue (dlg->category_from);
 
8022
      if (i <= 1) 
 
8023
      {
 
8024
        data->category_from = NULL;
 
8025
      }
 
8026
      else
 
8027
      {
 
8028
        data->category_from = inferencePrefix[i - 2];
 
8029
      }
 
8030
      i = GetValue (dlg->category_to);
 
8031
      if (i < 1)
 
8032
      {
 
8033
        data->category_to = NULL;
 
8034
      }
 
8035
      else
 
8036
      {
 
8037
        data->category_to = inferencePrefix[i - 1];
 
8038
      }
 
8039
      break;
 
8040
    case eInferenceApplyCategoryFields:
 
8041
     data->field_edit = DialogToPointer (dlg->apply_field);
 
8042
     break;
 
8043
    case eInferenceEditCategoryFields:
 
8044
     data->field_edit = DialogToPointer (dlg->edit_field);
 
8045
      break;
 
8046
    default:
 
8047
      break;
 
8048
  }
 
8049
 
 
8050
  return data;
 
8051
}
 
8052
 
 
8053
 
 
8054
static void ChangeInferenceEditAction (PopuP p)
 
8055
{
 
8056
  InferenceEditDialogPtr dlg;
 
8057
  Int4                   i;
 
8058
 
 
8059
  dlg = (InferenceEditDialogPtr) GetObjectExtra (p);
 
8060
  if (dlg == NULL) return;
 
8061
 
 
8062
  ResetClip();
 
8063
  for (i = 0; i < eNumInferenceEditActions; i++)
 
8064
  {
 
8065
    Hide (dlg->action_pages[i]);
 
8066
  }
 
8067
 
 
8068
  i = GetValue (dlg->action);
 
8069
  if (i > 0 && i <= eNumInferenceEditActions)
 
8070
  {
 
8071
    Show (dlg->action_pages[i - 1]);
 
8072
  }
 
8073
 
 
8074
  if (dlg->change_notify != NULL) 
 
8075
  {
 
8076
    (dlg->change_notify) (dlg->change_userdata);
 
8077
  }
 
8078
}
 
8079
 
 
8080
 
 
8081
static void ChangeInferenceCategoryChoice (PopuP p)
 
8082
{
 
8083
  InferenceEditDialogPtr dlg;
 
8084
 
 
8085
  dlg = (InferenceEditDialogPtr) GetObjectExtra (p);
 
8086
  if (dlg == NULL) return;
 
8087
 
 
8088
  if (dlg->change_notify != NULL) 
 
8089
  {
 
8090
    (dlg->change_notify) (dlg->change_userdata);
 
8091
  }
 
8092
}
 
8093
 
 
8094
 
 
8095
static ValNodePtr TestInferenceEditDialog (DialoG d)
 
8096
{
 
8097
  ValNodePtr             err_list = NULL;
 
8098
  InferenceEditPtr       iep;
 
8099
 
 
8100
  iep = DialogToPointer (d);
 
8101
  if (iep == NULL)
 
8102
  {
 
8103
    ValNodeAddPointer (&err_list, 0, "no values");
 
8104
  }
 
8105
  else
 
8106
  {
 
8107
    switch (iep->action)
 
8108
    {
 
8109
      case eInferenceRemove:
 
8110
        /* nothing to check */
 
8111
        break;
 
8112
      case eInferenceEditCategory:
 
8113
        if (StringHasNoText (iep->category_from))
 
8114
        {
 
8115
          ValNodeAddPointer (&err_list, 0, "missing category from");
 
8116
        }
 
8117
        if (StringHasNoText (iep->category_to))
 
8118
        {
 
8119
          ValNodeAddPointer (&err_list, 0, "missing category to");
 
8120
        }
 
8121
        break;
 
8122
      case eInferenceApplyCategoryFields:
 
8123
      case eInferenceEditCategoryFields:
 
8124
        if (iep->field_edit == NULL)
 
8125
        {
 
8126
          ValNodeAddPointer (&err_list, 0, "missing edit data");
 
8127
        }
 
8128
        break;
 
8129
      default:
 
8130
        break;
 
8131
    }
 
8132
  }
 
8133
  iep = InferenceEditFree (iep);
 
8134
 
 
8135
  return err_list;
 
8136
}
 
8137
 
 
8138
 
 
8139
extern DialoG CreateInferenceEditDialog 
 
8140
(GrouP                    h,
 
8141
 Nlm_ChangeNotifyProc     change_notify,
 
8142
 Pointer                  change_userdata)
 
8143
{
 
8144
  InferenceEditDialogPtr dlg;
 
8145
  GrouP                  p, g;
 
8146
  Int4                   i;
 
8147
  Nlm_EnumFieldAssocPtr  eap;
 
8148
 
 
8149
  dlg = (InferenceEditDialogPtr) MemNew (sizeof (InferenceEditDialogData));
 
8150
  if (dlg == NULL)
 
8151
  {
 
8152
    return NULL;
 
8153
  }
 
8154
  p = HiddenGroup (h, -1, 0, NULL);
 
8155
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
8156
  SetGroupSpacing (p, 10, 10);
 
8157
  
 
8158
  dlg->dialog = (DialoG) p;
 
8159
  dlg->todialog = NULL;
 
8160
  dlg->fromdialog = InferenceEditDataFromDialog;
 
8161
  dlg->dialogmessage = NULL;
 
8162
  dlg->testdialog = TestInferenceEditDialog;
 
8163
 
 
8164
  dlg->change_notify = change_notify;
 
8165
  dlg->change_userdata = change_userdata;
 
8166
 
 
8167
  dlg->action = PopupList (p, TRUE, ChangeInferenceEditAction);
 
8168
  SetObjectExtra (dlg->action, dlg, NULL);
 
8169
  PopupItem (dlg->action, "Remove");
 
8170
  PopupItem (dlg->action, "Change Category");
 
8171
  PopupItem (dlg->action, "Apply Category Fields");
 
8172
  PopupItem (dlg->action, "Edit Category Fields");
 
8173
  SetValue (dlg->action, eInferenceRemove + 1);
 
8174
 
 
8175
  g = HiddenGroup (p, 0, 0, NULL);
 
8176
  i = 0;
 
8177
 
 
8178
  /* remove group */
 
8179
  dlg->action_pages[i] = HiddenGroup (g, -1, 0, NULL);
 
8180
  StaticPrompt (dlg->action_pages[i], "Hit Accept to Remove Inferences", 0, popupMenuHeight, programFont, 'c');
 
8181
  i++;
 
8182
 
 
8183
  /* edit category group */
 
8184
  dlg->action_pages[i] = HiddenGroup (g, 2, 0, NULL);
 
8185
  StaticPrompt (dlg->action_pages[i], "Original Category", 0, popupMenuHeight, programFont, 'c');
 
8186
  dlg->category_from = PopupList (dlg->action_pages[i], TRUE, ChangeInferenceCategoryChoice);
 
8187
  SetObjectExtra (dlg->category_from, dlg, NULL);
 
8188
  PopupItem (dlg->category_from, "Any");
 
8189
  eap = inference_alist;
 
8190
  while (eap->name != NULL) {
 
8191
    PopupItem (dlg->category_from, eap->name);
 
8192
    eap++;
 
8193
  }
 
8194
  
 
8195
  StaticPrompt (dlg->action_pages[i], "New Category", 0, popupMenuHeight, programFont, 'c');
 
8196
  dlg->category_to = PopupList (dlg->action_pages[i], TRUE, ChangeInferenceCategoryChoice);
 
8197
  SetObjectExtra (dlg->category_to, dlg, NULL);
 
8198
  InitEnumPopup (dlg->category_to, inference_alist, NULL);
 
8199
  i++;
 
8200
 
 
8201
  dlg->action_pages[i] = HiddenGroup (g, 0, 0, NULL);
 
8202
  dlg->apply_field = CreateInferenceFieldEditApplyDialog (dlg->action_pages[i], eEditApplyChoice_Apply, change_notify, change_userdata);
 
8203
  i++;
 
8204
  
 
8205
  dlg->action_pages[i] = HiddenGroup (g, 0, 0, NULL);
 
8206
  dlg->edit_field = CreateInferenceFieldEditApplyDialog (dlg->action_pages[i], eEditApplyChoice_Edit, change_notify, change_userdata);
 
8207
  i++;
 
8208
  
 
8209
  AlignObjects (ALIGN_CENTER, (HANDLE) dlg->action_pages[0],
 
8210
                              (HANDLE) dlg->action_pages[1],
 
8211
                              (HANDLE) dlg->action_pages[2],
 
8212
                              (HANDLE) dlg->action_pages[3],
 
8213
                              NULL);
 
8214
  
 
8215
  AlignObjects (ALIGN_CENTER, (HANDLE) dlg->action, (HANDLE) g, NULL);
 
8216
 
 
8217
  ChangeInferenceEditAction (dlg->action);
 
8218
 
 
8219
  return (DialoG) p;
 
8220
}
 
8221
 
 
8222
 
 
8223
/* This section of code is for handling ClickableLists */
 
8224
 
 
8225
typedef struct clickablelist
 
8226
{
 
8227
  DIALOG_MESSAGE_BLOCK
 
8228
  DoC  doc;
 
8229
  DoC  clickable_item_list;
 
8230
  PrompT title1;
 
8231
  PrompT title2;
 
8232
  PrompT help1;
 
8233
  PrompT help2;
 
8234
  TexT find_txt;
 
8235
 
 
8236
  ClickableCallback item_single_click_callback;
 
8237
  ClickableCallback item_double_click_callback;
 
8238
  Pointer         item_click_callback_data;
 
8239
  GetClickableItemText get_item_text;
 
8240
  Boolean         dblClick;  
 
8241
  Int2            clicked;
 
8242
  Int2            selected;
 
8243
  Int2            item_selected;  
 
8244
  Int4            num_levels;
 
8245
  ValNodePtr      list_list;
 
8246
  Nlm_ColPtr PNTR col_fmt_array_array;
 
8247
 
 
8248
  Int2            text_select_item_start;
 
8249
  Int2            text_select_row_start;
 
8250
  Int2            text_select_char_start;
 
8251
  Int2            text_select_item_stop;
 
8252
  Int2            text_select_row_stop;
 
8253
  Int2            text_select_char_stop;
 
8254
  Int2            text_select_item_anchor;
 
8255
  Int2            text_select_row_anchor;
 
8256
  Int2            text_select_char_anchor;
 
8257
 
 
8258
} ClickableListData, PNTR ClickableListPtr;
 
8259
 
 
8260
 
 
8261
static Nlm_ParData clickableParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
 
8262
static Nlm_ColData clickableColFmt[2] = {{16, 0, 0, 0, NULL, 'l', 0,0,0,0, FALSE},
 
8263
                                    {1000, 0, 0, 0, NULL, 'l', 1,0,0,0, TRUE}};
 
8264
 
 
8265
static Nlm_ParData clickableItemParFmt = {FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0};
 
8266
static Nlm_ColData clickableItemColFmt [4] = {{0, 5, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
 
8267
                                         {0, 0, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
 
8268
                                         {0, 0, 10, 0, NULL, 'l', 1,0,0,0, FALSE},
 
8269
                                         {0, 0, 10, 0, NULL, 'l', 1,0,0,0, TRUE}};
 
8270
 
 
8271
 
 
8272
 
 
8273
static Nlm_ColPtr PNTR FreeColumnFormatArrays (Nlm_ColPtr PNTR col_fmt_array_array, Int4 num_levels)
 
8274
{
 
8275
  Int4 n;
 
8276
  
 
8277
  if (col_fmt_array_array == NULL || num_levels < 1)
 
8278
  {
 
8279
    return NULL;
 
8280
  }
 
8281
  for (n = 0; n < num_levels; n++)
 
8282
  {
 
8283
    col_fmt_array_array [n] = MemFree (col_fmt_array_array [n]);
 
8284
  }
 
8285
  col_fmt_array_array = MemFree (col_fmt_array_array);
 
8286
  return col_fmt_array_array;
 
8287
}
 
8288
 
 
8289
static void CleanupClickableListDialog (GraphiC g, VoidPtr data)
 
8290
 
 
8291
{
 
8292
  ClickableListPtr dlg;
 
8293
 
 
8294
  dlg = (ClickableListPtr) data;
 
8295
  if (dlg != NULL) {
 
8296
     dlg->col_fmt_array_array = FreeColumnFormatArrays (dlg->col_fmt_array_array, dlg->num_levels);
 
8297
  }
 
8298
  StdCleanupExtraProc (g, data);
 
8299
}
 
8300
 
 
8301
 
 
8302
static ClickableItemPtr GetSubItem (ValNodePtr item_list, Int2Ptr pitem)
 
8303
{
 
8304
  ClickableItemPtr cip = NULL;
 
8305
 
 
8306
  if (item_list == NULL || pitem == NULL)
 
8307
  {
 
8308
    return NULL;
 
8309
  }
 
8310
  while (*pitem > 0 && item_list != NULL)
 
8311
  {
 
8312
    (*pitem)--;
 
8313
    cip = (ClickableItemPtr) item_list->data.ptrvalue;
 
8314
    if (*pitem > 0)
 
8315
    {
 
8316
      if (cip != NULL && cip->expanded)
 
8317
      {
 
8318
        cip = GetSubItem (cip->subcategories, pitem);
 
8319
      }
 
8320
    }
 
8321
    item_list = item_list->next;
 
8322
  }
 
8323
  if (*pitem > 0)
 
8324
  {
 
8325
    cip = NULL;
 
8326
  }
 
8327
  return cip;
 
8328
}
 
8329
 
 
8330
static Int4 CountLevels (ValNodePtr item_list)
 
8331
{
 
8332
  Int4       num, num_sublevels = 0;
 
8333
  ValNodePtr vnp;
 
8334
  ClickableItemPtr cip;
 
8335
  
 
8336
  if (item_list == NULL) 
 
8337
  {
 
8338
    return 0;
 
8339
  }
 
8340
  
 
8341
  for (vnp = item_list; vnp != NULL; vnp = vnp->next)
 
8342
  {
 
8343
    cip = (ClickableItemPtr) vnp->data.ptrvalue;
 
8344
    if (cip == NULL || cip->subcategories == NULL || !cip->expanded)
 
8345
    {
 
8346
      continue;
 
8347
    }
 
8348
    num = CountLevels (cip->subcategories);
 
8349
    if (num > num_sublevels) num_sublevels = num;
 
8350
  }
 
8351
  
 
8352
  /* one level for the top plus levels for the subcategories */
 
8353
 
 
8354
  return 1 + num_sublevels;
 
8355
}
 
8356
 
 
8357
 
 
8358
static ClickableItemPtr GetSelectedClickableList (ValNodePtr item_list, Int2 item)
 
8359
{
 
8360
  ClickableItemPtr cip = NULL;
 
8361
  
 
8362
  cip = GetSubItem (item_list, &item);
 
8363
 
 
8364
  return cip;
 
8365
}
 
8366
 
 
8367
 
 
8368
static Nlm_ColPtr PNTR GetColumnFormatArrays (Int4 num_levels, DoC doc)
 
8369
{
 
8370
  Int4               n, k;
 
8371
  Nlm_ColPtr PNTR    col_fmt_array_array = NULL;
 
8372
  RecT               r;
 
8373
  Int4               doc_width;
 
8374
    
 
8375
  if (num_levels == 0)
 
8376
  {
 
8377
    return NULL;
 
8378
  }
 
8379
  
 
8380
  ObjectRect (doc, &r);
 
8381
  InsetRect (&r, 4, 4);
 
8382
  doc_width = r.right - r.left;
 
8383
  
 
8384
  col_fmt_array_array = (Nlm_ColPtr PNTR) MemNew (sizeof (Nlm_ColPtr) * num_levels);
 
8385
  for (n = 0; n < num_levels; n++)
 
8386
  {
 
8387
    col_fmt_array_array[n] = (Nlm_ColPtr) MemNew (sizeof (Nlm_ColData) * (n + 3));
 
8388
    for (k = 0; k < n + 2; k++)
 
8389
    {
 
8390
      col_fmt_array_array[n][k].pixWidth = 16;
 
8391
      col_fmt_array_array[n][k].pixInset = 0;
 
8392
      col_fmt_array_array[n][k].charWidth = 0;
 
8393
      col_fmt_array_array[n][k].charInset = 0;
 
8394
      col_fmt_array_array[n][k].font = programFont;
 
8395
      col_fmt_array_array[n][k].just = 'l';
 
8396
      col_fmt_array_array[n][k].wrap = 0;
 
8397
      col_fmt_array_array[n][k].bar = 0;
 
8398
      col_fmt_array_array[n][k].underline = 0;
 
8399
      col_fmt_array_array[n][k].left = 0;
 
8400
      col_fmt_array_array[n][k].last = 0;
 
8401
    }
 
8402
    col_fmt_array_array[n][k].pixWidth = doc_width - ((n + 2) * 16);
 
8403
    col_fmt_array_array[n][k].pixInset = 0;
 
8404
    col_fmt_array_array[n][k].charWidth = 0;
 
8405
    col_fmt_array_array[n][k].charInset = 0;
 
8406
    col_fmt_array_array[n][k].font = programFont;
 
8407
    col_fmt_array_array[n][k].just = 'l';
 
8408
    col_fmt_array_array[n][k].wrap = 1;
 
8409
    col_fmt_array_array[n][k].bar = 0;
 
8410
    col_fmt_array_array[n][k].underline = 0;
 
8411
    col_fmt_array_array[n][k].left = 0;
 
8412
    col_fmt_array_array[n][k].last = 1;
 
8413
  }
 
8414
  return col_fmt_array_array;
 
8415
}
 
8416
 
 
8417
 
 
8418
static void AddClickableItem (ClickableListPtr dlg, ClickableItemPtr cip, Int4 level)
 
8419
{
 
8420
  CharPtr            item_text;
 
8421
  ValNodePtr         vnp;
 
8422
  Int4               n;
 
8423
 
 
8424
  if (cip == NULL)
 
8425
  {
 
8426
    return;
 
8427
  }
 
8428
  item_text = (CharPtr) MemNew (sizeof (Char) * (StringLen (cip->description) + 6 + level));
 
8429
  for (n = 0; n < level; n++)
 
8430
  {
 
8431
    StringCat (item_text, "\t");
 
8432
  }
 
8433
  StringCat (item_text, " \t \t");
 
8434
  StringCat (item_text, cip->description);
 
8435
  StringCat (item_text, "\n");
 
8436
  AppendText (dlg->doc, item_text, &clickableParFmt, dlg->col_fmt_array_array [level], programFont);
 
8437
  if (cip->expanded)
 
8438
  {
 
8439
    for (vnp = cip->subcategories; vnp != NULL; vnp = vnp->next)
 
8440
    {
 
8441
      AddClickableItem (dlg, vnp->data.ptrvalue, level + 1);
 
8442
    }
 
8443
  }
 
8444
}
 
8445
 
 
8446
static void PopulateClickableList (ClickableListPtr dlg, ValNodePtr list_list)
 
8447
{
 
8448
  Int2               numItems;
 
8449
  Int4               num_levels;
 
8450
  
 
8451
  if (dlg == NULL || dlg->doc == NULL) 
 
8452
  {
 
8453
    return;
 
8454
  }
 
8455
  
 
8456
  Reset (dlg->doc);
 
8457
  
 
8458
  num_levels = CountLevels (dlg->list_list);
 
8459
  if (num_levels != dlg->num_levels)
 
8460
  {
 
8461
    dlg->col_fmt_array_array = FreeColumnFormatArrays (dlg->col_fmt_array_array, dlg->num_levels);
 
8462
    dlg->num_levels = num_levels;
 
8463
    dlg->col_fmt_array_array = GetColumnFormatArrays (dlg->num_levels, dlg->doc);
 
8464
  }
 
8465
  
 
8466
  while (list_list != NULL)
 
8467
  {
 
8468
    AddClickableItem (dlg, list_list->data.ptrvalue, 0);
 
8469
    list_list = list_list->next;
 
8470
  }
 
8471
  GetDocParams (dlg->doc, &numItems, NULL);
 
8472
  UpdateDocument (dlg->doc, 0, numItems);
 
8473
 
 
8474
}
 
8475
 
 
8476
 
 
8477
NLM_EXTERN Int2 PanelOffsetFromCharOffsetEx (DoC doc, FonT font, Int2 item, Int2 col, Int2 char_offset)
 
8478
{
 
8479
  Int2 numRows, numCols, lineHeight;
 
8480
  Int2 left_start, width, inset, char_width;
 
8481
 
 
8482
  if (doc == NULL) return 0;
 
8483
  GetItemParams4 (doc, item, NULL, &numRows, &numCols, &lineHeight, NULL);
 
8484
  GetColParams (doc, item, col, &left_start, &width, &inset, NULL);
 
8485
 
 
8486
  /* need to set font so that Nlm_CharWidth works properly */
 
8487
  SelectFont (font);
 
8488
  char_width = Nlm_CharWidth ('A');
 
8489
  return left_start + inset + char_offset * char_width;
 
8490
}
 
8491
 
 
8492
 
 
8493
static Int2 PanelOffsetFromCharOffset (ClickableListPtr dlg, Int2 item, Int2 char_offset)
 
8494
{
 
8495
  Int2 numCols;
 
8496
  if (dlg == NULL) return 0;
 
8497
  GetItemParams4 (dlg->doc, item, NULL, NULL, &numCols, NULL, NULL);
 
8498
 
 
8499
  return PanelOffsetFromCharOffsetEx (dlg->doc, dlg->col_fmt_array_array[0][0].font, item, numCols, char_offset);
 
8500
}
 
8501
 
 
8502
 
 
8503
NLM_EXTERN Int2 GetTextSelectCharOffsetEx (PoinT pt, DoC doc, FonT font, Int2 item, Int2 row, Int2 col)
 
8504
{
 
8505
  Int2 pixPos, pixInset;
 
8506
  Int2 one_char_width;
 
8507
  CharPtr txt;
 
8508
  Int4    len;
 
8509
  Int2    char_offset;
 
8510
 
 
8511
  if (doc == NULL) return 0;
 
8512
 
 
8513
  GetColParams (doc, item, col, &pixPos,
 
8514
                NULL, &pixInset, NULL);
 
8515
 
 
8516
  SelectFont (font);
 
8517
  one_char_width = Nlm_CharWidth ('A');
 
8518
  if (one_char_width == 0) return 0;
 
8519
 
 
8520
  char_offset = (pt.x - pixPos - pixInset) / one_char_width;
 
8521
  if (char_offset > 0) {
 
8522
    txt = GetDocText (doc, item, row, col);
 
8523
    len = StringLen (txt);
 
8524
    if (char_offset >= len) {
 
8525
      char_offset = - 1;
 
8526
    }
 
8527
  }
 
8528
 
 
8529
  return char_offset; 
 
8530
}
 
8531
 
 
8532
 
 
8533
static Int2 GetTextSelectCharOffset (PoinT pt, ClickableListPtr dlg, Int2 item, Int2 row, Int2 col)
 
8534
{
 
8535
  if (dlg == NULL) return 0;
 
8536
 
 
8537
  return GetTextSelectCharOffsetEx (pt, dlg->doc, dlg->col_fmt_array_array[0][0].font, item, row, col);
 
8538
}
 
8539
 
 
8540
 
 
8541
static void ClickList (DoC d, PoinT pt)
 
8542
 
 
8543
{
 
8544
  Int2             item, numItems;
 
8545
  Int2             row;
 
8546
  Int2             col;
 
8547
  ClickableListPtr dlg;
 
8548
  ClickableItemPtr cip;
 
8549
  Int4             offset;
 
8550
  Int2             first_shown;
 
8551
  Boolean          rsult;
 
8552
  RecT             r;
 
8553
 
 
8554
  dlg = GetObjectExtra (d);
 
8555
  if (dlg != NULL) {
 
8556
    MapDocPoint (d, pt, &item, &row, &col, NULL);
 
8557
    if (item > 0 && row > 0 && dlg->clicked == item) {
 
8558
      dlg->dblClick = dblClick;
 
8559
    } else {
 
8560
      dlg->dblClick = FALSE;
 
8561
    }
 
8562
    dlg->clicked = 0;
 
8563
    if (item > 0 && row > 0) {
 
8564
      dlg->clicked = item;
 
8565
    }
 
8566
    if (item > 0 && row > 0 && !dblClick)
 
8567
    {
 
8568
      cip = GetSelectedClickableList (dlg->list_list, item);
 
8569
      if (cip != NULL)
 
8570
      {
 
8571
        if (col == cip->level + 1)
 
8572
        {
 
8573
          cip->chosen = !cip->chosen;
 
8574
          GetDocParams (d, &numItems, NULL);
 
8575
          UpdateDocument (d, 0, numItems);
 
8576
        }
 
8577
        else if (col == cip->level + 2)
 
8578
        {
 
8579
          cip->expanded = !cip->expanded;
 
8580
          rsult = GetScrlParams4 (dlg->doc, &offset, &first_shown, NULL);
 
8581
          PopulateClickableList (dlg, dlg->list_list);
 
8582
          if (rsult) {
 
8583
            GetItemParams4 (dlg->doc, first_shown, &offset, NULL, NULL, NULL, NULL);
 
8584
            SetScrlParams4 (dlg->doc, offset);
 
8585
          }
 
8586
          ObjectRect (dlg->doc, &r);
 
8587
          InsetRect (&r, -1, -1);
 
8588
          InvalRect (&r);
 
8589
        } else {
 
8590
          dlg->text_select_item_anchor = item;
 
8591
          dlg->text_select_row_anchor = row;
 
8592
          dlg->text_select_char_anchor = GetTextSelectCharOffset (pt, dlg, item, row, col);
 
8593
 
 
8594
          dlg->text_select_char_start = dlg->text_select_char_anchor;
 
8595
          dlg->text_select_char_stop = dlg->text_select_char_start;
 
8596
          if (dlg->text_select_char_start < 0) {
 
8597
            dlg->text_select_item_start = -1;
 
8598
            dlg->text_select_row_start = -1;
 
8599
            dlg->text_select_item_stop = -1;
 
8600
            dlg->text_select_row_stop = -1;
 
8601
          } else {
 
8602
            dlg->text_select_item_start = item;
 
8603
            dlg->text_select_row_start = row;
 
8604
            dlg->text_select_item_stop = item;
 
8605
            dlg->text_select_row_stop = row;
 
8606
          }
 
8607
          GetDocParams (dlg->doc, &numItems, NULL);
 
8608
          UpdateDocument (dlg->doc, 0, numItems);
 
8609
        }
 
8610
      }
 
8611
    }
 
8612
  }
 
8613
}
 
8614
 
 
8615
static void UpdateClickableListTextSelection (ClickableListPtr dlg, Int2 item, Int2 row, Int2 col, PoinT pt)
 
8616
{
 
8617
  Int2 char_start, numCols;
 
8618
 
 
8619
  if (dlg == NULL || item < 1 || row < 1) return;
 
8620
 
 
8621
  /* only update for positions in the text area */
 
8622
  GetItemParams4 (dlg->doc, item, NULL, NULL, &numCols, NULL, NULL);
 
8623
  if (col != numCols) {
 
8624
    return;
 
8625
  }
 
8626
 
 
8627
  char_start = GetTextSelectCharOffset (pt, dlg, item, row, col);
 
8628
  if (char_start < 0) {
 
8629
    /* no updates unless mouse is in text area */
 
8630
    return;
 
8631
  }
 
8632
    
 
8633
  if (item < dlg->text_select_item_anchor) {
 
8634
    /* mouse is before anchor */
 
8635
    dlg->text_select_item_start = item;
 
8636
    dlg->text_select_row_start = row;
 
8637
    dlg->text_select_char_start = char_start;
 
8638
    dlg->text_select_item_stop = dlg->text_select_item_anchor;
 
8639
    dlg->text_select_row_stop = dlg->text_select_row_anchor;
 
8640
    dlg->text_select_char_stop = dlg->text_select_char_anchor;
 
8641
  } else if (item == dlg->text_select_item_anchor) {
 
8642
    /* start and stop in the anchor item */
 
8643
    dlg->text_select_item_start = item;
 
8644
    dlg->text_select_item_stop = item;
 
8645
    if (row < dlg->text_select_row_anchor) {
 
8646
      /* mouse is before anchor */
 
8647
      dlg->text_select_row_start = row;
 
8648
      dlg->text_select_char_start = char_start;
 
8649
      dlg->text_select_row_stop = dlg->text_select_row_anchor;
 
8650
      dlg->text_select_char_stop = dlg->text_select_char_anchor;
 
8651
    } else if (row == dlg->text_select_row_anchor) {
 
8652
      /* start and stop in the anchor row */
 
8653
      dlg->text_select_row_start = row;
 
8654
      dlg->text_select_row_stop = row;
 
8655
      if (char_start <= dlg->text_select_char_anchor) {
 
8656
        /* mouse is before anchor */
 
8657
        dlg->text_select_char_start = char_start;
 
8658
        dlg->text_select_char_stop = dlg->text_select_char_anchor;
 
8659
      } else {
 
8660
        dlg->text_select_char_start = dlg->text_select_char_anchor;
 
8661
        dlg->text_select_char_stop = char_start;
 
8662
      }
 
8663
    }
 
8664
  } else {
 
8665
    /* mouse is after anchor */
 
8666
    dlg->text_select_item_start = dlg->text_select_item_anchor;
 
8667
    dlg->text_select_row_start = dlg->text_select_row_anchor;
 
8668
    dlg->text_select_char_start = dlg->text_select_char_anchor;
 
8669
    dlg->text_select_item_stop = item;
 
8670
    dlg->text_select_row_stop = row;
 
8671
    dlg->text_select_char_stop = char_start;
 
8672
  }
 
8673
  InvalDocRows (dlg->doc, 0, 0, 0);
 
8674
}
 
8675
 
 
8676
static void DragClickableList (DoC d, PoinT pt)
 
8677
{
 
8678
  Int2            item, row, col, numCols;
 
8679
 
 
8680
  ClickableListPtr dlg;
 
8681
 
 
8682
  dlg = GetObjectExtra (d);
 
8683
  if (dlg != NULL) {
 
8684
    MapDocPoint (d, pt, &item, &row, &col, NULL);
 
8685
    GetItemParams4 (d, item, NULL, NULL, &numCols, NULL, NULL);
 
8686
    if (col == numCols) {
 
8687
      UpdateClickableListTextSelection (dlg, item, row, col, pt);
 
8688
    }
 
8689
  }
 
8690
}
 
8691
 
 
8692
 
 
8693
static void InvalBorder (DoC d, Int2 item)
 
8694
 
 
8695
{
 
8696
  Int2  bottom;
 
8697
  RecT  r;
 
8698
  Int2  top;
 
8699
 
 
8700
  ObjectRect (d, &r);
 
8701
  InsetRect (&r, 4, 4);
 
8702
  if (ItemIsVisible (d, item, &top, &bottom, NULL)) {
 
8703
    r.top = top;
 
8704
    r.bottom = bottom;
 
8705
    r.right = r.left + 4;
 
8706
    InsetRect (&r, -1, -1);
 
8707
    InvalRect (&r);
 
8708
  }
 
8709
}
 
8710
 
 
8711
static void ActOnClickableList (ValNodePtr list_list, Int2 item)
 
8712
{
 
8713
  ClickableItemPtr cip;
 
8714
  
 
8715
  cip = GetSelectedClickableList (list_list, item);
 
8716
  if (cip != NULL && cip->callback_func != NULL)
 
8717
  {
 
8718
    (cip->callback_func) (cip->item_list, cip->callback_data);
 
8719
  }
 
8720
}
 
8721
 
 
8722
 
 
8723
static void PopulateClickableItemList (DoC doc, ClickableItemPtr cip, GetClickableItemText get_item_text)
 
8724
{
 
8725
  ValNodePtr        vnp;
 
8726
  Int2              numItems;
 
8727
  CharPtr           row_text;
 
8728
  RecT              r;
 
8729
  
 
8730
  if (doc == NULL || get_item_text == NULL)
 
8731
  {
 
8732
    return;
 
8733
  }
 
8734
  Reset (doc);
 
8735
  
 
8736
  if (cip == NULL)
 
8737
  {
 
8738
    return;
 
8739
  }
 
8740
  
 
8741
  if (cip->item_list == NULL)
 
8742
  {
 
8743
    AppendText (doc, "No items listed", NULL, NULL, programFont);
 
8744
  }
 
8745
  
 
8746
  ObjectRect (doc, &r);
 
8747
  InsetRect (&r, 4, 4);
 
8748
  
 
8749
  clickableItemColFmt[0].pixWidth = 5 * stdCharWidth;
 
8750
  clickableItemColFmt[1].pixWidth = (r.right - r.left - clickableItemColFmt[0].pixWidth) / 3;
 
8751
  clickableItemColFmt[2].pixWidth = (r.right - r.left - clickableItemColFmt[0].pixWidth) / 3;
 
8752
  clickableItemColFmt[3].pixWidth = (r.right - r.left - clickableItemColFmt[0].pixWidth) / 3;
 
8753
  
 
8754
  vnp = cip->item_list;
 
8755
  
 
8756
  while (vnp != NULL)
 
8757
  {
 
8758
    row_text = get_item_text (vnp);
 
8759
    if (row_text != NULL)
 
8760
    {
 
8761
      if (vnp->choice == OBJ_SEQFEAT)
 
8762
      {
 
8763
        AppendText (doc, row_text, &clickableItemParFmt, clickableItemColFmt, programFont);
 
8764
      }
 
8765
      else
 
8766
      {
 
8767
        AppendText (doc, row_text, &clickableItemParFmt, NULL, programFont);
 
8768
      }
 
8769
      row_text = MemFree (row_text);
 
8770
    }
 
8771
    vnp = vnp->next;
 
8772
  }
 
8773
  GetDocParams (doc, &numItems, NULL);
 
8774
  UpdateDocument (doc, 0, numItems);  
 
8775
}
 
8776
 
 
8777
static void ReleaseClickableList (DoC d, PoinT pt)
 
8778
 
 
8779
{
 
8780
  Int2           item;
 
8781
  Int2           old;
 
8782
  Int2           row, col;
 
8783
  ClickableListPtr dlg;
 
8784
 
 
8785
  dlg = GetObjectExtra (d);
 
8786
  if (dlg != NULL) {
 
8787
    ResetClip ();
 
8788
    MapDocPoint (d, pt, &item, &row, &col, NULL);
 
8789
    /* update text selection */
 
8790
    UpdateClickableListTextSelection (dlg, item, row, col, pt);
 
8791
 
 
8792
    if (item > 0 && row > 0) {
 
8793
 
 
8794
      if (item == dlg->clicked) {
 
8795
        old = dlg->selected;
 
8796
        dlg->selected = item;
 
8797
        if (old != item) {
 
8798
          if (old == 0) {
 
8799
            UpdateDocument (d, item, item);
 
8800
          } else {
 
8801
            UpdateDocument (d, old, old);
 
8802
            UpdateDocument (d, item, item);
 
8803
          }
 
8804
          Update ();
 
8805
        }
 
8806
      }
 
8807
    } else if (dlg->clicked == 0) {
 
8808
      if (dlg->selected != 0) {
 
8809
        old = dlg->selected;
 
8810
        dlg->selected = 0;
 
8811
        InvalBorder (d, old);
 
8812
      }
 
8813
      Update ();
 
8814
    }
 
8815
    if (dlg->selected > 0 && dlg->dblClick)
 
8816
    {
 
8817
      ActOnClickableList (dlg->list_list, dlg->selected);
 
8818
    }
 
8819
    else if (dlg->selected > 0)
 
8820
    {
 
8821
      dlg->item_selected = 0;
 
8822
      PopulateClickableItemList (dlg->clickable_item_list, 
 
8823
                                 GetSelectedClickableList (dlg->list_list,
 
8824
                                                           dlg->selected),
 
8825
                                 dlg->get_item_text);
 
8826
      
 
8827
    }
 
8828
  }
 
8829
}
 
8830
 
 
8831
 
 
8832
static void DrawTextSelection (ClickableListPtr dlg, Int2 item, RectPtr r)
 
8833
{
 
8834
  Int2 lineHeight, numRows, numCols;
 
8835
  Int2 last_right;
 
8836
  Int2 left_start;
 
8837
  Int4 top, line_y;
 
8838
  CharPtr txt;
 
8839
 
 
8840
  if (dlg == NULL || r == NULL
 
8841
      || item < dlg->text_select_item_start
 
8842
      || item > dlg->text_select_item_stop) {
 
8843
    return;
 
8844
  }
 
8845
 
 
8846
  if (dlg->text_select_item_start == dlg->text_select_item_stop
 
8847
      && dlg->text_select_row_start == dlg->text_select_row_stop
 
8848
      && dlg->text_select_char_start == dlg->text_select_char_stop) {
 
8849
    /* if we've only selected one char, and it's blank, don't draw it. */
 
8850
    txt = GetSelectedClickableListText (dlg->dialog);
 
8851
    if (StringHasNoText (txt)) {
 
8852
      MemFree (txt);
 
8853
      return;
 
8854
    }
 
8855
    MemFree (txt);
 
8856
  }
 
8857
 
 
8858
  GetItemParams4 (dlg->doc, item, &top, &numRows, &numCols, &lineHeight, NULL);
 
8859
 
 
8860
  /* calculate missing rows from end first */
 
8861
  if (dlg->text_select_item_stop == item) {
 
8862
    numRows = dlg->text_select_row_stop;
 
8863
    last_right = PanelOffsetFromCharOffset (dlg, item, dlg->text_select_char_stop + 1);
 
8864
  } else {
 
8865
    last_right = r->right;
 
8866
  }
 
8867
 
 
8868
  if (dlg->text_select_item_start == item) {
 
8869
    left_start = PanelOffsetFromCharOffset (dlg, item, dlg->text_select_char_start);
 
8870
    line_y = r->top + (dlg->text_select_row_start) * lineHeight - 1;
 
8871
    numRows -= dlg->text_select_row_start - 1;
 
8872
  } else {
 
8873
    left_start = PanelOffsetFromCharOffset (dlg, item, 0);
 
8874
    line_y = r->top + lineHeight - 1;
 
8875
  }
 
8876
 
 
8877
  while (numRows > 1) {
 
8878
    MoveTo (left_start, line_y);
 
8879
    left_start = PanelOffsetFromCharOffset (dlg, item, 0);
 
8880
    LineTo (r->right, line_y);
 
8881
    line_y += lineHeight;
 
8882
    numRows--;
 
8883
  }
 
8884
  MoveTo (left_start, line_y);
 
8885
  LineTo (last_right, line_y);
 
8886
 
 
8887
}
 
8888
 
 
8889
static void DrawClickableList (DoC d, RectPtr r, Int2 item, Int2 firstLine)
 
8890
 
 
8891
{
 
8892
  ClickableListPtr dlg;
 
8893
  RecT             rct;
 
8894
  ClickableItemPtr cip;
 
8895
  Int4             level_offset;
 
8896
 
 
8897
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
8898
  if (dlg != NULL && r != NULL && item > 0 && firstLine == 0) {
 
8899
    rct = *r;
 
8900
  
 
8901
    cip = GetSelectedClickableList (dlg->list_list, item);
 
8902
    if (cip != NULL)
 
8903
    {
 
8904
      level_offset = cip->level * 16;
 
8905
      rct.left += level_offset;
 
8906
      rct.right += level_offset;
 
8907
    }
 
8908
 
 
8909
    /* draw text selection */
 
8910
    DrawTextSelection (dlg, item, &rct);
 
8911
 
 
8912
    /* draw selection */
 
8913
    if (item == dlg->selected) {
 
8914
      rct.right = rct.left + 4;
 
8915
      PaintRect (&rct);
 
8916
    }
 
8917
 
 
8918
    /* draw chosen checkboxes */
 
8919
    rct.left += 5;
 
8920
    rct.right = rct.left + 10;
 
8921
    rct.bottom = rct.top + (rct.right - rct.left);
 
8922
    FrameRect (&rct);
 
8923
    
 
8924
    if (cip != NULL && cip->chosen) {
 
8925
      MoveTo (rct.left, rct.top);
 
8926
      LineTo (rct.right - 1, rct.bottom - 1);
 
8927
      MoveTo (rct.left, rct.bottom - 1);
 
8928
      LineTo (rct.right - 1, rct.top);
 
8929
    }
 
8930
    
 
8931
    /* draw open/closed checkboxes */
 
8932
    if (cip!= NULL && cip->subcategories != NULL)
 
8933
    {
 
8934
      rct.left += 10;
 
8935
      rct.right = rct.left + 10;
 
8936
      rct.bottom = rct.top + (rct.right - rct.left);
 
8937
      FrameRect (&rct);
 
8938
      MoveTo (rct.left, (rct.top + rct.bottom) / 2);
 
8939
      LineTo (rct.right - 1, (rct.top + rct.bottom) / 2);
 
8940
      if (!cip->expanded)
 
8941
      {
 
8942
        MoveTo ((rct.left + rct.right) / 2, rct.top);
 
8943
        LineTo ((rct.left + rct.right) / 2, rct.bottom - 1);
 
8944
      }
 
8945
    }
 
8946
 
 
8947
  }
 
8948
}
 
8949
 
 
8950
 
 
8951
 
 
8952
static void DrawClickableListItem (DoC d, RectPtr r, Int2 item, Int2 firstLine)
 
8953
 
 
8954
{
 
8955
  ClickableListPtr dlg;
 
8956
  RecT             rct;
 
8957
 
 
8958
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
8959
  if (dlg != NULL && r != NULL && item > 0 && firstLine == 0) {
 
8960
    rct = *r;
 
8961
  
 
8962
    /* draw selection */
 
8963
    if (item == dlg->item_selected) {
 
8964
      rct = *r;
 
8965
      rct.right = rct.left + 4;
 
8966
      PaintRect (&rct);
 
8967
    }
 
8968
  }
 
8969
}
 
8970
 
 
8971
 
 
8972
static void ClickClickableListItem (DoC d, PoinT pt)
 
8973
 
 
8974
{
 
8975
  Int2             item, last_selected, numItems;
 
8976
  Int2             row;
 
8977
  ClickableListPtr dlg;
 
8978
  ClickableItemPtr cip;
 
8979
  ValNodePtr       vnp;
 
8980
 
 
8981
  dlg = GetObjectExtra (d);
 
8982
  if (dlg != NULL) {
 
8983
    MapDocPoint (d, pt, &item, &row, NULL, NULL);
 
8984
    if (item > 0 && row > 0) {  
 
8985
      cip = GetSelectedClickableList (dlg->list_list, dlg->selected);
 
8986
      if (cip != NULL && cip->item_list != NULL)
 
8987
      {
 
8988
        vnp = cip->item_list;
 
8989
        
 
8990
        last_selected = dlg->item_selected;
 
8991
        dlg->item_selected = item;
 
8992
        
 
8993
        if (item != last_selected)
 
8994
        {
 
8995
          GetDocParams (d, &numItems, NULL);
 
8996
          UpdateDocument (d, 0, numItems);
 
8997
        }
 
8998
    
 
8999
        /* find item in list */
 
9000
        while (item > 1 && vnp != NULL)
 
9001
        {
 
9002
          vnp = vnp->next;
 
9003
          item--;
 
9004
        }
 
9005
        
 
9006
        if (dblClick)
 
9007
        {
 
9008
          if (dlg->item_double_click_callback != NULL) {
 
9009
            (dlg->item_double_click_callback) (vnp, dlg->item_click_callback_data);
 
9010
          }
 
9011
        } else {
 
9012
          if (dlg->item_single_click_callback != NULL) {
 
9013
            (dlg->item_single_click_callback) (vnp, dlg->item_click_callback_data);
 
9014
          }
 
9015
        }          
 
9016
      }
 
9017
    }
 
9018
  }
 
9019
}
 
9020
 
 
9021
 
 
9022
static void ClickableListToDialog (DialoG d, Pointer userdata)
 
9023
{
 
9024
  ClickableListPtr dlg;
 
9025
 
 
9026
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9027
  if (dlg == NULL)
 
9028
  {
 
9029
    return;
 
9030
  }
 
9031
  
 
9032
  dlg->list_list = (ValNodePtr) userdata;
 
9033
 
 
9034
  PopulateClickableList (dlg, dlg->list_list);
 
9035
  if (dlg->list_list != NULL) {
 
9036
    dlg->selected = 1;
 
9037
    dlg->item_selected = 0;
 
9038
    PopulateClickableItemList (dlg->clickable_item_list, 
 
9039
                               GetSelectedClickableList (dlg->list_list,
 
9040
                                                         dlg->selected),
 
9041
                               dlg->get_item_text);
 
9042
  } else {
 
9043
    Reset (dlg->clickable_item_list);
 
9044
  }
 
9045
}
 
9046
 
 
9047
static void FindClickableText (ButtoN b) 
 
9048
{
 
9049
  ClickableListPtr dlg;
 
9050
  CharPtr          find_txt;
 
9051
 
 
9052
  dlg = (ClickableListPtr) GetObjectExtra (b);
 
9053
  if (dlg == NULL)
 
9054
  {
 
9055
    return;
 
9056
  }
 
9057
  
 
9058
  find_txt = SaveStringFromText (dlg->find_txt);
 
9059
  ScrollToNextClickableTextDescription (find_txt, dlg->dialog);
 
9060
  find_txt = MemFree (find_txt);
 
9061
}
 
9062
 
 
9063
 
 
9064
static void FindPreviousClickableText (ButtoN b)
 
9065
{
 
9066
  ClickableListPtr dlg;
 
9067
  CharPtr          find_txt;
 
9068
 
 
9069
  dlg = (ClickableListPtr) GetObjectExtra (b);
 
9070
  if (dlg == NULL)
 
9071
  {
 
9072
    return;
 
9073
  }
 
9074
  
 
9075
  find_txt = SaveStringFromText (dlg->find_txt);
 
9076
  ScrollToPreviousClickableTextDescription (find_txt, dlg->dialog);
 
9077
  find_txt = MemFree (find_txt);
 
9078
}
 
9079
 
 
9080
 
 
9081
static void ClickableListCopyToClipboard (DialoG d)
 
9082
{
 
9083
  ClickableListPtr dlg;
 
9084
  CharPtr          txt;
 
9085
  
 
9086
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9087
 
 
9088
  if (dlg == NULL) return;
 
9089
 
 
9090
  txt = GetSelectedClickableListText (d);
 
9091
  Nlm_StringToClipboard (txt);
 
9092
  txt = MemFree (txt);
 
9093
}
 
9094
 
 
9095
static void ClickableListMessage (DialoG d, Int2 mssg)
 
9096
 
 
9097
{
 
9098
  ClickableListPtr dlg;
 
9099
 
 
9100
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9101
  if (dlg != NULL) {
 
9102
    if (mssg == VIB_MSG_COPY) {
 
9103
      ClickableListCopyToClipboard(d);
 
9104
    }
 
9105
  }
 
9106
}
 
9107
 
 
9108
static void ClickableListOnKey (SlatE s, Char ch)
 
9109
{
 
9110
  DoC              d;
 
9111
  ClickableListPtr clp;
 
9112
#ifdef WIN_MSWIN
 
9113
  Int2             first_shown;
 
9114
  Int4             offset;
 
9115
  BaR              sb;
 
9116
#endif
 
9117
 
 
9118
  if ( (int) ch == 0 ) return;
 
9119
 
 
9120
  d = (DoC) s;
 
9121
  clp = (ClickableListPtr) GetObjectExtra (d);
 
9122
 
 
9123
  CaptureSlateFocus (s);
 
9124
  /* later, handle control key combos */
 
9125
#ifdef WIN_MSWIN
 
9126
  if (ch == 3)
 
9127
  {
 
9128
    ClickableListCopyToClipboard (clp->dialog);
 
9129
  }
 
9130
  else if (ch == 11) 
 
9131
  {
 
9132
    /* PageUp key pressed */
 
9133
    if (GetScrlParams4 (d, &offset, &first_shown, NULL) && first_shown > 0) 
 
9134
    {
 
9135
      sb = GetSlateVScrollBar (s);
 
9136
      Nlm_Scroll (sb, SCROLL_PAGEUP);
 
9137
    }
 
9138
  }
 
9139
  else if (ch == 12)
 
9140
  {
 
9141
    /* PageDown key pressed */
 
9142
    if (GetScrlParams4 (d, &offset, &first_shown, NULL)) 
 
9143
    {
 
9144
      sb = GetSlateVScrollBar (s);
 
9145
      Nlm_Scroll (sb, SCROLL_PAGEDN);
 
9146
    }
 
9147
  }
 
9148
  else if (ch == 30)
 
9149
  {
 
9150
    /* Up Arrow key pressed */
 
9151
    if (GetScrlParams4 (d, &offset, &first_shown, NULL) && first_shown > 0) 
 
9152
    {
 
9153
      GetItemParams4 (d, first_shown - 1, &offset, NULL, NULL, NULL, NULL);
 
9154
      SetScrlParams4 (d, offset);
 
9155
    }
 
9156
  }
 
9157
  else if (ch == 31)
 
9158
  {
 
9159
    /* Down Arrow key pressed */
 
9160
    if (GetScrlParams4 (d, &offset, &first_shown, NULL)) {
 
9161
      sb = GetSlateVScrollBar (s);
 
9162
      if (offset < GetBarMax (sb)) 
 
9163
      {
 
9164
        GetItemParams4 (d, first_shown + 1, &offset, NULL, NULL, NULL, NULL);
 
9165
        SetScrlParams4 (d, offset);
 
9166
      }
 
9167
    }
 
9168
  }
 
9169
#endif
 
9170
}
 
9171
 
 
9172
 
 
9173
extern DialoG 
 
9174
CreateClickableListDialogEx 
 
9175
(GrouP h, 
 
9176
 CharPtr label1, 
 
9177
 CharPtr label2,
 
9178
 CharPtr help1,
 
9179
 CharPtr help2,
 
9180
 ClickableCallback item_single_click_callback,
 
9181
 ClickableCallback item_double_click_callback,
 
9182
 Pointer         item_click_callback_data,
 
9183
 GetClickableItemText get_item_text,
 
9184
 Int4            left_width,
 
9185
 Int4            right_width,
 
9186
 Boolean         horizontal,
 
9187
 Boolean         show_find)
 
9188
{
 
9189
  GrouP p, pnl_grp, find_grp = NULL;
 
9190
  ClickableListPtr dlg;
 
9191
  RecT             r;
 
9192
  ButtoN           b;
 
9193
 
 
9194
  dlg = (ClickableListPtr) MemNew (sizeof (ClickableListData));
 
9195
  if (dlg == NULL)
 
9196
  {
 
9197
    return NULL;
 
9198
  }
 
9199
  p = HiddenGroup (h, -1, 0, NULL);
 
9200
  SetObjectExtra (p, dlg, CleanupClickableListDialog);
 
9201
  SetGroupSpacing (p, 10, 10);
 
9202
  
 
9203
  dlg->dialog = (DialoG) p;
 
9204
  dlg->todialog = ClickableListToDialog;
 
9205
  dlg->fromdialog = NULL;
 
9206
  dlg->dialogmessage = ClickableListMessage;
 
9207
  dlg->testdialog = NULL;
 
9208
  
 
9209
  dlg->item_single_click_callback = item_single_click_callback;
 
9210
  dlg->item_double_click_callback = item_double_click_callback;
 
9211
  dlg->item_click_callback_data = item_click_callback_data;
 
9212
  
 
9213
  dlg->get_item_text = get_item_text;
 
9214
  
 
9215
  if (horizontal) {
 
9216
    pnl_grp = HiddenGroup (p, 2, 0, NULL);
 
9217
    
 
9218
    if (label1 || label2) {
 
9219
      dlg->title1 = StaticPrompt (pnl_grp, label1, left_width, popupMenuHeight, programFont, 'c');
 
9220
      dlg->title2 = StaticPrompt (pnl_grp, label2, right_width, popupMenuHeight, programFont, 'c');
 
9221
    }
 
9222
    dlg->doc = DocumentPanel (pnl_grp, left_width, stdLineHeight * 20);
 
9223
    dlg->clickable_item_list = DocumentPanel (pnl_grp, right_width, stdLineHeight * 20);
 
9224
    if (help1 || help2) {
 
9225
      dlg->help1 = StaticPrompt (pnl_grp, help1, left_width, popupMenuHeight, programFont, 'c');
 
9226
      dlg->help2 = StaticPrompt (pnl_grp, help2, right_width, popupMenuHeight, programFont, 'c');
 
9227
    } 
 
9228
  } else {
 
9229
    pnl_grp = HiddenGroup (p, -1, 0, NULL);
 
9230
    dlg->title1 = StaticPrompt (pnl_grp, label1, left_width, popupMenuHeight, programFont, 'c');
 
9231
    dlg->doc = DocumentPanel (pnl_grp, left_width, stdLineHeight * 20);
 
9232
    if (help1 || help2) {
 
9233
      dlg->help1 = StaticPrompt (pnl_grp, help1, left_width, popupMenuHeight, programFont, 'c');
 
9234
    }
 
9235
    dlg->title2 = StaticPrompt (pnl_grp, label2, right_width, popupMenuHeight, programFont, 'c');
 
9236
    dlg->clickable_item_list = DocumentPanel (pnl_grp, right_width, stdLineHeight * 20);
 
9237
    if (help1 || help2) {
 
9238
      dlg->help2 = StaticPrompt (pnl_grp, help2, right_width, popupMenuHeight, programFont, 'c');
 
9239
    }
 
9240
    AlignObjects (ALIGN_CENTER, (HANDLE) dlg->title1, (HANDLE) dlg->doc, (HANDLE) dlg->title2, (HANDLE) dlg->clickable_item_list, 
 
9241
                                (HANDLE) (dlg->help1 == NULL ? dlg->help2 : dlg->help1), (HANDLE) (dlg->help1 == NULL ? NULL : dlg->help2), NULL);
 
9242
  }
 
9243
 
 
9244
  SetObjectExtra (dlg->doc, dlg, NULL);
 
9245
  SetDocAutoAdjust (dlg->doc, FALSE);
 
9246
  SetDocProcs (dlg->doc, ClickList, DragClickableList, ReleaseClickableList, NULL);
 
9247
  SetDocShade (dlg->doc, DrawClickableList, NULL, NULL, NULL);
 
9248
  
 
9249
  SetSlateChar ((SlatE) dlg->doc, ClickableListOnKey);
 
9250
 
 
9251
  SetObjectExtra (dlg->clickable_item_list, dlg, NULL);
 
9252
  SetDocAutoAdjust (dlg->clickable_item_list, FALSE);
 
9253
  SetDocProcs (dlg->clickable_item_list, ClickClickableListItem, NULL, NULL, NULL);
 
9254
  SetDocShade (dlg->clickable_item_list, DrawClickableListItem, NULL, NULL, NULL);
 
9255
  
 
9256
  /* adjust column width for discrepancy list */
 
9257
  ObjectRect (dlg->doc, &r);
 
9258
  InsetRect (&r, 4, 4);
 
9259
  clickableColFmt[1].pixWidth = r.right - r.left - clickableColFmt[0].pixWidth;
 
9260
  
 
9261
  if (show_find) {
 
9262
    find_grp = HiddenGroup (p, 4, 0, NULL);
 
9263
    SetGroupSpacing (find_grp, 10, 10);
 
9264
    StaticPrompt (find_grp, "Find Text", 0, popupMenuHeight, programFont, 'l');
 
9265
    dlg->find_txt = DialogText (find_grp, "", 20, NULL);
 
9266
    b = PushButton (find_grp, "<<", FindPreviousClickableText);
 
9267
    SetObjectExtra (b, dlg, NULL);
 
9268
    b = PushButton (find_grp, ">>", FindClickableText);
 
9269
    SetObjectExtra (b, dlg, NULL);
 
9270
  }
 
9271
  
 
9272
  AlignObjects (ALIGN_CENTER, (HANDLE) pnl_grp, (HANDLE) find_grp, NULL);
 
9273
  return (DialoG) p;
 
9274
}
 
9275
 
 
9276
extern void SetClickableListDialogTitles (DialoG d, CharPtr title1, CharPtr title2, CharPtr help1, CharPtr help2)
 
9277
{
 
9278
  ClickableListPtr dlg;
 
9279
 
 
9280
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9281
  if (dlg == NULL)
 
9282
  {
 
9283
    return;
 
9284
  }
 
9285
  SafeSetTitle (dlg->title1, title1);
 
9286
  SafeSetTitle (dlg->title2, title2);
 
9287
  SafeSetTitle (dlg->help1, help1);
 
9288
  SafeSetTitle (dlg->help2, help2);
 
9289
}
 
9290
 
 
9291
 
 
9292
extern DialoG 
 
9293
CreateClickableListDialog 
 
9294
(GrouP h, 
 
9295
 CharPtr label1, 
 
9296
 CharPtr label2,
 
9297
 ClickableCallback item_single_click_callback,
 
9298
 ClickableCallback item_double_click_callback,
 
9299
 Pointer         item_click_callback_data,
 
9300
 GetClickableItemText get_item_text)
 
9301
{
 
9302
  return CreateClickableListDialogEx (h, label1, label2, NULL, NULL,
 
9303
                                      item_single_click_callback,
 
9304
                                      item_double_click_callback,
 
9305
                                      item_click_callback_data,
 
9306
                                      get_item_text, 
 
9307
                                      stdCharWidth * 30,
 
9308
                                      stdCharWidth * 30 + 5,
 
9309
                                      TRUE, TRUE);
 
9310
}
 
9311
 
 
9312
 
 
9313
static Int4 CountExpandedSublevels (ValNodePtr subcategories)
 
9314
{
 
9315
  ValNodePtr vnp;
 
9316
  Int4       num = 0;
 
9317
  ClickableItemPtr cip;
 
9318
 
 
9319
  for (vnp = subcategories; vnp != NULL; vnp = vnp->next) {
 
9320
    cip = (ClickableItemPtr) vnp->data.ptrvalue;
 
9321
    if (cip != NULL) {
 
9322
      num++;
 
9323
      if (cip->expanded && cip->subcategories != NULL) {
 
9324
        num += CountExpandedSublevels(cip->subcategories);
 
9325
      }
 
9326
    }
 
9327
  }
 
9328
  return num;
 
9329
}
 
9330
 
 
9331
 
 
9332
/* First, need to locate items that have description that contains txt.
 
9333
 * Then need to make sure that they are visible.
 
9334
 * Then need to figure out how to scroll to them.
 
9335
 */
 
9336
static Boolean FindInClickableItemDescriptions (CharPtr txt, ValNodePtr clickable_item_list, ValNodePtr PNTR row_list, Int4Ptr row_offset)
 
9337
{
 
9338
  ValNodePtr       vnp;
 
9339
  ClickableItemPtr cip;
 
9340
  Boolean          found = FALSE;
 
9341
  Int4             lower_levels;
 
9342
  
 
9343
  if (StringHasNoText (txt) || clickable_item_list == NULL || row_list == NULL || row_offset == NULL) return FALSE;
 
9344
  
 
9345
  vnp = clickable_item_list;
 
9346
  while (vnp != NULL) {
 
9347
    (*row_offset)++;
 
9348
    cip = (ClickableItemPtr) vnp->data.ptrvalue;
 
9349
    if (StringStr (cip->description, txt) != NULL) {
 
9350
      ValNodeAddInt (row_list, 0, *row_offset);
 
9351
      found = TRUE;
 
9352
    }
 
9353
    lower_levels = *row_offset;
 
9354
    if (cip->subcategories != NULL) {
 
9355
      if (FindInClickableItemDescriptions (txt, cip->subcategories, row_list, &lower_levels)) {
 
9356
        cip->expanded = TRUE;
 
9357
        found = TRUE;
 
9358
      }
 
9359
      if (cip->expanded) {
 
9360
        (*row_offset) += CountExpandedSublevels (cip->subcategories);
 
9361
      }
 
9362
    }
 
9363
    vnp = vnp->next;
 
9364
  }
 
9365
  
 
9366
  return found;
 
9367
}
 
9368
 
 
9369
 
 
9370
extern void ScrollToNextClickableTextDescription (CharPtr txt, DialoG d)
 
9371
{
 
9372
  ClickableListPtr dlg;
 
9373
  ValNodePtr       found_list = NULL, vnp;
 
9374
  Int4             row_offset = 0, startsAt;
 
9375
  Int2             numRows, numCols, lineHeight;
 
9376
  
 
9377
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9378
  if (dlg == NULL)
 
9379
  {
 
9380
    return;
 
9381
  }
 
9382
 
 
9383
  if (!FindInClickableItemDescriptions (txt, dlg->list_list, &found_list, &row_offset)
 
9384
      || found_list == NULL) {
 
9385
    Message (MSG_OK, "Text not found!");
 
9386
    return;
 
9387
  }
 
9388
 
 
9389
  /* find first found txt after current selection */
 
9390
  vnp = found_list;
 
9391
  while (vnp != NULL && vnp->data.intvalue <= dlg->selected) {
 
9392
    vnp = vnp->next;
 
9393
  }
 
9394
  if (vnp == NULL) {
 
9395
   row_offset = found_list->data.intvalue;
 
9396
  } else {
 
9397
    row_offset = vnp->data.intvalue;
 
9398
  }
 
9399
 
 
9400
  dlg->selected = row_offset; 
 
9401
  PopulateClickableList (dlg, dlg->list_list);
 
9402
  SetDocAutoAdjust (dlg->doc, TRUE);   
 
9403
  UpdateDocument (dlg->doc, 0, 0);
 
9404
  SetDocAutoAdjust (dlg->doc, FALSE);
 
9405
  dlg->item_selected = 0;
 
9406
  PopulateClickableItemList (dlg->clickable_item_list, 
 
9407
                             GetSelectedClickableList (dlg->list_list,
 
9408
                                                       dlg->selected),
 
9409
                                                       dlg->get_item_text);
 
9410
 
 
9411
  GetItemParams4 (dlg->doc, row_offset, &startsAt, &numRows,
 
9412
                  &numCols, &lineHeight, NULL);
 
9413
  SetScrlParams4 (dlg->doc, startsAt);
 
9414
}
 
9415
 
 
9416
 
 
9417
extern void ScrollToPreviousClickableTextDescription (CharPtr txt, DialoG d)
 
9418
{
 
9419
  ClickableListPtr dlg;
 
9420
  ValNodePtr       found_list = NULL, vnp, vnp_prev = NULL;
 
9421
  Int4             row_offset = 0, startsAt;
 
9422
  Int2             numRows, numCols, lineHeight;
 
9423
  
 
9424
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9425
  if (dlg == NULL)
 
9426
  {
 
9427
    return;
 
9428
  }
 
9429
 
 
9430
  if (!FindInClickableItemDescriptions (txt, dlg->list_list, &found_list, &row_offset)
 
9431
      || found_list == NULL) {
 
9432
    Message (MSG_OK, "Text not found!");
 
9433
    return;
 
9434
  }
 
9435
 
 
9436
  /* find first found txt before current selection */
 
9437
  vnp = found_list;
 
9438
  while (vnp != NULL && vnp->data.intvalue < dlg->selected) {
 
9439
    vnp_prev = vnp;
 
9440
    vnp = vnp->next;
 
9441
  }
 
9442
  if (vnp_prev == NULL) {
 
9443
    /* use last item in list */
 
9444
    vnp = found_list;
 
9445
    while (vnp != NULL && vnp->next != NULL) {
 
9446
      vnp = vnp->next;
 
9447
    }
 
9448
    row_offset = vnp->data.intvalue;
 
9449
  } else {
 
9450
    row_offset = vnp_prev->data.intvalue;
 
9451
  }
 
9452
 
 
9453
  dlg->selected = row_offset; 
 
9454
  PopulateClickableList (dlg, dlg->list_list);
 
9455
  SetDocAutoAdjust (dlg->doc, TRUE);   
 
9456
  UpdateDocument (dlg->doc, 0, 0);
 
9457
  SetDocAutoAdjust (dlg->doc, FALSE);
 
9458
  dlg->item_selected = 0;
 
9459
  PopulateClickableItemList (dlg->clickable_item_list, 
 
9460
                             GetSelectedClickableList (dlg->list_list,
 
9461
                                                       dlg->selected),
 
9462
                                                       dlg->get_item_text);
 
9463
 
 
9464
  GetItemParams4 (dlg->doc, row_offset, &startsAt, &numRows,
 
9465
                  &numCols, &lineHeight, NULL);
 
9466
  SetScrlParams4 (dlg->doc, startsAt);
 
9467
}
 
9468
 
 
9469
 
 
9470
static CharPtr GetClickableTextFromItemList (ValNodePtr item_list, CharPtr separator) 
 
9471
{
 
9472
  Int4 text_len = 1;
 
9473
  ValNodePtr vnp;
 
9474
  CharPtr    txt;
 
9475
 
 
9476
  for (vnp = item_list; vnp != NULL; vnp = vnp->next) {
 
9477
    text_len += StringLen (vnp->data.ptrvalue) + StringLen (separator);
 
9478
  }
 
9479
 
 
9480
  txt = (CharPtr) MemNew (sizeof(Char) * text_len);
 
9481
  for (vnp = item_list; vnp != NULL; vnp = vnp->next) {
 
9482
    StringCat (txt, vnp->data.ptrvalue);
 
9483
    if (vnp->next != NULL) {
 
9484
      StringCat (txt, separator);
 
9485
    }
 
9486
  }
 
9487
  return txt;
 
9488
}
 
9489
 
 
9490
 
 
9491
static CharPtr
 
9492
GetFragmentFromDocRow
 
9493
(DoC  doc,
 
9494
 Int2 item,
 
9495
 Int2 col,
 
9496
 Int2 row,
 
9497
 Int2 char_start, Int2 char_stop)
 
9498
{
 
9499
  CharPtr txt = NULL, cp_txt;
 
9500
  Int4    len;
 
9501
 
 
9502
  txt = GetDocText (doc, item, row, col);
 
9503
 
 
9504
  if (char_start == 0 && char_stop < 0) {
 
9505
    /* take all of row */
 
9506
    return txt;
 
9507
  } else {
 
9508
    len = StringLen (txt);
 
9509
    if (char_stop >= len) {
 
9510
      /* selection was drawn beyond length of text */
 
9511
      char_stop = len - 1;
 
9512
    } else if (char_stop < 0) {
 
9513
      /* take all of row */
 
9514
      char_stop = len - 1;
 
9515
    }
 
9516
    if (char_start >= len) {
 
9517
      /* do nothing - selection is not within text */
 
9518
      txt = MemFree (txt);
 
9519
    } else {
 
9520
      cp_txt = (CharPtr) MemNew (sizeof (Char) * (2 + char_stop - char_start));
 
9521
      StringNCpy (cp_txt, txt + char_start, 1 + char_stop - char_start);
 
9522
      cp_txt[1 + char_stop - char_start] = 0;
 
9523
      txt = MemFree (txt);
 
9524
      txt = cp_txt;
 
9525
    }
 
9526
  }  
 
9527
  return txt;
 
9528
}
 
9529
 
 
9530
 
 
9531
static CharPtr 
 
9532
GetFragmentsFromDocCol
 
9533
(DoC  doc,
 
9534
 Int2 item,
 
9535
 Int2 col,
 
9536
 Int2 row_start, Int2 row_stop,
 
9537
 Int2 char_start, Int2 char_stop)
 
9538
{
 
9539
  Int2       row;
 
9540
  CharPtr    txt;
 
9541
  ValNodePtr fragments = NULL;
 
9542
 
 
9543
  if (row_start == row_stop) {
 
9544
    txt = GetFragmentFromDocRow (doc, item, col, row_start, char_start, char_stop);
 
9545
    if (StringHasNoText (txt)) {
 
9546
      txt = MemFree (txt);
 
9547
    } else {
 
9548
      ValNodeAddPointer (&fragments, 0, txt);
 
9549
    }
 
9550
  } else {
 
9551
    txt = GetFragmentFromDocRow (doc, item, col, row_start, char_start, -1);
 
9552
    if (StringHasNoText (txt)) {
 
9553
      txt = MemFree (txt);
 
9554
    } else {
 
9555
      ValNodeAddPointer (&fragments, 0, txt);
 
9556
    }
 
9557
    row = row_start + 1;
 
9558
    while (row < row_stop) {
 
9559
      txt = GetFragmentFromDocRow (doc, item, col, row, 0, -1);
 
9560
      if (StringHasNoText (txt)) {
 
9561
        txt = MemFree (txt);
 
9562
      } else {
 
9563
        ValNodeAddPointer (&fragments, 0, txt);
 
9564
      }
 
9565
      row++;
 
9566
    }
 
9567
    txt = GetFragmentFromDocRow (doc, item, col, row_stop, 0, char_stop);
 
9568
    if (StringHasNoText (txt)) {
 
9569
      txt = MemFree (txt);
 
9570
    } else {
 
9571
      ValNodeAddPointer (&fragments, 0, txt);
 
9572
    }
 
9573
  }
 
9574
  txt = GetClickableTextFromItemList (fragments, " ");
 
9575
  fragments = ValNodeFreeData (fragments);
 
9576
  return txt;
 
9577
}
 
9578
 
 
9579
 
 
9580
static Boolean CollectFromThisColumn (Int2 col, Int2Ptr only_these_columns, Int2 num_col)
 
9581
{
 
9582
  Int2 i;
 
9583
  Boolean rval = FALSE;
 
9584
 
 
9585
  if (only_these_columns == NULL) {
 
9586
    rval = TRUE;
 
9587
  } else {
 
9588
    for (i = 0; i < num_col; i++) {
 
9589
      if (only_these_columns[i] == col) {
 
9590
        rval = TRUE;
 
9591
      }
 
9592
    }
 
9593
  }
 
9594
  return rval;
 
9595
}
 
9596
 
 
9597
 
 
9598
static CharPtr
 
9599
GetFragmentsFromDocItem 
 
9600
(DoC  doc,
 
9601
 Int2 item, 
 
9602
 Int2 col_start, Int2 col_stop,
 
9603
 Int2 row_start, Int2 row_stop,
 
9604
 Int2 char_start, Int2 char_stop,
 
9605
 Int2Ptr only_these_columns, Int2 num_col)
 
9606
{
 
9607
  Int2       col;
 
9608
  CharPtr    txt;
 
9609
  Int2       num_rows, num_cols;
 
9610
  ValNodePtr fragments = NULL;
 
9611
 
 
9612
  GetItemParams4 (doc, item, NULL, &num_rows, &num_cols, NULL, NULL);
 
9613
  if (col_stop < 0) {
 
9614
    col_stop = num_cols;
 
9615
  }
 
9616
  if (row_stop < 0) {
 
9617
    row_stop = num_rows;
 
9618
  }
 
9619
 
 
9620
  if (col_start == col_stop) {
 
9621
    if (CollectFromThisColumn (col_start, only_these_columns, num_col)) {
 
9622
      txt = GetFragmentsFromDocCol (doc, item, col_start, row_start, row_stop, char_start, char_stop);
 
9623
      ValNodeAddPointer (&fragments, 0, txt);
 
9624
    }
 
9625
  } else {
 
9626
    if (CollectFromThisColumn (col_start, only_these_columns, num_col)) {
 
9627
      txt = GetFragmentsFromDocCol (doc, item, col_start, row_start, num_rows, char_start, -1);
 
9628
      ValNodeAddPointer (&fragments, 0, txt);
 
9629
    }
 
9630
    col = col_start + 1;
 
9631
    while (col < col_stop) {
 
9632
      if (CollectFromThisColumn (col, only_these_columns, num_col)) {
 
9633
        txt = GetFragmentsFromDocCol (doc, item, col, 1, num_rows, 0, -1);
 
9634
        ValNodeAddPointer (&fragments, 0, txt);
 
9635
      }
 
9636
      col++;
 
9637
    }
 
9638
    if (CollectFromThisColumn (col_stop, only_these_columns, num_col)) {
 
9639
      txt = GetFragmentsFromDocCol (doc, item, col_stop, 1, row_stop, 0, char_stop);
 
9640
      ValNodeAddPointer (&fragments, 0, txt);
 
9641
    }
 
9642
  }
 
9643
  txt = GetClickableTextFromItemList (fragments, "\t");
 
9644
  fragments = ValNodeFreeData (fragments);
 
9645
 
 
9646
  return txt;
 
9647
}
 
9648
 
 
9649
 
 
9650
NLM_EXTERN CharPtr GetSelectedDocText (DoC doc, Int2 item_start, Int2 row_start, Int2 col_start, Int2 char_start,
 
9651
                                       Int2 item_stop, Int2 row_stop, Int2 col_stop, Int2 char_stop,
 
9652
                                       Int2Ptr only_these_columns, Int2 num_col)
 
9653
{
 
9654
  Int2             item;
 
9655
  CharPtr          txt;
 
9656
  ValNodePtr       fragment_list = NULL;
 
9657
  
 
9658
  if (doc == NULL || item_start < 1)
 
9659
  {
 
9660
    return NULL;
 
9661
  }
 
9662
 
 
9663
  if (char_start < 0) char_start = 0;
 
9664
 
 
9665
  if (item_start == item_stop) {
 
9666
    txt = GetFragmentsFromDocItem (doc, item_start, col_start, col_stop, row_start, row_stop, char_start, char_stop, only_these_columns, num_col); 
 
9667
    ValNodeAddPointer (&fragment_list, 0, txt);
 
9668
  } else {
 
9669
    txt = GetFragmentsFromDocItem (doc, item_start, col_start, -1, row_start, -1, char_start, -1, only_these_columns, num_col);
 
9670
    ValNodeAddPointer (&fragment_list, 0, txt);
 
9671
    item = item_start + 1;
 
9672
    while (item < item_stop) {
 
9673
      txt = GetFragmentsFromDocItem (doc, item, 1, -1, 1, -1, 0, -1, only_these_columns, num_col);
 
9674
      ValNodeAddPointer (&fragment_list, 0, txt);
 
9675
      item++;
 
9676
    }
 
9677
    txt = GetFragmentsFromDocItem (doc, item, 1, col_stop, 1, row_stop, 0, char_stop, only_these_columns, num_col);
 
9678
    ValNodeAddPointer (&fragment_list, 0, txt);
 
9679
  }
 
9680
 
 
9681
  txt = GetClickableTextFromItemList (fragment_list, "\r\n");
 
9682
  fragment_list = ValNodeFreeData (fragment_list);
 
9683
  return txt;
 
9684
}
 
9685
 
 
9686
extern CharPtr GetSelectedClickableListText (DialoG d)
 
9687
{
 
9688
  ClickableListPtr dlg;
 
9689
  Int2             numRows;
 
9690
  Int2             item, row, col, char_offset;
 
9691
  Int4             text_len = 0, len = 0;
 
9692
  CharPtr          txt, cp_txt;
 
9693
  ValNodePtr       fragment_list = NULL, item_list = NULL;
 
9694
  
 
9695
  dlg = (ClickableListPtr) GetObjectExtra (d);
 
9696
  if (dlg == NULL || dlg->text_select_item_start < 1)
 
9697
  {
 
9698
    return NULL;
 
9699
  }
 
9700
 
 
9701
  item = dlg->text_select_item_start;
 
9702
  row = dlg->text_select_row_start;
 
9703
  char_offset = dlg->text_select_char_start;
 
9704
 
 
9705
  while (item <= dlg->text_select_item_stop) {
 
9706
    if (item == dlg->text_select_item_start) {
 
9707
      if (item == dlg->text_select_item_stop) {
 
9708
        /* all text from one item */
 
9709
        /* all text will be from last column in item */
 
9710
        GetItemParams4 (dlg->doc, item, NULL, NULL, &col, NULL, NULL);
 
9711
        if (row == dlg->text_select_row_stop) {
 
9712
          /* all text from one row */
 
9713
          txt = GetDocText (dlg->doc, item, row, col);
 
9714
          len = StringLen (txt);
 
9715
          if (dlg->text_select_char_stop >= len) {
 
9716
            /* selection was drawn beyond length of text */
 
9717
            dlg->text_select_char_stop = len - 1;
 
9718
          }
 
9719
          if (dlg->text_select_char_start >= len) {
 
9720
            /* do nothing - selection is not within text */
 
9721
          } else {
 
9722
            cp_txt = (CharPtr) MemNew (sizeof (Char) * (2 + dlg->text_select_char_stop - dlg->text_select_char_start));
 
9723
            StringNCpy (cp_txt, txt + dlg->text_select_char_start, 1 + dlg->text_select_char_stop - dlg->text_select_char_start);
 
9724
            cp_txt[1 + dlg->text_select_char_stop - dlg->text_select_char_start] = 0;
 
9725
            ValNodeAddPointer (&fragment_list, 0, cp_txt);
 
9726
          }
 
9727
          /* free txt read from Doc */
 
9728
          txt = MemFree (txt);
 
9729
        } else {
 
9730
          /* take text from several rows */
 
9731
          item_list = NULL;
 
9732
          while (row < dlg->text_select_row_stop) {
 
9733
            txt = GetDocText (dlg->doc, item, row, col);
 
9734
            len = StringLen (txt);
 
9735
            if (row == dlg->text_select_row_start && dlg->text_select_char_start >= len) {
 
9736
              /* do nothing - selection is not within text */
 
9737
              txt = MemFree (txt);
 
9738
            } else {
 
9739
              if (row == dlg->text_select_row_start && dlg->text_select_char_start > 0) {
 
9740
                cp_txt = (CharPtr) MemNew (sizeof (Char) * (1 + StringLen (txt) - dlg->text_select_char_start));
 
9741
                StringCpy (cp_txt, txt + dlg->text_select_char_start);
 
9742
                txt = MemFree (txt);
 
9743
                txt = cp_txt;
 
9744
              }
 
9745
              ValNodeAddPointer (&item_list, 0, txt);
 
9746
            }
 
9747
            row++;
 
9748
          }
 
9749
          txt = GetDocText (dlg->doc, item, row, col);
 
9750
          if (dlg->text_select_char_stop < len) {
 
9751
            txt[dlg->text_select_char_stop] = 0;
 
9752
          }
 
9753
          ValNodeAddPointer (&item_list, 0, txt);
 
9754
          txt = GetClickableTextFromItemList (item_list, " ");
 
9755
          ValNodeAddPointer (&fragment_list, 0, txt);
 
9756
          item_list = ValNodeFreeData (item_list);
 
9757
        }
 
9758
      } else {
 
9759
        /* take all text after first row and char offset */
 
9760
        item_list = NULL;
 
9761
        GetItemParams4 (dlg->doc, item, NULL, &numRows, &col, NULL, NULL);
 
9762
        while (row <= numRows) {
 
9763
          txt = GetDocText (dlg->doc, item, row, col);
 
9764
          len = StringLen (txt);
 
9765
          if (row == dlg->text_select_row_start && dlg->text_select_char_start >= len) {
 
9766
            /* do nothing = selection is outside text */
 
9767
            txt = MemFree (txt);
 
9768
          } else {
 
9769
            if (row == dlg->text_select_row_start && dlg->text_select_char_start > 0) {
 
9770
              cp_txt = (CharPtr) MemNew (sizeof (Char) * (1 + StringLen (txt) - dlg->text_select_char_start));
 
9771
              StringCpy (cp_txt, txt + dlg->text_select_char_start);
 
9772
              txt = MemFree (txt);
 
9773
              txt = cp_txt;
 
9774
            }
 
9775
            ValNodeAddPointer (&item_list, 0, txt);
 
9776
          }
 
9777
          row++;
 
9778
        }
 
9779
        txt = GetClickableTextFromItemList (item_list, " ");
 
9780
        ValNodeAddPointer (&fragment_list, 0, txt);
 
9781
        item_list = ValNodeFreeData (item_list);
 
9782
      }
 
9783
    } else if (item == dlg->text_select_item_stop) {
 
9784
      /* take all text until last row and char offset */
 
9785
      row = 1;
 
9786
      item_list = NULL;
 
9787
      GetItemParams4 (dlg->doc, item, NULL, NULL, &col, NULL, NULL);
 
9788
      while (row < dlg->text_select_row_stop) {
 
9789
        txt = GetDocText (dlg->doc, item, row, col);
 
9790
        ValNodeAddPointer (&item_list, 0, txt);
 
9791
      }
 
9792
      txt = GetDocText (dlg->doc, item, row, col);
 
9793
      if (dlg->text_select_char_stop + 1 < StringLen (txt)) {
 
9794
        txt[dlg->text_select_char_stop + 1] = 0;
 
9795
      }
 
9796
      ValNodeAddPointer (&item_list, 0, txt);
 
9797
      txt = GetClickableTextFromItemList (item_list, " ");
 
9798
      ValNodeAddPointer (&fragment_list, 0, txt);
 
9799
      item_list = ValNodeFreeData (item_list);
 
9800
    } else {
 
9801
      GetItemParams4 (dlg->doc, item, NULL, NULL, &col, NULL, NULL);
 
9802
      txt = GetDocText (dlg->doc, item, 0, col);
 
9803
      if (txt != NULL && txt[StringLen(txt) - 1] == '\n') {
 
9804
        /* remove terminal carriage return */
 
9805
        txt[StringLen(txt) - 1] = 0;
 
9806
      }
 
9807
      ValNodeAddPointer (&fragment_list, 0, txt);
 
9808
      text_len += StringLen (txt) + 1;
 
9809
    }
 
9810
    item++;
 
9811
  }
 
9812
  txt = GetClickableTextFromItemList (fragment_list, "\r\n");
 
9813
  fragment_list = ValNodeFreeData (fragment_list);
 
9814
  return txt;
 
9815
}
 
9816
 
 
9817
typedef struct basegbqualeditor {
 
9818
  DIALOG_MESSAGE_BLOCK
 
9819
  TaglistCallback tlp_callback; 
 
9820
  Pointer         callback_data;
 
9821
} BaseGBQualEditor, PNTR BaseGBQualEditorPtr;
 
9822
 
 
9823
static void ChangeGBQualEditorPopup (PopuP p)
 
9824
{
 
9825
  BaseGBQualEditorPtr dlg;
 
9826
 
 
9827
  dlg = (BaseGBQualEditorPtr) GetObjectExtra (p);
 
9828
  if (dlg != NULL && dlg->tlp_callback != NULL) {
 
9829
    (dlg->tlp_callback)(dlg->callback_data);
 
9830
  }
 
9831
}
 
9832
 
 
9833
static void ChangeGBQualEditorButton (ButtoN b)
 
9834
{
 
9835
  BaseGBQualEditorPtr dlg;
 
9836
 
 
9837
  dlg = (BaseGBQualEditorPtr) GetObjectExtra (b);
 
9838
  if (dlg != NULL && dlg->tlp_callback != NULL) {
 
9839
    (dlg->tlp_callback)(dlg->callback_data);
 
9840
  }
 
9841
}
 
9842
 
 
9843
static void ChangeGBQualEditorText (TexT t)
 
9844
{
 
9845
  BaseGBQualEditorPtr dlg;
 
9846
 
 
9847
  dlg = (BaseGBQualEditorPtr) GetObjectExtra (t);
 
9848
  if (dlg != NULL && dlg->tlp_callback != NULL) {
 
9849
    (dlg->tlp_callback)(dlg->callback_data);
 
9850
  }
 
9851
}
 
9852
 
 
9853
 
 
9854
/* collection_date has a controlled format.  
 
9855
 * It is YYYY or Mmm-YYYY or DD-Mmm-YYYY where Mmm = Jan, Feb, Mar, Apr, May, 
 
9856
 *                                                   Jun, Jul, Aug, Sep, Oct, 
 
9857
 *                                                   Nov, Dec
 
9858
 * This function will convert other formats  to this format.
 
9859
 * For instance, September 12, 2004 should be converted to 12-Sep-2004
 
9860
 * 12/15/2003 should be converted to 15-Dec-2003.  
 
9861
 * 
 
9862
 * If the date supplied is ambiguous (01/03/05), can you allow the indexer to choose which field goes in Mmm and which in DD.
 
9863
 */
 
9864
 
 
9865
static Int4 ReadNumberFromToken (CharPtr token, Int4 token_len)
 
9866
{
 
9867
  Int4 val = 0;
 
9868
  
 
9869
  if (token == NULL || !isdigit (*token))
 
9870
  {
 
9871
    return val;
 
9872
  }
 
9873
  while (token_len > 0)
 
9874
  {
 
9875
    val *= 10;
 
9876
    val += *token - '0';
 
9877
    token++;
 
9878
    token_len--;
 
9879
  }
 
9880
  
 
9881
  return val;
 
9882
}
 
9883
 
 
9884
static Int4 GetYearFromNumber(Int4 year)
 
9885
{
 
9886
        Nlm_DayTime dt;
 
9887
 
 
9888
  if (year < 1000)
 
9889
  {
 
9890
    GetDayTime (&dt);
 
9891
    if (year + 2000 > dt.tm_year + 1901)
 
9892
    {
 
9893
      year += 1900;
 
9894
    }
 
9895
    else
 
9896
    {
 
9897
      year += 2000;
 
9898
    }
 
9899
  }
 
9900
  return year;
 
9901
}
 
9902
 
 
9903
static Int4 GetYearFromToken (CharPtr token, Int4 token_len)
 
9904
{
 
9905
  Int4        year = 0;
 
9906
  
 
9907
  if (token == NULL || token_len == 0 || token_len > 4)
 
9908
  {
 
9909
    return 0;
 
9910
  }
 
9911
  
 
9912
  year = GetYearFromNumber(ReadNumberFromToken (token, token_len));
 
9913
  
 
9914
  return year;
 
9915
}
 
9916
 
 
9917
static CharPtr month_abbrevs [12] =
 
9918
{
 
9919
  "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
 
9920
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 
9921
};
 
9922
 
 
9923
static Int4 days_in_month [12] =
 
9924
{
 
9925
  31, 29, 31, 30, 31, 30,
 
9926
  31, 31, 30, 31, 30, 31
 
9927
};
 
9928
 
 
9929
static Int4 GetMonthNumFromAbbrev (CharPtr month_abbrev) 
 
9930
{
 
9931
  Int4 i;
 
9932
 
 
9933
  for (i = 0; i < 12; i++) {
 
9934
    if (StringICmp (month_abbrev, month_abbrevs[i]) == 0) {
 
9935
      return i;
 
9936
    }
 
9937
  }
 
9938
  return -1;
 
9939
}
 
9940
 
 
9941
static Int4 GetDaysInMonth (CharPtr month)
 
9942
{
 
9943
  Int4 month_num;
 
9944
  
 
9945
  for (month_num = 0; month_num < 12; month_num++)
 
9946
  {
 
9947
    if (StringCmp (month, month_abbrevs [month_num]) == 0)
 
9948
    {
 
9949
      return days_in_month [month_num];
 
9950
    }
 
9951
  }
 
9952
  return 0;
 
9953
}
 
9954
 
 
9955
static CharPtr GetMonthFromToken (CharPtr token, Int4 token_len)
 
9956
{
 
9957
  Int4    month_num;
 
9958
  
 
9959
  if (token == NULL || token_len == 0)
 
9960
  {
 
9961
    return NULL;
 
9962
  }
 
9963
  
 
9964
  if (isdigit (*token)) 
 
9965
  {
 
9966
    if (token_len > 2)
 
9967
    {
 
9968
      return NULL;
 
9969
    }
 
9970
    else
 
9971
    {
 
9972
      month_num = ReadNumberFromToken (token, token_len);
 
9973
      if (month_num == 0 || month_num > 12)
 
9974
      {
 
9975
        return NULL;
 
9976
      }
 
9977
      else
 
9978
      {
 
9979
        return month_abbrevs [month_num - 1];
 
9980
      }
 
9981
    }
 
9982
  }
 
9983
  else
 
9984
  {
 
9985
    for (month_num = 0; month_num < 12; month_num++)
 
9986
    {
 
9987
      if (StringNICmp (token, month_abbrevs[month_num], 3) == 0)
 
9988
      {
 
9989
        return month_abbrevs[month_num];
 
9990
      }
 
9991
    }
 
9992
    return NULL;
 
9993
  }
 
9994
}
 
9995
 
 
9996
static Boolean
 
9997
ChooseDayAndYear 
 
9998
(Int4    num_1,
 
9999
 Int4    num_2,
 
10000
 CharPtr month,
 
10001
 Boolean year_first,
 
10002
 Int4Ptr day,
 
10003
 Int4Ptr year)
 
10004
{  
 
10005
  if (day == NULL || year == NULL)
 
10006
  {
 
10007
    return FALSE;
 
10008
  }
 
10009
  
 
10010
  if (num_1 == 0 && num_2 == 0)
 
10011
  {
 
10012
    return FALSE;
 
10013
  }
 
10014
  else if (num_1 == 0)
 
10015
  {
 
10016
    *year = 2000;
 
10017
    *day = num_2;
 
10018
  }
 
10019
  else if (num_2 == 0)
 
10020
  {
 
10021
    *year = 2000;
 
10022
    *day = num_1;
 
10023
  }
 
10024
  else if (num_1 > GetDaysInMonth (month))
 
10025
  {
 
10026
    *year = num_1;
 
10027
    *day = num_2;
 
10028
  }
 
10029
  else if (num_2 > GetDaysInMonth (month))
 
10030
  {
 
10031
    *year = num_2;
 
10032
    *day = num_1;
 
10033
  }
 
10034
  else if (year_first)
 
10035
  {
 
10036
    *year = num_1;
 
10037
    *day = num_2;
 
10038
  }
 
10039
  else
 
10040
  {
 
10041
    *year = num_2;
 
10042
    *day = num_1;
 
10043
  }
 
10044
  
 
10045
  return TRUE;
 
10046
}
 
10047
 
 
10048
static Boolean 
 
10049
ChooseMonthAndYear
 
10050
(Int4    num_1,
 
10051
 Int4    num_2,
 
10052
 Boolean month_first,
 
10053
 CharPtr PNTR month,
 
10054
 Int4Ptr year,
 
10055
 BoolPtr month_ambiguous)
 
10056
{
 
10057
  if (year == NULL || month == NULL 
 
10058
      || (num_1 == 0 && num_2 == 0)
 
10059
      || (num_1 > 12 && num_2 > 12)
 
10060
      || (num_1 == 0 && num_2 > 12)
 
10061
      || (num_2 == 0 && num_1 > 12))
 
10062
  {
 
10063
    return FALSE;
 
10064
  }
 
10065
  
 
10066
  if (num_1 == 0)
 
10067
  {
 
10068
    *year = 2000;
 
10069
    *month = month_abbrevs[num_2 - 1];
 
10070
  }
 
10071
  else if (num_2 == 0)
 
10072
  {
 
10073
    *year = 2000;
 
10074
    *month = month_abbrevs[num_1 - 1];
 
10075
  }
 
10076
  else if (num_1 > 12)
 
10077
  {
 
10078
    *year = GetYearFromNumber(num_1);
 
10079
    *month = month_abbrevs [num_2 - 1];
 
10080
  }
 
10081
  else if (num_2 > 12)
 
10082
  {
 
10083
    *year = GetYearFromNumber(num_2);
 
10084
    *month = month_abbrevs [num_1 - 1];
 
10085
  }
 
10086
  else if (month_first)
 
10087
  {
 
10088
    if (month_ambiguous != NULL) 
 
10089
    {
 
10090
      *month_ambiguous = TRUE;
 
10091
    }
 
10092
    *year = GetYearFromNumber(num_2);
 
10093
    *month = month_abbrevs [num_1 - 1];
 
10094
  }
 
10095
  else
 
10096
  {
 
10097
    if (month_ambiguous != NULL) 
 
10098
    {
 
10099
      *month_ambiguous = TRUE;
 
10100
    }
 
10101
    *year = GetYearFromNumber(num_1);
 
10102
    *month = month_abbrevs [num_2 - 1];
 
10103
  }
 
10104
  return TRUE;
 
10105
}
 
10106
 
 
10107
 
 
10108
static Boolean ChooseMonthAndDay 
 
10109
(Int4    num_1,
 
10110
 Int4    num_2,
 
10111
 Boolean month_first,
 
10112
 CharPtr PNTR month,
 
10113
 Int4Ptr day,
 
10114
 BoolPtr month_ambiguous)
 
10115
{
 
10116
  if (day == NULL || month == NULL || num_1 == 0 || num_2 == 0
 
10117
      || (num_1 > 12 && num_2 > 12))
 
10118
  {
 
10119
    return FALSE;
 
10120
  }
 
10121
  
 
10122
  if (num_1 > 12)
 
10123
  {
 
10124
    *day = num_1;
 
10125
    *month = month_abbrevs [num_2 - 1];
 
10126
  }
 
10127
  else if (num_2 > 12)
 
10128
  {
 
10129
    *day = num_2;
 
10130
    *month = month_abbrevs [num_1 - 1];
 
10131
  }
 
10132
  else if (month_first)
 
10133
  {
 
10134
    if (month_ambiguous != NULL) 
 
10135
    {
 
10136
      *month_ambiguous = TRUE;
 
10137
    }
 
10138
    *day = num_2;
 
10139
    *month = month_abbrevs [num_1 - 1];
 
10140
  }
 
10141
  else
 
10142
  {
 
10143
    if (month_ambiguous != NULL) 
 
10144
    {
 
10145
      *month_ambiguous = TRUE;
 
10146
    }
 
10147
    *day = num_1;
 
10148
    *month = month_abbrevs [num_2 - 1];
 
10149
  }
 
10150
  return TRUE;
 
10151
}
 
10152
 
 
10153
extern CharPtr ReformatDateStringEx (CharPtr orig_date, Boolean month_first, BoolPtr month_ambiguous)
 
10154
{
 
10155
  CharPtr reformatted_date = NULL, cp;
 
10156
  Int4    year = 0, day = 0;
 
10157
  CharPtr month = NULL;
 
10158
  CharPtr token_list[3];
 
10159
  Int4    token_lens[3];
 
10160
  CharPtr numbers = "0123456789";
 
10161
  CharPtr letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
10162
  Int4    num_tokens = 0;
 
10163
  Int4    token_len;
 
10164
  Int4    month_token = -1;
 
10165
  Boolean is_num;
 
10166
  Int4    num_1, num_2, num_3;
 
10167
  
 
10168
  if (StringHasNoText (orig_date))
 
10169
  {
 
10170
    return NULL;
 
10171
  }
 
10172
  
 
10173
  /* divide our original date into tokens */
 
10174
  /* skip over any leading spaces */
 
10175
  cp = orig_date;
 
10176
  while (*cp != 0 && num_tokens < 3)
 
10177
  {
 
10178
    is_num = FALSE;
 
10179
    token_len = StringSpn (cp, numbers);  
 
10180
    if (token_len == 0)
 
10181
    {
 
10182
      token_len = StringSpn (cp, letters);
 
10183
    }
 
10184
    else
 
10185
    {
 
10186
      is_num = TRUE;
 
10187
    }
 
10188
    if (token_len == 0)
 
10189
    {
 
10190
      cp++;
 
10191
    }
 
10192
    else
 
10193
    {
 
10194
      if (!is_num)
 
10195
      {
 
10196
        if (month_token == -1)
 
10197
        {
 
10198
          month_token = num_tokens;
 
10199
        }
 
10200
        else
 
10201
        {
 
10202
          /* already found a month string */
 
10203
          return NULL;
 
10204
        }
 
10205
      }
 
10206
      token_list [num_tokens] = cp;
 
10207
      token_lens [num_tokens] = token_len;
 
10208
      num_tokens ++;
 
10209
      cp += token_len;
 
10210
    }
 
10211
  }
 
10212
 
 
10213
  if (num_tokens == 0 || *cp != 0)
 
10214
  {
 
10215
    return NULL;
 
10216
  }
 
10217
 
 
10218
  if (num_tokens == 1)
 
10219
  {
 
10220
    if (month_token == 0)
 
10221
    {
 
10222
      return NULL;
 
10223
    }
 
10224
    year = GetYearFromToken (token_list [0], token_lens [0]);
 
10225
  }
 
10226
  else if (num_tokens == 2)
 
10227
  {
 
10228
    if (month_token == 0)
 
10229
    {
 
10230
      month = GetMonthFromToken (token_list [0], token_lens [0]);
 
10231
      year = GetYearFromToken (token_list [1], token_lens [1]);
 
10232
    }
 
10233
    else if (month_token == 1)
 
10234
    {
 
10235
      month = GetMonthFromToken (token_list [1], token_lens [1]);
 
10236
      year = GetYearFromToken (token_list [0], token_lens [0]);
 
10237
    }
 
10238
    else
 
10239
    {
 
10240
      num_1 = ReadNumberFromToken (token_list [0], token_lens [0]);
 
10241
      num_2 = ReadNumberFromToken (token_list [1], token_lens [1]);
 
10242
      if (! ChooseMonthAndYear (num_1, num_2, month_first, &month, &year, month_ambiguous))
 
10243
      {
 
10244
        return NULL;
 
10245
      }
 
10246
    }
 
10247
  }
 
10248
  else if (num_tokens == 3)
 
10249
  {
 
10250
    if (month_token == 0)
 
10251
    {
 
10252
      month = GetMonthFromToken (token_list [0], token_lens [0]);
 
10253
      num_1 = ReadNumberFromToken (token_list [1], token_lens [1]);
 
10254
      num_2 = ReadNumberFromToken (token_list [2], token_lens [2]);
 
10255
      if (!ChooseDayAndYear (num_1, num_2, month, FALSE, &day, &year))
 
10256
      {
 
10257
        return NULL;
 
10258
      }
 
10259
    }
 
10260
    else if (month_token == 1)
 
10261
    {
 
10262
      month = GetMonthFromToken (token_list [1], token_lens [1]);
 
10263
      num_1 = ReadNumberFromToken (token_list [0], token_lens [0]);
 
10264
      num_2 = ReadNumberFromToken (token_list [2], token_lens [2]);
 
10265
      if (!ChooseDayAndYear (num_1, num_2, month, FALSE, &day, &year))
 
10266
      {
 
10267
        return NULL;
 
10268
      }
 
10269
    }
 
10270
    else if (month_token == 2)
 
10271
    {
 
10272
      month = GetMonthFromToken (token_list [2], token_lens [2]);
 
10273
      num_1 = ReadNumberFromToken (token_list [0], token_lens [0]);
 
10274
      num_2 = ReadNumberFromToken (token_list [1], token_lens [1]);
 
10275
      if (!ChooseDayAndYear (num_1, num_2, month, FALSE, &day, &year))
 
10276
      {
 
10277
        return NULL;
 
10278
      }
 
10279
    }
 
10280
    else
 
10281
    {
 
10282
      num_1 = ReadNumberFromToken (token_list [0], token_lens [0]);
 
10283
      num_2 = ReadNumberFromToken (token_list [1], token_lens [1]);
 
10284
      num_3 = ReadNumberFromToken (token_list [2], token_lens [2]);
 
10285
      
 
10286
      if (num_1 > 31 || num_1 == 0)
 
10287
      {
 
10288
        year = num_1;
 
10289
        if (! ChooseMonthAndDay (num_2, num_3, month_first, &month, &day, month_ambiguous))
 
10290
        {
 
10291
          return NULL;
 
10292
        }
 
10293
      }
 
10294
      else if (num_2 > 31 || num_2 == 0)
 
10295
      {
 
10296
        year = num_2;
 
10297
        if (! ChooseMonthAndDay (num_1, num_3, month_first, &month, &day, month_ambiguous))
 
10298
        {
 
10299
          return NULL;
 
10300
        }
 
10301
      }
 
10302
      else if (num_3 > 31 || num_3 == 0)
 
10303
      {
 
10304
        year = num_3;
 
10305
        if (! ChooseMonthAndDay (num_1, num_2, month_first, &month, &day, month_ambiguous))
 
10306
        {
 
10307
          return NULL;
 
10308
        }
 
10309
      }
 
10310
      else if (num_1 > 0 && num_1 < 13 && num_2 > days_in_month [num_1] && num_3 <= days_in_month [num_1])
 
10311
      {
 
10312
        month = month_abbrevs [num_1 - 1];
 
10313
        year = num_2;
 
10314
        day = num_3;
 
10315
      }
 
10316
      else if (num_1 > 0 && num_1 < 13 && num_3 > days_in_month [num_1] && num_2 <= days_in_month [num_1])
 
10317
      {
 
10318
        month = month_abbrevs [num_1 - 1];
 
10319
        year = num_3;
 
10320
        day = num_2;
 
10321
      }
 
10322
      else if (num_2 > 0 && num_2 < 13 && num_1 > days_in_month [num_2] && num_3 <= days_in_month [num_1])
 
10323
      {
 
10324
        month = month_abbrevs [num_2 - 1];
 
10325
        year = num_1;
 
10326
        day = num_3;
 
10327
      }
 
10328
      else if (num_2 > 0 && num_2 < 13 && num_3 > days_in_month [num_2] && num_1 <= days_in_month [num_1])
 
10329
      {
 
10330
        month = month_abbrevs [num_2 - 1];
 
10331
        year = num_3;
 
10332
        day = num_1;
 
10333
      }
 
10334
      else if (num_3 > 0 && num_3 < 13 && num_1 > days_in_month [num_3] && num_2 <= days_in_month [num_1])
 
10335
      {
 
10336
        month = month_abbrevs [num_3 - 1];
 
10337
        year = num_1;
 
10338
        day = num_2;
 
10339
      }
 
10340
      else if (num_3 > 0 && num_3 < 13 && num_2 > days_in_month [num_3] && num_1 <= days_in_month [num_1])
 
10341
      {
 
10342
        month = month_abbrevs [num_3 - 1];
 
10343
        year = num_2;
 
10344
        day = num_1;
 
10345
      }
 
10346
      else
 
10347
      {
 
10348
        year = num_3;
 
10349
        if (! ChooseMonthAndDay (num_1, num_2, month_first, &month, &day, month_ambiguous))
 
10350
        {
 
10351
          year = num_1;
 
10352
          if (!ChooseMonthAndDay (num_2, num_3, month_first, &month, &day, month_ambiguous))
 
10353
          {
 
10354
            return NULL;
 
10355
          }
 
10356
        }
 
10357
      }
 
10358
                
 
10359
    }
 
10360
    year = GetYearFromNumber(year);
 
10361
  }
 
10362
  
 
10363
  if (month == NULL && day > 0)
 
10364
  {
 
10365
    return NULL;
 
10366
  }
 
10367
  
 
10368
  reformatted_date = (CharPtr) MemNew (sizeof (Char) * 12);
 
10369
  if (reformatted_date == NULL)
 
10370
  {
 
10371
    return NULL;
 
10372
  }
 
10373
   
 
10374
  if (month == NULL)
 
10375
  {
 
10376
    sprintf (reformatted_date, "%d", year);
 
10377
  }
 
10378
  else if (day == 0)
 
10379
  {
 
10380
    sprintf (reformatted_date, "%s-%d", month, year);
 
10381
  }
 
10382
  else
 
10383
  {
 
10384
    sprintf (reformatted_date, "%02d-%s-%d", day, month, year);
 
10385
  }
 
10386
  return reformatted_date;
 
10387
}
 
10388
 
 
10389
typedef struct collectiondatedlg {
 
10390
  DIALOG_MESSAGE_BLOCK
 
10391
  TaglistCallback tlp_callback; 
 
10392
  Pointer callback_data;
 
10393
  PopuP month;
 
10394
  PopuP day;
 
10395
  PopuP year;
 
10396
  Int4  start_year;
 
10397
} CollectionDateDlgData, PNTR CollectionDateDlgPtr;
 
10398
 
 
10399
static void PopulateDayPopup (PopuP p, Int4 month);
 
10400
 
 
10401
static void PointerToCollectionDateDialog (DialoG d, Pointer data)
 
10402
{
 
10403
  CollectionDateDlgPtr dlg;
 
10404
  CharPtr              val, reformatted;
 
10405
  Boolean              ambiguous = FALSE;
 
10406
  CharPtr              cp, cp2, month_abbrev;
 
10407
  Int4                 year = 1, month = 1, day = 1;
 
10408
 
 
10409
  dlg = (CollectionDateDlgPtr) GetObjectExtra (d);
 
10410
  if (dlg == NULL) return;
 
10411
 
 
10412
  SetValue (dlg->year, 1);
 
10413
  SetValue (dlg->month, 1);
 
10414
  SetValue (dlg->day, 1);
 
10415
  Disable (dlg->month);
 
10416
  Disable (dlg->day);
 
10417
 
 
10418
  val = (CharPtr) data;
 
10419
 
 
10420
  reformatted = ReformatDateStringEx (val, TRUE, &ambiguous);
 
10421
  if (StringHasNoText (reformatted) || ambiguous) {
 
10422
    /* do nothing */
 
10423
  } else {
 
10424
    cp = StringChr (reformatted, '-');
 
10425
    if (cp == NULL) {
 
10426
      year = GetYearFromToken (reformatted, StringLen (reformatted));
 
10427
      year = year - dlg->start_year + 2;
 
10428
    } else {
 
10429
      if (isdigit (*reformatted)) {
 
10430
        day = ReadNumberFromToken (reformatted, cp - reformatted);
 
10431
        day += 1;
 
10432
        cp++;
 
10433
        cp2 = StringChr (cp, '-');
 
10434
        month_abbrev = GetMonthFromToken (cp, cp2 - cp);
 
10435
        month = GetMonthNumFromAbbrev (month_abbrev);
 
10436
        if (month > -1) {
 
10437
          month += 2;
 
10438
        } else {
 
10439
          month = 1;
 
10440
        }
 
10441
        year = GetYearFromToken (cp2 + 1, StringLen (cp2 + 1));
 
10442
        year = year - dlg->start_year + 2;
 
10443
      }
 
10444
      else
 
10445
      {
 
10446
        month_abbrev = GetMonthFromToken (reformatted, cp - reformatted);
 
10447
        month = GetMonthNumFromAbbrev (month_abbrev);
 
10448
        if (month > -1) {
 
10449
          month += 2;
 
10450
        } else {
 
10451
          month = 1;
 
10452
        }
 
10453
        year = GetYearFromToken (cp + 1, StringLen (cp + 1));
 
10454
        year = year - dlg->start_year + 2;
 
10455
      }
 
10456
    }
 
10457
    SetValue (dlg->year, year);
 
10458
    Enable (dlg->month);
 
10459
    SetValue (dlg->month, month);
 
10460
    if (month > 1) {
 
10461
      PopulateDayPopup (dlg->day, month);
 
10462
      Enable (dlg->day);
 
10463
    }
 
10464
    SetValue (dlg->day, day);
 
10465
  }  
 
10466
}
 
10467
 
 
10468
static Pointer CollectionDateDialogToPointer (DialoG d)
 
10469
{
 
10470
  CollectionDateDlgPtr dlg;
 
10471
  Int4                 year, month = -1, day = 0;
 
10472
  CharPtr              year_fmt = "%d";
 
10473
  CharPtr              mon_year_fmt = "%s-%d";
 
10474
  CharPtr              day_mon_year_fmt = "%d-%s-%d";
 
10475
  Char                 date_str[100];
 
10476
 
 
10477
  dlg = (CollectionDateDlgPtr) GetObjectExtra (d);
 
10478
  date_str[0] = 0;
 
10479
  if (dlg != NULL) {
 
10480
    year = GetValue (dlg->year);
 
10481
    if (year < 2) {
 
10482
      return NULL;
 
10483
    } else {
 
10484
      year = year + dlg->start_year - 2;
 
10485
      month = GetValue (dlg->month);
 
10486
      if (month < 2) {
 
10487
        sprintf (date_str, year_fmt, year);
 
10488
      } else {
 
10489
        day = GetValue (dlg->day);
 
10490
        if (day < 2) {
 
10491
          sprintf (date_str, mon_year_fmt, month_abbrevs[month - 2], year);
 
10492
        } else {
 
10493
          sprintf (date_str, day_mon_year_fmt, day - 1, month_abbrevs[month - 2], year);
 
10494
        }
 
10495
      }
 
10496
    }
 
10497
  }
 
10498
 
 
10499
  return StringSave (date_str);
 
10500
}
 
10501
 
 
10502
static void PopulateDayPopup (PopuP p, Int4 month)
 
10503
{
 
10504
  Int4 i;
 
10505
  Char day[10];
 
10506
 
 
10507
  Reset (p);
 
10508
  PopupItem (p, "");
 
10509
 
 
10510
  if (month > 1) {
 
10511
    for (i = 1; i <= days_in_month [month - 2]; i++) {
 
10512
      sprintf (day, "%d", i);
 
10513
      PopupItem (p, day);
 
10514
    }
 
10515
  }
 
10516
}
 
10517
 
 
10518
static void PopulateMonthPopup (PopuP p)
 
10519
{
 
10520
  Int4 i;
 
10521
 
 
10522
  PopupItem (p, "");
 
10523
  for (i = 0; i < 12; i++) {
 
10524
    PopupItem (p, month_abbrevs[i]);
 
10525
  }
 
10526
}
 
10527
 
 
10528
static void ChangeCollectionDateMonth (PopuP p)
 
10529
{
 
10530
  CollectionDateDlgPtr dlg;
 
10531
  Int4                 month;
 
10532
 
 
10533
  dlg = (CollectionDateDlgPtr) GetObjectExtra (p);
 
10534
  if (dlg == NULL) return;
 
10535
 
 
10536
  month = GetValue (p);
 
10537
  if (month < 2) {
 
10538
    Disable (dlg->day);
 
10539
  } else {
 
10540
    PopulateDayPopup (dlg->day, month);
 
10541
    Enable (dlg->day);
 
10542
  }
 
10543
  if (dlg->tlp_callback != NULL) {
 
10544
    (dlg->tlp_callback) (dlg->callback_data);
 
10545
  }
 
10546
}
 
10547
 
 
10548
static Int4 PopulateYearPopup (PopuP p)
 
10549
{
 
10550
        Nlm_DayTime dt;
 
10551
  Char        year_str[20];
 
10552
  Int4        start_year, i, end_year;
 
10553
 
 
10554
  GetDayTime (&dt);
 
10555
  start_year = dt.tm_year + 1901 - 10;
 
10556
  end_year = start_year + 20;
 
10557
  PopupItem (p, " ");
 
10558
  for (i=start_year; i <= end_year; i++) {
 
10559
    sprintf (year_str, "%d", i);
 
10560
    PopupItem (p, year_str);
 
10561
  }
 
10562
  return start_year;
 
10563
}
 
10564
 
 
10565
static void ChangeCollectionDateYear (PopuP p)
 
10566
{
 
10567
  CollectionDateDlgPtr dlg;
 
10568
 
 
10569
  dlg = (CollectionDateDlgPtr) GetObjectExtra (p);
 
10570
  if (dlg == NULL) return;
 
10571
 
 
10572
  if (GetValue (p) < 2) {
 
10573
    Disable (dlg->month);
 
10574
    Disable (dlg->day);
 
10575
  } else {
 
10576
    Enable (dlg->month);
 
10577
    ChangeCollectionDateMonth (dlg->month);
 
10578
  }
 
10579
  if (dlg->tlp_callback != NULL) {
 
10580
    (dlg->tlp_callback) (dlg->callback_data);
 
10581
  }
 
10582
}
 
10583
 
 
10584
extern DialoG CollectionDateDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
10585
                               TaglistCallback tlp_callback,
 
10586
                               Pointer callback_data)
 
10587
{
 
10588
  CollectionDateDlgPtr dlg;
 
10589
  GrouP           p;
 
10590
 
 
10591
  p = HiddenGroup (h, 4, 0, NULL);
 
10592
  dlg = (CollectionDateDlgPtr) MemNew (sizeof(CollectionDateDlgData));
 
10593
 
 
10594
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
10595
  dlg->dialog = (DialoG) p;
 
10596
  dlg->todialog = PointerToCollectionDateDialog;
 
10597
  dlg->fromdialog = CollectionDateDialogToPointer;
 
10598
  dlg->testdialog = NULL;
 
10599
  dlg->tlp_callback = tlp_callback;
 
10600
  dlg->callback_data = callback_data;
 
10601
 
 
10602
  dlg->year = PopupList (p, TRUE, ChangeCollectionDateYear);
 
10603
  SetObjectExtra (dlg->year, dlg, NULL);
 
10604
  dlg->start_year = PopulateYearPopup (dlg->year);
 
10605
  SetValue (dlg->year, 1);
 
10606
 
 
10607
  dlg->month = PopupList (p, TRUE, ChangeCollectionDateMonth);
 
10608
  SetObjectExtra (dlg->month, dlg, NULL);
 
10609
  PopulateMonthPopup (dlg->month);
 
10610
  SetValue (dlg->month, 1);
 
10611
 
 
10612
  dlg->day = PopupList (p, TRUE, ChangeGBQualEditorPopup);
 
10613
  SetObjectExtra (dlg->day, dlg, NULL);
 
10614
 
 
10615
  return (DialoG) p;
 
10616
}
 
10617
 
 
10618
extern Boolean ParseCollectionDateOk (CharPtr txt)
 
10619
{
 
10620
  CharPtr date_str;
 
10621
  Boolean ambiguous = FALSE;
 
10622
  Boolean rval = FALSE;
 
10623
 
 
10624
  if (StringHasNoText (txt)) {
 
10625
    rval = TRUE;
 
10626
  } else {
 
10627
    date_str = ReformatDateStringEx (txt, TRUE, &ambiguous);
 
10628
    if (date_str != NULL && !ambiguous) {
 
10629
      rval = TRUE;
 
10630
    } 
 
10631
    date_str = MemFree (date_str);
 
10632
  }
 
10633
  return rval;
 
10634
}
 
10635
 
 
10636
typedef struct rptunitrangedlg {
 
10637
  DIALOG_MESSAGE_BLOCK
 
10638
  TaglistCallback tlp_callback; 
 
10639
  Pointer callback_data;
 
10640
  TexT  range_start;
 
10641
  TexT  range_stop;
 
10642
} RptUnitRangeDlgData, PNTR RptUnitRangeDlgPtr;
 
10643
 
 
10644
static Boolean ParseRptUnitRangeOkEx (CharPtr txt, Int4Ptr pstart, Int4Ptr pstop)
 
10645
{
 
10646
  CharPtr cp;
 
10647
  Int4    start = -1, stop = -1;
 
10648
  Char    ch;
 
10649
  Boolean rval = FALSE;
 
10650
 
 
10651
  if (StringHasNoText (txt)) {
 
10652
    return TRUE;
 
10653
  }
 
10654
  
 
10655
  cp = txt;
 
10656
  while (*cp != 0 && isdigit (*cp)) {
 
10657
    cp++;
 
10658
  }
 
10659
  if (cp != txt) {
 
10660
    ch = *cp;
 
10661
    *cp = 0;
 
10662
    start = atoi (txt);
 
10663
    *cp = ch;
 
10664
    cp++;
 
10665
    while (*cp == ch) {
 
10666
      cp++;
 
10667
    }
 
10668
    txt = cp;
 
10669
    while (isdigit (*cp)) {
 
10670
      cp++;
 
10671
    }
 
10672
    if (cp != txt) {
 
10673
      stop = atoi (txt);
 
10674
    }
 
10675
  }
 
10676
 
 
10677
  if (start > -1 && stop > -1) {
 
10678
    if (pstart != NULL) {
 
10679
      *pstart = start;
 
10680
    }
 
10681
    if (pstop != NULL) {
 
10682
      *pstop = stop;
 
10683
    }
 
10684
    rval = TRUE;
 
10685
  }
 
10686
  return rval;
 
10687
}
 
10688
 
 
10689
static void StringToRptUnitRangeDialog (DialoG d, Pointer data)
 
10690
{
 
10691
  RptUnitRangeDlgPtr dlg;
 
10692
  CharPtr            val;
 
10693
  Int4               start = -1, stop = -1;
 
10694
  Char               num_str[100];
 
10695
 
 
10696
  dlg = (RptUnitRangeDlgPtr) GetObjectExtra (d);
 
10697
  if (dlg == NULL) return;
 
10698
 
 
10699
  val = (CharPtr) data;
 
10700
  
 
10701
  ParseRptUnitRangeOkEx (val, &start, &stop);
 
10702
  if (start > -1 && stop > -1) {
 
10703
    sprintf (num_str, "%d", start);
 
10704
    SetTitle (dlg->range_start, num_str);
 
10705
    sprintf (num_str, "%d", stop);
 
10706
    SetTitle (dlg->range_stop, num_str);
 
10707
  } else {
 
10708
    SetTitle (dlg->range_start, "");
 
10709
    SetTitle (dlg->range_stop, "");
 
10710
  }
 
10711
}
 
10712
 
 
10713
static Pointer RptUnitRangeDialogToString (DialoG d)
 
10714
{
 
10715
  RptUnitRangeDlgPtr dlg;
 
10716
  CharPtr            val = NULL;
 
10717
  CharPtr            start, stop;
 
10718
 
 
10719
  dlg = (RptUnitRangeDlgPtr) GetObjectExtra (d);
 
10720
  if (dlg == NULL) return NULL;
 
10721
 
 
10722
  start = SaveStringFromText (dlg->range_start);
 
10723
  stop = SaveStringFromText (dlg->range_stop);
 
10724
 
 
10725
  if (StringHasNoText (start) && StringHasNoText (stop)) {
 
10726
    return StringSave ("");
 
10727
  } else {
 
10728
    val = (CharPtr) MemNew (sizeof (Char) * (StringLen (start) + StringLen (stop) + 3));
 
10729
    sprintf (val, "%s..%s", start == NULL ? "" : start, stop == NULL ? "" : stop);
 
10730
  }
 
10731
  start = MemFree (start);
 
10732
  stop = MemFree (stop);
 
10733
  return val;
 
10734
}
 
10735
 
 
10736
 
 
10737
extern DialoG CreateRptUnitRangeDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
10738
                                         TaglistCallback tlp_callback,
 
10739
                                         Pointer callback_data)
 
10740
{
 
10741
  RptUnitRangeDlgPtr dlg;
 
10742
  GrouP           p;
 
10743
 
 
10744
  p = HiddenGroup (h, 6, 0, NULL);
 
10745
  dlg = (RptUnitRangeDlgPtr) MemNew (sizeof(RptUnitRangeDlgData));
 
10746
 
 
10747
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
10748
  dlg->dialog = (DialoG) p;
 
10749
  dlg->todialog = StringToRptUnitRangeDialog;
 
10750
  dlg->fromdialog = RptUnitRangeDialogToString;
 
10751
  dlg->testdialog = NULL;
 
10752
 
 
10753
  dlg->tlp_callback = tlp_callback;
 
10754
  dlg->callback_data = callback_data;
 
10755
 
 
10756
  StaticPrompt (p, "Start", 0, dialogTextHeight, programFont, 'l');
 
10757
  dlg->range_start = DialogText (p, "", 5, ChangeGBQualEditorText);
 
10758
  SetObjectExtra (dlg->range_start, dlg, NULL);
 
10759
  StaticPrompt (p, "Stop", 0, dialogTextHeight, programFont, 'l');
 
10760
  dlg->range_stop = DialogText (p, "", 5, ChangeGBQualEditorText);
 
10761
  SetObjectExtra (dlg->range_stop, dlg, NULL);
 
10762
 
 
10763
 
 
10764
  return (DialoG) p;
 
10765
}
 
10766
 
 
10767
static Boolean ParseRptUnitRangeOk (CharPtr txt)
 
10768
{
 
10769
  return ParseRptUnitRangeOkEx (txt, NULL, NULL);
 
10770
}
 
10771
 
 
10772
 
 
10773
typedef struct mobileelementdlg {
 
10774
  DIALOG_MESSAGE_BLOCK
 
10775
  TaglistCallback tlp_callback; 
 
10776
  Pointer callback_data;
 
10777
  PopuP element_type;
 
10778
  TexT  description;
 
10779
} MobileElementDlgData, PNTR MobileElementDlgPtr;
 
10780
 
 
10781
CharPtr mobile_element_keywords[] = 
 
10782
{ " ",
 
10783
  "transposon",
 
10784
  "retrotransposon",
 
10785
  "integron",
 
10786
  "insertion sequence", 
 
10787
  "non-LTR retrotransposon",              
 
10788
  "SINE", 
 
10789
  "MITE", 
 
10790
  "LINE", 
 
10791
  "other",
 
10792
  NULL};
 
10793
 
 
10794
static Int2 GetMobileElementNum (CharPtr txt, CharPtr PNTR desc_start)
 
10795
{
 
10796
  CharPtr cp;
 
10797
  Int2    i;
 
10798
  Int4    keyword_len;
 
10799
 
 
10800
  if (desc_start != NULL) {
 
10801
    *desc_start = NULL;
 
10802
  }
 
10803
  if (StringHasNoText (txt)) {
 
10804
    return 0;
 
10805
  }
 
10806
  /* skip over any leading spaces */
 
10807
  while (isspace (*txt)) {
 
10808
    txt++;
 
10809
  }
 
10810
  cp = StringChr (txt, ':');
 
10811
  if (cp == NULL) {
 
10812
    for (i = 1; mobile_element_keywords[i] != NULL; i++) {
 
10813
      if (StringICmp (txt, mobile_element_keywords[i]) == 0) {
 
10814
        return i;
 
10815
      }
 
10816
    }
 
10817
    return -1;
 
10818
  } else {
 
10819
    keyword_len = cp - txt;
 
10820
    while (keyword_len > 0 && isspace (txt[keyword_len - 1])) {
 
10821
      keyword_len--;
 
10822
    }
 
10823
    if (keyword_len == 0) {
 
10824
      return 0;
 
10825
    }
 
10826
    for (i = 1; mobile_element_keywords[i] != NULL; i++) {
 
10827
      if (StringNICmp (txt, mobile_element_keywords[i], keyword_len) == 0) {
 
10828
        if (desc_start != NULL && !StringHasNoText (cp + 1)) {
 
10829
          *desc_start = cp + 1;
 
10830
          while (isspace(**desc_start)) {
 
10831
            (*desc_start)++;
 
10832
          }
 
10833
        }
 
10834
        return i;
 
10835
      }
 
10836
    }
 
10837
  }
 
10838
  return -1;
 
10839
}
 
10840
 
 
10841
static Boolean ParseMobileElementOk (CharPtr txt)
 
10842
{
 
10843
 
 
10844
  if (GetMobileElementNum(txt, NULL) > -1) {
 
10845
    return TRUE;
 
10846
  } else {
 
10847
    return FALSE;
 
10848
  }
 
10849
}
 
10850
 
 
10851
static void ChangeMobileElementType (PopuP p)
 
10852
{
 
10853
  MobileElementDlgPtr dlg;
 
10854
 
 
10855
  dlg = (MobileElementDlgPtr) GetObjectExtra (p);
 
10856
  if (dlg == NULL) return;
 
10857
 
 
10858
  if (GetValue (dlg->element_type) <= 1) {
 
10859
    Disable (dlg->description);
 
10860
  } else {
 
10861
    Enable (dlg->description);
 
10862
  }
 
10863
  ChangeGBQualEditorPopup (p);
 
10864
}
 
10865
 
 
10866
static void StringToMobileElementDialog (DialoG d, Pointer data)
 
10867
{
 
10868
  MobileElementDlgPtr dlg;
 
10869
  CharPtr             val;
 
10870
  CharPtr             desc_start = NULL;
 
10871
  Int2                num;
 
10872
 
 
10873
  dlg = (MobileElementDlgPtr) GetObjectExtra (d);
 
10874
  if (dlg == NULL) return;
 
10875
 
 
10876
  val = (CharPtr) data;
 
10877
 
 
10878
  num = GetMobileElementNum (val, &desc_start);
 
10879
 
 
10880
  if (num >= 0) {
 
10881
    SetValue (dlg->element_type, num + 1);
 
10882
    SetTitle (dlg->description, desc_start == NULL ? "" : desc_start);
 
10883
  }
 
10884
}
 
10885
 
 
10886
static Pointer MobileElementDialogToString (DialoG d)
 
10887
{
 
10888
  MobileElementDlgPtr dlg;
 
10889
  CharPtr             val = NULL;
 
10890
  CharPtr             desc_start = NULL;
 
10891
  Int2                num;
 
10892
 
 
10893
  dlg = (MobileElementDlgPtr) GetObjectExtra (d);
 
10894
  if (dlg == NULL) return NULL;
 
10895
 
 
10896
  num = GetValue (dlg->element_type);
 
10897
 
 
10898
  if (num >= 1) {
 
10899
    desc_start = SaveStringFromText (dlg->description);
 
10900
    if (StringHasNoText (desc_start)) {
 
10901
      val = StringSave (mobile_element_keywords[num - 1]);
 
10902
    } else {
 
10903
      val = (CharPtr) MemNew (sizeof (Char) * (StringLen (mobile_element_keywords[num - 1]) + StringLen (desc_start) + 2));
 
10904
      sprintf (val, "%s:%s", mobile_element_keywords[num - 1], desc_start);
 
10905
    }
 
10906
  }
 
10907
  return (Pointer) val;
 
10908
}
 
10909
 
 
10910
 
 
10911
static DialoG CreateMobileElementDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
10912
                                         TaglistCallback tlp_callback,
 
10913
                                         Pointer callback_data)
 
10914
{
 
10915
  MobileElementDlgPtr dlg;
 
10916
  GrouP           p;
 
10917
  Int2            i;
 
10918
 
 
10919
  p = HiddenGroup (h, 3, 0, NULL);
 
10920
  dlg = (MobileElementDlgPtr) MemNew (sizeof(MobileElementDlgData));
 
10921
 
 
10922
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
10923
  dlg->dialog = (DialoG) p;
 
10924
  dlg->todialog = StringToMobileElementDialog;
 
10925
  dlg->fromdialog = MobileElementDialogToString;
 
10926
  dlg->testdialog = NULL;
 
10927
 
 
10928
  dlg->tlp_callback = tlp_callback;
 
10929
  dlg->callback_data = callback_data;
 
10930
 
 
10931
  dlg->element_type = PopupList (p, TRUE, ChangeMobileElementType);
 
10932
  for (i = 0; mobile_element_keywords[i] != NULL; i++) {
 
10933
    PopupItem (dlg->element_type, mobile_element_keywords[i]);
 
10934
  }
 
10935
  SetValue (dlg->element_type, 1);
 
10936
  SetObjectExtra (dlg->element_type, dlg, NULL);
 
10937
 
 
10938
  dlg->description = DialogText (p, "", 15, ChangeGBQualEditorText);
 
10939
  SetObjectExtra (dlg->description, dlg, NULL);
 
10940
 
 
10941
  return (DialoG) p;
 
10942
}
 
10943
 
 
10944
static void CopyTextToMobileElementDialog (DialoG d, CharPtr txt)
 
10945
{
 
10946
  MobileElementDlgPtr dlg;
 
10947
 
 
10948
  dlg = (MobileElementDlgPtr) GetObjectExtra (d);
 
10949
 
 
10950
  if (dlg == NULL || StringHasNoText (txt)) return;
 
10951
 
 
10952
  SetTitle (dlg->description, txt);
 
10953
}
 
10954
 
 
10955
 
 
10956
typedef struct truefalsedlg {
 
10957
  DIALOG_MESSAGE_BLOCK
 
10958
  TaglistCallback tlp_callback; 
 
10959
  Pointer callback_data;
 
10960
  ButtoN is_true;
 
10961
} TrueFalseDlgData, PNTR TrueFalseDlgPtr;
 
10962
 
 
10963
static void PointerToTrueFalseDialog (DialoG d, Pointer data)
 
10964
{
 
10965
  TrueFalseDlgPtr dlg;
 
10966
  CharPtr         val;
 
10967
 
 
10968
  dlg = (TrueFalseDlgPtr) GetObjectExtra (d);
 
10969
  if (dlg == NULL) return;
 
10970
 
 
10971
  val = (CharPtr) data;
 
10972
 
 
10973
  if (StringICmp (val, "TRUE") == 0) {
 
10974
    SetStatus (dlg->is_true, TRUE);
 
10975
  } else {
 
10976
    SetStatus (dlg->is_true, FALSE);
 
10977
  }
 
10978
}
 
10979
 
 
10980
static Pointer TrueFalseDialogToPointer (DialoG d)
 
10981
{
 
10982
  TrueFalseDlgPtr dlg;
 
10983
 
 
10984
  dlg = (TrueFalseDlgPtr) GetObjectExtra (d);
 
10985
  if (dlg == NULL) return StringSave ("FALSE");
 
10986
 
 
10987
  if (GetStatus (dlg->is_true)) {
 
10988
    return StringSave ("TRUE");
 
10989
  } else {
 
10990
    return StringSave ("FALSE");
 
10991
  }
 
10992
}
 
10993
 
 
10994
static DialoG TrueFalseDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
10995
                               TaglistCallback tlp_callback,
 
10996
                               Pointer callback_data)
 
10997
{
 
10998
  TrueFalseDlgPtr dlg;
 
10999
  GrouP           p;
 
11000
 
 
11001
  p = HiddenGroup (h, 2, 0, NULL);
 
11002
  dlg = (TrueFalseDlgPtr) MemNew (sizeof(TrueFalseDlgData));
 
11003
 
 
11004
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
11005
  dlg->dialog = (DialoG) p;
 
11006
  dlg->todialog = PointerToTrueFalseDialog;
 
11007
  dlg->fromdialog = TrueFalseDialogToPointer;
 
11008
  dlg->testdialog = NULL;
 
11009
  dlg->tlp_callback = tlp_callback;
 
11010
  dlg->callback_data = callback_data;
 
11011
 
 
11012
  dlg->is_true = CheckBox (p, "", ChangeGBQualEditorButton);
 
11013
  SetObjectExtra (dlg->is_true, dlg, NULL);
 
11014
 
 
11015
  return (DialoG) p;
 
11016
}
 
11017
 
 
11018
static Boolean ParseTrueFalseOk (CharPtr txt)
 
11019
{
 
11020
  if (StringHasNoText (txt) || StringICmp (txt, "TRUE") == 0 || StringICmp (txt, "FALSE") == 0) {
 
11021
    return TRUE;
 
11022
  } else {
 
11023
    return FALSE;
 
11024
  }
 
11025
}
 
11026
 
 
11027
typedef struct simplelistqualdlg {
 
11028
  DIALOG_MESSAGE_BLOCK
 
11029
  TaglistCallback tlp_callback; 
 
11030
  Pointer callback_data;
 
11031
  PopuP list;
 
11032
  CharPtr PNTR val_list;
 
11033
} SimpleListQualDlgData, PNTR SimpleListQualDlgPtr;
 
11034
 
 
11035
static Int2 GetListNum (CharPtr val, CharPtr PNTR val_list)
 
11036
{
 
11037
  Int2 i;
 
11038
  if (StringHasNoText (val)) return 0;
 
11039
  for (i = 1; val_list[i] != NULL; i++) {
 
11040
    if (StringICmp (val, val_list[i]) == 0) {
 
11041
      return i;
 
11042
    }
 
11043
  }
 
11044
  return -1;
 
11045
}
 
11046
 
 
11047
static void StringToSimpleListQualDialog (DialoG d, Pointer data)
 
11048
{
 
11049
  SimpleListQualDlgPtr dlg;
 
11050
  CharPtr              val;
 
11051
  Int2                 num;
 
11052
 
 
11053
  dlg = (SimpleListQualDlgPtr) GetObjectExtra (d);
 
11054
  if (dlg == NULL) return;
 
11055
  val = (CharPtr) data;
 
11056
  num = GetListNum (val, dlg->val_list);
 
11057
  if (num > -1) {
 
11058
    SetValue (dlg->list, num + 1);
 
11059
  } else {
 
11060
    SetValue (dlg->list, 1);
 
11061
  }
 
11062
}
 
11063
 
 
11064
static Pointer SimpleListQualDialogToString (DialoG d)
 
11065
{
 
11066
  SimpleListQualDlgPtr dlg;
 
11067
  CharPtr              val = NULL;
 
11068
  Int2                 num;
 
11069
 
 
11070
  dlg = (SimpleListQualDlgPtr) GetObjectExtra (d);
 
11071
  if (dlg == NULL) return NULL;
 
11072
 
 
11073
  num = GetValue (dlg->list);
 
11074
  if (num > 1) {
 
11075
    val = StringSave (dlg->val_list[num - 1]);
 
11076
  }
 
11077
  return (Pointer) val;
 
11078
}
 
11079
 
 
11080
static DialoG SimpleListQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name, CharPtr PNTR list,
 
11081
                                    TaglistCallback tlp_callback,
 
11082
                                    Pointer callback_data)
 
11083
{
 
11084
  SimpleListQualDlgPtr dlg;
 
11085
  GrouP           p;
 
11086
  Int2            i;
 
11087
 
 
11088
  p = HiddenGroup (h, 2, 0, NULL);
 
11089
  dlg = (SimpleListQualDlgPtr) MemNew (sizeof(SimpleListQualDlgData));
 
11090
 
 
11091
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
11092
  dlg->dialog = (DialoG) p;
 
11093
  dlg->todialog = StringToSimpleListQualDialog;
 
11094
  dlg->fromdialog = SimpleListQualDialogToString;
 
11095
  dlg->testdialog = NULL;
 
11096
  dlg->tlp_callback = tlp_callback;
 
11097
  dlg->callback_data = callback_data;
 
11098
 
 
11099
  dlg->list = PopupList (p, TRUE, ChangeGBQualEditorPopup);
 
11100
  SetObjectExtra (dlg->list, dlg, NULL);
 
11101
  dlg->val_list = list;
 
11102
  if (dlg->val_list != NULL) {
 
11103
    for (i = 0; dlg->val_list[i] != NULL; i++) {
 
11104
      PopupItem (dlg->list, dlg->val_list[i]);
 
11105
    }
 
11106
    SetValue (dlg->list, 1);
 
11107
  }
 
11108
  return (DialoG) p;
 
11109
}
 
11110
 
 
11111
typedef struct multilistqualdlg {
 
11112
  DIALOG_MESSAGE_BLOCK
 
11113
  TaglistCallback tlp_callback; 
 
11114
  Pointer callback_data;
 
11115
  ButtoN  *button_list;
 
11116
  TexT    last_txt;
 
11117
 
 
11118
  CharPtr PNTR val_list;
 
11119
} MultiListQualDlgData, PNTR MultiListQualDlgPtr;
 
11120
 
 
11121
static void CleanupMultiListQualDlg (GraphiC g, VoidPtr data)
 
11122
 
 
11123
{
 
11124
  MultiListQualDlgPtr  dlg;
 
11125
 
 
11126
  dlg = (MultiListQualDlgPtr) data;
 
11127
  if (dlg != NULL) {
 
11128
    dlg->button_list = MemFree (dlg->button_list);
 
11129
  }
 
11130
  StdCleanupExtraProc (g, data);
 
11131
}
 
11132
 
 
11133
static void CheckMultiListLast (ButtoN b)
 
11134
{
 
11135
  MultiListQualDlgPtr dlg;
 
11136
 
 
11137
  dlg = (MultiListQualDlgPtr) GetObjectExtra (b);
 
11138
  if (dlg == NULL) return;
 
11139
 
 
11140
  if (GetStatus (b)) {
 
11141
    Enable (dlg->last_txt);
 
11142
  } else {
 
11143
    Disable (dlg->last_txt);
 
11144
  }
 
11145
  if (dlg->tlp_callback) {
 
11146
    (dlg->tlp_callback) (dlg->callback_data);
 
11147
  }
 
11148
}
 
11149
 
 
11150
static void ApplyOneValToMultiListQualDialog (MultiListQualDlgPtr dlg, CharPtr val, CharPtr PNTR other_text)
 
11151
{
 
11152
  Int2    i;
 
11153
  CharPtr tmp;
 
11154
 
 
11155
  if (dlg == NULL || StringHasNoText (val) || other_text == NULL) return;
 
11156
 
 
11157
  i = GetListNum (val, dlg->val_list);
 
11158
  if (i > 0) {
 
11159
    SetStatus (dlg->button_list[i - 1], TRUE);
 
11160
  } else {
 
11161
    if (*other_text == NULL) {
 
11162
      *other_text = StringSave (val);
 
11163
    } else {
 
11164
      tmp = (CharPtr) MemNew (sizeof (Char) * (StringLen (*other_text) + StringLen (val) + 2));
 
11165
      sprintf (tmp, "%s,%s", *other_text, val);
 
11166
      *other_text = MemFree (*other_text);
 
11167
      *other_text = tmp;
 
11168
    }
 
11169
  }
 
11170
}
 
11171
 
 
11172
static void StringToMultiListQualDialog (DialoG d, Pointer data)
 
11173
{
 
11174
  MultiListQualDlgPtr dlg;
 
11175
  CharPtr             val, cp, other_text = NULL;
 
11176
  Int2                i;
 
11177
 
 
11178
  dlg = (MultiListQualDlgPtr) GetObjectExtra (d);
 
11179
  if (dlg == NULL) return;
 
11180
  for (i = 1; dlg->val_list[i] != NULL; i++) {
 
11181
    SetStatus (dlg->button_list[i - 1], FALSE);
 
11182
  }
 
11183
  SetStatus (dlg->button_list[i - 1], FALSE);
 
11184
  SetTitle (dlg->last_txt, "");
 
11185
 
 
11186
  val = (CharPtr) data;
 
11187
  if (StringHasNoText (val)) {
 
11188
    return;
 
11189
  }
 
11190
  
 
11191
  if (*val == '(' && val[StringLen(val) - 1] == ')') {
 
11192
    /* parentheses list */
 
11193
    val++;
 
11194
    cp = StringChr (val, ',');
 
11195
    while (cp != NULL) {
 
11196
      *cp = 0;
 
11197
      ApplyOneValToMultiListQualDialog (dlg, val, &other_text);
 
11198
      *cp = ',';
 
11199
      val = cp + 1;
 
11200
      while (isspace(*val)) {
 
11201
        val++;
 
11202
      }
 
11203
      cp = StringChr (val, ',');
 
11204
    }
 
11205
    val[StringLen(val) - 1] = 0;
 
11206
    ApplyOneValToMultiListQualDialog (dlg, val, &other_text);
 
11207
    val[StringLen(val) - 1] = ')';
 
11208
  } else {
 
11209
    ApplyOneValToMultiListQualDialog (dlg, val, &other_text);
 
11210
  }
 
11211
  if (dlg->last_txt != NULL)
 
11212
  {
 
11213
    if (!StringHasNoText (other_text)) {
 
11214
      SetTitle (dlg->last_txt, other_text);
 
11215
      SetStatus (dlg->button_list[i - 1], TRUE);
 
11216
      Enable (dlg->last_txt);
 
11217
    } else {
 
11218
      Disable (dlg->last_txt);
 
11219
    }
 
11220
  }
 
11221
  other_text = MemFree (other_text);
 
11222
}
 
11223
 
 
11224
static Pointer MultiListQualDialogToString (DialoG d)
 
11225
{
 
11226
  MultiListQualDlgPtr dlg;
 
11227
  CharPtr             val = NULL, tmp;
 
11228
  Int2                i;
 
11229
 
 
11230
  dlg = (MultiListQualDlgPtr) GetObjectExtra (d);
 
11231
  if (dlg == NULL) return NULL;
 
11232
  for (i = 1; dlg->val_list[i] != NULL; i++) {
 
11233
    if (GetStatus (dlg->button_list[i - 1])) {
 
11234
      if (val == NULL) {
 
11235
        val = StringSave (dlg->val_list[i]);
 
11236
      } else {
 
11237
        tmp = StringSave (dlg->val_list[i]);
 
11238
        val = CombineSplitGBQual (val, tmp);
 
11239
      }
 
11240
    }
 
11241
  }
 
11242
  if (dlg->last_txt != NULL
 
11243
      && GetStatus (dlg->button_list[i - 1]) 
 
11244
      && !TextHasNoText (dlg->last_txt)) {
 
11245
    if (val == NULL) {
 
11246
      val = SaveStringFromText (dlg->last_txt);
 
11247
    } else {
 
11248
      tmp = SaveStringFromText (dlg->last_txt);
 
11249
      val = CombineSplitGBQual (val, tmp);
 
11250
      tmp = MemFree (tmp);
 
11251
    }
 
11252
  }
 
11253
  return val;
 
11254
}
 
11255
 
 
11256
static DialoG MultiListQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name, CharPtr PNTR list,
 
11257
                                   Boolean allow_not_in_list,
 
11258
                                   TaglistCallback tlp_callback,
 
11259
                                   Pointer callback_data)
 
11260
{
 
11261
  MultiListQualDlgPtr dlg;
 
11262
  GrouP           p, g, last_button = NULL;
 
11263
  Int2            i, num_buttons = 1; /* start with one, for the type-in wildcard value */
 
11264
 
 
11265
  p = HiddenGroup (h, -1, 0, NULL);
 
11266
  dlg = (MultiListQualDlgPtr) MemNew (sizeof(MultiListQualDlgData));
 
11267
 
 
11268
  SetObjectExtra (p, dlg, CleanupMultiListQualDlg);
 
11269
  dlg->dialog = (DialoG) p;
 
11270
  dlg->todialog = StringToMultiListQualDialog;
 
11271
  dlg->fromdialog = MultiListQualDialogToString;
 
11272
  dlg->testdialog = NULL;
 
11273
  dlg->tlp_callback = tlp_callback;
 
11274
  dlg->callback_data = callback_data;
 
11275
  dlg->val_list = list;
 
11276
 
 
11277
  /* start with 1, skip blank at start of list */
 
11278
  for (i = 1; dlg->val_list[i] != NULL; i++) {
 
11279
    num_buttons ++;
 
11280
  }
 
11281
 
 
11282
  dlg->button_list = (ButtoN *) MemNew (num_buttons * sizeof (ButtoN));
 
11283
 
 
11284
  g = HiddenGroup (p, 4, 0, NULL);
 
11285
  for (i = 1; dlg->val_list [i] != NULL; i++) {
 
11286
    dlg->button_list[i - 1] = CheckBox (g, dlg->val_list[i], ChangeGBQualEditorButton);
 
11287
    SetObjectExtra (dlg->button_list[i - 1], dlg, NULL);
 
11288
  }
 
11289
  if (allow_not_in_list)
 
11290
  {
 
11291
    last_button = HiddenGroup (p, 2, 0, NULL);
 
11292
    dlg->button_list[i - 1] = CheckBox (last_button, "", CheckMultiListLast);
 
11293
    SetObjectExtra (dlg->button_list[i - 1], dlg, NULL);
 
11294
    dlg->last_txt = DialogText (last_button, "", 20, ChangeGBQualEditorText);
 
11295
    SetObjectExtra (dlg->last_txt, dlg, NULL);
 
11296
    Disable (dlg->last_txt);
 
11297
  }
 
11298
 
 
11299
  AlignObjects (ALIGN_CENTER, (HANDLE) g, (HANDLE) last_button, NULL);
 
11300
    
 
11301
  return (DialoG) p;
 
11302
}
 
11303
 
 
11304
static Boolean ParseMultiListQualOk (CharPtr val)
 
11305
{
 
11306
  return TRUE;
 
11307
}
 
11308
 
 
11309
CharPtr codon_start_values[] = {" ", "1", "2", "3", NULL};
 
11310
static DialoG CodonStartQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
11311
                                    TaglistCallback tlp_callback,
 
11312
                                    Pointer callback_data)
 
11313
 
 
11314
{
 
11315
  return SimpleListQualDialog (h, sep, name, codon_start_values, tlp_callback, callback_data);
 
11316
}
 
11317
static Boolean ParseCodonStartOk (CharPtr val)
 
11318
{
 
11319
  if (GetListNum (val, codon_start_values) > -1) {
 
11320
    return TRUE;
 
11321
  } else {
 
11322
    return FALSE;
 
11323
  }
 
11324
}
 
11325
 
 
11326
CharPtr mol_type_values[] = {" ", "genomic DNA", "genomic RNA", "mRNA", "tRNA", "rRNA",
 
11327
                "snoRNA", "snRNA", "scRNA", "pre-RNA", "other RNA",
 
11328
                "other DNA", "viral cRNA", "unassigned DNA", "unassigned RNA", NULL};
 
11329
static DialoG MolTypeQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
11330
                                 TaglistCallback tlp_callback,
 
11331
                                 Pointer callback_data)
 
11332
{
 
11333
  return SimpleListQualDialog (h, sep, name, mol_type_values, tlp_callback, callback_data);
 
11334
}
 
11335
static Boolean ParseMolTypeOk (CharPtr val)
 
11336
{
 
11337
  if (GetListNum (val, mol_type_values) > -1) {
 
11338
    return TRUE;
 
11339
  } else {
 
11340
    return FALSE;
 
11341
  }
 
11342
}
 
11343
 
 
11344
CharPtr organelle_values[] = {" ", "mitochondrion", "nucleomorph", "plastid",
 
11345
                              "mitochondrion:kinetoplast",
 
11346
                              "plastid:chloroplast", "plastid:apicoplast", 
 
11347
                              "plastid:chromoplast", "plastid:cyanelle", 
 
11348
                              "plastid:leucoplast", "plastid:proplastid", NULL};
 
11349
static DialoG OrganelleQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
11350
                                   TaglistCallback tlp_callback,
 
11351
                                   Pointer callback_data)
 
11352
{
 
11353
  return SimpleListQualDialog (h, sep, name, organelle_values, tlp_callback, callback_data);
 
11354
}
 
11355
static Boolean ParseOrganelleOk (CharPtr val)
 
11356
{
 
11357
  if (GetListNum (val, organelle_values) > -1) {
 
11358
    return TRUE;
 
11359
  } else {
 
11360
    return FALSE;
 
11361
  }
 
11362
}
 
11363
 
 
11364
CharPtr rpt_type_values[] = {" ", "tandem", "inverted", "flanking", "terminal", 
 
11365
                             "direct", "dispersed", "other", NULL};
 
11366
static DialoG RptTypeQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
11367
                                 TaglistCallback tlp_callback,
 
11368
                                 Pointer callback_data)
 
11369
{
 
11370
 
 
11371
 
 
11372
  return MultiListQualDialog (h, sep, name, rpt_type_values, FALSE, tlp_callback, callback_data);
 
11373
}
 
11374
 
 
11375
static Boolean ParseRptTypeOk (CharPtr val)
 
11376
{
 
11377
  CharPtr cpy, cp, check;
 
11378
  Boolean rval = TRUE;
 
11379
 
 
11380
  if (StringHasNoText (val))
 
11381
  {
 
11382
    return TRUE;
 
11383
  }
 
11384
  else if (val[0] == '(' && val[StringLen(val) - 1] == ')')
 
11385
  {
 
11386
    cpy = StringSave (val + 1);
 
11387
    cpy [StringLen (cpy) - 1] = 0;
 
11388
    check = cpy;
 
11389
    cp = StringChr (cpy, ',');
 
11390
    while (cp != NULL && rval)
 
11391
    {
 
11392
      *cp = 0;
 
11393
      TrimSpacesAroundString (check);
 
11394
      if (GetListNum (check, rpt_type_values) < 0)
 
11395
      {
 
11396
        rval = FALSE;
 
11397
      }
 
11398
      check = cp + 1;
 
11399
      cp = StringChr (check, ',');
 
11400
    }
 
11401
    if (rval)
 
11402
    {
 
11403
      TrimSpacesAroundString (check);
 
11404
      if (GetListNum (check, rpt_type_values) < 0)
 
11405
      {
 
11406
        rval = FALSE;
 
11407
      }
 
11408
    }
 
11409
    cpy = MemFree (cpy);
 
11410
  }
 
11411
  else if (GetListNum (val, rpt_type_values) < 0)
 
11412
  {
 
11413
    rval = FALSE;
 
11414
  }
 
11415
  return rval;
 
11416
}
 
11417
 
 
11418
CharPtr direction_values[] = {" ", "LEFT", "RIGHT", "BOTH", NULL};
 
11419
static DialoG DirectionQualDialog (GrouP h, SeqEntryPtr sep, CharPtr name,
 
11420
                                 TaglistCallback tlp_callback,
 
11421
                                 Pointer callback_data)
 
11422
{
 
11423
  return SimpleListQualDialog (h, sep, name, direction_values, tlp_callback, callback_data);
 
11424
}
 
11425
static Boolean ParseDirectionOk (CharPtr val)
 
11426
{
 
11427
  if (GetListNum (val, direction_values) > -1) {
 
11428
    return TRUE;
 
11429
  } else {
 
11430
    return FALSE;
 
11431
  }
 
11432
}
 
11433
 
 
11434
typedef DialoG (*BuildQualEditorDialog) PROTO ((GrouP, SeqEntryPtr, CharPtr, 
 
11435
                                                TaglistCallback, Pointer));
 
11436
typedef void (*CopyTextToEditor) PROTO ((DialoG, CharPtr));
 
11437
 
 
11438
typedef struct gbqualeditlist {
 
11439
  CharPtr               name;
 
11440
  BuildQualEditorDialog build_dlg;
 
11441
  ParseOK               parse_ok;
 
11442
  CopyTextToEditor      copy_txt;
 
11443
} GBQualEditListData, PNTR GBQualEditListPtr;
 
11444
 
 
11445
GBQualEditListData gbqual_edit_list[] = {
 
11446
  {"chloroplast",          TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11447
  {"chromoplast",          TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11448
  {"codon_start",          CodonStartQualDialog,      ParseCodonStartOk,     NULL },
 
11449
  {"collection_date",      CollectionDateDialog,      ParseCollectionDateOk, NULL },
 
11450
  {"cyanelle",             TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11451
  {"direction",            DirectionQualDialog,       ParseDirectionOk,      NULL },
 
11452
  {"germline",             TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11453
  {"kinetoplast",          TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11454
  {"macronuclear",         TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11455
  {"mitochondrion",        TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11456
  {"mobile_element",       CreateMobileElementDialog, ParseMobileElementOk,  CopyTextToMobileElementDialog },
 
11457
  {"mol_type",             MolTypeQualDialog,         ParseMolTypeOk,        NULL },
 
11458
  {"organelle",            OrganelleQualDialog,       ParseOrganelleOk,      NULL },
 
11459
  {"partial",              TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11460
  {"proviral",             TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11461
  {"pseudo",               TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11462
  {"rearranged",           TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11463
  {"rpt_type",             RptTypeQualDialog,         ParseRptTypeOk,        NULL },
 
11464
  {"rpt_unit_range",       CreateRptUnitRangeDialog,  ParseRptUnitRangeOk,   NULL } ,
 
11465
  {"virion",               TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11466
  {"focus",                TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11467
  {"transgenic",           TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11468
  {"environmental_sample", TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11469
  {"ribosomal_slippage",   TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11470
  {"trans_splicing",       TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11471
  {"metagenomic",          TrueFalseDialog,           ParseTrueFalseOk,      NULL },
 
11472
  {NULL, NULL, NULL}};
 
11473
 
 
11474
 
 
11475
typedef struct singlegbqualedit {
 
11476
  DIALOG_MESSAGE_BLOCK
 
11477
  TaglistCallback tlp_callback;
 
11478
  Pointer callback_data;
 
11479
  DialoG editor;
 
11480
  TexT   txt;
 
11481
  GrouP  choice_grp;
 
11482
  ButtoN            use_editor;
 
11483
  ButtoN            use_text;
 
11484
  ButtoN            copy_text;
 
11485
  GBQualEditListPtr edit_list;
 
11486
  CharPtr           name;
 
11487
  Boolean           force_string;
 
11488
} SingleGBQualEditData, PNTR SingleGBQualEditPtr;
 
11489
 
 
11490
static void ChangeSingleQualEdit (GrouP g)
 
11491
{
 
11492
  SingleGBQualEditPtr dlg;
 
11493
 
 
11494
  dlg = (SingleGBQualEditPtr) GetObjectExtra (g);
 
11495
  if (dlg != NULL) {
 
11496
    if (GetValue (dlg->choice_grp) == 1) {
 
11497
      SafeEnable (dlg->editor);
 
11498
      Disable (dlg->txt);
 
11499
    } else {
 
11500
      SetValue (dlg->choice_grp, 2);
 
11501
      SafeDisable (dlg->editor);
 
11502
      Enable (dlg->txt);
 
11503
    }
 
11504
    if (dlg->tlp_callback != NULL) {
 
11505
      (dlg->tlp_callback) (dlg->callback_data);
 
11506
    }
 
11507
  }
 
11508
}
 
11509
 
 
11510
static void StringToSingleGBQualEditDialog (DialoG d, Pointer data)
 
11511
{
 
11512
  SingleGBQualEditPtr dlg;
 
11513
  CharPtr             val;
 
11514
 
 
11515
  dlg = (SingleGBQualEditPtr) GetObjectExtra (d);
 
11516
  if (dlg == NULL) return;
 
11517
 
 
11518
  val = (CharPtr) data;
 
11519
 
 
11520
  if (StringHasNoText (val) || (!dlg->force_string && dlg->edit_list != NULL && (dlg->edit_list->parse_ok(val)))) {
 
11521
    SetTitle (dlg->txt, "");
 
11522
    if (dlg->choice_grp != NULL) {
 
11523
      SetValue (dlg->choice_grp, 1);
 
11524
      Hide (dlg->use_editor);
 
11525
      Hide (dlg->use_text);
 
11526
      Hide (dlg->txt);
 
11527
      Hide (dlg->copy_text);
 
11528
      PointerToDialog (dlg->editor, val);
 
11529
      Enable (dlg->editor);
 
11530
      Disable (dlg->txt);
 
11531
    }
 
11532
  } else {
 
11533
    SetTitle (dlg->txt, val);
 
11534
    if (dlg->choice_grp != NULL) {
 
11535
      SetValue (dlg->choice_grp, 2);
 
11536
      Show (dlg->use_editor);
 
11537
      Show (dlg->use_text);
 
11538
      Show (dlg->txt);
 
11539
      Show (dlg->copy_text);
 
11540
      PointerToDialog (dlg->editor, NULL);
 
11541
      Enable (dlg->txt);
 
11542
      Disable (dlg->editor);
 
11543
    }
 
11544
  }
 
11545
}
 
11546
 
 
11547
static Pointer SingleGBQualEditDialogToString (DialoG d)
 
11548
{
 
11549
  SingleGBQualEditPtr dlg;
 
11550
  CharPtr             val;
 
11551
 
 
11552
  dlg = (SingleGBQualEditPtr) GetObjectExtra (d);
 
11553
  if (dlg == NULL) return NULL;
 
11554
  if (dlg->choice_grp == NULL || GetValue (dlg->choice_grp) == 2) {
 
11555
    val = SaveStringFromText (dlg->txt);
 
11556
  } else {
 
11557
    val = DialogToPointer (dlg->editor);
 
11558
  }
 
11559
  
 
11560
  return val;
 
11561
}
 
11562
 
 
11563
static void GBQualEditDialogMessage (DialoG d, Int2 mssg)
 
11564
 
 
11565
{
 
11566
  SingleGBQualEditPtr dlg;
 
11567
 
 
11568
  dlg = (SingleGBQualEditPtr) GetObjectExtra (d);
 
11569
  if (dlg != NULL) {
 
11570
    if (mssg == VIB_MSG_INIT 
 
11571
        || mssg == VIB_MSG_ENTER) {
 
11572
      if (dlg->choice_grp == NULL || GetValue (dlg->choice_grp) == 2) {
 
11573
        Select (dlg->txt);
 
11574
      } else {
 
11575
        Select (dlg->editor);
 
11576
      }
 
11577
    }
 
11578
  }
 
11579
}
 
11580
 
 
11581
static void GBQualEditDialogCopyText (ButtoN b)
 
11582
{
 
11583
  SingleGBQualEditPtr dlg;
 
11584
  CharPtr             txt;
 
11585
 
 
11586
  dlg = (SingleGBQualEditPtr) GetObjectExtra (b);
 
11587
  if (dlg != NULL && dlg->edit_list != NULL && dlg->edit_list->copy_txt != NULL) {
 
11588
    txt = SaveStringFromText (dlg->txt);
 
11589
    (dlg->edit_list->copy_txt)(dlg->editor, txt);
 
11590
    txt = MemFree (txt);
 
11591
  }
 
11592
}
 
11593
 
 
11594
static DialoG CreateSingleGBQualEditDialog (GrouP h, SeqEntryPtr sep, CharPtr name, 
 
11595
                                            Boolean force_string,
 
11596
                                            TaglistCallback tlp_callback, 
 
11597
                                            Pointer callback_data)
 
11598
{
 
11599
  SingleGBQualEditPtr dlg;
 
11600
  GrouP           p;
 
11601
  Int4            i;
 
11602
 
 
11603
  p = HiddenGroup (h, 2, 0, NULL);
 
11604
  SetGroupSpacing (p, 10, 10);
 
11605
  dlg = (SingleGBQualEditPtr) MemNew (sizeof(SingleGBQualEditData));
 
11606
 
 
11607
  SetObjectExtra (p, dlg, StdCleanupExtraProc);
 
11608
  dlg->dialog = (DialoG) p;
 
11609
  dlg->todialog = StringToSingleGBQualEditDialog;
 
11610
  dlg->fromdialog = SingleGBQualEditDialogToString;
 
11611
  dlg->testdialog = NULL;
 
11612
  dlg->dialogmessage = GBQualEditDialogMessage;
 
11613
  dlg->tlp_callback = tlp_callback;
 
11614
  dlg->callback_data = callback_data;
 
11615
  dlg->force_string = force_string;
 
11616
 
 
11617
  dlg->name = name;
 
11618
  dlg->edit_list = NULL;
 
11619
  for (i = 0; gbqual_edit_list[i].name != NULL && dlg->edit_list == NULL; i++) {
 
11620
    if (StringICmp (gbqual_edit_list[i].name, name) == 0) {
 
11621
      dlg->edit_list = gbqual_edit_list + i;
 
11622
    }
 
11623
  }
 
11624
 
 
11625
  dlg->copy_text = NULL;
 
11626
 
 
11627
  if (dlg->edit_list == NULL || dlg->edit_list->build_dlg == NULL || force_string) {
 
11628
    dlg->txt = DialogText (p, "", 20, ChangeGBQualEditorText);
 
11629
    SetObjectExtra (dlg->txt, dlg, NULL);
 
11630
    dlg->editor = NULL;
 
11631
    dlg->choice_grp = NULL;
 
11632
  } else {
 
11633
    dlg->choice_grp = HiddenGroup (p, 0, 2, ChangeSingleQualEdit);
 
11634
    SetObjectExtra (dlg->choice_grp, dlg, NULL);
 
11635
    dlg->use_editor = RadioButton (dlg->choice_grp, "");
 
11636
    dlg->use_text = RadioButton (dlg->choice_grp, "");
 
11637
    dlg->editor = (dlg->edit_list->build_dlg) (dlg->choice_grp, sep, name, tlp_callback, callback_data);
 
11638
    dlg->txt = DialogText (dlg->choice_grp, "", 20, ChangeGBQualEditorText);
 
11639
    SetObjectExtra (dlg->txt, dlg, NULL);
 
11640
    SetValue (dlg->choice_grp, 1);
 
11641
    if (dlg->edit_list->copy_txt != NULL) {
 
11642
      dlg->copy_text = PushButton (dlg->choice_grp, "Copy Text", GBQualEditDialogCopyText);
 
11643
      SetObjectExtra (dlg->copy_text, dlg, NULL);
 
11644
    }
 
11645
//    AlignObjects (ALIGN_LOWER, (HANDLE) dlg->use_text, (HANDLE) dlg->txt, NULL);
 
11646
    AlignObjects (ALIGN_LOWER, (HANDLE) dlg->txt, (HANDLE) dlg->use_text, NULL);
 
11647
    ChangeSingleQualEdit (dlg->choice_grp);
 
11648
  }
 
11649
 
 
11650
  return (DialoG) p;
 
11651
}
 
11652
 
 
11653
typedef struct newfieldpage {
 
11654
  DIALOG_MESSAGE_BLOCK
 
11655
  Int2               numfields;
 
11656
  DialoG             PNTR editors;
 
11657
 
 
11658
  GBQualPtr          new_gbq;
 
11659
  Uint1              subtype;
 
11660
  Boolean            allowProductGBQual;
 
11661
  Int2               last_viewed;
 
11662
} NewFieldPage, PNTR NewFieldPagePtr;
 
11663
 
 
11664
static void CleanupNewFieldsPage (GraphiC g, VoidPtr data)
 
11665
 
 
11666
{
 
11667
  NewFieldPagePtr  fpf;
 
11668
 
 
11669
  fpf = (NewFieldPagePtr) data;
 
11670
  if (fpf != NULL) {
 
11671
    MemFree (fpf->editors);
 
11672
    fpf->new_gbq = GBQualFree (fpf->new_gbq);
 
11673
  }
 
11674
  MemFree (data);
 
11675
}
 
11676
 
 
11677
static CharPtr GetDisplayQualName (CharPtr qual_name, Boolean is_legal)
 
11678
{
 
11679
  CharPtr display_name;
 
11680
 
 
11681
  if (is_legal) {
 
11682
    display_name = StringSave (qual_name);
 
11683
  } else {
 
11684
    display_name = (CharPtr) MemNew (sizeof (Char) * (StringLen (qual_name) + 2));
 
11685
    sprintf (display_name, "*%s", qual_name);
 
11686
  }
 
11687
  return display_name;
 
11688
}
 
11689
 
 
11690
static Boolean QualNamesMatch (CharPtr qual_name1, CharPtr qual_name2)
 
11691
{
 
11692
  if (StringICmp (qual_name1, qual_name2) == 0) {
 
11693
    return TRUE;
 
11694
  } else if (qual_name1 != NULL 
 
11695
             && *(qual_name1) == '*' 
 
11696
             && StringICmp (qual_name1 + 1, qual_name2) == 0) {
 
11697
    return TRUE;
 
11698
  } else if (qual_name2 != NULL
 
11699
             && *qual_name2 == '*'
 
11700
             && StringICmp (qual_name1, qual_name2 + 1) == 0) {
 
11701
    return TRUE;
 
11702
  } else {
 
11703
    return FALSE;
 
11704
  }
 
11705
}
 
11706
 
 
11707
static Boolean IsCombinableQual (Int2 qual)
 
11708
{
 
11709
  Boolean   combine_qual = FALSE;
 
11710
 
 
11711
  if (qual == GBQUAL_rpt_type 
 
11712
      || qual == GBQUAL_rpt_unit 
 
11713
      || qual == GBQUAL_rpt_unit_range
 
11714
      || qual == GBQUAL_rpt_unit_seq 
 
11715
      || qual == GBQUAL_replace 
 
11716
      || qual == GBQUAL_compare
 
11717
      || qual == GBQUAL_old_locus_tag
 
11718
      || qual == GBQUAL_usedin) {
 
11719
    combine_qual = TRUE;
 
11720
  }
 
11721
  return combine_qual;
 
11722
}
 
11723
 
 
11724
static void AddTemporaryGBQual (GBQualPtr PNTR gbq_list, CharPtr qual_name, GBQualPtr gbq_feat, Boolean is_legal)
 
11725
{
 
11726
  Int2 qual;
 
11727
  GBQualPtr gbq_last = NULL;
 
11728
  GBQualPtr gbq_new = NULL;
 
11729
  Boolean   found = FALSE;
 
11730
  Boolean   combine_qual = FALSE;
 
11731
  CharPtr   blank_val = "\"\"";
 
11732
 
 
11733
  if (gbq_list == NULL) return;
 
11734
 
 
11735
  gbq_last = *gbq_list;
 
11736
  while (gbq_last != NULL && gbq_last->next != NULL) {
 
11737
    if (QualNamesMatch (gbq_last->qual, qual_name)) {
 
11738
      /* already added */
 
11739
      return;
 
11740
    }
 
11741
    gbq_last = gbq_last->next;
 
11742
  }
 
11743
  if (gbq_last != NULL && QualNamesMatch (gbq_last->qual, qual_name)) {
 
11744
    /* already added */
 
11745
    return;
 
11746
  }
 
11747
 
 
11748
  /* add value.  If none in feature, if true/false, add TRUE or FALSE, else use blank. */
 
11749
  qual = GBQualNameValid (qual_name);
 
11750
 
 
11751
  combine_qual = IsCombinableQual (qual);
 
11752
 
 
11753
  while (gbq_feat != NULL) {
 
11754
    if (StringICmp (qual_name, gbq_feat->qual) == 0) {
 
11755
      if (StringHasNoText (gbq_feat->val)) {
 
11756
        if (qual > -1 && ParFlat_GBQual_names [qual].gbclass == Class_none && !found) {
 
11757
          /* if this is a true-false, only add one qualifier */
 
11758
          gbq_new = GBQualNew ();
 
11759
          gbq_new->qual = GetDisplayQualName (qual_name, is_legal);
 
11760
          gbq_new->val = StringSave ("TRUE");
 
11761
          if (gbq_last == NULL) {
 
11762
            *gbq_list = gbq_new;
 
11763
          } else {
 
11764
            gbq_last->next = gbq_new;
 
11765
          }
 
11766
          gbq_last = gbq_new;
 
11767
          found = TRUE;
 
11768
        } else if (qual == GBQUAL_replace) {
 
11769
          /* save blank values */
 
11770
          gbq_new = NULL;
 
11771
          if (found && combine_qual) {
 
11772
            gbq_new = *gbq_list;
 
11773
            while (gbq_new != NULL && !QualNamesMatch (gbq_feat->qual, gbq_new->qual)) {
 
11774
              gbq_new = gbq_new->next;
 
11775
            }
 
11776
          }
 
11777
          if (gbq_new == NULL) {
 
11778
            /* make new qualifier */
 
11779
            gbq_new = GBQualNew ();
 
11780
            gbq_new->qual = GetDisplayQualName (qual_name, is_legal);
 
11781
            gbq_new->val = StringSave (blank_val);
 
11782
            /* add to list */
 
11783
            if (gbq_last == NULL) {
 
11784
              *gbq_list = gbq_new;
 
11785
            } else {
 
11786
              gbq_last->next = gbq_new;
 
11787
            }
 
11788
            gbq_last = gbq_new;
 
11789
          } else {
 
11790
            /* combine with previous value */
 
11791
            gbq_new->val = CombineSplitGBQual (gbq_new->val, blank_val);
 
11792
          }
 
11793
          found = TRUE;
 
11794
        } else {
 
11795
          /* if not true-false or already have true-false, we'll just be adding a blank value later */    
 
11796
          /* so do nothing here */
 
11797
        }
 
11798
      } else {
 
11799
        gbq_new = NULL;
 
11800
        if (found && combine_qual) {
 
11801
          gbq_new = *gbq_list;
 
11802
          while (gbq_new != NULL && !QualNamesMatch (gbq_feat->qual, gbq_new->qual)) {
 
11803
            gbq_new = gbq_new->next;
 
11804
          }
 
11805
        }
 
11806
        if (gbq_new == NULL) {
 
11807
          /* make new qualifier */
 
11808
          gbq_new = GBQualNew ();
 
11809
          gbq_new->qual = GetDisplayQualName (qual_name, is_legal);
 
11810
          gbq_new->val = StringSave (gbq_feat->val);
 
11811
          /* add to list */
 
11812
          if (gbq_last == NULL) {
 
11813
            *gbq_list = gbq_new;
 
11814
          } else {
 
11815
            gbq_last->next = gbq_new;
 
11816
          }
 
11817
          gbq_last = gbq_new;
 
11818
        } else {
 
11819
          /* combine with previous value */
 
11820
          gbq_new->val = CombineSplitGBQual (gbq_new->val, gbq_feat->val);
 
11821
        }
 
11822
        found = TRUE;
 
11823
      }
 
11824
    }
 
11825
    gbq_feat = gbq_feat->next;
 
11826
  }
 
11827
   
 
11828
  if (!found) {
 
11829
    gbq_new = GBQualNew ();
 
11830
    gbq_new->qual = GetDisplayQualName (qual_name, is_legal);
 
11831
    if (qual > -1 && ParFlat_GBQual_names [qual].gbclass == Class_none) {
 
11832
      gbq_new->val = StringSave ("FALSE");
 
11833
    } else {
 
11834
      gbq_new->val = StringSave ("");
 
11835
    }
 
11836
    if (gbq_last == NULL) {
 
11837
      *gbq_list = gbq_new;
 
11838
    } else {
 
11839
      gbq_last->next = gbq_new;
 
11840
    }
 
11841
  }
 
11842
}
 
11843
 
 
11844
static Boolean IsRarelyUsed (Int2 qual)
 
11845
{
 
11846
  if (qual == GBQUAL_allele
 
11847
      || qual == GBQUAL_function
 
11848
      || qual == GBQUAL_map
 
11849
      || qual == GBQUAL_standard_name
 
11850
      || qual == GBQUAL_old_locus_tag) {
 
11851
    return TRUE;
 
11852
  } else {
 
11853
    return FALSE;
 
11854
  }
 
11855
}
 
11856
 
 
11857
static Pointer NewDialogToImportFields (DialoG d)
 
11858
{
 
11859
  NewFieldPagePtr fpf;
 
11860
  GBQualPtr       gbq_list = NULL, gbq_last = NULL, gbq_new, gbq_it;
 
11861
  Int2            qual, i;
 
11862
  CharPtr         val, qual_name;
 
11863
 
 
11864
  fpf = (NewFieldPagePtr) GetObjectExtra (d);
 
11865
  if (fpf == NULL) return NULL;
 
11866
 
 
11867
  for (gbq_it = fpf->new_gbq, i = 0; gbq_it != NULL; gbq_it = gbq_it->next, i++) {
 
11868
    gbq_it->val = MemFree (gbq_it->val);
 
11869
    gbq_it->val = DialogToPointer (fpf->editors[i]);
 
11870
  }
 
11871
 
 
11872
  for (gbq_it = fpf->new_gbq; gbq_it != NULL; gbq_it = gbq_it->next) {
 
11873
    if (StringHasNoText (gbq_it->val)) {
 
11874
      continue;
 
11875
    }
 
11876
    qual_name = gbq_it->qual;
 
11877
    if (qual_name != NULL && *qual_name == '*') {
 
11878
      qual_name++;
 
11879
    }
 
11880
    qual = GBQualNameValid (qual_name);
 
11881
 
 
11882
    val = gbq_it->val;
 
11883
    if (qual > -1 && ParFlat_GBQual_names [qual].gbclass == Class_none) {
 
11884
      if (StringICmp (val, "TRUE") == 0) {
 
11885
        /* don't put "true" in qual, just use empty string */
 
11886
        val = "";
 
11887
      } else if (StringICmp (val, "FALSE") == 0) {
 
11888
        /* don't add FALSE qual */
 
11889
        continue;
 
11890
      }
 
11891
      /* any other values, add as they are */
 
11892
    } 
 
11893
 
 
11894
    gbq_new = GBQualNew();
 
11895
    gbq_new->qual = StringSave (qual_name);
 
11896
    gbq_new->val = StringSave (val);
 
11897
    if (gbq_last == NULL) {
 
11898
      gbq_list = gbq_new;
 
11899
    } else {
 
11900
      gbq_last->next = gbq_new;
 
11901
    }
 
11902
    gbq_last = gbq_new;
 
11903
  }
 
11904
  return (Pointer) gbq_list;
 
11905
}
 
11906
 
 
11907
static void 
 
11908
AddMandatoryAndOptionalQuals 
 
11909
(CharPtr         name,
 
11910
 NewFieldPagePtr fpf,
 
11911
 GBQualPtr       gbq, 
 
11912
 Boolean         use_rarely_used)
 
11913
{
 
11914
  Int2 index, i, qual;
 
11915
  SematicFeatPtr  sefp;
 
11916
 
 
11917
  if (name == NULL) return;
 
11918
 
 
11919
  index = GBFeatKeyNameValid (&name, FALSE);
 
11920
  if (index < 0) return;
 
11921
 
 
11922
  sefp = &(ParFlat_GBFeat [index]);
 
11923
  /* add mandatory quals first */
 
11924
  for (i = 0; i < sefp->mand_num; i++) {
 
11925
    qual = sefp->mand_qual [i];
 
11926
    if (qual > -1 
 
11927
        && ShouldBeAGBQual (fpf->subtype, qual, fpf->allowProductGBQual)
 
11928
        && ((use_rarely_used && IsRarelyUsed (qual))
 
11929
            || (!use_rarely_used && ! IsRarelyUsed (qual)))) {
 
11930
      AddTemporaryGBQual (&(fpf->new_gbq), ParFlat_GBQual_names [qual].name, gbq, TRUE);
 
11931
    }
 
11932
  }
 
11933
  /* add optional quals next */
 
11934
  for (i = 0; i < sefp->opt_num; i++) {
 
11935
    qual = sefp->opt_qual [i];
 
11936
    if (qual > -1 
 
11937
        && ShouldBeAGBQual (fpf->subtype, qual, fpf->allowProductGBQual)
 
11938
        && ((use_rarely_used && IsRarelyUsed (qual))
 
11939
            || (!use_rarely_used && ! IsRarelyUsed (qual)))) {
 
11940
      AddTemporaryGBQual (&(fpf->new_gbq), ParFlat_GBQual_names [qual].name, gbq, TRUE);
 
11941
    }
 
11942
  }
 
11943
}
 
11944
 
 
11945
 
 
11946
extern DialoG NewCreateImportFields (GrouP h, CharPtr name, SeqFeatPtr sfp, Boolean allowProductGBQual)
 
11947
{
 
11948
  NewFieldPagePtr fpf;
 
11949
  GrouP           g, g1, g2 = NULL;
 
11950
  GBQualPtr       gbq = NULL, gbq_it;
 
11951
  Int2            j;
 
11952
  Int2            max;
 
11953
  Int2            num = 0, num_legal = 0;
 
11954
  GrouP           p;
 
11955
  Int2            qual;
 
11956
  Int2            wid;
 
11957
  PrompT          ill_q = NULL;
 
11958
 
 
11959
  p = HiddenGroup (h, -1, 0, NULL);
 
11960
  fpf = (NewFieldPagePtr) MemNew (sizeof (NewFieldPage));
 
11961
  if (fpf != NULL) {
 
11962
 
 
11963
    SetObjectExtra (p, fpf, CleanupNewFieldsPage);
 
11964
    fpf->dialog = (DialoG) p;
 
11965
    fpf->todialog = NULL;
 
11966
    fpf->fromdialog = NewDialogToImportFields;
 
11967
    fpf->testdialog = NULL;
 
11968
 
 
11969
    fpf->allowProductGBQual = allowProductGBQual;
 
11970
    if (sfp == NULL) {
 
11971
      fpf->subtype = FEATDEF_ANY;
 
11972
    } else {
 
11973
      fpf->subtype = sfp->idx.subtype;
 
11974
      gbq = sfp->qual;
 
11975
    }
 
11976
 
 
11977
    fpf->last_viewed = -1;
 
11978
 
 
11979
    /* create list of temporary GBQuals */
 
11980
    /* list mandatory/optional quals that are not rarely used first */
 
11981
    AddMandatoryAndOptionalQuals (name, fpf, gbq, FALSE);
 
11982
 
 
11983
    /* add rarely used quals here */
 
11984
    AddMandatoryAndOptionalQuals (name, fpf, gbq, TRUE);
 
11985
 
 
11986
    /* count legal values - all others to be listed as simple strings */
 
11987
    for (gbq_it = fpf->new_gbq; gbq_it != NULL; gbq_it = gbq_it->next) {
 
11988
      num_legal++;
 
11989
    }
 
11990
 
 
11991
    /* add legal added qualifiers next */
 
11992
    gbq_it = gbq;
 
11993
    while (gbq_it != NULL) {
 
11994
      qual = GBQualNameValid (gbq_it->qual);
 
11995
      if (qual > -1 && ShouldBeAGBQual (fpf->subtype, qual, fpf->allowProductGBQual)) {
 
11996
        AddTemporaryGBQual (&(fpf->new_gbq), ParFlat_GBQual_names [qual].name, gbq, FALSE);
 
11997
      } 
 
11998
      gbq_it = gbq_it->next;
 
11999
    }
 
12000
 
 
12001
    /* add remaining qualifiers last */
 
12002
    gbq_it = gbq;
 
12003
    while (gbq_it != NULL) {  
 
12004
      if (!ShouldSuppressGBQual(fpf->subtype, gbq_it->qual)) {
 
12005
        AddTemporaryGBQual (&(fpf->new_gbq), gbq_it->qual, gbq, FALSE);
 
12006
      }
 
12007
      gbq_it = gbq_it->next;
 
12008
    }
 
12009
 
 
12010
    /* calculate maximum name width */
 
12011
    SelectFont (systemFont);
 
12012
    max = 0;
 
12013
    for (gbq_it = fpf->new_gbq; gbq_it != NULL; gbq_it = gbq_it->next) {
 
12014
      num++;
 
12015
      wid = StringWidth (gbq_it->qual) + 2;
 
12016
      if (wid > max) {
 
12017
        max = wid;
 
12018
      }
 
12019
    }
 
12020
    SelectFont (systemFont);
 
12021
 
 
12022
    fpf->numfields = num;
 
12023
 
 
12024
    if (num > 0) {
 
12025
      g1 = HiddenGroup (p, 2, 0, NULL);     
 
12026
      g = g1;
 
12027
      fpf->editors = MemNew (sizeof (DialoG) * (num + 1));
 
12028
      for (gbq_it = fpf->new_gbq, j = 0; gbq_it != NULL; gbq_it = gbq_it->next) {
 
12029
        if (j == num_legal) {
 
12030
          ill_q = StaticPrompt (p, "*** Illegal Qualifiers ***", 0, dialogTextHeight, programFont, 'l');
 
12031
          g2 = HiddenGroup (p, 2, 0, NULL);
 
12032
          g = g2;
 
12033
        }
 
12034
        StaticPrompt (g, gbq_it->qual, 0, dialogTextHeight, programFont, 'l');
 
12035
        fpf->editors[j] = CreateSingleGBQualEditDialog (g, NULL, gbq_it->qual,
 
12036
                                                        j < num_legal ? FALSE : TRUE,
 
12037
                                                        NULL, NULL);
 
12038
        PointerToDialog (fpf->editors[j], gbq_it->val);
 
12039
        j++;
 
12040
      }   
 
12041
      AlignObjects (ALIGN_CENTER, (HANDLE) g1, (HANDLE) ill_q, (HANDLE) g2, NULL);  
 
12042
    } else {
 
12043
      fpf->editors = NULL;
 
12044
      StaticPrompt (p, "See Attributes page to set legal qualifiers for this feature.",
 
12045
                    0, 0, programFont, 'c');
 
12046
    }
 
12047
  }
 
12048
  return (DialoG) p;
 
12049
}
 
12050
 
 
12051
 
 
12052
typedef struct specialcharacterdialog 
 
12053
{
 
12054
  TexT PNTR       text_list;
 
12055
  ButtoN          accept_btn;
 
12056
  Int4            num_chars;
 
12057
  ValNodePtr      find_list;
 
12058
} SpecialCharacterDialogData, PNTR SpecialCharacterDialogPtr;  
 
12059
 
 
12060
 
 
12061
static void EnableSpecialCharacterAccept (TexT t)
 
12062
{
 
12063
  SpecialCharacterDialogPtr sd;
 
12064
  Int4                      pos;
 
12065
  CharPtr                   str;
 
12066
  Boolean                   has_bad = FALSE;
 
12067
 
 
12068
  sd = (SpecialCharacterDialogPtr) GetObjectExtra (t);
 
12069
  if (sd == NULL) return;
 
12070
 
 
12071
  for (pos = 0; pos < sd->num_chars && !has_bad; pos++)
 
12072
  {
 
12073
    str = SaveStringFromText (sd->text_list[pos]);
 
12074
    SpecialCharFind (&str, NULL, &has_bad, NULL);
 
12075
    str = MemFree (str);
 
12076
  }
 
12077
  if (has_bad) 
 
12078
  {
 
12079
    Disable (sd->accept_btn);
 
12080
  }
 
12081
  else
 
12082
  {
 
12083
    Enable (sd->accept_btn);
 
12084
  }
 
12085
}
 
12086
 
 
12087
 
 
12088
static void SetWindowsSpecialCharacterDefaults (ButtoN b)
 
12089
{
 
12090
  SpecialCharacterDialogPtr sd;
 
12091
  Int4                      pos;
 
12092
  CharPtr                   str;
 
12093
  ValNodePtr                vnp;
 
12094
 
 
12095
  sd = (SpecialCharacterDialogPtr) GetObjectExtra (b);
 
12096
  if (sd == NULL) return;
 
12097
 
 
12098
  for (vnp = sd->find_list, pos = 0; vnp != NULL; vnp = vnp->next, pos++)
 
12099
  {
 
12100
    str = GetSpecialWinCharacterReplacement ((unsigned char) vnp->choice);
 
12101
    SetTitle (sd->text_list[pos], str);
 
12102
  }
 
12103
}
 
12104
 
 
12105
 
 
12106
static void SetMacSpecialCharacterDefaults (ButtoN b)
 
12107
{
 
12108
  SpecialCharacterDialogPtr sd;
 
12109
  Int4                      pos;
 
12110
  CharPtr                   str;
 
12111
  ValNodePtr                vnp;
 
12112
 
 
12113
  sd = (SpecialCharacterDialogPtr) GetObjectExtra (b);
 
12114
  if (sd == NULL) return;
 
12115
 
 
12116
  for (vnp = sd->find_list, pos = 0; vnp != NULL; vnp = vnp->next, pos++)
 
12117
  {
 
12118
    str = GetSpecialMacCharacterReplacement ((unsigned char) vnp->choice);
 
12119
    SetTitle (sd->text_list[pos], str);
 
12120
  }
 
12121
 
 
12122
}
 
12123
 
 
12124
 
 
12125
extern Boolean FixSpecialCharactersForStringsInList (ValNodePtr find_list, CharPtr exp_text, Boolean force_fix)
 
12126
{
 
12127
  ValNodePtr      vnp, context_list, vnp_c;
 
12128
  Int4            pos;
 
12129
  CharPtr         repl;
 
12130
  WindoW          w;
 
12131
  GrouP           h, c, g, p1, g2;
 
12132
  PrompT          p2;
 
12133
  LisT            contexts;
 
12134
  ButtoN          b;
 
12135
  SpecialCharacterDialogData sd;
 
12136
  ModalAcceptCancelData      acd;
 
12137
  Char                  label[2];
 
12138
  Int4                  num_contexts;
 
12139
  Boolean               rval = FALSE;
 
12140
 
 
12141
  if (find_list == NULL) {
 
12142
    return TRUE;
 
12143
  } 
 
12144
 
 
12145
  ArrowCursor();
 
12146
  Update();
 
12147
 
 
12148
  sd.find_list = find_list;
 
12149
  sd.num_chars = ValNodeLen (find_list);
 
12150
  
 
12151
  acd.accepted = FALSE;
 
12152
  acd.cancelled = FALSE;
 
12153
  
 
12154
  w = ModalWindow(-20, -13, -10, -10, NULL);
 
12155
  h = HiddenGroup (w, -1, 0, NULL);
 
12156
  SetGroupSpacing (h, 10, 10);
 
12157
  
 
12158
  p1 = MultiLinePrompt (h, exp_text, 27 * stdCharWidth, programFont);
 
12159
  p2 = StaticPrompt (h, "Choose replacement characters.", 0, 0, programFont, 'l');
 
12160
 
 
12161
  g = HiddenGroup (h, 3, 0, NULL);
 
12162
  StaticPrompt (g, "Character", 0, 0, programFont, 'l');
 
12163
  StaticPrompt (g, "Replacement", 0, 0, programFont, 'l');
 
12164
  StaticPrompt (g, "Contexts", 0, 0, programFont, 'l');
 
12165
 
 
12166
  sd.text_list = MemNew (sizeof (TexT) * sd.num_chars);
 
12167
  label[1] = 0;
 
12168
  for (vnp = find_list, pos = 0; vnp != NULL; vnp = vnp->next, pos++)
 
12169
  {
 
12170
    label[0] = vnp->choice;
 
12171
    StaticPrompt (g, label, 0, 0, programFont, 'l');
 
12172
    repl = GetSpecialCharacterReplacement (vnp->choice);
 
12173
    sd.text_list[pos] = DialogText (g, repl, 5, EnableSpecialCharacterAccept);
 
12174
    SetObjectExtra (sd.text_list[pos], &sd, NULL);
 
12175
    context_list = vnp->data.ptrvalue;
 
12176
    num_contexts = ValNodeLen (context_list);
 
12177
    if (num_contexts == 0)
 
12178
    {
 
12179
      StaticPrompt (g, "", 0, 0, programFont, 'l');
 
12180
    }
 
12181
    else if (num_contexts == 1)
 
12182
    {
 
12183
      StaticPrompt (g, *((CharPtr PNTR)context_list->data.ptrvalue), 0, 0, programFont, 'l');
 
12184
    }
 
12185
    else
 
12186
    {
 
12187
      contexts = SingleList (g, 16, MIN (num_contexts, 5), NULL);
 
12188
      for (vnp_c = context_list; vnp_c != NULL; vnp_c = vnp_c->next)
 
12189
      {
 
12190
        ListItem (contexts, *((CharPtr PNTR)vnp_c->data.ptrvalue));
 
12191
      }
 
12192
      SetValue (contexts, 1);
 
12193
    }
 
12194
  }
 
12195
 
 
12196
  g2 = HiddenGroup (h, 2, 0, NULL);
 
12197
  SetGroupSpacing (g2, 10, 10);
 
12198
  b = PushButton (g2, "Suggest Windows Replacements", SetWindowsSpecialCharacterDefaults);
 
12199
  SetObjectExtra (b, &sd, NULL);
 
12200
  b = PushButton (g2, "Suggest Mac Replacements", SetMacSpecialCharacterDefaults);
 
12201
  SetObjectExtra (b, &sd, NULL);
 
12202
 
 
12203
  c = HiddenGroup (h, 3, 0, NULL);
 
12204
  SetGroupSpacing (c, 10, 10);
 
12205
  sd.accept_btn = PushButton (c, "Replace Characters", ModalAcceptButton);
 
12206
  SetObjectExtra (sd.accept_btn, &acd, NULL);
 
12207
  b = PushButton (c, "Cancel", ModalCancelButton);
 
12208
  SetObjectExtra (b, &acd, NULL);
 
12209
  AlignObjects (ALIGN_CENTER, (HANDLE) p1, (HANDLE) p2, (HANDLE) g, (HANDLE) g2, (HANDLE) c, NULL);
 
12210
  
 
12211
  Show(w); 
 
12212
  Select (w);
 
12213
  while (!acd.accepted && ! acd.cancelled)
 
12214
  {
 
12215
    ProcessExternalEvent ();
 
12216
    Update ();
 
12217
  }
 
12218
  ProcessAnEvent ();
 
12219
  if (acd.accepted)
 
12220
  {
 
12221
    for (vnp = find_list, pos = 0; vnp != NULL; vnp = vnp->next, pos++)
 
12222
    {
 
12223
      repl = JustSaveStringFromText (sd.text_list[pos]);
 
12224
      label[0] = vnp->choice;
 
12225
      for (vnp_c = vnp->data.ptrvalue; vnp_c != NULL; vnp_c = vnp_c->next)
 
12226
      {
 
12227
        FindReplaceString (vnp_c->data.ptrvalue, label, repl, TRUE, FALSE);
 
12228
      }
 
12229
      repl = MemFree (repl);
 
12230
    }
 
12231
 
 
12232
    rval = TRUE;
 
12233
  }
 
12234
  else if (force_fix)
 
12235
  {
 
12236
    for (vnp = find_list; vnp != NULL; vnp = vnp->next)
 
12237
    {
 
12238
      label[0] = vnp->choice;
 
12239
      for (vnp_c = vnp->data.ptrvalue; vnp_c != NULL; vnp_c = vnp_c->next)
 
12240
      {
 
12241
        FindReplaceString (vnp_c->data.ptrvalue, label, "#", TRUE, FALSE);
 
12242
      }
 
12243
    }
 
12244
    rval = TRUE;
 
12245
  }
 
12246
 
 
12247
  Remove (w);
 
12248
  return rval;
 
12249
 
 
12250
}
 
12251
 
 
12252
 
 
12253
NLM_EXTERN Boolean FixSpecialCharacters (Uint2 entityID)
 
12254
{
 
12255
  ValNodePtr      find_list = NULL;
 
12256
  Boolean         rval;
 
12257
 
 
12258
  StringActionInEntity (entityID, FALSE, UPDATE_NEVER, NULL, NULL, NULL, TRUE,
 
12259
                        SpecialCharFindWithContext, NULL, &find_list);
 
12260
 
 
12261
  rval = FixSpecialCharactersForStringsInList (find_list,
 
12262
              "The ASN.1 contains special characters.\nIf you save it without stripping them,\nyou will be unable to load the file in Sequin.",
 
12263
              FALSE);
 
12264
 
 
12265
  find_list = FreeContextList (find_list);
 
12266
  if (rval) 
 
12267
  {
 
12268
    ObjMgrSetDirtyFlag (entityID, TRUE);
 
12269
    ObjMgrSendMsg (OM_MSG_UPDATE, entityID, 0, 0);
 
12270
  }
 
12271
  return rval;
 
12272
}
 
12273
 
 
12274
 
 
12275
NLM_EXTERN Boolean FixSpecialCharactersForObject (Uint2 datatype, Pointer objdata, CharPtr msg, Boolean force_fix, BoolPtr changed)
 
12276
{
 
12277
  ValNodePtr      find_list = NULL;
 
12278
  Boolean         rval;
 
12279
 
 
12280
  StringActionForObject (datatype, objdata, 0, FALSE, UPDATE_NEVER,
 
12281
                        SpecialCharFindWithContext, NULL, &find_list);
 
12282
 
 
12283
  rval = FixSpecialCharactersForStringsInList (find_list,
 
12284
              msg == NULL ?
 
12285
                     "The ASN.1 contains special characters.\nIf you save it without stripping them,\nyou will be unable to load the file in Sequin."
 
12286
                     : msg,
 
12287
              force_fix);
 
12288
 
 
12289
  if (changed != NULL)
 
12290
  {
 
12291
    if (find_list == NULL)
 
12292
    {
 
12293
      *changed = FALSE;
 
12294
    }
 
12295
    else
 
12296
    {
 
12297
      *changed = rval;
 
12298
    }
 
12299
  } 
 
12300
 
 
12301
  find_list = FreeContextList (find_list);
 
12302
  return rval;
 
12303
}
 
12304
 
 
12305
 
 
12306