|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/desktop/e2trmlst.c |
source navigation diff markup identifier search freetext search file search |
1 /* e2trmlst.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: e2trmlst.c
27 *
28 * Author: Jonathan Kans, Greg Schuler, Jonathan Epstein, Tim Ford
29 *
30 * Version Creation Date: 10/30/01
31 *
32 * $Revision: 6.44 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 *
39 * ==========================================================================
40 */
41
42 #include <vibrant.h>
43 #include <document.h>
44 #include <asn.h>
45 #include <ent2api.h>
46 #include <urlquery.h>
47 #include <dlogutil.h>
48 #include <medview.h>
49 #include <bspview.h>
50 #include <accutils.h>
51
52 #include <entrez2.h>
53
54 /*-------------------*/
55 /* Defined constants */
56 /*-------------------*/
57
58 #define MAX_TAXONOMY_TREE_DEPTH 1024
59 #define TL_TERM_DELIMITER ':'
60 #define E2_STR_BUFF_SIZE 256
61 #define E2_EXPLODE FALSE
62 #define E2_DO_NOT_EXPLODE TRUE
63 #define E2_TRANSLATE FALSE
64 #define E2_DO_NOT_TRANSLATE TRUE
65 #define E2_TERM_COL 1
66 #define E2_COUNT_COL 2
67 #define E2_LIST_MODIFIED TRUE
68 #define E2_LIST_NOT_MODIFIED FALSE
69
70 #define MAX_MODES 11
71
72 #define STATE_OFF 0
73 #define STATE_ON 1
74
75 #define E2_RANGE_FROM 1
76 #define E2_RANGE_TO 2
77
78 #define GROUP_NONE 0
79 #define GROUP_SINGLE 1
80 #define GROUP_FIRST 2
81 #define GROUP_MIDDLE 3
82 #define GROUP_LAST 4
83
84 #define TERMLIST_OPERATOR 2
85 #define TERMLIST_TERM 3
86
87 #define ADV_QUERY_INVALID_STATE 0
88 #define ADV_QUERY_EVALUATE_STATE 1
89 #define ADV_QUERY_RETRIEVE_STATE 2
90
91 #define AVAIL_WINDOW_ROWS 7
92 #define ADV_TEXT_MAX_LENGTH 8192
93 #define ADV_TEXT_WIDTH 20
94 #define ADV_TEXT_HEIGHT 7
95
96 #define LEXCHAR_LPAREN 1
97 #define LEXCHAR_RPAREN 2
98 #define LEXCHAR_LBRACKET 3
99 #define LEXCHAR_RBRACKET 4
100 #define LEXCHAR_QUOTE 5
101 #define LEXCHAR_AND 6
102 #define LEXCHAR_OR 7
103 #define LEXCHAR_NOT 8
104 #define LEXCHAR_COMMA 9
105 #define LEXCHAR_ATSIGN 10
106 #define LEXCHAR_BACKSLASH 11
107 #define LEXCHAR_WHITESPACE 12
108 #define LEXCHAR_SEMICOLON 13
109 #define LEXCHAR_COLON 14
110 #define LEXCHAR_EOL 15
111 #define LEXCHAR_NULL 16
112 #define LEXCHAR_OTHER 17
113
114 #define LEXSTATE_IDLE 0
115 #define LEXSTATE_BACKSLASHED 1
116 #define LEXSTATE_INQUOTE 2
117 #define LEXSTATE_INQUOTE_AFTERBSLASH 3
118 #define LEXSTATE_INSTRING 4
119 #define LEXSTATE_ERROR 5
120
121 #define LEXTOK_LPAREN 1
122 #define LEXTOK_RPAREN 2
123 #define LEXTOK_LBRACKET 3
124 #define LEXTOK_RBRACKET 4
125 #define LEXTOK_AND 5
126 #define LEXTOK_OR 6
127 #define LEXTOK_NOT 7
128 #define LEXTOK_COMMA 8
129 #define LEXTOK_ATSIGN 9
130 #define LEXTOK_STRING 10
131 #define LEXTOK_RANGE 11
132
133 #define ERR_CD_LEX 17
134
135 /*------------------------------*/
136 /* Defines for enumerated lists */
137 /*------------------------------*/
138
139 typedef enum {
140 SELECTION_MODE = 1,
141 AUTOMATIC_MODE,
142 WILD_CARD_MODE,
143 MESH_TREE_MODE,
144 TAXONOMY_MODE,
145 RANGE_MODE,
146 LOOKUP_ACCN_MODE,
147 VIEW_ACCN_MODE,
148 LOOKUP_UID_MODE,
149 VIEW_UID_MODE,
150 TRANSLATE_MODE
151 } ModeChoice;
152
153 static ENUM_ALIST(mult_alist)
154 {"Multiple", AUTOMATIC_MODE},
155 {"Selection", SELECTION_MODE},
156 {"Wild Card", WILD_CARD_MODE},
157 END_ENUM_ALIST
158
159 static ENUM_ALIST(auto_alist)
160 {"Automatic", TRANSLATE_MODE},
161 {"Multiple", AUTOMATIC_MODE},
162 {"Selection", SELECTION_MODE},
163 {"Wild Card", WILD_CARD_MODE},
164 END_ENUM_ALIST
165
166 static ENUM_ALIST(accn_alist)
167 {"Lookup", LOOKUP_ACCN_MODE},
168 {"Range", RANGE_MODE},
169 {"Selection", SELECTION_MODE},
170 {"Wild Card", WILD_CARD_MODE},
171 {"View", VIEW_ACCN_MODE},
172 END_ENUM_ALIST
173
174 static ENUM_ALIST(mesh_alist)
175 {"MeSH Tree", MESH_TREE_MODE},
176 {"Selection", SELECTION_MODE},
177 {"Wild Card", WILD_CARD_MODE},
178 END_ENUM_ALIST
179
180 static ENUM_ALIST(tax_alist)
181 {"Selection", SELECTION_MODE},
182 {"Taxonomy", TAXONOMY_MODE},
183 {"Wild Card", WILD_CARD_MODE},
184 END_ENUM_ALIST
185
186 static ENUM_ALIST(default_alist)
187 {"Range", RANGE_MODE},
188 {"Selection", SELECTION_MODE},
189 {"Wild Card", WILD_CARD_MODE},
190 END_ENUM_ALIST
191
192 static ENUM_ALIST(range_alist)
193 {"Range", RANGE_MODE},
194 {"Selection", SELECTION_MODE},
195 END_ENUM_ALIST
196
197 static ENUM_ALIST(trunc_alist)
198 {"Selection", SELECTION_MODE},
199 {"Wild Card", WILD_CARD_MODE},
200 END_ENUM_ALIST
201
202 static ENUM_ALIST(uid_alist)
203 {"Lookup", LOOKUP_UID_MODE},
204 {"View", VIEW_UID_MODE},
205 END_ENUM_ALIST
206
207 static EnumFieldAssocPtr mode_alists [] = {
208 mult_alist,
209 auto_alist,
210 accn_alist,
211 mesh_alist,
212 tax_alist,
213 default_alist,
214 range_alist,
215 trunc_alist,
216 uid_alist,
217 NULL
218 };
219
220 typedef enum {
221 POPUP_MULT = 0,
222 POPUP_AUTO,
223 POPUP_ACCN,
224 POPUP_MESH,
225 POPUP_TAX,
226 POPUP_DEFAULT,
227 POPUP_RANGE,
228 POPUP_TRUNC,
229 POPUP_UID
230 } ModeIndex;
231
232 /*-----------------------*/
233 /* Structure definitions */
234 /*-----------------------*/
235
236 typedef struct trmstatedata {
237 CharPtr term;
238 CharPtr field;
239 Int4 count;
240 Int2 db;
241 Int2 fld;
242 Int2 group;
243 Int2 above;
244 Int2 below;
245 Int2 state;
246 Int4Ptr uids;
247 CharPtr key;
248 struct trmstatedata PNTR prev;
249 struct trmstatedata PNTR next;
250 } StateData, PNTR StateDataPtr;
251
252 typedef struct {
253 FORM_MESSAGE_BLOCK
254 E2RetrieveDocsProc retrieveDocsProc;
255 E2RetrieveUidProc retrieveUidProc;
256 GrouP stdQueryGroup;
257 GrouP advQueryGroup;
258 ButtoN advEvaluateButton;
259 ButtoN advRetrieveButton;
260 Int2 advQueryState;
261 ButtoN advResetButton;
262 TexT advQueryText;
263 Int2 advQueryLexPos;
264 CharPtr advQueryLexStr;
265 Int2 advQueryLexState;
266 ValNodePtr advQueryNextToken;
267 ValNode advQueryNextRealNode;
268 Boolean advQueryNewGroup;
269 PopuP PNTR fieldsPopup;
270 PopuP modesPopup [MAX_MODES];
271 GrouP termGroup;
272 GrouP rangeGroup;
273 IteM advancedQueryItem;
274 IteM explodeItem;
275 ModeChoice currMode;
276 Int2 currField;
277 Int2 currDb;
278 DoC availDoc;
279 Int2 availItem;
280 Int2 availRow;
281 Int2 availClickItem;
282 Int2 availClickRow;
283 Int4 availNumTerms;
284 Int4 availPageSize;
285 Int2 availNumPages;
286 Int2 availCurrentPage;
287 Boolean textChanged;
288 Int2 okayToAccept;
289 TexT termText;
290 TexT fromText;
291 TexT toText;
292 Boolean isValidFrom;
293 Boolean isValidTo;
294 Boolean isFromTextChanged;
295 Boolean isToTextChanged;
296 Int2 currRangeField;
297 ButtoN acceptButton;
298 PopuP taxLineagePopup;
299 ValNodePtr taxStrings;
300 PopuP databasePopup;
301 ButtoN retrieveButton;
302 ButtoN resetButton;
303 Boolean wasDoubleClick;
304 DoC chosenDoc;
305 Int2 chosenItem;
306 Int2 chosenClickItem;
307 Int2 chosenClickRow;
308 Int2 chosenClickCol;
309 Boolean chosenInAboveBox;
310 Boolean chosenInBelowBox;
311 Int2 chosenNumLines;
312 RecT trackRect;
313 PoinT trackPt;
314 StateDataPtr termList;
315 } FormInfo, PNTR FormInfoPtr;
316
317 /*----------------------------*/
318 /* File-wide static variables */
319 /*----------------------------*/
320
321 static ChoicE s_showASNItem;
322 static Entrez2InfoPtr s_masterE2ip = NULL;
323
324 static ParData availParFmt = { FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 };
325 static ColData availColFmt [] = {
326 {0, 5, 70, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* term */
327 {0, 5, 10, 0, NULL, 'r', FALSE, TRUE, FALSE, FALSE, FALSE}, /* count */
328 {0, 5, 10, 0, NULL, 'r', FALSE, FALSE, FALSE, FALSE, TRUE} /* leaf */
329 };
330
331 static ParData chosenParFmt = { FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 };
332 static ColData chosenColFmt [] = {
333 {0, 23, 70, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* term */
334 {0, 5, 10, 0, NULL, 'l', FALSE, FALSE, FALSE, FALSE, FALSE}, /* field */
335 {0, 5, 10, 0, NULL, 'r', FALSE, TRUE, FALSE, FALSE, TRUE} /* count */
336 };
337
338 /*---------------------*/
339 /* Function prototpyes */
340 /*---------------------*/
341
342 static Boolean RemoveTermFromList (
343 FormInfoPtr pFormInfo,
344 StateDataPtr sdp,
345 Boolean goingDown,
346 Boolean lastDraggedDown
347 );
348 static Boolean Query_TranslateAndAddBoolTerm (
349 ForM f,
350 Int2 currDb,
351 Int2 currFld,
352 CharPtr strs,
353 Int2 state,
354 Int4 num
355 );
356
357 static Boolean LoadAvailList (FormInfoPtr pFormInfo, CharPtr str);
358
359 /*==================================================================*/
360 /* */
361 /* ShowASN () - Returns the current setting of the s_showASN */
362 /* static variable. */
363 /* */
364 /*==================================================================*/
365
366 NLM_EXTERN Boolean ShowASN (void)
367
368 {
369 Int2 val;
370
371 /*
372 return GetStatus (s_showASNItem);
373 */
374 val = GetValue (s_showASNItem);
375 if (val >= 11) return TRUE;
376 if (val < 2) return FALSE;
377 SetValue (s_showASNItem, val - 1);
378 if (val < 2) return FALSE;
379 return TRUE;
380 }
381
382 static void LogOrLaunch (CharPtr path, CharPtr title)
383
384 {
385 Char buf [257];
386 size_t ct;
387 FILE *ifp;
388 FILE *ofp;
389 Int2 val;
390
391 val = GetValue (s_showASNItem);
392 if (val == 12) {
393 ifp = FileOpen (path, "r");
394 ofp = FileOpen ("entrez2.log", "a");
395 if (ifp != NULL && ofp != NULL) {
396 while ((ct = FileRead (buf, 1, sizeof (buf) - 1, ifp)) > 0) {
397 FileWrite (buf, 1, ct, ofp);
398 }
399 fprintf (ofp, "\n");
400 }
401 FileClose (ofp);
402 FileClose (ifp);
403 } else {
404 LaunchGeneralTextViewer (path, title);
405 }
406 }
407
408 /*==================================================================*/
409 /* */
410 /* DisplayEntrezRequest () - Displays an Entrez2 request in a */
411 /* pop-up window. */
412 /* */
413 /*==================================================================*/
414
415 NLM_EXTERN void DisplayEntrezRequest (Entrez2RequestPtr e2rq)
416
417 {
418 AsnIoPtr aip;
419 Char path [PATH_MAX];
420
421 if (e2rq == NULL) return;
422 TmpNam (path);
423 aip = AsnIoOpen (path, "w");
424 if (aip == NULL) return;
425 Entrez2RequestAsnWrite (e2rq, aip, NULL);
426 AsnIoClose (aip);
427 LogOrLaunch (path, "Entrez2RequestAsnWrite");
428 FileRemove (path);
429 }
430
431 /*==================================================================*/
432 /* */
433 /* DisplayEntrezReply () - Displays an Entrez2 reply in a pop-up */
434 /* window. */
435 /* */
436 /*==================================================================*/
437
438 NLM_EXTERN void DisplayEntrezReply (Entrez2ReplyPtr e2ry)
439
440 {
441 AsnIoPtr aip;
442 Char path [PATH_MAX];
443
444 if (e2ry == NULL) return;
445 TmpNam (path);
446 aip = AsnIoOpen (path, "w");
447 if (aip == NULL) return;
448 Entrez2ReplyAsnWrite (e2ry, aip, NULL);
449 AsnIoClose (aip);
450 LogOrLaunch (path, "Entrez2ReplyAsnWrite");
451 FileRemove (path);
452 }
453
454 /* text version of entrez2 query for debugging purposes */
455
456 static Entrez2ReplyPtr EntrezTextWaitForReply (
457 CONN conn
458 )
459
460 {
461 AsnIoConnPtr aicp;
462 AsnIoPtr aip;
463 Char buffer [1025];
464 time_t currtime, starttime;
465 Entrez2ReplyPtr e2ry = NULL;
466 Boolean first;
467 FILE * fp;
468 time_t max = 0;
469 size_t n_read;
470 Boolean special_read = FALSE;
471 EIO_Status status;
472 STimeout timeout;
473 Char tmp [PATH_MAX];
474
475 if (conn == NULL) return NULL;
476
477 timeout.sec = 100;
478 timeout.usec = 0;
479
480 starttime = GetSecs ();
481 while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) {
482 currtime = GetSecs ();
483 max = currtime - starttime;
484 }
485 if (status == eIO_Success) {
486 #ifdef OS_UNIX
487 if (getenv ("ENTREZ2_RECORD_QUERY") != 0) {
488 special_read = TRUE;
489 }
490 #endif
491 if (special_read) {
492 TmpNam (tmp);
493 #ifdef OS_UNIX
494 printf ("TmpNam '%s'\n", tmp);
495 #endif
496 fp = FileOpen (tmp, "w");
497 if (fp != NULL) {
498
499 first = TRUE;
500 do {
501 status = CONN_Read (conn, buffer, sizeof (buffer) -1, &n_read,
502 first ? eIO_ReadPersist : eIO_ReadPlain);
503 buffer [n_read] = '\0';
504 if (first) {
505 if (StringStr (buffer, "Entrez2-reply") == NULL) {
506 ErrPostEx (SEV_ERROR, 0, 0, "EntrezReadReply failed on '%s'", buffer);
507 FileClose (fp);
508 /*
509 FileRemove (tmp);
510 */
511 return NULL;
512 }
513 first = FALSE;
514 }
515 fprintf (fp, "%s", buffer);
516 } while (status == eIO_Success);
517 FileClose (fp);
518
519 aip = AsnIoOpen (tmp, "r");
520 e2ry = Entrez2ReplyAsnRead (aip, NULL);
521 AsnIoClose (aip);
522 /*
523 FileRemove (tmp);
524 */
525 }
526 } else {
527 aicp = QUERY_AsnIoConnOpen ("r", conn);
528 e2ry = Entrez2ReplyAsnRead (aicp->aip, NULL);
529 QUERY_AsnIoConnClose (aicp);
530 }
531 }
532 CONN_Close (conn);
533
534 return e2ry;
535 }
536
537 static Entrez2ReplyPtr EntrezSpecialSynchronousQuery (
538 Entrez2RequestPtr e2rq,
539 Boolean textmode
540 )
541
542 {
543 AsnIoConnPtr aicp;
544 CONN conn;
545 Entrez2ReplyPtr e2ry;
546 CharPtr tempcookie = NULL;
547 CharPtr host_machine = NULL;
548 Uint2 host_port = 0;
549 CharPtr host_path = NULL;
550 CharPtr env_machine = NULL;
551 CharPtr env_path = NULL;
552 CharPtr env_port = NULL;
553 CharPtr env_service = NULL;
554 int val = 0;
555
556 if (e2rq == NULL) return NULL;
557
558 #ifdef OS_UNIX
559 env_machine = (CharPtr) getenv ("NCBI_ENTREZ2_HOST_MACHINE");
560 if (! StringHasNoText (env_machine)) {
561 host_machine = env_machine;
562 }
563 #endif
564 if (StringHasNoText (host_machine)) {
565 host_machine = "www.ncbi.nlm.nih.gov";
566 }
567
568 #ifdef OS_UNIX
569 env_port = (CharPtr) getenv ("NCBI_ENTREZ2_HOST_PORT");
570 if (! StringHasNoText (env_port)) {
571 if (sscanf (env_port, "%d", &val) == 1) {
572 host_port = (Uint2) val;
573 }
574 }
575 #endif
576 if (host_port == 0) {
577 host_port = 80;
578 }
579
580 #ifdef OS_UNIX
581 env_path = (CharPtr) getenv ("NCBI_ENTREZ2_HOST_PATH");
582 if (! StringHasNoText (env_path)) {
583 host_path = env_path;
584 }
585 #endif
586 if (StringHasNoText (host_path)) {
587 host_path = "/entrez/eutils/entrez2server.fcgi";
588 }
589
590 if (textmode) {
591 conn = QUERY_OpenUrlQuery (host_machine, host_port, host_path, NULL,
592 "Entrez2Text", 30, eMIME_T_NcbiData,
593 eMIME_AsnText, eENCOD_None, 0);
594
595 aicp = QUERY_AsnIoConnOpen ("w", conn);
596 } else {
597 conn = QUERY_OpenUrlQuery (host_machine, host_port, host_path, NULL,
598 "Entrez2Text", 30, eMIME_T_NcbiData,
599 eMIME_AsnBinary, eENCOD_None, 0);
600
601 aicp = QUERY_AsnIoConnOpen ("wb", conn);
602 }
603
604 tempcookie = e2rq->cookie;
605
606 Entrez2RequestAsnWrite (e2rq, aicp->aip, NULL);
607
608 e2rq->cookie = tempcookie;
609
610 AsnIoFlush (aicp->aip);
611 QUERY_AsnIoConnClose (aicp);
612
613 QUERY_SendQuery (conn);
614
615 if (textmode) {
616 e2ry = EntrezTextWaitForReply (conn);
617 } else {
618 e2ry = EntrezWaitForReply (conn);
619 }
620
621 return e2ry;
622 }
623
624 extern Entrez2ReplyPtr SpecialEntrezSynchronousQuery (
625 Entrez2RequestPtr e2rq
626 );
627
628 extern Entrez2ReplyPtr SpecialEntrezSynchronousQuery (
629 Entrez2RequestPtr e2rq
630 )
631
632 {
633 #ifdef OS_UNIX
634 if (getenv ("ENTREZ2_TEXT_QUERY") != 0) {
635 return EntrezSpecialSynchronousQuery (e2rq, TRUE);
636 }
637 if (getenv ("ENTREZ2_BINARY_QUERY") != 0) {
638 return EntrezSpecialSynchronousQuery (e2rq, FALSE);
639 }
640 #endif
641 return EntrezSynchronousQuery (e2rq);
642 }
643
644 /*==================================================================*/
645 /* */
646 /* DBGetInfo () - Given a database ID, return the DB pointer. */
647 /* */
648 /*==================================================================*/
649
650 static Entrez2DbInfoPtr DBGetInfo (Int2 dbId)
651
652 {
653 Int2 count;
654 Entrez2InfoPtr e2ip;
655 Entrez2DbInfoPtr e2db;
656
657 /*------------------*/
658 /* Check parameters */
659 /*------------------*/
660
661 if (dbId < 0) return NULL;
662
663 /*----------------------------------*/
664 /* Get information on the databases */
665 /*----------------------------------*/
666
667 e2ip = Query_GetInfo ();
668
669 /*-----------------------*/
670 /* Find the requested DB */
671 /*-----------------------*/
672
673 for (e2db = e2ip->db_info, count = 0; e2db != NULL; e2db = e2db->next, count++) {
674 if (count == dbId) return e2db;
675 }
676
677 return NULL;
678 }
679
680 /*==================================================================*/
681 /* */
682 /* DBGetNameFromID () - Given a DB ID, returns its name. */
683 /* */
684 /*==================================================================*/
685
686 NLM_EXTERN CharPtr DBGetNameFromID (Int2 dbId)
687
688 {
689 Int2 count;
690 Entrez2InfoPtr e2ip;
691 Entrez2DbInfoPtr e2db;
692
693 /*-----------------*/
694 /* Check parameter */
695 /*-----------------*/
696
697 if (dbId < 0) return NULL;
698
699 /*----------------------------------*/
700 /* Get information on the databases */
701 /*----------------------------------*/
702
703 e2ip = Query_GetInfo ();
704
705 /*--------------------------*/
706 /* Find to the requested DB */
707 /*--------------------------*/
708
709 for (e2db = e2ip->db_info, count = 0; e2db != NULL; e2db = e2db->next, count++) {
710 if (count == dbId) return e2db->db_name;
711 }
712
713 return NULL;
714 }
715
716 /*==================================================================*/
717 /* */
718 /* DBGetIDFromName () - Given a DB name, returns its unique ID. */
719 /* */
720 /*==================================================================*/
721
722 NLM_EXTERN Int2 DBGetIDFromName (CharPtr dbName)
723
724 {
725 Int2 count;
726 Entrez2InfoPtr e2ip;
727 Entrez2DbInfoPtr e2db;
728
729 /*-----------------*/
730 /* Check parameter */
731 /*-----------------*/
732
733 if (dbName == NULL) return -1;
734
735 /*----------------------------------*/
736 /* Get information on the databases */
737 /*----------------------------------*/
738
739 e2ip = Query_GetInfo ();
740
741 /*---------------------------*/
742 /* Look for the requested DB */
743 /*---------------------------*/
744
745 for (e2db = e2ip->db_info, count = 0; e2db != NULL; e2db = e2db->next, count++) {
746 if (StrICmp (e2db->db_name, dbName) == 0) return count;
747 }
748
749 return -1;
750 }
751
752 /*==================================================================*/
753 /* */
754 /* FieldGetInfo () - Given a database ID and a field ID, return */
755 /* the field name. */
756 /* */
757 /*==================================================================*/
758
759 static Entrez2FieldInfoPtr FieldGetInfo (Int2 dbId, Int2 fieldId)
760
761 {
762 Int2 count;
763 Entrez2DbInfoPtr e2db;
764 Entrez2FieldInfoPtr e2fd;
765
766 /*------------------*/
767 /* Check parameters */
768 /*------------------*/
769
770 if (dbId < 0 || fieldId < 0) return NULL;
771
772 /*----------------------------------*/
773 /* Find the requested DB */
774 /*----------------------------------*/
775
776 e2db = DBGetInfo (dbId);
777 if (e2db == NULL) return NULL;
778
779 /*----------------*/
780 /* Get field info */
781 /*----------------*/
782
783 for (e2fd = e2db->fields, count = 0; e2fd != NULL; e2fd = e2fd->next, count++) {
784 if (count == fieldId) return e2fd;
785 }
786
787 return NULL;
788 }
789
790 /*==================================================================*/
791 /* */
792 /* IsValidFieldName () - Given a database ID and a field name, */
793 /* check to see if it is as valid name. */
794 /* */
795 /*==================================================================*/
796
797 static Boolean IsValidFieldName (Int2 dbId, CharPtr fieldName)
798
799 {
800 Entrez2DbInfoPtr e2db;
801 Entrez2FieldInfoPtr e2fd;
802
803 /*------------------*/
804 /* Check parameters */
805 /*------------------*/
806
807 if (dbId < 0 || fieldName == NULL) return FALSE;
808
809 /*-----------------------*/
810 /* Find the requested DB */
811 /*-----------------------*/
812
813 e2db = DBGetInfo (dbId);
814 if (e2db == NULL) return FALSE;
815
816 /*----------------*/
817 /* Get field info */
818 /*----------------*/
819
820 for (e2fd = e2db->fields; e2fd != NULL; e2fd = e2fd->next) {
821 if (StrICmp (e2fd->field_name, fieldName) == 0)
822 return TRUE;
823 }
824
825 return FALSE;
826 }
827
828 /*===================================================================*/
829 /* */
830 /* FieldGetNameFromMenuName () - Given a field menu name and a */
831 /* database ID, return the field name. */
832 /* */
833 /*===================================================================*/
834
835 static CharPtr FieldGetNameFromMenuName (Int2 dbId, CharPtr menuName)
836
837 {
838 Entrez2DbInfoPtr e2db;
839 Entrez2FieldInfoPtr e2fd;
840
841 /*------------------*/
842 /* Check parameters */
843 /*------------------*/
844
845 if (menuName == NULL || dbId < 0) return NULL;
846
847 /*-----------------------*/
848 /* Find the requested DB */
849 /*-----------------------*/
850
851 e2db = DBGetInfo (dbId);
852 if (e2db == NULL) return NULL;
853
854 /*--------------------------*/
855 /* Find the requested field */
856 /*--------------------------*/
857
858 for (e2fd = e2db->fields; e2fd != NULL; e2fd = e2fd->next) {
859 if (StrICmp (e2fd->field_menu, menuName) == 0) return e2fd->field_name;
860 }
861
862 return NULL;
863 }
864
865 /*==================================================================*/
866 /* */
867 /* FieldGetIDFromName () - Given a field name and a database ID, */
868 /* return the field ID. */
869 /* */
870 /*==================================================================*/
871
872 static Int2 FieldGetIDFromName (Int2 dbId, CharPtr fieldName)
873
874 {
875 Int2 count;
876 Entrez2DbInfoPtr e2db;
877 Entrez2FieldInfoPtr e2fd;
878
879 /*------------------*/
880 /* Check parameters */
881 /*------------------*/
882
883 if (fieldName == NULL || dbId < 0) return -1;
884
885 /*-----------------------*/
886 /* Find the requested DB */
887 /*-----------------------*/
888
889 e2db = DBGetInfo (dbId);
890 if (e2db == NULL) return -1;
891
892 /*--------------------------*/
893 /* Find the requested field */
894 /*--------------------------*/
895
896 for (e2fd = e2db->fields, count = 0; e2fd != NULL; e2fd = e2fd->next, count++) {
897 if (StrICmp (e2fd->field_name, fieldName) == 0) return count;
898 }
899
900 return -1;
901 }
902
903 /*==================================================================*/
904 /* */
905 /* FieldGetInfoFromName () - This is desigend to get field info */
906 /* given only a field name. It is useful */
907 /* for a getting information on a field */
908 /* in a sorted alist of fields. */
909 /* */
910 /*==================================================================*/
911
912 static Entrez2FieldInfoPtr FieldGetInfoFromName (CharPtr fieldName)
913
914 {
915 Int2 count;
916 Entrez2InfoPtr e2ip;
917 Entrez2DbInfoPtr e2db;
918 Entrez2FieldInfoPtr e2fd;
919
920 /*------------------*/
921 /* Check parameters */
922 /*------------------*/
923
924 if (fieldName == NULL) return NULL;
925
926 /*----------------------------------*/
927 /* Get information on the databases */
928 /*----------------------------------*/
929
930 e2ip = Query_GetInfo ();
931
932 /*-------------------------------*/
933 /* Find the requested field info */
934 /*-------------------------------*/
935
936 for (e2db = e2ip->db_info, count = 0; e2db != NULL; e2db = e2db->next, count++) {
937 for (e2fd = e2db->fields; e2fd != NULL; e2fd = e2fd->next) {
938 if (StrICmp (e2fd->field_name, fieldName) == 0) return e2fd;
939 }
940 }
941
942 return NULL;
943 }
944
945 /*==================================================================*/
946 /* */
947 /* FieldGetModePopup () - */
948 /* */
949 /*==================================================================*/
950
951 static Int2 FieldGetModePopup (Int2 dbId, Int2 fieldId, EnumFieldAssocPtr fieldAList, FormInfoPtr pFormInfo)
952
953 {
954 Entrez2DbInfoPtr dbInfo;
955 Entrez2FieldInfoPtr fieldInfo;
956 Boolean is_rangable;
957 Boolean is_truncatable;
958 ModeIndex modeId = POPUP_DEFAULT;
959
960 /*-----------------------------------------*/
961 /* Find the requested field, and determine */
962 /* its corresponding mode list popup. */
963 /*-----------------------------------------*/
964
965 dbInfo = DBGetInfo (dbId);
966 if (dbInfo == NULL) return -1;
967
968 fieldInfo = FieldGetInfo (dbId, fieldId);
969 if (fieldInfo == NULL) return -1;
970
971 /* is_rangable = fieldInfo->is_rangable; */
972 is_rangable = (Boolean) (fieldInfo->is_date || fieldInfo->is_numerical);
973 /* is_truncatable = fieldInfo->is_truncatable; */
974 is_truncatable = (Boolean) (! is_rangable);
975
976 if (StringICmp (dbInfo->db_name, "PubMed") == 0 &&
977 StringICmp (fieldInfo->field_name, "ALL") == 0) {
978 modeId = POPUP_AUTO;
979 } else if (StringICmp (fieldInfo->field_name, "ALL") == 0) {
980 modeId = POPUP_MULT;
981 } else if ((StringICmp (fieldInfo->field_name, "TITL") == 0) ||
982 (StringICmp (fieldInfo->field_name, "WORD") == 0) ||
983 (StringICmp (fieldInfo->field_name, "TIAB") == 0)) {
984 modeId = POPUP_MULT;
985 } else if (StringICmp (fieldInfo->field_name, "ACCN") == 0 ||
986 StringICmp (fieldInfo->field_name, "PACC") == 0) {
987 modeId = POPUP_ACCN;
988 } else if (StringICmp (fieldInfo->field_name, "ORGN") == 0) {
989 modeId = POPUP_TAX;
990 } else if (StringICmp (fieldInfo->field_name, "MESH") == 0 ||
991 StringICmp (fieldInfo->field_name, "MAJR") == 0) {
992 modeId = POPUP_MESH;
993 } else if (StringICmp (fieldInfo->field_name, "UID") == 0) {
994 modeId = POPUP_UID;
995 } else if (is_rangable && is_truncatable) {
996 modeId = POPUP_DEFAULT;
997 } else if (is_rangable) {
998 modeId = POPUP_RANGE;
999 } else if (is_truncatable) {
1000 modeId = POPUP_TRUNC;
1001 } else {
1002 modeId = POPUP_DEFAULT;
1003 }
1004
1005 pFormInfo->currField = FieldGetIDFromName (dbId, fieldInfo->field_name);
1006 return modeId;
1007 }
1008
1009 /*==================================================================*/
1010 /* */
1011 /* CreateDatabaseAlist () - Returns alist of database names */
1012 /* */
1013 /*==================================================================*/
1014
1015 EnumFieldAssocPtr CreateDatabaseAlist (Entrez2InfoPtr e2ip)
1016
1017 {
1018 EnumFieldAssocPtr alist;
1019 Uint1 choice;
1020 Entrez2DbInfoPtr e2db;
1021 ValNodePtr head = NULL;
1022
1023 if (e2ip == NULL || e2ip->db_count < 1) return NULL;
1024
1025 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
1026 choice = (Uint1) DBGetIDFromName (e2db->db_name);
1027 ValNodeCopyStr (&head, choice, e2db->db_menu);
1028 }
1029
1030 alist = MakeEnumFieldAlistFromValNodeList (head);
1031 ValNodeFreeData (head);
1032
1033 return alist;
1034 }
1035
1036 /*==================================================================*/
1037 /* */
1038 /* CreateFieldAlist () - Returns sorted alist of field names for */
1039 /* the given database. */
1040 /* */
1041 /*==================================================================*/
1042
1043 EnumFieldAssocPtr CreateFieldAlist (Entrez2DbInfoPtr e2db)
1044
1045 {
1046 EnumFieldAssocPtr alist;
1047 Uint1 choice;
1048 Entrez2FieldInfoPtr fieldInfo;
1049 Int2 dbId;
1050 ValNodePtr head = NULL;
1051
1052 if (e2db == NULL || e2db->field_count < 1) return NULL;
1053
1054 dbId = DBGetIDFromName (e2db->db_name);
1055 for (fieldInfo = e2db->fields; fieldInfo != NULL; fieldInfo = fieldInfo->next) {
1056 choice = (Uint1) FieldGetIDFromName (dbId, fieldInfo->field_name);
1057 ValNodeCopyStr (&head, choice, fieldInfo->field_menu);
1058 }
1059
1060 head = ValNodeSort (head, SortVnpByString);
1061
1062 alist = MakeEnumFieldAlistFromValNodeList (head);
1063 ValNodeFreeData (head);
1064
1065 return alist;
1066 }
1067
1068 /*==================================================================*/
1069 /* */
1070 /* CreateAllFieldsAlist () - Returns sorted uniqued alist of all */
1071 /* field names. */
1072 /* */
1073 /*==================================================================*/
1074
1075 static EnumFieldAssocPtr CreateAllFieldsAlist (Entrez2InfoPtr e2ip)
1076
1077 {
1078 EnumFieldAssocPtr alist;
1079 Uint1 choice;
1080 Entrez2DbInfoPtr e2db;
1081 Entrez2FieldInfoPtr fieldInfo;
1082 Int2 dbId;
1083 ValNodePtr head = NULL;
1084
1085 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
1086 dbId = DBGetIDFromName (e2db->db_name);
1087 for (fieldInfo = e2db->fields; fieldInfo != NULL; fieldInfo = fieldInfo->next) {
1088 choice = (Uint1) FieldGetIDFromName (dbId, fieldInfo->field_name);
1089 ValNodeCopyStr (&head, choice, fieldInfo->field_name);
1090 }
1091 }
1092
1093 head = ValNodeSort (head, SortVnpByString);
1094 head = UniqueValNode (head);
1095
1096 alist = MakeEnumFieldAlistFromValNodeList (head);
1097 ValNodeFreeData (head);
1098
1099 return alist;
1100 }
1101
1102 /*==================================================================*/
1103 /* */
1104 /* GetUidFromAccn () - */
1105 /* */
1106 /*==================================================================*/
1107
1108 static Uint4 GetUidFromAccn (CharPtr dbName, CharPtr accn)
1109
1110 {
1111 Entrez2BooleanReplyPtr e2br;
1112 Entrez2IdListPtr e2id;
1113 Entrez2RequestPtr e2rq;
1114 Entrez2ReplyPtr e2ry;
1115 Char ch;
1116 CharPtr ptr;
1117 Char str [61];
1118 Uint4 uid = 0;
1119
1120 if (StringHasNoText (dbName) || StringHasNoText (accn)) return 0;
1121
1122 StringNCpy_0 (str, accn, sizeof (str));
1123 ptr = str;
1124 ch = *ptr;
1125 while (ch != '\0') {
1126 if (ch == '|' || ch == '.') {
1127 *ptr = ' ';
1128 }
1129 ptr++;
1130 ch = *ptr;
1131 }
1132 TrimSpacesAroundString (str);
1133 if (StringStr (str, "[ACCN]") == NULL) {
1134 StringCat (str, "[ACCN]");
1135 }
1136 e2rq = EntrezCreateBooleanRequest (TRUE, FALSE, dbName, str, 0, 0, NULL, 1, 0);
1137
1138 if (e2rq == NULL) return 0;
1139 e2ry = SpecialEntrezSynchronousQuery (e2rq);
1140 e2rq = Entrez2RequestFree (e2rq);
1141 if (e2ry == NULL) return 0;
1142 e2br = EntrezExtractBooleanReply (e2ry);
1143 if (e2br == NULL) return 0;
1144
1145 if (e2br->count > 0) {
1146 e2id = e2br->uids;
1147 if (e2id != NULL && e2id->num > 0 && e2id->uids != NULL) {
1148 BSSeek (e2id->uids, 0, SEEK_SET);
1149 uid = Nlm_BSGetUint4 (e2id->uids);
1150 }
1151 }
1152
1153 Entrez2BooleanReplyFree (e2br);
1154
1155 return uid;
1156 }
1157
1158 /*==================================================================*/
1159 /* */
1160 /* ProcessDirectLookup () - */
1161 /* */
1162 /*==================================================================*/
1163
1164 static void ProcessDirectLookup (FormInfoPtr pFormInfo, CharPtr str)
1165
1166 {
1167 CharPtr dbName;
1168 Int4 uid;
1169
1170 uid = 0;
1171
1172 /*----------------------------------------*/
1173 /* Convert the given string to a UID and */
1174 /* check to see if it is a valid one. */
1175 /*---------------------------------------*/
1176
1177 if ((pFormInfo->currMode == LOOKUP_ACCN_MODE) || (pFormInfo->currMode == VIEW_ACCN_MODE)) {
1178 if (StringLen (str) > 0) {
1179 dbName = DBGetNameFromID (pFormInfo->currDb);
1180 uid = GetUidFromAccn (dbName, str);
1181 }
1182 } else if ((pFormInfo->currMode == LOOKUP_UID_MODE) || (pFormInfo->currMode == VIEW_UID_MODE)) {
1183 if (! StrToLong (str, &uid)) {
1184 Message (MSG_OK, "You must enter an integer");
1185 return;
1186 }
1187 } else
1188 return;
1189
1190 if (uid <= 0) {
1191 if (pFormInfo->currMode == LOOKUP_ACCN_MODE || pFormInfo->currMode == VIEW_ACCN_MODE) {
1192 Message (MSG_OK, "This accession is not present in the database");
1193 } else {
1194 Message (MSG_OK, "This UID is not present in the database");
1195 }
1196 return;
1197 }
1198
1199 /*-------------------------------------*/
1200 /* Lookup the record for the given UID */
1201 /* and display it in a DocSum window. */
1202 /*-------------------------------------*/
1203
1204 if (pFormInfo->currMode == LOOKUP_ACCN_MODE || pFormInfo->currMode == LOOKUP_UID_MODE) {
1205 dbName = DBGetNameFromID (pFormInfo->currDb);
1206 pFormInfo->retrieveUidProc (pFormInfo->form, uid, dbName);
1207 } else {
1208 LaunchRecViewer (pFormInfo->form, uid, 1, &uid, pFormInfo->currDb, 1);
1209 }
1210 }
1211
1212 /*==================================================================*/
1213 /* */
1214 /* DoResetAvail () - Clears out the Term List object. */
1215 /* */
1216 /*==================================================================*/
1217
1218 static void DoResetAvail (FormInfoPtr pFormInfo, Boolean clearTerm)
1219
1220 {
1221 Int2 i;
1222
1223 if (clearTerm) {
1224 SafeSetTitle (pFormInfo->termText, "");
1225 SafeSetTitle (pFormInfo->toText, "");
1226 SafeSetTitle (pFormInfo->fromText, "");
1227 SafeDisable (pFormInfo->acceptButton);
1228 } else if (pFormInfo->currMode == RANGE_MODE) {
1229 if (TextHasNoText (pFormInfo->fromText) && TextHasNoText (pFormInfo->toText))
1230 SafeDisable (pFormInfo->acceptButton);
1231 else
1232 SafeEnable (pFormInfo->acceptButton);
1233 } else {
1234 if (TextHasNoText (pFormInfo->termText))
1235 SafeDisable (pFormInfo->acceptButton);
1236 else
1237 SafeEnable (pFormInfo->acceptButton);
1238 }
1239
1240 pFormInfo->availItem = 0;
1241 pFormInfo->availRow = 0;
1242 Reset (pFormInfo->availDoc);
1243 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
1244
1245 for (i = 0; i < 7; i++)
1246 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt, systemFont);
1247
1248 InvalDocument (pFormInfo->availDoc);
1249 SafeHide (pFormInfo->taxLineagePopup);
1250 Reset (pFormInfo->taxLineagePopup);
1251 pFormInfo->taxStrings = ValNodeFreeData (pFormInfo->taxStrings);
1252 pFormInfo->availNumTerms = 0;
1253 pFormInfo->availPageSize = 0;
1254 pFormInfo->availNumPages = 0;
1255 }
1256
1257 /*==================================================================*/
1258 /* */
1259 /* FreeTerm () - Frees a given term from the term list. */
1260 /* */
1261 /*==================================================================*/
1262
1263 static void FreeTerm (StateDataPtr termPtr)
1264
1265 {
1266 MemFree (termPtr->term);
1267 MemFree (termPtr->field);
1268 MemFree (termPtr);
1269 }
1270
1271 /*==================================================================*/
1272 /* */
1273 /* FreeTermList () - Frees all the terms in the current query */
1274 /* term list. */
1275 /* */
1276 /*==================================================================*/
1277
1278 static StateDataPtr FreeTermList (FormInfoPtr pFormInfo)
1279
1280 {
1281 StateDataPtr next;
1282
1283 while (pFormInfo->termList != NULL) {
1284 next = pFormInfo->termList->next;
1285 FreeTerm (pFormInfo->termList);
1286 pFormInfo->termList = next;
1287 }
1288
1289 return NULL;
1290 }
1291
1292 /*==================================================================*/
1293 /* */
1294 /* ResetChosen () - Clears out the Query Refinement object. */
1295 /* */
1296 /*==================================================================*/
1297
1298 static void ResetChosen (FormInfoPtr pFormInfo)
1299
1300 {
1301 /*--------------*/
1302 /* Clear it out */
1303 /*--------------*/
1304
1305 Reset (pFormInfo->chosenDoc);
1306 FreeTermList (pFormInfo);
1307 SetDocCache (pFormInfo->chosenDoc, NULL, NULL, NULL);
1308
1309 InvalDocument (pFormInfo->chosenDoc);
1310 pFormInfo->chosenNumLines = 0;
1311
1312 SafeSetTitle (pFormInfo->retrieveButton, "Retrieve 0 Documents");
1313 SafeDisable (pFormInfo->retrieveButton);
1314 }
1315
1316 /*==================================================================*/
1317 /* */
1318 /* Reset_Callback () - Called when reset button is pushed. Clears */
1319 /* the Term List and Query Refinement windows. */
1320 /* */
1321 /*==================================================================*/
1322
1323 static void Reset_Callback (ButtoN b)
1324
1325 {
1326 FormInfoPtr pFormInfo;
1327
1328 pFormInfo = (FormInfoPtr) GetObjectExtra (b);
1329 DoResetAvail (pFormInfo, TRUE);
1330 ResetChosen (pFormInfo);
1331 Reset (pFormInfo->advQueryText);
1332 pFormInfo->isValidFrom = FALSE;
1333 pFormInfo->isValidTo = FALSE;
1334 }
1335
1336 /*==================================================================*/
1337 /* */
1338 /* StateDataNew() - Creates a new Query term structure and adds */
1339 /* it to the query term list. */
1340 /* */
1341 /*==================================================================*/
1342
1343 static StateDataPtr StateDataNew (FormInfoPtr pFormInfo)
1344
1345 {
1346 StateDataPtr newNode;
1347 StateDataPtr tempNode;
1348
1349 /*-------------------*/
1350 /* Create a new node */
1351 /*-------------------*/
1352
1353 newNode = (StateDataPtr) MemNew (sizeof (StateData));
1354 if (newNode == NULL) return NULL;
1355
1356 /*-------------------------------*/
1357 /* Add it to the end of the list */
1358 /*-------------------------------*/
1359
1360 tempNode = pFormInfo->termList;
1361 if (tempNode != NULL) {
1362 while (tempNode->next != NULL)
1363 tempNode = tempNode->next;
1364 tempNode->next = newNode;
1365 newNode->prev = tempNode;
1366 } else { /* Empty list -- this is first term */
1367
1368 newNode->prev = NULL;
1369 newNode->next = NULL;
1370 pFormInfo->termList = newNode;
1371 }
1372
1373 /*---------------------*/
1374 /* Return successfully */
1375 /*---------------------*/
1376
1377 return newNode;
1378 }
1379
1380 /*===================================================================*/
1381 /* */
1382 /* CreateTerm () - Creates a new boolean term using the given */
1383 /* data and adds it to the linked list of */
1384 /* terms. */
1385 /* */
1386 /*===================================================================*/
1387
1388 static StateDataPtr CreateTerm (
1389 ForM f,
1390 Int2 currDb,
1391 Int2 currFld,
1392 CharPtr strs,
1393 Int2 state,
1394 Int4 num,
1395 Boolean allowDuplicates
1396 )
1397
1398 {
1399 StateDataPtr prev;
1400 StateDataPtr sdp;
1401 Entrez2FieldInfoPtr fieldInfo;
1402 FormInfoPtr pFormInfo;
1403
1404 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
1405
1406 /*----------------------------------*/
1407 /* Make sure we're don't try to add */
1408 /* the same string twice. */
1409 /*----------------------------------*/
1410
1411 if (! allowDuplicates) {
1412 for (sdp = pFormInfo->termList; sdp != NULL; sdp = sdp->next) {
1413 if (MeshStringICmp (sdp->term, strs) == 0 &&
1414 sdp->db == currDb && sdp->fld == currFld) return NULL;
1415 }
1416 }
1417
1418 /*------------------------------*/
1419 /* Create a term for the string */
1420 /* on the end of the list. */
1421 /*------------------------------*/
1422
1423 sdp = StateDataNew (pFormInfo);
1424 if (pFormInfo->termList == NULL)
1425 pFormInfo->termList = sdp;
1426
1427 if (sdp == NULL) return NULL;
1428
1429 (pFormInfo->chosenNumLines)++;
1430
1431 sdp->term = StringSave (strs);
1432 sdp->count = num;
1433 sdp->db = currDb;
1434 sdp->fld = currFld;
1435 sdp->uids = NULL;
1436 sdp->key = NULL;
1437 fieldInfo = FieldGetInfo (currDb, currFld);
1438 if (fieldInfo == NULL) return NULL;
1439 sdp->field = StringSave (fieldInfo->field_name);
1440 if (sdp->field == NULL)
1441 sdp->field = StringSave ("----");
1442 sdp->group = GROUP_SINGLE;
1443 sdp->above = ENTREZ_OP_NONE;
1444
1445 /*-------------------------------------*/
1446 /* Add the term to the current Query's */
1447 /* linked list of terms. */
1448 /*-------------------------------------*/
1449
1450 prev = sdp->prev;
1451 if (prev != NULL) {
1452 sdp->above = ENTREZ_OP_AND;
1453 prev->below = ENTREZ_OP_AND;
1454 }
1455 sdp->below = ENTREZ_OP_NONE;
1456 sdp->state = state;
1457
1458 /*------------------------------*/
1459 /* Return a ptr to the new term */
1460 /*------------------------------*/
1461
1462 return sdp;
1463 }
1464
1465 /*==================================================================*/
1466 /* */
1467 /* DisplayTerm () - */
1468 /* */
1469 /*==================================================================*/
1470
1471 static void DisplayTerm (FormInfoPtr pFormInfo, CharPtr term, CharPtr fieldName, Int4 total)
1472
1473 {
1474 RecT r;
1475 BaR sb;
1476 Char strn [256];
1477
1478 /*------------------------------------------*/
1479 /* Create a display string for the term and */
1480 /* add it to the 'chosen' window. */
1481 /*------------------------------------------*/
1482
1483 sprintf (strn, "%s\t [%s]\t%ld\n", term, fieldName, (long) total);
1484 AppendText (pFormInfo->chosenDoc, strn, &chosenParFmt, chosenColFmt, systemFont);
1485
1486 /*---------------------------------*/
1487 /* Display our new query string in */
1488 /* Query Refinement window. */
1489 /*---------------------------------*/
1490
1491 InvalDocRows (pFormInfo->chosenDoc, pFormInfo->chosenNumLines, 1, 1);
1492 AdjustDocScroll (pFormInfo->chosenDoc);
1493 sb = GetSlateVScrollBar ((SlatE) pFormInfo->chosenDoc);
1494 ResetClip ();
1495 SetBarValue (sb, MAX (pFormInfo->chosenNumLines - 7, 0));
1496 ObjectRect (pFormInfo->chosenDoc, &r);
1497 InsetRect (&r, 4, 4);
1498 r.right = r.left + 16;
1499 InsetRect (&r, -1, -1);
1500 Select (pFormInfo->chosenDoc);
1501 InvalRect (&r);
1502
1503 Update ();
1504 }
1505
1506 /*==================================================================*/
1507 /* */
1508 /* Query_AddBoolTerm () - Adds a boolean term to the linked list */
1509 /* of terms that form the query. */
1510 /* */
1511 /*==================================================================*/
1512
1513 static StateDataPtr Query_AddBoolTerm (ForM f, Int2 currDb, Int2 currFld, CharPtr strs, Int2 state, Int4 num)
1514
1515 {
1516 StateDataPtr sdp;
1517 FormInfoPtr pFormInfo;
1518
1519 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
1520
1521 /*-----------------------------*/
1522 /* Add the term and display it */
1523 /*-----------------------------*/
1524
1525 sdp = CreateTerm (f, currDb, currFld, strs, state, num, FALSE);
1526 if (sdp != NULL) {
1527 DisplayTerm (pFormInfo, strs, sdp->field, num);
1528 }
1529
1530 /*------------------------------*/
1531 /* Return a ptr to the new term */
1532 /*------------------------------*/
1533
1534 return sdp;
1535 }
1536
1537 /*==================================================================*/
1538 /* */
1539 /* ProcessMeshTerm () - */
1540 /* */
1541 /*==================================================================*/
1542
1543 static void ProcessMeshTerm (FormInfoPtr pFormInfo, CharPtr str)
1544
1545 {
1546 Int4 iTermCount;
1547 CharPtr ptr;
1548 CharPtr text;
1549
1550 /*---------------------------*/
1551 /* Trim off extra spaces and */
1552 /* curly-bracketed info */
1553 /*---------------------------*/
1554
1555 ptr = str;
1556 while (*ptr != '\0' && *ptr != '{') {
1557 ptr++;
1558 }
1559 *ptr = '\0';
1560
1561 /*-----------------------------*/
1562 /* Get the term count from the */
1563 /* term selection window. */
1564 /*-----------------------------*/
1565
1566 text = GetDocText (pFormInfo->availDoc, pFormInfo->availItem, pFormInfo->availRow, E2_COUNT_COL);
1567 TrimSpacesAroundString (text);
1568 StrToLong (text, &iTermCount);
1569 MemFree (text);
1570
1571 /*-------------------------------*/
1572 /* Load the chosen term into the */
1573 /* query refinement window. */
1574 /*-------------------------------*/
1575
1576 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb, pFormInfo->currField, str, STATE_ON, iTermCount);
1577 }
1578
1579 /*==================================================================*/
1580 /* */
1581 /* ValNodeMerge () - */
1582 /* */
1583 /*==================================================================*/
1584
1585 static CharPtr ValNodeMerge (ValNodePtr head)
1586
1587 {
1588 size_t len;
1589 CharPtr str;
1590 CharPtr to;
1591 ValNodePtr vnp;
1592
1593 if (head == NULL) return NULL;
1594
1595 for (vnp = head, len = 0; vnp != NULL; vnp = vnp->next)
1596 len += StringLen ((CharPtr) vnp->data.ptrvalue);
1597
1598 str = (CharPtr) MemNew (len + 4);
1599 if (str == NULL) return NULL;
1600
1601 for (vnp = head, to = str; vnp != NULL; vnp = vnp->next)
1602 to = StringMove (to, (CharPtr) vnp->data.ptrvalue);
1603
1604 return str;
1605 }
1606
1607 /*==================================================================*/
1608 /* */
1609 /* FetchFromTermList () - */
1610 /* */
1611 /*==================================================================*/
1612
1613 static CharPtr FetchFromTermList (DoC d, Int2 item, Pointer ptr)
1614
1615 {
1616 FormInfoPtr pFormInfo;
1617 CharPtr db, field;
1618 Entrez2RequestPtr e2rq;
1619 Entrez2ReplyPtr e2ry;
1620 Entrez2TermListPtr e2tl;
1621 Entrez2TermPtr e2tp;
1622 Entrez2FieldInfoPtr fieldInfo;
1623 Int4 firstPos, numTerms, page;
1624 ValNodePtr head = NULL;
1625 CharPtr rsult = NULL;
1626 Char str [256], tmp [16];
1627
1628 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
1629
1630 if (item < 1) return NULL;
1631
1632 page = item - 1;
1633
1634 db = DBGetNameFromID (pFormInfo->currDb);
1635 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
1636 field = fieldInfo->field_name;
1637 if (StringHasNoText (db) || StringHasNoText (field)) return NULL;
1638
1639 firstPos = pFormInfo->availPageSize * page;
1640 numTerms = pFormInfo->availPageSize;
1641 if (firstPos + numTerms > pFormInfo->availNumTerms)
1642 numTerms = pFormInfo->availNumTerms - firstPos;
1643
1644 e2rq = EntrezCreateGetTermListRequest (db, field, firstPos, numTerms);
1645 if (e2rq == NULL) return NULL;
1646
1647 if (ShowASN () == TRUE)
1648 DisplayEntrezRequest (e2rq);
1649
1650 e2ry = SpecialEntrezSynchronousQuery (e2rq);
1651 if (e2ry != NULL) {
1652 if (ShowASN () == TRUE)
1653 DisplayEntrezReply (e2ry);
1654
1655 e2tl = EntrezExtractTermListReply (e2ry);
1656 if (e2tl != NULL)
1657 for (e2tp = e2tl->list; e2tp != NULL; e2tp = e2tp->next) {
1658 StringNCpy_0 (str, e2tp->term, sizeof (str) - 16);
1659 sprintf (tmp, "\t%ld\n", (long) e2tp->count);
1660 StringCat (str, tmp);
1661 ValNodeCopyStr (&head, 0, str);
1662 }
1663 }
1664 Entrez2RequestFree (e2rq);
1665
1666 rsult = ValNodeMerge (head);
1667 ValNodeFreeData (head);
1668
1669 return rsult;
1670 }
1671
1672 /*==================================================================*/
1673 /* */
1674 /* GetTermPage () - */
1675 /* */
1676 /*==================================================================*/
1677
1678 static Int4 GetTermPage (FormInfoPtr pFormInfo, CharPtr str)
1679
1680 {
1681 CharPtr db;
1682 CharPtr field;
1683 Entrez2RequestPtr e2rq;
1684 Entrez2ReplyPtr e2ry;
1685 Int4 pagesize = -1;
1686 Int4 pos = -1;
1687 Int4 rsult = -1;
1688 Entrez2FieldInfoPtr fieldInfo;
1689
1690 db = DBGetNameFromID (pFormInfo->currDb);
1691 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
1692 field = fieldInfo->field_name;
1693
1694 if (StringHasNoText (db) || StringHasNoText (field)) return rsult;
1695
1696 e2rq = EntrezCreateGetTermPositionRequest (db, field, str);
1697 if (e2rq == NULL) return rsult;
1698
1699 if (ShowASN () == TRUE)
1700 DisplayEntrezRequest (e2rq);
1701
1702 e2ry = SpecialEntrezSynchronousQuery (e2rq);
1703 if (e2ry != NULL) {
1704 if (ShowASN () == TRUE)
1705 DisplayEntrezReply (e2ry);
1706
1707 pos = EntrezExtractTermPosReply (e2ry);
1708 pagesize = pFormInfo->availPageSize;
1709 if (pagesize > 0)
1710 rsult = (pos - 1) / pagesize;
1711 }
1712 Entrez2RequestFree (e2rq);
1713
1714 if (pos == -1) return -1;
1715
1716 return rsult;
1717 }
1718
1719 /*==================================================================*/
1720 /* */
1721 /* ChangeUnderscoreToSpace () - */
1722 /* */
1723 /*==================================================================*/
1724
1725 static void ChangeUnderscoreToSpace (CharPtr str)
1726
1727 {
1728 Char ch;
1729 CharPtr ptr;
1730
1731 if (str == NULL) return;
1732 ptr = str;
1733 ch = *ptr;
1734 while (ch != '\0') {
1735 if (ch == '_')
1736 *ptr = ' ';
1737 ptr++;
1738 ch = *ptr;
1739 }
1740 }
1741
1742 /*==================================================================*/
1743 /* */
1744 /* ChangePeriodToSpace () - */
1745 /* */
1746 /*==================================================================*/
1747
1748 static void ChangePeriodToSpace (CharPtr str)
1749
1750 {
1751 Char ch;
1752 CharPtr ptr;
1753
1754 if (str == NULL) return;
1755 ptr = str;
1756 ch = *ptr;
1757 while (ch != '\0') {
1758 if (ch == '.')
1759 *ptr = ' ';
1760 ptr++;
1761 ch = *ptr;
1762 }
1763 }
1764
1765 /*==================================================================*/
1766 /* */
1767 /* ChangeMeshSlashSymbol () - */
1768 /* */
1769 /*==================================================================*/
1770
1771 static void ChangeMeshSlashSymbol (CharPtr str)
1772
1773 {
1774 Char ch;
1775 CharPtr ptr;
1776
1777 if (str == NULL) return;
1778
1779 ptr = str;
1780 ch = *ptr;
1781 while (ch != '\0') {
1782 if (ch == '/')
1783 *ptr = '\31';
1784 ptr++;
1785 ch = *ptr;
1786 }
1787 }
1788
1789 /*==================================================================*/
1790 /* */
1791 /* FindLineOfText () - Assumes a string of text separated by */
1792 /* newline, characters, and terminated by a */
1793 /* newline */
1794 /* */
1795 /*==================================================================*/
1796
1797 static Int2 FindLineOfText (CharPtr text, CharPtr str)
1798
1799 {
1800 Char ch;
1801 Int2 compare, idx, left, mid, numLines, right;
1802 CharPtr PNTR index;
1803 CharPtr lookfor, ptr;
1804 size_t len;
1805
1806 /* Check parameters */
1807
1808 if (StringLen (text) == 0 || StringLen (str) == 0) return 0;
1809
1810 /* Count the number of lines to be searched */
1811
1812 mid = 0;
1813 lookfor = StringSave (str);
1814 ChangeMeshSlashSymbol (lookfor);
1815 numLines = 0;
1816 ptr = text;
1817 ch = *ptr;
1818 while (ch != '\0') {
1819 if (ch == '\n')
1820 numLines++;
1821 ptr++;
1822 ch = *ptr;
1823 }
1824
1825 if (numLines <= 0) {
1826 MemFree (lookfor);
1827 return 0;
1828 }
1829
1830 /* Create an array of pointers to the lines */
1831
1832 index = MemNew (sizeof (CharPtr) * (size_t) (numLines + 3));
1833 if (index != NULL) {
1834 idx = 0;
1835 ptr = text;
1836 ch = *ptr;
1837 index [idx] = ptr;
1838 while (ch != '\0') {
1839 if (ch == '\n') {
1840 idx++;
1841 *ptr = '\0';
1842 ptr++;
1843 ch = *ptr;
1844 index [idx] = ptr;
1845 } else {
1846 ptr++;
1847 ch = *ptr;
1848 }
1849 }
1850 }
1851
1852 /* Do a binary search for the search string */
1853
1854 if (index != NULL) {
1855 left = 1;
1856 right = numLines;
1857 while (left <= right) {
1858 mid = (left + right) / 2;
1859 compare = StringICmp (lookfor, index [mid - 1]);
1860 if (compare <= 0)
1861 right = mid - 1;
1862 if (compare >= 0)
1863 left = mid + 1;
1864 }
1865
1866 if (left <= right + 1) {
1867 len = StringLen (lookfor);
1868 compare = StringNICmp (lookfor, index [mid - 1], len);
1869 if (compare > 0) {
1870 mid++;
1871 /*
1872 if (mid <= numLines) {
1873 compare = StringNICmp (lookfor, index [mid - 1], len);
1874 if (compare > 0)
1875 mid = 0;
1876 } else
1877 mid = 0;
1878 */
1879 }
1880 /*
1881 else
1882 mid = 0;
1883 */
1884 }
1885 }
1886
1887 /* Clean up and return */
1888
1889 MemFree (index);
1890 MemFree (lookfor);
1891 return mid;
1892 }
1893
1894 /*==================================================================*/
1895 /* */
1896 /* ScrollToText () - */
1897 /* */
1898 /*==================================================================*/
1899
1900 static void ScrollToText (FormInfoPtr pFormInfo,
1901 CharPtr str,
1902 Int2 page,
1903 Boolean hard,
1904 Boolean exact)
1905
1906 {
1907 Int2 compare, oldItem, oldRow, perfect, row;
1908 size_t len;
1909 Int4 numLines, startsAt;
1910 BaR sb;
1911 Char temp [256];
1912 CharPtr text;
1913
1914 /* Check parameters */
1915
1916 if (StringHasNoText (str) || page == 0) return;
1917
1918 /* Clean up the text string */
1919
1920 StringNCpy_0 (temp, str, sizeof (temp));
1921 ChangeUnderscoreToSpace (temp);
1922 ChangePeriodToSpace (temp);
1923 ChangeMeshSlashSymbol (temp);
1924
1925 /* Get the information on the current page of data */
1926
1927 text = GetDocText (pFormInfo->availDoc, page, 0, 1);
1928 GetItemParams4 (pFormInfo->availDoc, page, &startsAt, NULL, NULL, NULL, NULL);
1929 GetDocParams4 (pFormInfo->availDoc, NULL, &numLines);
1930 ChangeMeshSlashSymbol (text);
1931
1932 /* Search for the text string in the current page of data */
1933
1934 row = FindLineOfText (text, temp);
1935 MemFree (text);
1936
1937 /* If the text string is not on the page */
1938 /* then go to the top of the page. */
1939
1940 if (row < 1 || row > numLines)
1941 /*
1942 return;
1943 */
1944 row = 1;
1945
1946 /* If the term is not on the current page then */
1947 /* we have to load and search the new page. */
1948
1949 /*
1950 if (row <= 1 || row >= numLines) {
1951 LoadAvailList (pFormInfo, str);
1952 return;
1953 }
1954 */
1955
1956 /* Redisplay the page with the text string highlighted */
1957
1958 startsAt += row - 1;
1959 sb = GetSlateVScrollBar ((SlatE) pFormInfo->availDoc);
1960 CorrectBarMax (sb, numLines - 7);
1961 if (!RowIsVisible (pFormInfo->availDoc, page, row, NULL, NULL)) {
1962 ForceFormat (pFormInfo->availDoc, page); /* forces UpdateLineStarts */
1963 GetItemParams4 (pFormInfo->availDoc, page, &startsAt, NULL, NULL,
1964 NULL, NULL);
1965 GetDocParams4 (pFormInfo->availDoc, NULL, &numLines);
1966 startsAt += row - 1;
1967 sb = GetSlateVScrollBar ((SlatE) pFormInfo->availDoc);
1968 CorrectBarMax (sb, numLines - 7);
1969 if (hard)
1970 SetBarValue (sb, startsAt);
1971 else
1972 CorrectBarValue (sb, startsAt);
1973 }
1974 text = GetDocText (pFormInfo->availDoc, page, row, 1);
1975 ChangeMeshSlashSymbol (text);
1976 perfect = StringICmp (text, temp);
1977 len = StringLen (temp);
1978 compare = StringNICmp (text, temp, len);
1979 MemFree (text);
1980 if (compare == 0) {
1981 oldItem = pFormInfo->availItem;
1982 oldRow = pFormInfo->availRow;
1983 if (oldItem != page || oldRow != row) {
1984 pFormInfo->availItem = page;
1985 pFormInfo->availRow = row;
1986 InvalDocRows (pFormInfo->availDoc, oldItem, oldRow, oldRow);
1987 InvalDocRows (pFormInfo->availDoc, pFormInfo->availItem,
1988 pFormInfo->availRow, pFormInfo->availRow);
1989 }
1990 if (exact) {
1991 if (perfect == 0)
1992 pFormInfo->textChanged = FALSE;
1993 } else
1994 pFormInfo->textChanged = FALSE;
1995 } else {
1996 pFormInfo->availItem = 0;
1997 pFormInfo->availRow = 0;
1998 }
1999 }
2000
2001 /*==================================================================*/
2002 /* */
2003 /* LoadAvailList () - */
2004 /* */
2005 /*==================================================================*/
2006
2007 static Boolean LoadAvailList (FormInfoPtr pFormInfo, CharPtr str)
2008
2009 {
2010 Int4 count;
2011 Entrez2FieldInfoPtr fieldInfo;
2012 Int4 pagesize;
2013 Int2 numpages = 0;
2014 Int2 page = 0;
2015
2016 pFormInfo->availItem = 0;
2017 pFormInfo->availRow = 0;
2018 Reset (pFormInfo->availDoc);
2019 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
2020 Update ();
2021 if (str [0] == '\0') return FALSE;
2022
2023 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
2024 count = fieldInfo->term_count;
2025 if (count == 0) return FALSE;
2026
2027 pFormInfo->availNumTerms = count;
2028 pagesize = 1;
2029 while (count > pagesize) {
2030 count /= 2;
2031 pagesize *= 2;
2032 }
2033
2034 while (count < 16000 && pagesize > 128) {
2035 count *= 2;
2036 pagesize /= 2;
2037 }
2038 pFormInfo->availPageSize = pagesize;
2039 numpages = (Int2) ((pFormInfo->availNumTerms + pagesize - 1) / pagesize);
2040 pFormInfo->availNumPages = numpages;
2041
2042 BulkAppendItem (pFormInfo->availDoc, numpages, FetchFromTermList, pagesize, &availParFmt, availColFmt, systemFont);
2043 AppendText (pFormInfo->availDoc, "\n\n\n\n\n\n\n\n\n\n\n\n \n", &availParFmt, availColFmt, systemFont);
2044
2045 SetDocCache (pFormInfo->availDoc, StdPutDocCache, StdGetDocCache, StdResetDocCache);
2046
2047 page = GetTermPage (pFormInfo, str);
2048 pFormInfo->availCurrentPage = page + 1;
2049 if (page != -1) {
2050 ScrollToText (pFormInfo, str, pFormInfo->availCurrentPage, FALSE, FALSE);
2051 }
2052
2053 InvalDocument (pFormInfo->availDoc);
2054 Update ();
2055 AdjustDocScroll (pFormInfo->availDoc);
2056
2057 return TRUE;
2058 }
2059
2060 /*==================================================================*/
2061 /* */
2062 /* ProcessSelectionTerm () - */
2063 /* */
2064 /*==================================================================*/
2065
2066 static void ProcessSelectionTerm (FormInfoPtr pFormInfo, CharPtr str)
2067
2068 {
2069 Int4 iTermCount;
2070 Char termText [E2_STR_BUFF_SIZE];
2071 CharPtr text;
2072
2073 /* If a new term has been typed into the */
2074 /* term text entry box, then do a lookup */
2075 /* of that term. */
2076
2077 if (pFormInfo->textChanged) {
2078 LoadAvailList (pFormInfo, str);
2079 pFormInfo->textChanged = FALSE;
2080 pFormInfo->okayToAccept = FALSE;
2081 }
2082
2083 /* Process the highlighted term from */
2084 /* the term selection box */
2085
2086 else if (pFormInfo->okayToAccept &&
2087 pFormInfo->availItem > 0 &&
2088 pFormInfo->availRow > 0) {
2089
2090 text = GetDocText (pFormInfo->availDoc, pFormInfo->availItem,
2091 pFormInfo->availRow, E2_TERM_COL);
2092 if (NULL == text)
2093 return;
2094
2095 GetTitle (pFormInfo->termText, termText, E2_STR_BUFF_SIZE);
2096
2097 /* If the higlighted term is the same as */
2098 /* in the text entry box, then add the */
2099 /* term to the Query Refinement list. */
2100
2101 if (StringICmp (termText, text) == 0) {
2102 if (StringICmp (str, text) == 0) {
2103 MemFree (text);
2104 text = GetDocText (pFormInfo->availDoc, pFormInfo->availItem,
2105 pFormInfo->availRow, E2_COUNT_COL);
2106 TrimSpacesAroundString (text);
2107 StrToLong (text, &iTermCount);
2108 MemFree (text);
2109 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb,
2110 pFormInfo->currField, str, STATE_ON,
2111 iTermCount);
2112 Select (pFormInfo->termText);
2113 pFormInfo->okayToAccept = FALSE;
2114 }
2115 }
2116
2117 /* Otherwise, just move the higlighted */
2118 /* term to the text box. */
2119
2120 else {
2121 TrimSpacesAroundString (text);
2122 SafeSetTitle (pFormInfo->termText, text);
2123 Select (pFormInfo->termText);
2124 Update ();
2125 StringNCpy_0 (str, text, E2_STR_BUFF_SIZE);
2126 }
2127
2128 }
2129 }
2130
2131 /*==================================================================*/
2132 /* */
2133 /* ProcessTaxonomyTerm () - */
2134 /* */
2135 /*==================================================================*/
2136
2137 static void ProcessTaxonomyTerm (FormInfoPtr pFormInfo, CharPtr str)
2138
2139 {
2140 Int4 iTermCount;
2141 CharPtr text;
2142
2143 /*----------------------*/
2144 /* Get the term's count */
2145 /*----------------------*/
2146
2147 text = GetDocText (pFormInfo->availDoc, pFormInfo->availItem, pFormInfo->availRow, E2_COUNT_COL);
2148 TrimSpacesAroundString (text);
2149 StrToLong (text, &iTermCount);
2150 MemFree (text);
2151
2152 /*-----------------------------------*/
2153 /* Add the term to the current query */
2154 /*-----------------------------------*/
2155
2156 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb, pFormInfo->currField, str, STATE_ON, iTermCount);
2157 Select (pFormInfo->termText);
2158 pFormInfo->okayToAccept = FALSE;
2159 }
2160
2161 /*===================================================================*/
2162 /* */
2163 /* ReadAFew () - Fetches the count for a given term and for several */
2164 /* following terms and displays them in the term list */
2165 /* panel. */
2166 /* */
2167 /*===================================================================*/
2168
2169 static Boolean ReadAFew (FormInfoPtr pFormInfo, CharPtr str, CharPtr actual, size_t maxsize, Int4Ptr count)
2170
2171 {
2172 Char displayStr [256];
2173 Boolean found;
2174 Entrez2TermListPtr e2TermListPtr;
2175 Entrez2FieldInfoPtr fieldInfo;
2176 CharPtr dbName;
2177 CharPtr fieldName;
2178 Int2 row;
2179 Entrez2TermPtr termPtr;
2180
2181 /*------------------------------*/
2182 /* Get the names of the current */
2183 /* db and the current field. */
2184 /*------------------------------*/
2185
2186 found = FALSE;
2187 dbName = DBGetNameFromID (pFormInfo->currDb);
2188 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
2189 fieldName = fieldInfo->field_name;
2190 if (StringHasNoText (dbName) || StringHasNoText (fieldName)) return FALSE;
2191
2192 /*----------------------------------------*/
2193 /* Fetch a count for the requested string */
2194 /* and for several strings after it. */
2195 /*----------------------------------------*/
2196
2197 e2TermListPtr = Query_FetchSeveralCounts (dbName, fieldName, str, AVAIL_WINDOW_ROWS);
2198
2199 if (e2TermListPtr == NULL) return FALSE;
2200
2201 /*-------------------------------*/
2202 /* Did we find the desired term? */
2203 /*-------------------------------*/
2204
2205 if (StringICmp (e2TermListPtr->list->term, str) == 0) {
2206 found = TRUE;
2207 } else {
2208 found = FALSE;
2209 StringCpy (actual, e2TermListPtr->list->term);
2210 }
2211
2212 /*----------------------------*/
2213 /* Send the count back to the */
2214 /* calling function. */
2215 /*----------------------------*/
2216
2217 *count = e2TermListPtr->list->count;
2218
2219 /*-------------------------------------*/
2220 /* Display the term and it's neighbors */
2221 /* in the term list window. */
2222 /*-------------------------------------*/
2223
2224 termPtr = e2TermListPtr->list;
2225
2226 for (row = 1, termPtr = e2TermListPtr->list; row <= *count, termPtr != NULL; row++, termPtr = termPtr->next) {
2227 sprintf (displayStr, "%s\t%ld\t%d\n", termPtr->term, (long) (termPtr->count), (int) (termPtr->is_leaf_node ? 1 : 0));
2228 AppendText (pFormInfo->availDoc, displayStr, &availParFmt, availColFmt, systemFont);
2229 }
2230
2231 if (found) {
2232 pFormInfo->availItem = 1;
2233 pFormInfo->availRow = 1;
2234 }
2235 InvalDocument (pFormInfo->availDoc);
2236
2237 /*---------------------*/
2238 /* Return successfully */
2239 /*---------------------*/
2240
2241 return found;
2242 }
2243
2244 /*==================================================================*/
2245 /* */
2246 /* ProcessMultipleTerms () - */
2247 /* */
2248 /*==================================================================*/
2249
2250 static void ProcessMultipleTerms (FormInfoPtr pFormInfo, CharPtr strs)
2251
2252 {
2253 Char actual [256];
2254 Char ch;
2255 Int4 count = 0;
2256 Boolean found;
2257 Int2 i;
2258 Int2 j;
2259 Int2 k;
2260 Char str [256];
2261
2262 i = 0;
2263 while (StringLen (strs + i) > 0) {
2264
2265 /*--------------------------------*/
2266 /* Parse a term out of the string */
2267 /*--------------------------------*/
2268
2269 StringNCpy_0 (str, strs + i, sizeof (str));
2270 k = 0;
2271 ch = str [k];
2272 while (ch == ' ') {
2273 k++;
2274 ch = str [k];
2275 }
2276 j = 0;
2277 if (ch == '"') {
2278 k++;
2279 ch = str [j + k];
2280 while (ch != '\0' && ch != '"') {
2281 j++;
2282 ch = str [j + k];
2283 }
2284 if (ch == '"') {
2285 str [j + k] = '\0';
2286 i += j + k + 1;
2287 } else
2288 i += j + k;
2289 } else {
2290 while (ch != '\0' && ch != ' ') {
2291 j++;
2292 ch = str [j + k];
2293 }
2294 if (ch == ' ') {
2295 str [j + k] = '\0';
2296 i += j + k + 1;
2297 } else
2298 i += j + k;
2299 }
2300
2301 /*-----------------------------------*/
2302 /* If we successfully parsed a term, */
2303 /* look it up and then add it to the */
2304 /* boolean query if found. */
2305 /*-----------------------------------*/
2306
2307 if (StringLen (str + k) > 0) {
2308 pFormInfo->availItem = 0;
2309 pFormInfo->availRow = 0;
2310 Reset (pFormInfo->availDoc);
2311 actual [0] = '\0';
2312 found = ReadAFew (pFormInfo, str + k, actual, sizeof (actual), &count);
2313 Update ();
2314 if (found) {
2315 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb, pFormInfo->currField, str + k, STATE_ON, count);
2316 } else {
2317 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb, pFormInfo->currField, actual, STATE_OFF, count);
2318 }
2319 }
2320 }
2321
2322 /*-------------------------------------*/
2323 /* Clear out the term selection window */
2324 /* and the term entry fields. */
2325 /*-------------------------------------*/
2326
2327 pFormInfo->availItem = 0;
2328 pFormInfo->availRow = 0;
2329 Reset (pFormInfo->availDoc);
2330
2331 InvalDocument (pFormInfo->availDoc);
2332 SafeSetTitle (pFormInfo->termText, "");
2333 SafeSetTitle (pFormInfo->fromText, "");
2334 SafeSetTitle (pFormInfo->toText, "");
2335 SafeDisable (pFormInfo->acceptButton);
2336 if (Visible (pFormInfo->termText)) {
2337 Select (pFormInfo->termText);
2338 }
2339 }
2340
2341 /*==================================================================*/
2342 /* */
2343 /* RecalculateChosen () - */
2344 /* */
2345 /*==================================================================*/
2346
2347 static void RecalculateChosen (FormInfoPtr pFormInfo)
2348
2349 {
2350 Int4 count;
2351 Char tmp [32];
2352
2353 /*-------------------------------*/
2354 /* Get a count of documents that */
2355 /* satisfy the current query. */
2356 /*-------------------------------*/
2357
2358 count = Query_FetchCount (pFormInfo->form);
2359
2360 /*-----------------------------------*/
2361 /* Update the retrieve message count */
2362 /*-----------------------------------*/
2363
2364 if (count < 1)
2365 sprintf (tmp, "Retrieve 0 Documents");
2366 else if (count > 1)
2367 sprintf (tmp, "Retrieve %ld Documents", (long) count);
2368 else
2369 sprintf (tmp, "Retrieve %ld Document", (long) count);
2370
2371 SafeSetTitle (pFormInfo->retrieveButton, tmp);
2372 SafeSetTitle (pFormInfo->advRetrieveButton, tmp);
2373
2374 if (count < 1 || count > 32000) {
2375 SafeDisable (pFormInfo->retrieveButton);
2376 SafeDisable (pFormInfo->advRetrieveButton);
2377 } else {
2378 SafeEnable (pFormInfo->retrieveButton);
2379 SafeEnable (pFormInfo->advRetrieveButton);
2380 }
2381 }
2382
2383 /*==================================================================*/
2384 /* */
2385 /* Query_TruncateCount () - */
2386 /* */
2387 /*==================================================================*/
2388
2389 static Int4 Query_TruncateCount (FormInfoPtr pFormInfo, CharPtr str)
2390
2391 {
2392 CharPtr dbName;
2393 Boolean doNotExplode;
2394 Boolean doNotTranslate;
2395 Int4 count;
2396 Entrez2RequestPtr e2RequestPtr;
2397 Entrez2ReplyPtr e2ReplyPtr;
2398 Entrez2BooleanReplyPtr e2BooleanPtr;
2399 Entrez2FieldInfoPtr fieldInfo;
2400
2401 if (pFormInfo == NULL || StringHasNoText (str)) return 0;
2402
2403 /*--------------------------------*/
2404 /* Get the name of the current DB */
2405 /*--------------------------------*/
2406
2407 dbName = DBGetNameFromID (pFormInfo->currDb);
2408 if (StringHasNoText (dbName)) return 0;
2409
2410 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
2411 if (fieldInfo == NULL) return 0;
2412
2413 /*---------------------------------*/
2414 /* Create an empty Boolean request */
2415 /*---------------------------------*/
2416
2417 e2RequestPtr = EntrezCreateBooleanRequest (FALSE, FALSE, dbName, NULL, 0, 0, NULL, 0, 0);
2418 if (e2RequestPtr == NULL) return 0;
2419
2420 /*--------------------------------------------------*/
2421 /* Send truncated term count request to the server. */
2422 /*--------------------------------------------------*/
2423
2424 doNotTranslate = FALSE;
2425 doNotExplode = !GetStatus (pFormInfo->explodeItem);
2426 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, fieldInfo->field_name,
2427 str, NULL, 0, 0, NULL, NULL,
2428 doNotExplode, doNotTranslate);
2429
2430 if (ShowASN () == TRUE)
2431 DisplayEntrezRequest (e2RequestPtr);
2432
2433 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
2434
2435 if (ShowASN () == TRUE)
2436 DisplayEntrezReply (e2ReplyPtr);
2437
2438 if (e2ReplyPtr == NULL) return 0;
2439
2440 /*----------------------------------*/
2441 /* Parse the count out of the reply */
2442 /*----------------------------------*/
2443
2444 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
2445 count = e2BooleanPtr->count;
2446
2447 /*----------------------------------*/
2448 /* Clean up and return successfully */
2449 /*----------------------------------*/
2450
2451 Entrez2BooleanReplyFree (e2BooleanPtr);
2452 Entrez2RequestFree (e2RequestPtr);
2453
2454 return count;
2455 }
2456
2457 /*==================================================================*/
2458 /* */
2459 /* Query_FetchRangeCount () - */
2460 /* */
2461 /*==================================================================*/
2462
2463 static Int4 Query_FetchRangeCount (FormInfoPtr pFormInfo, CharPtr str)
2464
2465 {
2466 CharPtr dbName;
2467 Int4 count;
2468 Entrez2RequestPtr e2RequestPtr;
2469 Entrez2ReplyPtr e2ReplyPtr;
2470 Entrez2BooleanReplyPtr e2BooleanPtr;
2471 Entrez2FieldInfoPtr fieldInfo;
2472 Boolean doNotTranslate;
2473
2474 if (pFormInfo == NULL || StringHasNoText (str)) return 0;
2475
2476 /*--------------------------------*/
2477 /* Get the name of the current DB */
2478 /*--------------------------------*/
2479
2480 dbName = DBGetNameFromID (pFormInfo->currDb);
2481 if (StringHasNoText (dbName)) return 0;
2482
2483 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
2484 if (fieldInfo == NULL) return 0;
2485
2486 /*---------------------------------*/
2487 /* Create an empty Boolean request */
2488 /*---------------------------------*/
2489
2490 e2RequestPtr = EntrezCreateBooleanRequest (FALSE, FALSE, dbName, NULL, 0, 0, NULL, 0, 0);
2491 if (e2RequestPtr == NULL) return 0;
2492
2493 /*--------------------------------------------------*/
2494 /* Send truncated term count request to the server. */
2495 /*--------------------------------------------------*/
2496
2497 doNotTranslate = FALSE;
2498 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, fieldInfo->field_name, str, NULL, 0, 0, NULL, NULL, FALSE, doNotTranslate);
2499
2500 if (ShowASN () == TRUE)
2501 DisplayEntrezRequest (e2RequestPtr);
2502
2503 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
2504
2505 if (ShowASN () == TRUE)
2506 DisplayEntrezReply (e2ReplyPtr);
2507
2508 if (e2ReplyPtr == NULL) return 0;
2509
2510 /*----------------------------------*/
2511 /* Parse the count out of the reply */
2512 /*----------------------------------*/
2513
2514 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
2515 if (e2BooleanPtr != NULL)
2516 count = e2BooleanPtr->count;
2517 else {
2518 Entrez2RequestFree (e2RequestPtr);
2519 return 0;
2520 }
2521
2522
2523 /*----------------------------------*/
2524 /* Clean up and return successfully */
2525 /*----------------------------------*/
2526
2527 Entrez2BooleanReplyFree (e2BooleanPtr);
2528 Entrez2RequestFree (e2RequestPtr);
2529
2530 return count;
2531 }
2532
2533 /*===================================================================*/
2534 /* */
2535 /* ProcessRangeTerms () */
2536 /* */
2537 /*===================================================================*/
2538
2539 static void ProcessRangeTerms (FormInfoPtr pFormInfo)
2540 {
2541 Char fromStr [E2_STR_BUFF_SIZE];
2542 Char toStr [E2_STR_BUFF_SIZE];
2543 Char rangeStr [2 * E2_STR_BUFF_SIZE + 1];
2544 StateDataPtr sdp;
2545 Int4 count;
2546 CharPtr text;
2547
2548 /* If a new term has been typed into the */
2549 /* 'To' text box, then do a lookup of */
2550 /* that term. */
2551
2552 if (pFormInfo->isToTextChanged) {
2553 GetTitle (pFormInfo->toText, toStr, E2_STR_BUFF_SIZE);
2554 pFormInfo->isValidTo = LoadAvailList (pFormInfo, toStr);
2555 pFormInfo->isToTextChanged = FALSE;
2556 }
2557 /* If we have valid 'From' and 'To' terms then */
2558 /* create a range term in the query window. */
2559
2560 else if ((pFormInfo->isValidFrom) && (pFormInfo->isValidTo)) {
2561
2562 /* Get the 'from' and 'to' strings */
2563
2564 GetTitle (pFormInfo->toText, toStr, E2_STR_BUFF_SIZE);
2565 GetTitle (pFormInfo->fromText, fromStr, E2_STR_BUFF_SIZE);
2566 sprintf(rangeStr, "%s:%s", fromStr, toStr);
2567
2568 /* Get a count for the range */
2569
2570 count = Query_FetchRangeCount (pFormInfo, rangeStr);
2571
2572 /* Add a term to the linked list */
2573
2574 sdp = CreateTerm (pFormInfo->form, pFormInfo->currDb,
2575 pFormInfo->currField, rangeStr, STATE_ON, count,
2576 FALSE);
2577 if (NULL == sdp)
2578 return;
2579
2580 /* Display the range as one term */
2581
2582 DisplayTerm (pFormInfo, rangeStr, sdp->field, sdp->count);
2583
2584 Select (pFormInfo->fromText);
2585 Reset (pFormInfo->availDoc);
2586 pFormInfo->okayToAccept = FALSE;
2587 }
2588
2589 /* If a new term has been typed into the */
2590 /* 'From' text box, then do a lookup of */
2591 /* that term. */
2592
2593 else if (pFormInfo->isFromTextChanged) {
2594 GetTitle (pFormInfo->fromText, fromStr, E2_STR_BUFF_SIZE);
2595 pFormInfo->isValidFrom = LoadAvailList (pFormInfo, fromStr);
2596 pFormInfo->isFromTextChanged = FALSE;
2597 }
2598
2599 else if (pFormInfo->okayToAccept &&
2600 pFormInfo->availItem > 0 &&
2601 pFormInfo->availRow > 0) {
2602 text = GetDocText (pFormInfo->availDoc, pFormInfo->availItem,
2603 pFormInfo->availRow, E2_TERM_COL);
2604 if (text != NULL) {
2605 TrimSpacesAroundString (text);
2606 if (pFormInfo->currRangeField == E2_RANGE_FROM) {
2607 SafeSetTitle (pFormInfo->fromText, text);
2608 Select (pFormInfo->fromText);
2609 pFormInfo->isValidFrom = TRUE;
2610 pFormInfo->isFromTextChanged = FALSE;
2611 }
2612 else {
2613 SafeSetTitle (pFormInfo->toText, text);
2614 Select (pFormInfo->toText);
2615 pFormInfo->isValidTo = TRUE;
2616 pFormInfo->isToTextChanged = FALSE;
2617 }
2618 Update ();
2619 }
2620 MemFree (text);
2621 }
2622
2623 /* Return successfully */
2624
2625 return;
2626 }
2627
2628 /*===================================================================*/
2629 /* */
2630 /* Accept_Callback () - Called when the accept button is pressed, */
2631 /* if fetches a term list or adds term to query */
2632 /* list. */
2633 /* */
2634 /*===================================================================*/
2635
2636 static void Accept_Callback (ButtoN b)
2637
2638 {
2639 Int4 count;
2640 FormInfoPtr pFormInfo;
2641 StateDataPtr sdp;
2642 Char str [E2_STR_BUFF_SIZE];
2643
2644 pFormInfo = (FormInfoPtr) GetObjectExtra (b);
2645
2646 str [0] = '\0';
2647 if (pFormInfo->currMode == RANGE_MODE)
2648 GetTitle (CurrentText (), str, E2_STR_BUFF_SIZE);
2649 else
2650 GetTitle (pFormInfo->termText, str, E2_STR_BUFF_SIZE);
2651 if (str [0] == '\0') return;
2652
2653 WatchCursor ();
2654 switch (pFormInfo->currMode) {
2655 case TRANSLATE_MODE:
2656 Query_TranslateAndAddBoolTerm (pFormInfo->form, pFormInfo->currDb,
2657 pFormInfo->currField, str, STATE_ON, 0);
2658 SafeSetTitle (pFormInfo->termText, "");
2659 if (Visible (pFormInfo->termText))
2660 Select (pFormInfo->termText);
2661 pFormInfo->availItem = 0;
2662 pFormInfo->availRow = 0;
2663 Reset (pFormInfo->availDoc);
2664 break;
2665 case SELECTION_MODE:
2666 ProcessSelectionTerm (pFormInfo, str);
2667 /*
2668 pFormInfo->availCurrentPage = 0;
2669 */
2670 break;
2671 case AUTOMATIC_MODE:
2672 ProcessMultipleTerms (pFormInfo, str);
2673 break;
2674 case WILD_CARD_MODE:
2675 StringCat (str, "*");
2676 count = Query_TruncateCount (pFormInfo, str);
2677 sdp = CreateTerm (pFormInfo->form, pFormInfo->currDb,
2678 pFormInfo->currField, str, STATE_ON, count, FALSE);
2679 if (sdp != NULL) {
2680 DisplayTerm (pFormInfo, str, sdp->field, count);
2681 }
2682 SafeSetTitle (pFormInfo->termText, "");
2683 if (Visible (pFormInfo->termText))
2684 Select (pFormInfo->termText);
2685 pFormInfo->availItem = 0;
2686 pFormInfo->availRow = 0;
2687 Reset (pFormInfo->availDoc);
2688 break;
2689 case MESH_TREE_MODE:
2690 ProcessMeshTerm (pFormInfo, str);
2691 break;
2692 case TAXONOMY_MODE:
2693 ProcessTaxonomyTerm (pFormInfo, str);
2694 break;
2695 case RANGE_MODE:
2696 ProcessRangeTerms (pFormInfo);
2697 break;
2698 case LOOKUP_ACCN_MODE:
2699 case LOOKUP_UID_MODE:
2700 case VIEW_ACCN_MODE:
2701 case VIEW_UID_MODE:
2702 ProcessDirectLookup (pFormInfo, str);
2703 ArrowCursor ();
2704 Update ();
2705 return;
2706 default:
2707 break;
2708 }
2709 Update ();
2710
2711 RecalculateChosen (pFormInfo);
2712
2713 ArrowCursor ();
2714 Update ();
2715 }
2716
2717 /*===================================================================*/
2718 /* */
2719 /* EvaluateRetrieve_Callback () - This is the callback for the */
2720 /* Evaluate/Retrieve button in */
2721 /* advanced query mode. */
2722 /* */
2723 /*===================================================================*/
2724
2725 static void EvaluateRetrieve_Callback (ButtoN evaluateRetrieveButton)
2726
2727 {
2728 FormInfoPtr pFormInfo;
2729
2730 pFormInfo = (FormInfoPtr) GetObjectExtra (evaluateRetrieveButton);
2731
2732 if (pFormInfo->advQueryState == ADV_QUERY_EVALUATE_STATE) {
2733 WatchCursor ();
2734 Update ();
2735 RecalculateChosen (pFormInfo);
2736 pFormInfo->advQueryState = ADV_QUERY_RETRIEVE_STATE;
2737 ArrowCursor ();
2738 } else if (pFormInfo->advQueryState == ADV_QUERY_RETRIEVE_STATE) {
2739 pFormInfo->retrieveDocsProc (evaluateRetrieveButton);
2740 pFormInfo->advQueryState = ADV_QUERY_INVALID_STATE;
2741 }
2742 }
2743
2744 /*===================================================================*/
2745 /* */
2746 /* DatabaseView_Callback () and FieldView_Callback () - */
2747 /* Callback functions for items in Help menu. */
2748 /* */
2749 /*===================================================================*/
2750
2751 static void DatabaseView_Callback (IteM i)
2752
2753 {
2754 Entrez2DbInfoPtr e2db;
2755 Entrez2InfoPtr e2ip;
2756 FILE *fp;
2757 Int2 len;
2758 Int2 max_menu = 0;
2759 Int2 max_name = 0;
2760 Char path [PATH_MAX];
2761
2762 e2ip = Query_GetInfo ();
2763 if (e2ip == NULL) return;
2764 TmpNam (path);
2765 fp = FileOpen (path, "w");
2766 if (fp == NULL) return;
2767 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
2768 len = (Int2) StringLen (e2db->db_name);
2769 max_name = MAX (len, max_name);
2770 len = (Int2) StringLen (e2db->db_menu);
2771 max_menu = MAX (len, max_menu);
2772 }
2773 max_name += 2;
2774 max_menu += 2;
2775 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
2776 len = (Int2) StringLen (e2db->db_name);
2777 max_name = MAX (len, max_name);
2778 len = (Int2) StringLen (e2db->db_menu);
2779 max_menu = MAX (len, max_menu);
2780 }
2781 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
2782 len = (Int2) StringLen (e2db->db_name);
2783 fprintf (fp, "%s", e2db->db_name);
2784 while (len < max_name) {
2785 fprintf (fp, " ");
2786 len++;
2787 }
2788 len = (Int2) StringLen (e2db->db_menu);
2789 fprintf (fp, "%s", e2db->db_menu);
2790 while (len < max_menu) {
2791 fprintf (fp, " ");
2792 len++;
2793 }
2794 fprintf (fp, "%s", e2db->db_descr);
2795 fprintf (fp, "\n");
2796 }
2797 FileClose (fp);
2798 LaunchGeneralTextViewer (path, "Database Summary");
2799 FileRemove (path);
2800 }
2801
2802 static void FieldView_Callback (IteM i)
2803
2804 {
2805 Entrez2InfoPtr e2ip;
2806 EnumFieldAssocPtr fieldAlist;
2807 Entrez2FieldInfoPtr fieldInfo;
2808 FILE *fp;
2809 Int2 j;
2810 Int2 len;
2811 Int2 max_menu = 0;
2812 Int2 max_name = 0;
2813 Char path [PATH_MAX];
2814
2815 e2ip = Query_GetInfo ();
2816 if (e2ip == NULL) return;
2817 fieldAlist = CreateAllFieldsAlist (e2ip);
2818 if (fieldAlist == NULL) return;
2819 TmpNam (path);
2820 fp = FileOpen (path, "w");
2821 if (fp == NULL) return;
2822 for (j = 0; fieldAlist [j].name != NULL; j++) {
2823 fieldInfo = FieldGetInfoFromName (fieldAlist [j].name);
2824 len = (Int2) StringLen (fieldInfo->field_name);
2825 max_name = MAX (len, max_name);
2826 len = (Int2) StringLen (fieldInfo->field_menu);
2827 max_menu = MAX (len, max_menu);
2828 }
2829 max_name += 2;
2830 max_menu += 2;
2831 for (j = 0; fieldAlist [j].name != NULL; j++) {
2832 fieldInfo = FieldGetInfoFromName (fieldAlist [j].name);
2833 len = (Int2) StringLen (fieldInfo->field_name);
2834 fprintf (fp, "%s", fieldInfo->field_name);
2835 while (len < max_name) {
2836 fprintf (fp, " ");
2837 len++;
2838 }
2839 len = (Int2) StringLen (fieldInfo->field_menu);
2840 fprintf (fp, "%s", fieldInfo->field_menu);
2841 while (len < max_menu) {
2842 fprintf (fp, " ");
2843 len++;
2844 }
2845 fprintf (fp, "%s", fieldInfo->field_descr);
2846 fprintf (fp, "\n");
2847 }
2848 FileClose (fp);
2849 LaunchGeneralTextViewer (path, "Field Summary");
2850 FileRemove (path);
2851 FreeEnumFieldAlist (fieldAlist);
2852 }
2853
2854 static CharPtr modeSummary [] = {
2855 "Automatic Terms are processed through PubMed query engine",
2856 "Lookup Accession looked up directly into Document window",
2857 "MeSH Tree MeSH hierarchy above current level displayed in popup",
2858 "Multiple Terms extracted and processed one at a time",
2859 "Range From and To values entered as a composite term",
2860 "Selection Available terms are displayed in Term Selection box",
2861 "Taxonomy Organism hierarchy above current level displayed in popup",
2862 "View Accession looked up directly into Viewer window",
2863 "Wild Card Term appended with asterisk and processed",
2864 NULL
2865 };
2866
2867 static void ModeView_Callback (IteM i)
2868
2869 {
2870 FILE *fp;
2871 Int2 j;
2872 Char path [PATH_MAX];
2873
2874 TmpNam (path);
2875 fp = FileOpen (path, "w");
2876 if (fp == NULL) return;
2877 for (j = 0; modeSummary [j] != NULL; j++) {
2878 fprintf (fp, "%s\n", modeSummary [j]);
2879 }
2880 FileClose (fp);
2881 LaunchGeneralTextViewer (path, "Mode Summary");
2882 FileRemove (path);
2883 }
2884
2885 /*==================================================================*/
2886 /* */
2887 /* AddPopupItem () - Add an item to a popup list. This is used to */
2888 /* create the lineage popup list in taxonomy */
2889 /* mode. */
2890 /* */
2891 /*==================================================================*/
2892
2893 static void AddPopupItem (PopuP p, CharPtr str, Int2 maxwid)
2894
2895 {
2896 Char ch;
2897 Int2 hbounds;
2898 Int2 i;
2899 CharPtr ptr;
2900 Char title [256];
2901 Int2 wid;
2902
2903 if (p != NULL && str != NULL) {
2904 StringNCpy_0 (title, str, sizeof (title));
2905 i = StringLen (title);
2906 title [i] = '\0';
2907 ptr = title;
2908 ch = *ptr;
2909 while (ch != '\0') {
2910 if (ch == '/') {
2911 *ptr = '-';
2912 }
2913 ptr++;
2914 ch = *ptr;
2915 }
2916 #ifdef WIN_MAC
2917 hbounds = 13;
2918 #endif
2919 #ifdef WIN_MSWIN
2920 hbounds = 13;
2921 #endif
2922 #ifdef WIN_MOTIF
2923 hbounds = 24;
2924 #endif
2925 maxwid -= StringWidth ("...") + hbounds * 2 + StringWidth (" ");
2926 wid = 0;
2927 i = 0;
2928 ch = title [i];
2929 while (ch != '\0' && wid <= maxwid) {
2930 wid += CharWidth (ch);
2931 i++;
2932 ch = title [i];
2933 }
2934 title [i] = '\0';
2935 if (ch != '\0' && i <= (Int2) StringLen (str)) {
2936 StringCat (title, "...");
2937 }
2938 PopupItem (p, title);
2939 }
2940 }
2941
2942 /*==================================================================*/
2943 /* */
2944 /* AvailGetColWidth () - Returns the pixel width of the given */
2945 /* column. */
2946 /* */
2947 /*==================================================================*/
2948
2949 static Int2 AvailGetColWidth (Int2 columnNum)
2950
2951 {
2952 return availColFmt [columnNum].pixWidth;
2953 }
2954
2955 /*==================================================================*/
2956 /* */
2957 /* RepopulateTaxonomy () - Given a term and a database, will */
2958 /* look up the term in the taxonomy tree */
2959 /* and populate the Term Selection window */
2960 /* with the term's 'children' in the tree. */
2961 /* */
2962 /*==================================================================*/
2963
2964 static Boolean RepopulateTaxonomy (FormInfoPtr pFormInfo, CharPtr taxterm)
2965
2966 {
2967 CharPtr aLineage [MAX_TAXONOMY_TREE_DEPTH];
2968 Int2 delta;
2969 CharPtr dbName;
2970 CharPtr fieldName;
2971 Int2 i;
2972 Int2 maxwidth;
2973 RecT r;
2974 RecT s;
2975 Char str [256];
2976 Int4 taxId;
2977 Int2 wid;
2978 Entrez2TermPtr childPtr;
2979 Entrez2RequestPtr e2Request;
2980 Entrez2ReplyPtr e2Reply;
2981 Entrez2HierNodePtr e2TermNode;
2982 Entrez2TermPtr currentLineage = NULL;
2983 Entrez2FieldInfoPtr fieldInfo;
2984
2985 /*--------------------------*/
2986 /* Build an Entrez2 request */
2987 /*--------------------------*/
2988
2989 taxId = 0;
2990 dbName = DBGetNameFromID (pFormInfo->currDb);
2991 fieldInfo = FieldGetInfo (pFormInfo->currDb, pFormInfo->currField);
2992 fieldName = fieldInfo->field_name;
2993 if (StringHasNoText (dbName) || StringHasNoText (fieldName)) return FALSE;
2994
2995 e2Request = EntrezCreateGetTermHierarchyRequest (dbName, fieldName, taxterm, taxId);
2996
2997 /*----------------------------------*/
2998 /* Send off the request and extract */
2999 /* the resulting reply. */
3000 /*----------------------------------*/
3001
3002 if (ShowASN () == TRUE)
3003 DisplayEntrezRequest (e2Request);
3004
3005 e2Reply = SpecialEntrezSynchronousQuery (e2Request);
3006
3007 if (ShowASN () == TRUE)
3008 DisplayEntrezReply (e2Reply);
3009
3010 if (e2Reply == NULL) {
3011 Show (pFormInfo->taxLineagePopup);
3012 Update ();
3013 return FALSE;
3014 }
3015
3016 e2TermNode = EntrezExtractHierNodeReply (e2Reply);
3017 if (e2TermNode == NULL) {
3018 Show (pFormInfo->taxLineagePopup);
3019 Update ();
3020 return FALSE;
3021 }
3022
3023 Entrez2RequestFree (e2Request);
3024
3025 /*-------------------------*/
3026 /* Clear any old terms out */
3027 /* of the Avail window. */
3028 /*-------------------------*/
3029
3030 SafeSetTitle (pFormInfo->termText, taxterm);
3031 Hide (pFormInfo->taxLineagePopup);
3032 Reset (pFormInfo->taxLineagePopup);
3033 pFormInfo->taxStrings = ValNodeFreeData (pFormInfo->taxStrings);
3034 pFormInfo->availItem = 0;
3035 pFormInfo->availRow = 0;
3036 Reset (pFormInfo->availDoc);
3037 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
3038 Update ();
3039 maxwidth = AvailGetColWidth (0);
3040
3041 /*------------------------------------------------*/
3042 /* Create a selection list of a term's "lineage" */
3043 /* NOTE: The lineage is provided in the */
3044 /* reverse order from how we want to */
3045 /* add it to the list box, so they must */
3046 /* be put into a random-access structure */
3047 /* and then reverse added. */
3048 /*------------------------------------------------*/
3049
3050 for (i = 0; i < e2TermNode->lineage_count; i++) {
3051 if (i == 0)
3052 currentLineage = e2TermNode->lineage;
3053 else
3054 currentLineage = currentLineage->next;
3055
3056 if (currentLineage == NULL)
3057 break;
3058
3059 aLineage [i] = currentLineage->term;
3060 }
3061
3062 for (i = e2TermNode->lineage_count - 1; i >= 0; i--) {
3063 AddPopupItem (pFormInfo->taxLineagePopup, aLineage [i], maxwidth);
3064 ValNodeCopyStr (&(pFormInfo->taxStrings), 0, aLineage [i]);
3065 }
3066
3067 /*----------------------------------------------*/
3068 /* Adjust the size of the Pull Down list box to */
3069 /* accomodate the lineage list just created. */
3070 /*----------------------------------------------*/
3071
3072 SetValue (pFormInfo->taxLineagePopup, e2TermNode->lineage_count);
3073 ObjectRect (pFormInfo->taxLineagePopup, &r);
3074 ObjectRect (pFormInfo->availDoc, &s);
3075 InsetRect (&s, 4, 4);
3076 wid = r.right - r.left;
3077 delta = (maxwidth - wid) / 2;
3078 r.left = s.left + delta;
3079 r.right = r.left + wid;
3080 SetPosition (pFormInfo->taxLineagePopup, &r);
3081
3082 /*---------------------------------*/
3083 /* Add the children of the current */
3084 /* term to the Selection Box. */
3085 /*---------------------------------*/
3086
3087 childPtr = e2TermNode->children;
3088
3089 for (i = 0; i < e2TermNode->child_count; i++) {
3090 sprintf (str, "%s\t%ld\t%d\n", childPtr->term, (long) (childPtr->count), (int) (childPtr->is_leaf_node ? 1 : 0));
3091 AppendText (pFormInfo->availDoc, str, &availParFmt, availColFmt, systemFont);
3092 childPtr = childPtr->next;
3093 }
3094
3095 for (i = e2TermNode->child_count; i < 7; i++)
3096 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt, systemFont);
3097
3098 /*-------------------------*/
3099 /* Redraw the avail window */
3100 /* with the new terms. */
3101 /*-------------------------*/
3102
3103 InvalDocument (pFormInfo->availDoc);
3104 Show (pFormInfo->taxLineagePopup);
3105 Update ();
3106 AdjustDocScroll (pFormInfo->availDoc);
3107
3108 return TRUE;
3109 }
3110
3111 /*==================================================================*/
3112 /* */
3113 /* RepopulateTaxonomyRoot () - */
3114 /* */
3115 /*==================================================================*/
3116
3117 static void RepopulateTaxonomyRoot (FormInfoPtr pFormInfo)
3118
3119 {
3120 CharPtr dbName;
3121
3122 dbName = DBGetNameFromID (pFormInfo->currDb);
3123
3124 if (StringICmp (dbName, "PubMed") == 0) {
3125 RepopulateTaxonomy (pFormInfo, "All MeSH Categories");
3126 } else {
3127 RepopulateTaxonomy (pFormInfo, "root");
3128 }
3129 }
3130
3131 /*===================================================================*/
3132 /* */
3133 /* ChangeTaxParents_Callback () - Called when a 'Parent' term is */
3134 /* selected from the taxonomy lineage */
3135 /* popup list. */
3136 /* */
3137 /* Makes the selected term the active */
3138 /* one and re-queries for it. */
3139 /* */
3140 /*===================================================================*/
3141
3142 static void ChangeTaxParents_Callback (PopuP p)
3143
3144 {
3145 FormInfoPtr pFormInfo;
3146 Int2 val;
3147 ValNodePtr vnp;
3148
3149 pFormInfo = (FormInfoPtr) GetObjectExtra (p);
3150
3151 val = GetValue (p);
3152 if (val <= 0) return;
3153
3154 vnp = pFormInfo->taxStrings;
3155 while (val > 1 && vnp != NULL) {
3156 val--;
3157 vnp = vnp->next;
3158 }
3159 if (vnp != NULL) {
3160 WatchCursor ();
3161 RepopulateTaxonomy (pFormInfo, (CharPtr) vnp->data.ptrvalue);
3162 ArrowCursor ();
3163 }
3164 }
3165
3166 /*===================================================================*/
3167 /* */
3168 /* TextAction () - Called when a key is type into the "Term:" text */
3169 /* entry box. Enables/disables the accept button */
3170 /* and scroll to text. */
3171 /* */
3172 /*===================================================================*/
3173
3174 static void TextAction (TexT t)
3175
3176 {
3177 Int2 i;
3178 FormInfoPtr pFormInfo;
3179 Char str [256];
3180
3181 pFormInfo = (FormInfoPtr) GetObjectExtra (t);
3182
3183 /* Enable or disable the 'Accept' button based */
3184 /* on the mode and the current text. */
3185
3186 if (pFormInfo->currMode == RANGE_MODE) {
3187 if (TextHasNoText (pFormInfo->fromText) &&
3188 TextHasNoText (pFormInfo->toText))
3189 SafeDisable (pFormInfo->acceptButton);
3190 else
3191 SafeEnable (pFormInfo->acceptButton);
3192 } else {
3193 GetTitle (pFormInfo->termText, str, sizeof (str));
3194 if (StringHasNoText (str)) {
3195 if (pFormInfo->currMode == SELECTION_MODE && str [0] == ' ')
3196 SafeEnable (pFormInfo->acceptButton);
3197 else
3198 SafeDisable (pFormInfo->acceptButton);
3199 } else
3200 SafeEnable (pFormInfo->acceptButton);
3201 }
3202
3203 /* Get the current text */
3204
3205 GetTitle (t, str, sizeof (str));
3206
3207 /* If there is no text then clear */
3208 /* the 'Term Selection' window. */
3209
3210 if (str [0] == '\0') {
3211 pFormInfo->availItem = 0;
3212 pFormInfo->availRow = 0;
3213 Reset (pFormInfo->availDoc);
3214 for (i = 0; i < 7; i++)
3215 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt,
3216 systemFont);
3217 InvalDocument (pFormInfo->availDoc);
3218 pFormInfo->textChanged = FALSE;
3219 pFormInfo->okayToAccept = FALSE;
3220 pFormInfo->availCurrentPage = 0;
3221 }
3222
3223 /* If there is text, then attempt to scroll */
3224 /* to it in the 'Term Selection' window. */
3225
3226 else {
3227 pFormInfo->textChanged = TRUE;
3228 pFormInfo->okayToAccept = FALSE;
3229 if (pFormInfo->availCurrentPage > 0 &&
3230 pFormInfo->currMode == SELECTION_MODE)
3231 ScrollToText (pFormInfo, str, pFormInfo->availCurrentPage, TRUE, TRUE);
3232 Update ();
3233 }
3234 }
3235
3236 /*==================================================================*/
3237 /* */
3238 /* ToTextAction () - */
3239 /* */
3240 /*===================================================================*/
3241
3242 static void ToTextAction (TexT t)
3243
3244 {
3245 Int2 i;
3246 FormInfoPtr pFormInfo;
3247 Char str [256];
3248
3249 pFormInfo = (FormInfoPtr) GetObjectExtra (t);
3250
3251 pFormInfo->currRangeField = E2_RANGE_TO;
3252
3253 if (TextHasNoText (pFormInfo->fromText) &&
3254 TextHasNoText (pFormInfo->toText))
3255 SafeDisable (pFormInfo->acceptButton);
3256 else
3257 SafeEnable (pFormInfo->acceptButton);
3258
3259 GetTitle (t, str, sizeof (str));
3260 if (str [0] == '\0') {
3261 pFormInfo->availItem = 0;
3262 pFormInfo->availRow = 0;
3263 Reset (pFormInfo->availDoc);
3264 for (i = 0; i < 7; i++)
3265 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt, systemFont);
3266 InvalDocument (pFormInfo->availDoc);
3267 pFormInfo->isToTextChanged = FALSE;
3268 pFormInfo->isValidTo = FALSE;
3269 pFormInfo->availCurrentPage = 0;
3270 } else {
3271 pFormInfo->isToTextChanged = TRUE;
3272 pFormInfo->isValidTo = TRUE;
3273 if (pFormInfo->availCurrentPage > 0)
3274 ScrollToText (pFormInfo, str, pFormInfo->availCurrentPage, TRUE, TRUE);
3275 Update ();
3276 }
3277 }
3278
3279 /*==================================================================*/
3280 /* */
3281 /* FromTextAction () - */
3282 /* */
3283 /*===================================================================*/
3284
3285 static void FromTextAction (TexT t)
3286
3287 {
3288 Int2 i;
3289 FormInfoPtr pFormInfo;
3290 Char str [256];
3291
3292 pFormInfo = (FormInfoPtr) GetObjectExtra (t);
3293
3294 pFormInfo->currRangeField = E2_RANGE_FROM;
3295
3296 if (TextHasNoText (pFormInfo->fromText) &&
3297 TextHasNoText (pFormInfo->toText))
3298 SafeDisable (pFormInfo->acceptButton);
3299 else
3300 SafeEnable (pFormInfo->acceptButton);
3301
3302 GetTitle (t, str, sizeof (str));
3303 if (str [0] == '\0') {
3304 pFormInfo->availItem = 0;
3305 pFormInfo->availRow = 0;
3306 Reset (pFormInfo->availDoc);
3307 for (i = 0; i < 7; i++)
3308 AppendText (pFormInfo->availDoc, " \n", &availParFmt,
3309 availColFmt, systemFont);
3310 InvalDocument (pFormInfo->availDoc);
3311 pFormInfo->isFromTextChanged = FALSE;
3312 pFormInfo->isValidFrom = FALSE;
3313 pFormInfo->availCurrentPage = 0;
3314 } else {
3315 pFormInfo->isFromTextChanged = TRUE;
3316 pFormInfo->isValidFrom = TRUE;
3317 if (pFormInfo->availCurrentPage > 0)
3318 ScrollToText (pFormInfo, str, pFormInfo->availCurrentPage, TRUE, TRUE);
3319 Update ();
3320 }
3321 }
3322
3323 /*==================================================================*/
3324 /* */
3325 /* ChangeMode () - */
3326 /* */
3327 /*==================================================================*/
3328
3329 static void ChangeMode (PopuP p)
3330
3331 {
3332 AlistDialogPtr adp;
3333 Char ch;
3334 Int2 i;
3335 EnumFieldAssocPtr modeSet;
3336 ModeChoice menuMode;
3337 ModeChoice selectedMode;
3338 CharPtr ptr, text;
3339 FormInfoPtr pFormInfo;
3340
3341
3342 /*------------------------------------------*/
3343 /* Convert the menu choice into a mode type */
3344 /*------------------------------------------*/
3345
3346 adp = (AlistDialogPtr) GetObjectExtra (p);
3347 pFormInfo = adp->userdata;
3348 modeSet = adp->alist;
3349 menuMode = (ModeChoice) (GetValue (p) - 1);
3350 selectedMode = (ModeChoice) modeSet [menuMode].value;
3351
3352 pFormInfo->currMode = selectedMode;
3353
3354 /* handle special modes, populate termlist */
3355 if (selectedMode == TAXONOMY_MODE || selectedMode == MESH_TREE_MODE) {
3356 SafeHide (pFormInfo->termGroup);
3357 SafeHide (pFormInfo->rangeGroup);
3358 text = SaveStringFromText (pFormInfo->termText);
3359 WatchCursor ();
3360 Update ();
3361 if (text != NULL) {
3362 ptr = text;
3363 ch = *ptr;
3364 while (ch != '\0' && ch >= ' ') {
3365 ptr++;
3366 ch = *ptr;
3367 }
3368 *ptr = '\0';
3369 if ((*text == '\0') || (! RepopulateTaxonomy (pFormInfo, text))) {
3370 RepopulateTaxonomyRoot (pFormInfo);
3371 }
3372 } else {
3373 RepopulateTaxonomyRoot (pFormInfo);
3374 }
3375 ArrowCursor ();
3376 MemFree (text);
3377 SafeShow (pFormInfo->taxLineagePopup);
3378 pFormInfo->textChanged = FALSE;
3379 pFormInfo->okayToAccept = TRUE;
3380 } else if (selectedMode == RANGE_MODE) {
3381 SafeHide (pFormInfo->termGroup);
3382 SafeHide (pFormInfo->taxLineagePopup);
3383 SafeShow (pFormInfo->rangeGroup);
3384 TextAction (pFormInfo->fromText);
3385 pFormInfo->availItem = 0;
3386 pFormInfo->availRow = 0;
3387 Reset (pFormInfo->availDoc);
3388 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
3389 for (i = 0; i < 7; i++) {
3390 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt, systemFont);
3391 }
3392 InvalDocument (pFormInfo->availDoc);
3393 Select (pFormInfo->fromText);
3394 } else {
3395 SafeHide (pFormInfo->rangeGroup);
3396 SafeHide (pFormInfo->taxLineagePopup);
3397 SafeShow (pFormInfo->termGroup);
3398 pFormInfo->availItem = 0;
3399 pFormInfo->availRow = 0;
3400 pFormInfo->availCurrentPage = 0;
3401 TextAction (pFormInfo->termText);
3402 Reset (pFormInfo->availDoc);
3403 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
3404 for (i = 0; i < 7; i++) {
3405 AppendText (pFormInfo->availDoc, " \n", &availParFmt, availColFmt, systemFont);
3406 }
3407 InvalDocument (pFormInfo->availDoc);
3408 Select (pFormInfo->termText);
3409 }
3410
3411 Update ();
3412 }
3413
3414 /*==================================================================*/
3415 /* */
3416 /* ChangeMode_Callback () - */
3417 /* */
3418 /*==================================================================*/
3419
3420 static void ChangeMode_Callback (PopuP p)
3421
3422 {
3423 ChangeMode (p);
3424 }
3425
3426 /*==================================================================*/
3427 /* */
3428 /* ChangeField () - Sets the current field to the one selected in */
3429 /* the given PopuP object, then selects the */
3430 /* corresponding modes PopuP that contains the */
3431 /* possible modes for this field. */
3432 /* */
3433 /*==================================================================*/
3434
3435 static void ChangeField (PopuP p)
3436
3437 {
3438 AlistDialogPtr adp;
3439 EnumFieldAssocPtr fieldAList;
3440 Int2 fieldId;
3441 ModeIndex md, mode;
3442 Int2 menuChoice;
3443 FormInfoPtr pFormInfo;
3444
3445 /*------------------------*/
3446 /* Get the selected field */
3447 /*------------------------*/
3448
3449 adp = (AlistDialogPtr) GetObjectExtra (p);
3450 pFormInfo = adp->userdata;
3451 fieldAList = adp->alist;
3452
3453 menuChoice = GetValue (p) - 1;
3454 if (menuChoice < 0) return;
3455
3456 fieldId = fieldAList [menuChoice].value;
3457
3458 /*--------------------------------*/
3459 /* Select and make active the set */
3460 /* of modes for this field. */
3461 /*--------------------------------*/
3462
3463 mode = (ModeIndex) FieldGetModePopup (pFormInfo->currDb, fieldId, fieldAList, pFormInfo);
3464 if (mode < 0) return;
3465
3466 for (md = POPUP_MULT; md <= POPUP_UID; md++)
3467 if (md != mode)
3468 SafeHide (pFormInfo->modesPopup [md]);
3469
3470 SafeShow (pFormInfo->modesPopup [mode]);
3471 ChangeMode (pFormInfo->modesPopup [mode]);
3472 }
3473
3474 /*==================================================================*/
3475 /* */
3476 /* ChangeField_Callback () - */
3477 /* */
3478 /*==================================================================*/
3479
3480 static void ChangeField_Callback (PopuP p)
3481
3482 {
3483 ChangeField (p);
3484 }
3485
3486 /*==================================================================*/
3487 /* */
3488 /* ChangeDatabase () - */
3489 /* */
3490 /*==================================================================*/
3491
3492 static void ChangeDatabase (PopuP p)
3493
3494 {
3495 FormInfoPtr pFormInfo;
3496 Int2 db;
3497 Int2 dbase;
3498 UIEnum val;
3499 Entrez2InfoPtr e2ip;
3500
3501 pFormInfo = (FormInfoPtr) GetObjectExtra (p);
3502 if (pFormInfo == NULL || pFormInfo->fieldsPopup == NULL) return;
3503
3504 e2ip = Query_GetInfo ();
3505
3506 val = GetValue (p) - 1;
3507
3508 for (db = 0; db < e2ip->db_count; db++) {
3509 if (db != (Int2) val) {
3510 SafeHide (pFormInfo->fieldsPopup [db]);
3511 }
3512 }
3513
3514 dbase = (Int2) val;
3515 pFormInfo->currDb = dbase;
3516 SafeShow (pFormInfo->fieldsPopup [dbase]);
3517 ChangeField (pFormInfo->fieldsPopup [dbase]);
3518
3519 DoResetAvail (pFormInfo, FALSE);
3520 ResetChosen (pFormInfo);
3521
3522 if (pFormInfo->currMode == TAXONOMY_MODE || pFormInfo->currMode == MESH_TREE_MODE) {
3523 SafeHide (pFormInfo->termGroup);
3524 SafeHide (pFormInfo->rangeGroup);
3525 SafeShow (pFormInfo->taxLineagePopup);
3526 } else if (pFormInfo->currMode == RANGE_MODE) {
3527 SafeHide (pFormInfo->termGroup);
3528 SafeHide (pFormInfo->taxLineagePopup);
3529 SafeShow (pFormInfo->rangeGroup);
3530 Select (pFormInfo->fromText);
3531 } else {
3532 SafeHide (pFormInfo->rangeGroup);
3533 SafeHide (pFormInfo->taxLineagePopup);
3534 SafeShow (pFormInfo->termGroup);
3535 Select (pFormInfo->termText);
3536 }
3537
3538 Reset (pFormInfo->advQueryText);
3539 }
3540
3541 /*==================================================================*/
3542 /* */
3543 /* ChangeDatabase_Callback () - */
3544 /* */
3545 /*==================================================================*/
3546
3547 static void ChangeDatabase_Callback (PopuP p)
3548
3549 {
3550 ChangeDatabase (p);
3551 }
3552
3553 /*==================================================================*/
3554 /* */
3555 /* EditMessage_Callback () - */
3556 /* */
3557 /*==================================================================*/
3558
3559 static void EditMessage_Callback (ForM f, Int2 mssg)
3560
3561 {
3562 FormInfoPtr pFormInfo;
3563
3564 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
3565
3566 switch (mssg) {
3567 case VIB_MSG_CUT:
3568 StdCutTextProc (NULL);
3569 break;
3570 case VIB_MSG_COPY:
3571 StdCopyTextProc (NULL);
3572 break;
3573 case VIB_MSG_PASTE:
3574 StdPasteTextProc (NULL);
3575 break;
3576 case VIB_MSG_DELETE:
3577 StdDeleteTextProc (NULL);
3578 break;
3579 default:
3580 if (pFormInfo->appmessage != NULL) {
3581 pFormInfo->appmessage (f, mssg);
3582 }
3583 break;
3584 }
3585 }
3586
3587 /*==================================================================*/
3588 /* */
3589 /* TermListActivate_Callback () - */
3590 /* */
3591 /*==================================================================*/
3592
3593 static void TermListActivate_Callback (WindoW w)
3594
3595 {
3596 FormInfoPtr pFormInfo;
3597
3598 pFormInfo = (FormInfoPtr) GetObjectExtra (w);
3599
3600 if (pFormInfo->activate != NULL)
3601 pFormInfo->activate (w);
3602 }
3603
3604 /*==================================================================*/
3605 /* */
3606 /* TermListCleanup_Callback () - */
3607 /* */
3608 /*==================================================================*/
3609
3610 static void TermListCleanup_Callback (GraphiC g, VoidPtr data)
3611
3612 {
3613 FormInfoPtr pFormInfo;
3614
3615 pFormInfo = (FormInfoPtr) GetObjectExtra (g);
3616
3617 MemFree (pFormInfo->fieldsPopup);
3618 StdCleanupFormProc (g, data);
3619 }
3620
3621 /*==================================================================*/
3622 /* */
3623 /* Quit_Callback () - */
3624 /* */
3625 /*==================================================================*/
3626
3627 static void Quit_Callback (IteM i)
3628
3629 {
3630 QuitProgram ();
3631 }
3632
3633 /*==================================================================*/
3634 /* */
3635 /* StripNewLine () - Strip the newline character from the end of */
3636 /* a string. */
3637 /* */
3638 /*==================================================================*/
3639
3640 static void StripNewLine (CharPtr str)
3641
3642 {
3643 CharPtr chptr;
3644
3645 if (StringHasNoText (str))
3646 return;
3647 chptr = StringRChr (str, '\n');
3648 if (chptr != NULL) {
3649 *chptr = '\0';
3650 }
3651 chptr = StringRChr (str, '\r');
3652 if (chptr != NULL) {
3653 *chptr = '\0';
3654 }
3655 }
3656
3657 /*==================================================================*/
3658 /* */
3659 /* Query_AddUidsTerm () - */
3660 /* */
3661 /*==================================================================*/
3662
3663 static Boolean Query_AddUidsTerm (ForM f, CharPtr uidListName, Int4 iUidCount, Int4Ptr uids, Int2 db)
3664
3665 {
3666 CharPtr dbName;
3667 Entrez2RequestPtr e2rq;
3668 Entrez2ReplyPtr e2ry;
3669 StateDataPtr sdp;
3670 StateDataPtr prev;
3671 Char displayStr [256];
3672 RecT r;
3673 BaR sb;
3674 FormInfoPtr pFormInfo;
3675 Boolean doNotTranslate;
3676
3677 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
3678
3679 /*-----------------------------------------*/
3680 /* Make sure we don't add a Uid list twice */
3681 /*-----------------------------------------*/
3682
3683 for (sdp = pFormInfo->termList; sdp != NULL; sdp = sdp->next)
3684 if (MeshStringICmp (sdp->term, uidListName) == 0) return FALSE;
3685
3686 /*--------------------------------*/
3687 /* Create a term for the UID list */
3688 /*--------------------------------*/
3689
3690 sdp = StateDataNew (pFormInfo);
3691 if (pFormInfo->termList == NULL)
3692 pFormInfo->termList = sdp;
3693
3694 if (sdp == NULL) return FALSE;
3695
3696 (pFormInfo->chosenNumLines)++;
3697
3698 sdp->field = StringSave ("----");
3699 /* sdp->term = StringSave (uidListName); */
3700 sdp->count = iUidCount;
3701 /* sdp->uids = uids; */
3702 sdp->group = GROUP_SINGLE;
3703 sdp->above = ENTREZ_OP_NONE;
3704
3705 dbName = DBGetNameFromID (pFormInfo->currDb);
3706 e2rq = EntrezCreateBooleanRequest (FALSE, FALSE, dbName, NULL, 0, 0, NULL, 0, 0);
3707 if (e2rq == NULL) return FALSE;
3708
3709 doNotTranslate = FALSE;
3710 EntrezAddToBooleanRequest (e2rq, NULL, 0, NULL, NULL, NULL, 0, iUidCount, uids, NULL, FALSE, doNotTranslate);
3711 EntrezSetUseHistoryFlag (e2rq);
3712
3713 if (ShowASN () == TRUE)
3714 DisplayEntrezRequest (e2rq);
3715
3716 e2ry = SpecialEntrezSynchronousQuery (e2rq);
3717 if (e2ry == NULL) return FALSE;
3718
3719 if (ShowASN () == TRUE)
3720 DisplayEntrezReply (e2ry);
3721
3722 e2rq = Entrez2RequestFree (e2rq);
3723 sdp->key = StringSave (e2ry->key);
3724 sdp->term = StringSave (e2ry->key);
3725 Entrez2ReplyFree (e2ry);
3726
3727 /*-------------------------------------*/
3728 /* Add the term to the current Query's */
3729 /* linked list of terms. */
3730 /*-------------------------------------*/
3731
3732 prev = sdp->prev;
3733 if (prev != NULL) {
3734 sdp->above = ENTREZ_OP_AND;
3735 prev->below = ENTREZ_OP_AND;
3736 }
3737 sdp->below = ENTREZ_OP_NONE;
3738 sdp->state = STATE_ON;
3739
3740 /*---------------------------------------------*/
3741 /* Add the term to the query refinement window */
3742 /*---------------------------------------------*/
3743
3744 sprintf (displayStr, "%s\t [%s]\t%ld\n", sdp->term, sdp->field, (long) iUidCount);
3745 AppendText (pFormInfo->chosenDoc, displayStr, &chosenParFmt, chosenColFmt, systemFont);
3746
3747 /*---------------------------------*/
3748 /* Display our new query string in */
3749 /* Query Refinement window. */
3750 /*---------------------------------*/
3751
3752 InvalDocRows (pFormInfo->chosenDoc, pFormInfo->chosenNumLines, 1, 1);
3753 AdjustDocScroll (pFormInfo->chosenDoc);
3754 sb = GetSlateVScrollBar ((SlatE) pFormInfo->chosenDoc);
3755 ResetClip ();
3756 SetBarValue (sb, MAX (pFormInfo->chosenNumLines - 7, 0));
3757 ObjectRect (pFormInfo->chosenDoc, &r);
3758 InsetRect (&r, 4, 4);
3759 r.right = r.left + 16;
3760 InsetRect (&r, -1, -1);
3761 Select (pFormInfo->chosenDoc);
3762 InvalRect (&r);
3763
3764 Update ();
3765
3766 return TRUE;
3767 }
3768
3769 /*==================================================================*/
3770 /* */
3771 /* ImportUIDs_Callback () - */
3772 /* */
3773 /*==================================================================*/
3774
3775 static void ImportUIDs_Callback (IteM i)
3776
3777 {
3778 Entrez2InfoPtr e2ip;
3779 Entrez2DbInfoPtr e2dbInfo;
3780 FILE *fp;
3781 FormInfoPtr pFormInfo;
3782 ByteStorePtr bsp;
3783 Int4 iUidCount;
3784 Char fullName [PATH_MAX];
3785 CharPtr baseName;
3786 Char str [32];
3787 Int4 uid;
3788 Int4Ptr uids = NULL;
3789 WindoW w;
3790
3791 /*----------------------------*/
3792 /* Get the Term Form info for */
3793 /* the parent window. */
3794 /*----------------------------*/
3795
3796 #ifdef WIN_MAC
3797 w = FrontWindow ();
3798 #else
3799 w = ParentWindow (i);
3800 #endif
3801
3802 pFormInfo = (FormInfoPtr) GetObjectExtra (w);
3803
3804 /*------------------------------*/
3805 /* Get the name of the UID file */
3806 /* and then open it. */
3807 /*------------------------------*/
3808
3809 if (! GetInputFileName (fullName, sizeof (fullName), "", "TEXT")) return;
3810
3811 fp = FileOpen (fullName, "r");
3812 if (fp == NULL) return;
3813
3814 /*-------------------------------*/
3815 /* Create a ByteStore Pointer to */
3816 /* store the UIDs in. */
3817 /*-------------------------------*/
3818
3819 bsp = BSNew (128);
3820 if (bsp == NULL) {
3821 FileClose (fp);
3822 return;
3823 }
3824
3825 /*-------------------------------------*/
3826 /* Read the first line of the file and */
3827 /* verify that it contains a valid */
3828 /* database name. */
3829 /* */
3830 /* NOTE - Special case for medline */
3831 /* needs to me removed once */
3832 /* it is fixed on the server. */
3833 /* */
3834 /*-------------------------------------*/
3835
3836 if (!FileGets (str, sizeof (str), fp)) {
3837 BSFree (bsp);
3838 FileClose (fp);
3839 return;
3840 }
3841
3842 StripNewLine (str);
3843
3844 e2ip = Query_GetInfo ();
3845
3846 for (e2dbInfo = e2ip->db_info; e2dbInfo != NULL; e2dbInfo = e2dbInfo->next)
3847 if (StringICmp (e2dbInfo->db_menu, &str [1]) == 0) break;
3848
3849 if (e2dbInfo == NULL) {
3850 Message (MSG_POSTERR, "First line must be in the form >DbName");
3851 BSFree (bsp);
3852 FileClose (fp);
3853 return;
3854 }
3855
3856 /*-----------------------------------*/
3857 /* Read the rest of the lines in and */
3858 /* add each UID to the byteStore. */
3859 /*-----------------------------------*/
3860
3861 while (FileGets (str, sizeof (str), fp)) {
3862 StripNewLine (str);
3863 if (str [0] != '\0' && StrToLong (str, &uid))
3864 BSWrite (bsp, &uid, sizeof (DocUid));
3865 }
3866
3867 BSSeek (bsp, 0L, 0);
3868 iUidCount = (Int4) ((BSLen (bsp)) / sizeof (Int4));
3869 uids = (Int4Ptr) BSMerge (bsp, NULL);
3870
3871 /*--------------------------------*/
3872 /* Add the list of UIDs as a term */
3873 /* in the current query. */
3874 /*--------------------------------*/
3875
3876 baseName = FileNameFind (fullName);
3877 Query_AddUidsTerm (pFormInfo->form, baseName, iUidCount, uids, pFormInfo->currDb);
3878 Select (pFormInfo->termText);
3879
3880 /*---------------------------*/
3881 /* Get a count of terms that */
3882 /* satisfy this query. */
3883 /*---------------------------*/
3884
3885 Update ();
3886 RecalculateChosen (pFormInfo);
3887 ArrowCursor ();
3888 Update ();
3889
3890 /*----------------------------------*/
3891 /* Clean up and return successfully */
3892 /*----------------------------------*/
3893
3894 BSFree (bsp);
3895 MemFree (uids);
3896 FileClose (fp);
3897 }
3898
3899 /*==================================================================*/
3900 /* */
3901 /* ExportUIDs_Callback () - */
3902 /* */
3903 /*==================================================================*/
3904
3905 static void ExportUIDs_Callback (IteM i)
3906
3907 {
3908 CharPtr dbName;
3909 Entrez2BooleanReplyPtr e2BooleanPtr;
3910 Entrez2IdListPtr e2UidList;
3911 FILE *fp;
3912 FormInfoPtr pFormInfo;
3913 Char path [PATH_MAX];
3914 Char headerStr [32];
3915 Int4Ptr uids;
3916 Int4 uidNum;
3917 Char uidStr [32];
3918 WindoW w;
3919
3920 /*----------------------------*/
3921 /* Get the Term Form info for */
3922 /* the parent window. */
3923 /*----------------------------*/
3924
3925 #ifdef WIN_MAC
3926 w = FrontWindow ();
3927 #else
3928 w = ParentWindow (i);
3929 #endif
3930
3931 pFormInfo = (FormInfoPtr) GetObjectExtra (w);
3932
3933 /*-------------------------------*/
3934 /* Get a file name from the user */
3935 /* and open that file. */
3936 /*-------------------------------*/
3937
3938 if (! GetOutputFileName (path, sizeof (path), NULL)) return;
3939
3940 #ifdef WIN_MAC
3941 FileCreate (path, "TEXT", "ttxt");
3942 #endif
3943
3944 fp = FileOpen (path, "w");
3945 if (fp == NULL) return;
3946
3947 WatchCursor ();
3948
3949 /*-----------------------------------*/
3950 /* Write the header line to the file */
3951 /*-----------------------------------*/
3952
3953 dbName = DBGetNameFromID (pFormInfo->currDb);
3954 sprintf (headerStr, ">%s\n", dbName);
3955 FilePuts (headerStr, fp);
3956
3957 /*-----------------------*/
3958 /* Create a list of UIDS */
3959 /*-----------------------*/
3960
3961 e2BooleanPtr = Query_FetchUIDs (pFormInfo->form);
3962 e2UidList = e2BooleanPtr->uids;
3963
3964 uids = (Int4Ptr) BSMerge (e2UidList->uids, NULL);
3965
3966 /*----------------------------*/
3967 /* Write the uids to the file */
3968 /*----------------------------*/
3969
3970 for (uidNum = 0; uidNum < e2UidList->num; uidNum++) {
3971 sprintf (uidStr, "%ld\n", (long) uids [uidNum]);
3972 FilePuts (uidStr, fp);
3973 }
3974
3975 /*----------------------------------*/
3976 /* Clean up and return successfully */
3977 /*----------------------------------*/
3978
3979 FileClose (fp);
3980 free (uids);
3981 ArrowCursor ();
3982 Entrez2BooleanReplyFree (e2BooleanPtr);
3983 }
3984
3985 /*==================================================================*/
3986 /* */
3987 /* AdvQueryInit () - Initialize the lexical static variables for */
3988 /* parsing a new string. */
3989 /* */
3990 /*==================================================================*/
3991
3992 static Int2 AdvQueryInit (FormInfoPtr pFormInfo, CharPtr newStr)
3993
3994 {
3995 /*-----------------*/
3996 /* Check parameter */
3997 /*-----------------*/
3998
3999 if (newStr == NULL) return -1;
4000
4001 /*-----------------------------------------*/
4002 /* Initialize the lexical static variables */
4003 /* using the new string. */
4004 /*-----------------------------------------*/
4005
4006 MemFree (pFormInfo->advQueryLexStr);
4007 pFormInfo->advQueryLexStr = StringSave (newStr);
4008 pFormInfo->advQueryLexPos = 0;
4009 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
4010
4011 /*-------------------------------------*/
4012 /* Free the linked list of query terms */
4013 /* so that we can build a new one with */
4014 /* the given string. */
4015 /*-------------------------------------*/
4016
4017 ResetChosen (pFormInfo);
4018
4019 /*---------------------*/
4020 /* Return successfully */
4021 /*---------------------*/
4022
4023 return 0;
4024 }
4025
4026 /*==================================================================*/
4027 /* */
4028 /* LexClassifyChar () - */
4029 /* */
4030 /* NOTE -- Taken from LexClassifyChar() in accutils.c */
4031 /* */
4032 /*==================================================================*/
4033
4034 static Int2 LexClassifyChar (Char c)
4035
4036 {
4037 Int2 retval;
4038
4039 switch (c) {
4040 case '(':
4041 retval = LEXCHAR_LPAREN;
4042 break;
4043 case ')':
4044 retval = LEXCHAR_RPAREN;
4045 break;
4046 case '[':
4047 retval = LEXCHAR_LBRACKET;
4048 break;
4049 case ']':
4050 retval = LEXCHAR_RBRACKET;
4051 break;
4052 case '"':
4053 retval = LEXCHAR_QUOTE;
4054 break;
4055 case '&':
4056 retval = LEXCHAR_AND;
4057 break;
4058 case '|':
4059 retval = LEXCHAR_OR;
4060 break;
4061 case '-':
4062 retval = LEXCHAR_NOT;
4063 break;
4064 case ',':
4065 retval = LEXCHAR_COMMA;
4066 break;
4067 case '@':
4068 retval = LEXCHAR_ATSIGN;
4069 break;
4070 case '\\':
4071 retval = LEXCHAR_BACKSLASH;
4072 break;
4073 case ' ':
4074 case '\t':
4075 retval = LEXCHAR_WHITESPACE;
4076 break;
4077 case ';':
4078 retval = LEXCHAR_SEMICOLON;
4079 break;
4080 case ':':
4081 retval = LEXCHAR_COLON;
4082 break;
4083 case '\0':
4084 retval = LEXCHAR_NULL;
4085 break;
4086 case '\r':
4087 case '\n':
4088 retval = LEXCHAR_EOL;
4089 break;
4090 default:
4091 retval = LEXCHAR_OTHER;
4092 break;
4093 }
4094
4095 return retval;
4096 }
4097
4098 /*==================================================================*/
4099 /* */
4100 /* AdvQueryGetNextToken() - */
4101 /* */
4102 /* Returns: */
4103 /* */
4104 /* StartPos - >0 : The position in the static string */
4105 /* pFormInfo->advQueryLexStr where the */
4106 /* token starts. */
4107 /* */
4108 /* -1 : No token found. */
4109 /* */
4110 /* Sets: */
4111 /* */
4112 /* pFormInfo->advQueryNextToken : Contains an */
4113 /* identifier specifying the type of */
4114 /* the token, and if the token is a */
4115 /* string also contains a pointer to */
4116 /* the string. */
4117 /* */
4118 /* Set to NULL if no token found. */
4119 /* */
4120 /*==================================================================*/
4121
4122 static Int2 AdvQueryGetNextToken (FormInfoPtr pFormInfo)
4123
4124 {
4125 Int2 startPos;
4126 Int2 classChar;
4127 Int2 token = 0;
4128 Boolean done;
4129 Char c;
4130 CharPtr lexToken = NULL;
4131 CharPtr lexTokenStart;
4132 Int2 len;
4133 Int2 pos;
4134
4135 /*------------------*/
4136 /* Check conditions */
4137 /*------------------*/
4138
4139 if (pFormInfo->advQueryLexStr == NULL) {
4140 pFormInfo->advQueryNextToken = NULL;
4141 return -1;
4142 }
4143
4144 pFormInfo->advQueryNextToken = &pFormInfo->advQueryNextRealNode;
4145
4146 /*--------------------------------------*/
4147 /* Find the beginning of the next token */
4148 /* and malloc space for it. */
4149 /*--------------------------------------*/
4150
4151 len = StringLen (pFormInfo->advQueryLexStr);
4152 startPos = pFormInfo->advQueryLexPos;
4153
4154 if (pFormInfo->advQueryLexPos >= len) {
4155 pFormInfo->advQueryLexState = LEXSTATE_ERROR;
4156 token = -1;
4157 lexToken = MemNew (1);
4158 } else {
4159 pos = pFormInfo->advQueryLexPos;
4160 lexToken = MemNew (StringLen (&pFormInfo->advQueryLexStr [pos]) + 1);
4161 }
4162
4163 lexTokenStart = lexToken;
4164
4165 /*------------------*/
4166 /*------------------*/
4167
4168 for (done = FALSE; !done && pFormInfo->advQueryLexPos <= len; pFormInfo->advQueryLexPos++) {
4169 c = pFormInfo->advQueryLexStr [pFormInfo->advQueryLexPos];
4170 classChar = LexClassifyChar (c);
4171 switch (pFormInfo->advQueryLexState) {
4172 case LEXSTATE_IDLE:
4173 switch (classChar) {
4174 case LEXCHAR_LPAREN:
4175 token = LEXTOK_LPAREN;
4176 done = TRUE;
4177 break;
4178 case LEXCHAR_RPAREN:
4179 token = LEXTOK_RPAREN;
4180 done = TRUE;
4181 break;
4182 case LEXCHAR_LBRACKET:
4183 token = LEXTOK_LBRACKET;
4184 done = TRUE;
4185 break;
4186 case LEXCHAR_RBRACKET:
4187 token = LEXTOK_RBRACKET;
4188 done = TRUE;
4189 break;
4190 case LEXCHAR_AND:
4191 token = LEXTOK_AND;
4192 done = TRUE;
4193 break;
4194 case LEXCHAR_OR:
4195 token = LEXTOK_OR;
4196 done = TRUE;
4197 break;
4198 case LEXCHAR_NOT:
4199 token = LEXTOK_NOT;
4200 done = TRUE;
4201 break;
4202 case LEXCHAR_COMMA:
4203 token = LEXTOK_COMMA;
4204 done = TRUE;
4205 break;
4206 case LEXCHAR_ATSIGN:
4207 token = LEXTOK_ATSIGN;
4208 done = TRUE;
4209 break;
4210 case LEXCHAR_COLON:
4211 token = LEXTOK_RANGE;
4212 done = TRUE;
4213 break;
4214 case LEXCHAR_QUOTE:
4215 pFormInfo->advQueryLexState = LEXSTATE_INQUOTE;
4216 break;
4217 case LEXCHAR_BACKSLASH:
4218 pFormInfo->advQueryLexState = LEXSTATE_BACKSLASHED;
4219 break;
4220 case LEXCHAR_EOL:
4221 case LEXCHAR_WHITESPACE:
4222 startPos = pFormInfo->advQueryLexPos + 1;
4223 break;
4224 case LEXCHAR_SEMICOLON:
4225 case LEXCHAR_NULL:
4226 pFormInfo->advQueryLexState = LEXSTATE_ERROR;
4227 done = TRUE;
4228 break;
4229 case LEXCHAR_OTHER:
4230 default:
4231 pFormInfo->advQueryLexState = LEXSTATE_INSTRING;
4232 *lexToken++ = c;
4233 break;
4234 }
4235 break;
4236 case LEXSTATE_BACKSLASHED:
4237 switch (classChar) {
4238 case LEXCHAR_NULL:
4239 case LEXCHAR_EOL:
4240 *lexToken++ = '\0';
4241 done = TRUE;
4242 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
4243 break;
4244 case LEXCHAR_LPAREN:
4245 case LEXCHAR_RPAREN:
4246 case LEXCHAR_LBRACKET:
4247 case LEXCHAR_RBRACKET:
4248 case LEXCHAR_QUOTE:
4249 case LEXCHAR_AND:
4250 case LEXCHAR_OR:
4251 case LEXCHAR_NOT:
4252 case LEXCHAR_COMMA:
4253 case LEXCHAR_ATSIGN:
4254 case LEXCHAR_BACKSLASH:
4255 case LEXCHAR_WHITESPACE:
4256 case LEXCHAR_SEMICOLON:
4257 case LEXCHAR_COLON:
4258 case LEXCHAR_OTHER:
4259 default:
4260 pFormInfo->advQueryLexState = LEXSTATE_INSTRING;
4261 *lexToken++ = c;
4262 break;
4263 }
4264 break;
4265 case LEXSTATE_INQUOTE:
4266 switch (classChar) {
4267 case LEXCHAR_QUOTE:
4268 token = LEXTOK_STRING;
4269 *lexToken++ = '\0';
4270 done = TRUE;
4271 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
4272 break;
4273 case LEXCHAR_BACKSLASH:
4274 pFormInfo->advQueryLexState = LEXSTATE_INQUOTE_AFTERBSLASH;
4275 break;
4276 case LEXCHAR_NULL:
4277 case LEXCHAR_EOL:
4278 pFormInfo->advQueryLexState = LEXSTATE_ERROR;
4279 done = TRUE;
4280 break;
4281 default:
4282 *lexToken++ = c;
4283 break;
4284 }
4285 break;
4286 case LEXSTATE_INQUOTE_AFTERBSLASH:
4287 switch (classChar) {
4288 case LEXCHAR_NULL:
4289 case LEXCHAR_EOL:
4290 pFormInfo->advQueryLexState = LEXSTATE_ERROR;
4291 done = TRUE;
4292 break;
4293 default:
4294 pFormInfo->advQueryLexState = LEXSTATE_INQUOTE;
4295 *lexToken++ = c;
4296 break;
4297 }
4298 break;
4299 case LEXSTATE_INSTRING:
4300 switch (classChar) {
4301 case LEXCHAR_WHITESPACE:
4302 case LEXCHAR_SEMICOLON:
4303 case LEXCHAR_NULL:
4304 case LEXCHAR_EOL:
4305 token = LEXTOK_STRING;
4306 *lexToken++ = '\0';
4307 done = TRUE;
4308 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
4309 break;
4310 case LEXCHAR_BACKSLASH:
4311 pFormInfo->advQueryLexState = LEXSTATE_BACKSLASHED;
4312 break;
4313 case LEXCHAR_QUOTE:
4314 pFormInfo->advQueryLexState = LEXSTATE_INQUOTE;
4315 break;
4316 case LEXCHAR_OTHER:
4317 *lexToken++ = c;
4318 break;
4319 default:
4320 token = LEXTOK_STRING;
4321 *lexToken++ = '\0';
4322 done = TRUE;
4323 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
4324 pFormInfo->advQueryLexPos--; /* push back last character */
4325 break;
4326 }
4327 break;
4328 case LEXSTATE_ERROR:
4329 done = TRUE;
4330 break;
4331 }
4332 }
4333
4334 pFormInfo->advQueryNextToken->choice = (Uint1) token;
4335 pFormInfo->advQueryNextToken->data.ptrvalue = NULL;
4336
4337 if (token == LEXTOK_STRING)
4338 pFormInfo->advQueryNextToken->data.ptrvalue = lexTokenStart;
4339 else
4340 MemFree (lexTokenStart);
4341
4342 if (pFormInfo->advQueryLexState == LEXSTATE_ERROR) {
4343 pFormInfo->advQueryNextToken = NULL;
4344 return -1;
4345 } else
4346 return startPos;
4347 }
4348
4349 /*===================================================================*/
4350 /* */
4351 /* CloseGroup () - */
4352 /* */
4353 /*===================================================================*/
4354
4355 static Boolean CloseGroup (FormInfoPtr pFormInfo)
4356
4357 {
4358 StateDataPtr pLastTerm;
4359
4360 /*--------------*/
4361 /* Sanity check */
4362 /*--------------*/
4363
4364 if (pFormInfo == NULL || pFormInfo->termList == NULL) return FALSE;
4365
4366 /*--------------------------------*/
4367 /* Find the last term in the list */
4368 /*--------------------------------*/
4369
4370 pLastTerm = pFormInfo->termList;
4371 while (pLastTerm->next != NULL)
4372 pLastTerm = pLastTerm->next;
4373
4374 /*----------------------*/
4375 /* Set its group status */
4376 /*----------------------*/
4377
4378 switch (pLastTerm->group) {
4379 case GROUP_SINGLE:
4380 case GROUP_LAST:
4381 break;
4382 case GROUP_FIRST:
4383 pLastTerm->group = GROUP_SINGLE;
4384 break;
4385 case GROUP_MIDDLE:
4386 pLastTerm->group = GROUP_LAST;
4387 break;
4388 default:
4389 break;
4390 }
4391
4392 /*---------------------*/
4393 /* Return successfully */
4394 /*---------------------*/
4395
4396 return TRUE;
4397 }
4398
4399 /*===================================================================*/
4400 /* */
4401 /* ParseANDedTerms () - */
4402 /* */
4403 /* NOTE -- Brought over from accutils.c */
4404 /* */
4405 /*===================================================================*/
4406
4407 /* prototype for recursive function */
4408
4409 static Boolean ParseTermList (FormInfoPtr pFormInfo, Int2 db, Int2 fld, Int2 currOp);
4410
4411 static Boolean ParseANDedTerms (FormInfoPtr pFormInfo, Int2 db, Int2 fld, Int2 currOp)
4412
4413 {
4414 if (! ParseTermList (pFormInfo, db, fld, currOp)) return FALSE;
4415
4416 while (pFormInfo->advQueryNextToken != NULL && pFormInfo->advQueryNextToken->choice == LEXTOK_AND) {
4417 AdvQueryGetNextToken (pFormInfo);
4418 if (! ParseTermList (pFormInfo, db, fld, LEXCHAR_AND)) return FALSE;
4419 }
4420
4421 return TRUE;
4422 }
4423
4424 /*===================================================================*/
4425 /* */
4426 /* ParseORedTerms () - */
4427 /* */
4428 /* NOTE -- Brought over from accutils.c */
4429 /* */
4430 /*===================================================================*/
4431
4432 static Boolean ParseORedTerms (FormInfoPtr pFormInfo, Int2 db, Int2 fld, Int2 currOp)
4433
4434 {
4435 if (! ParseANDedTerms (pFormInfo, db, fld, currOp)) return FALSE;
4436
4437 while (pFormInfo->advQueryNextToken != NULL && pFormInfo->advQueryNextToken->choice == LEXTOK_OR) {
4438 AdvQueryGetNextToken (pFormInfo);
4439 if (! ParseANDedTerms (pFormInfo, db, fld, LEXCHAR_OR)) return FALSE;
4440 }
4441
4442 return TRUE;
4443 }
4444
4445 /*===================================================================*/
4446 /* */
4447 /* ParseNOTedTerms () - */
4448 /* */
4449 /* NOTE -- This function brought over from accutils.c */
4450 /* */
4451 /*===================================================================*/
4452
4453 static Boolean ParseNOTedTerms (FormInfoPtr pFormInfo, Int2 db, Int2 fld, Int2 currOp)
4454
4455 {
4456 if (! ParseORedTerms (pFormInfo, db, fld, currOp)) return FALSE;
4457
4458 while ((pFormInfo->advQueryNextToken != NULL) && (pFormInfo->advQueryNextToken->choice == LEXTOK_NOT)) {
4459 AdvQueryGetNextToken (pFormInfo);
4460 if (! ParseORedTerms (pFormInfo, db, fld, LEXCHAR_NOT)) return FALSE;
4461 }
4462
4463 return TRUE;
4464 }
4465
4466 /*===================================================================*/
4467 /* */
4468 /* ParseTermList () - */
4469 /* */
4470 /*===================================================================*/
4471
4472 static Boolean ParseTermList (FormInfoPtr pFormInfo, Int2 db, Int2 fld, Int2 currOp)
4473
4474 {
4475 CharPtr term;
4476 CharPtr fldStr;
4477 CharPtr highRangeStr = NULL;
4478 StateDataPtr newTermPtr;
4479 Int2 nOperator;
4480
4481 /*---------------------------------------------*/
4482 /* Check for proper conditions to run function */
4483 /*---------------------------------------------*/
4484
4485 if (pFormInfo->advQueryNextToken == NULL) {
4486 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "Null factor");
4487 return FALSE;
4488 }
4489
4490 /*------------------------------------------*/
4491 /* If we have a left paren, then recursivly */
4492 /* parse what follows it as a term list. */
4493 /*------------------------------------------*/
4494
4495 if (pFormInfo->advQueryNextToken->choice == LEXTOK_LPAREN) {
4496 pFormInfo->advQueryNewGroup = TRUE;
4497 AdvQueryGetNextToken (pFormInfo);
4498 if (! ParseNOTedTerms (pFormInfo, db, fld, currOp))
4499 return FALSE;
4500
4501 /*---------------------------*/
4502 /* If we have a right paren, */
4503 /* close out group. */
4504 /*---------------------------*/
4505
4506 if (pFormInfo->advQueryNextToken != NULL && pFormInfo->advQueryNextToken->choice == LEXTOK_RPAREN) {
4507 CloseGroup (pFormInfo);
4508 AdvQueryGetNextToken (pFormInfo);
4509 } else {
4510 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "Missing right paren");
4511 return FALSE;
4512 }
4513
4514 return TRUE;
4515 }
4516
4517 /*--------------------------*/
4518 /* Otherwise, grab the term */
4519 /*--------------------------*/
4520
4521 if (pFormInfo->advQueryNextToken->choice != LEXTOK_STRING) {
4522 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "invalid token");
4523 return FALSE;
4524 }
4525
4526 term = (CharPtr) (pFormInfo->advQueryNextToken->data.ptrvalue);
4527 AdvQueryGetNextToken (pFormInfo);
4528
4529 /*---------------------------------------*/
4530 /* If it's a range, grab the second term */
4531 /*---------------------------------------*/
4532
4533 if ((pFormInfo->advQueryNextToken != NULL) && (pFormInfo->advQueryNextToken->choice == LEXTOK_RANGE)) {
4534 AdvQueryGetNextToken (pFormInfo);
4535 if ((pFormInfo->advQueryNextToken == NULL) || (pFormInfo->advQueryNextToken->choice != LEXTOK_STRING)) {
4536 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "missing second half of range");
4537 MemFree (term);
4538 return FALSE;
4539 }
4540 highRangeStr = (CharPtr) (pFormInfo->advQueryNextToken->data.ptrvalue);
4541 AdvQueryGetNextToken (pFormInfo);
4542 }
4543
4544 /*----------------------*/
4545 /* Parse the field name */
4546 /*----------------------*/
4547
4548 if ((pFormInfo->advQueryNextToken != NULL) && (pFormInfo->advQueryNextToken->choice == LEXTOK_LBRACKET)) {
4549
4550 /*----------------------*/
4551 /* Get the field string */
4552 /*----------------------*/
4553
4554 AdvQueryGetNextToken (pFormInfo);
4555 if ((pFormInfo->advQueryNextToken == NULL) || (pFormInfo->advQueryNextToken->choice != LEXTOK_STRING)) {
4556 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "missing field id after bracket");
4557 MemFree (term);
4558 MemFree (highRangeStr);
4559 return FALSE;
4560 }
4561
4562 fldStr = (CharPtr) (pFormInfo->advQueryNextToken->data.ptrvalue);
4563
4564 /*-------------------------------------*/
4565 /* Convert string to field ID, mapping */
4566 /* wildcard '*' to 'ALL'. */
4567 /*-------------------------------------*/
4568
4569 if (fldStr != NULL && StrCmp (fldStr, "*") == 0)
4570 fld = FieldGetIDFromName (db, "ALL");
4571 else
4572 fld = FieldGetIDFromName (db, fldStr);
4573
4574 MemFree (pFormInfo->advQueryNextToken->data.ptrvalue);
4575 if (fld < 0) {
4576 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "bad field identifier");
4577 MemFree (term);
4578 MemFree (highRangeStr);
4579 return FALSE;
4580 }
4581
4582 /*----------------------------------*/
4583 /* Check to see if the fields are a */
4584 /* comma-seperated range. */
4585 /*----------------------------------*/
4586
4587 AdvQueryGetNextToken (pFormInfo);
4588 if ((pFormInfo->advQueryNextToken == NULL) ||
4589 (pFormInfo->advQueryNextToken->choice != LEXTOK_COMMA && pFormInfo->advQueryNextToken->choice != LEXTOK_RBRACKET)) {
4590 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "missing right bracket");
4591 MemFree (term);
4592 MemFree (highRangeStr);
4593 return FALSE;
4594 }
4595 if (pFormInfo->advQueryNextToken->choice == LEXTOK_COMMA) {
4596 AdvQueryGetNextToken (pFormInfo);
4597 if ((pFormInfo->advQueryNextToken == NULL) ||
4598 (pFormInfo->advQueryNextToken->choice != LEXTOK_STRING) || StringCmp (pFormInfo->advQueryNextToken->data.ptrvalue, "S") != 0) {
4599 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "field qualifier error");
4600 MemFree (term);
4601 MemFree (highRangeStr);
4602 return FALSE;
4603 }
4604 MemFree (pFormInfo->advQueryNextToken->data.ptrvalue);
4605 AdvQueryGetNextToken (pFormInfo);
4606 if ((pFormInfo->advQueryNextToken == NULL) || (pFormInfo->advQueryNextToken->choice != LEXTOK_RBRACKET)) {
4607 ErrPostEx (SEV_WARNING, ERR_CD_LEX, 0, "missing right bracket");
4608 MemFree (term);
4609 MemFree (highRangeStr);
4610 return FALSE;
4611 }
4612 }
4613 AdvQueryGetNextToken (pFormInfo);
4614 }
4615
4616 /*-------------------------------------*/
4617 /* Add in the high range, if it exists */
4618 /*-------------------------------------*/
4619
4620 if (highRangeStr != NULL) {
4621 StringCat (term, ":");
4622 StringCat (term, highRangeStr);
4623 }
4624
4625 /*-----------------------------------------------*/
4626 /* Create a new term and add it to the term list */
4627 /*-----------------------------------------------*/
4628
4629 newTermPtr = Query_AddBoolTerm (pFormInfo->form, db, fld, term, STATE_ON, 0);
4630
4631 if (newTermPtr == NULL) return FALSE;
4632
4633 /*---------------------------------------*/
4634 /* Select the proper operator with which */
4635 /* to connect it to the previous term. */
4636 /*---------------------------------------*/
4637
4638 switch (currOp) {
4639 case LEXCHAR_OR:
4640 nOperator = ENTREZ_OP_OR;
4641 break;
4642 case LEXCHAR_AND:
4643 nOperator = ENTREZ_OP_AND;
4644 break;
4645 case LEXCHAR_NOT:
4646 nOperator = ENTREZ_OP_BUTNOT;
4647 break;
4648 default:
4649 nOperator = ENTREZ_OP_NONE;
4650 break;
4651 }
4652 newTermPtr->above = nOperator;
4653 if (newTermPtr->prev != NULL)
4654 newTermPtr->prev->below = nOperator;
4655
4656 /*-------------------------------*/
4657 /* Set its group status properly */
4658 /*-------------------------------*/
4659
4660 if (pFormInfo->advQueryNewGroup == TRUE) {
4661 newTermPtr->group = GROUP_FIRST;
4662 pFormInfo->advQueryNewGroup = FALSE;
4663 } else if (newTermPtr->prev != NULL) {
4664 switch (newTermPtr->prev->group) {
4665 case GROUP_SINGLE:
4666 newTermPtr->group = GROUP_SINGLE;
4667 break;
4668 case GROUP_FIRST:
4669 case GROUP_MIDDLE:
4670 newTermPtr->group = GROUP_MIDDLE;
4671 break;
4672 default:
4673 newTermPtr->group = GROUP_SINGLE;
4674 break;
4675 }
4676 }
4677
4678
4679 /*----------------------------------*/
4680 /* Clean up and return successfully */
4681 /*----------------------------------*/
4682
4683 MemFree (term);
4684 MemFree (highRangeStr);
4685
4686 return TRUE;
4687 }
4688
4689 /*===================================================================*/
4690 /* */
4691 /* Query_ParseString () - */
4692 /* */
4693 /* NOTE -- This function is based on EntrezPMTLParseString() */
4694 /* from accutil.c */
4695 /* */
4696 /*===================================================================*/
4697
4698 static Boolean Query_ParseString (ForM f, CharPtr str, Int2 db, Int2 fld)
4699
4700 {
4701 Boolean retval;
4702 FormInfoPtr pFormInfo;
4703
4704 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
4705
4706 /*---------------------------*/
4707 /* Check parameters, setting */
4708 /* defaults if necessary. */
4709 /*---------------------------*/
4710
4711 if (str == NULL || *str == '\0') return FALSE;
4712
4713 /*------------------------------------*/
4714 /* Clear out the existing query terms */
4715 /*------------------------------------*/
4716
4717 AdvQueryInit (pFormInfo, str);
4718
4719 /*------------------------------------*/
4720 /* Recursively parse the query string */
4721 /*------------------------------------*/
4722
4723 AdvQueryGetNextToken (pFormInfo);
4724
4725 if ((ParseNOTedTerms (pFormInfo, db, fld, 0) == TRUE) && (pFormInfo->advQueryNextToken == NULL))
4726 retval = TRUE;
4727 else {
4728 ResetChosen (pFormInfo);
4729 retval = FALSE;
4730 }
4731
4732 /*---------------------*/
4733 /* Return successfully */
4734 /*---------------------*/
4735
4736 return retval;
4737 }
4738
4739 /*==================================================================*/
4740 /* */
4741 /* AdvancedQueryText_Callback () - */
4742 /* */
4743 /*==================================================================*/
4744
4745 static void AdvancedQueryText_Callback (TexT queryTextBox)
4746
4747 {
4748 CharPtr curstr;
4749 FormInfoPtr pFormInfo;
4750
4751 pFormInfo = (FormInfoPtr) GetObjectExtra (queryTextBox);
4752
4753 curstr = SaveStringFromText (pFormInfo->advQueryText);
4754
4755 if (Query_ParseString (pFormInfo->form, curstr, pFormInfo->currDb, -1)) {
4756
4757 SafeEnable (pFormInfo->advRetrieveButton);
4758 pFormInfo->advQueryState = ADV_QUERY_EVALUATE_STATE;
4759 SafeSetTitle (pFormInfo->advRetrieveButton, "Evaluate");
4760 } else {
4761 SafeDisable (pFormInfo->advRetrieveButton);
4762 pFormInfo->advQueryState = ADV_QUERY_INVALID_STATE;
4763 }
4764
4765 MemFree (curstr);
4766 }
4767
4768 /*==================================================================*/
4769 /* */
4770 /* SetAdvancedText () - */
4771 /* */
4772 /*==================================================================*/
4773
4774 static void SetAdvancedText (TexT advancedText, CharPtr str)
4775
4776 {
4777 SetTitle (advancedText, str);
4778 }
4779
4780 /*==================================================================*/
4781 /* */
4782 /* RepopulateChosen () - */
4783 /* */
4784 /*==================================================================*/
4785
4786 static void RepopulateChosen (FormInfoPtr pFormInfo)
4787
4788 {
4789 Int4 off;
4790 BaR sb;
4791 StateDataPtr sdp;
4792 Char strn [256];
4793
4794 sb = GetSlateVScrollBar ((SlatE) pFormInfo->chosenDoc);
4795 off = GetBarValue (sb);
4796 Reset (pFormInfo->chosenDoc);
4797
4798 InvalDocument (pFormInfo->chosenDoc);
4799 pFormInfo->chosenNumLines = 0;
4800 for (sdp = pFormInfo->termList; sdp != NULL; sdp = sdp->next) {
4801 (pFormInfo->chosenNumLines)++;
4802 if (sdp->field == NULL)
4803 sprintf (strn, "%s\t [----]\t%ld\n", sdp->term, (long) sdp->count);
4804 else
4805 sprintf (strn, "%s\t [%s]\t%ld\n", sdp->term, sdp->field, (long) sdp->count);
4806 AppendText (pFormInfo->chosenDoc, strn, &chosenParFmt, chosenColFmt, systemFont);
4807 }
4808 InvalDocument (pFormInfo->chosenDoc);
4809 AdjustDocScroll (pFormInfo->chosenDoc);
4810 CorrectBarValue (sb, off);
4811 Update ();
4812 }
4813
4814 /*==================================================================*/
4815 /* */
4816 /* Query_ConvertToString () - Convert the current linked list of */
4817 /* terms into a string that can be */
4818 /* displayed in the advanced query win. */
4819 /* */
4820 /*==================================================================*/
4821
4822 static CharPtr Query_ConvertToString (ForM f)
4823
4824 {
4825 Entrez2FieldInfoPtr fieldInfo;
4826 Int2 group;
4827 Int2 last;
4828 CharPtr ptr;
4829 StateDataPtr sdp;
4830 CharPtr tmp;
4831 CharPtr advQueryString;
4832 FormInfoPtr pFormInfo;
4833
4834 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
4835
4836 if (pFormInfo->termList == NULL) return NULL;
4837
4838 if (pFormInfo->chosenNumLines < 1) return NULL;
4839
4840 advQueryString = MemNew (1000);
4841 advQueryString [0] = '\0';
4842 group = 0;
4843 last = 0;
4844 for (sdp = pFormInfo->termList; sdp != NULL; sdp = sdp->next) {
4845 if (sdp->group == GROUP_SINGLE || sdp->group == GROUP_FIRST)
4846 group++;
4847
4848 if (sdp->state == STATE_ON) {
4849 if (last == 0) {
4850 StrCat (advQueryString, "( ");
4851 StrCat (advQueryString, "( ");
4852 } else if (last == group) {
4853 StrCat (advQueryString, " | ");
4854 } else if (sdp->above == ENTREZ_OP_BUTNOT) {
4855 StrCat (advQueryString, " )");
4856 StrCat (advQueryString, " )");
4857 StrCat (advQueryString, " - ");
4858 StrCat (advQueryString, "( ");
4859 StrCat (advQueryString, "( ");
4860 } else {
4861 StrCat (advQueryString, " )");
4862 StrCat (advQueryString, " & ");
4863 StrCat (advQueryString, "( ");
4864 }
4865 StringCat (advQueryString, "\"");
4866 tmp = StringSave (sdp->term);
4867 ptr = StringChr (tmp, ':');
4868 if (ptr != NULL) {
4869 *ptr = '\0';
4870 ptr++;
4871 TrimSpacesAroundString (tmp);
4872 TrimSpacesAroundString (ptr);
4873 StringCat (advQueryString, tmp);
4874 StringCat (advQueryString, "\" : \"");
4875 StringCat (advQueryString, ptr);
4876 } else
4877 StringCat (advQueryString, tmp);
4878 MemFree (tmp);
4879 StringCat (advQueryString, "\"[");
4880 fieldInfo = FieldGetInfo (sdp->db, sdp->fld);
4881 StringCat (advQueryString, fieldInfo->field_name);
4882 StringCat (advQueryString, "]");
4883 last = group;
4884 }
4885 }
4886
4887 if (group > 0 && last > 0) {
4888 StrCat (advQueryString, " )");
4889 StrCat (advQueryString, " )");
4890 }
4891
4892 return advQueryString;
4893 }
4894
4895 /*==================================================================*/
4896 /* */
4897 /* AdvancedQueryToggle_Callback () - Called when the "Advanced */
4898 /* Queries" menu option is */
4899 /* selected. */
4900 /* */
4901 /*==================================================================*/
4902
4903 static void AdvancedQueryToggle_Callback (IteM i)
4904
4905 {
4906 FormInfoPtr pFormInfo;
4907 CharPtr str;
4908
4909 pFormInfo = (FormInfoPtr) GetObjectExtra (i);
4910
4911 /*-----------------------*/
4912 /* Advanced ==> Standard */
4913 /*-----------------------*/
4914
4915 if (! GetStatus (pFormInfo->advancedQueryItem)) {
4916 SafeHide (pFormInfo->advQueryGroup);
4917 Reset (pFormInfo->advQueryText);
4918 RepopulateChosen (pFormInfo);
4919 SafeShow (pFormInfo->stdQueryGroup);
4920 }
4921
4922 /*-----------------------*/
4923 /* Standard ==> Advanced */
4924 /*-----------------------*/
4925
4926 else {
4927 str = Query_ConvertToString (pFormInfo->form);
4928 SetAdvancedText (pFormInfo->advQueryText, str);
4929 MemFree (str);
4930 SafeHide (pFormInfo->stdQueryGroup);
4931 SafeShow (pFormInfo->advQueryGroup);
4932 }
4933 }
4934
4935 /*==================================================================*/
4936 /* */
4937 /* ExplodeTermsToggle_Callback () - Called when the "Explode */
4938 /* Terms" menu option is */
4939 /* selected. */
4940 /* */
4941 /*==================================================================*/
4942
4943 static void ExplodeTermsToggle_Callback (IteM i)
4944
4945 {
4946 FormInfoPtr pFormInfo;
4947
4948 pFormInfo = (FormInfoPtr) GetObjectExtra (i);
4949 if (pFormInfo == NULL) return;
4950
4951 WatchCursor ();
4952 Update ();
4953 RecalculateChosen (pFormInfo);
4954 ArrowCursor ();
4955 Update ();
4956 }
4957
4958 /*===================================================================*/
4959 /* */
4960 /* TermList_UnselectAll () -- Marks all terms in the term list as */
4961 /* unselected. */
4962 /* */
4963 /*===================================================================*/
4964
4965 NLM_EXTERN Boolean TermList_UnselectAll (ForM f)
4966
4967 {
4968 Int2 count = 0;
4969 Int2 item;
4970 FormInfoPtr pFormInfo;
4971 StateDataPtr sdp;
4972
4973 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
4974
4975 sdp = pFormInfo->termList;
4976 while (sdp != NULL) {
4977 sdp->state = STATE_OFF;
4978 sdp = sdp->next;
4979 count++;
4980 }
4981
4982 ResetClip ();
4983 WatchCursor ();
4984 for (item = 1; item <= count; item++) {
4985 InvalDocCols (pFormInfo->chosenDoc, item, 3, 3);
4986 }
4987 Update ();
4988 RecalculateChosen (pFormInfo);
4989 ArrowCursor ();
4990
4991 return TRUE;
4992 }
4993
4994 /*==================================================================*/
4995 /* */
4996 /* AlphabetizeGroups () - */
4997 /* */
4998 /*==================================================================*/
4999
5000 static void AlphabetizeGroups (FormInfoPtr pFormInfo)
5001
5002 {
5003 Int2 compare;
5004 Boolean keepGoing;
5005 StateDataPtr next;
5006 StateDataPtr sdp;
5007 StateData tmp;
5008
5009 if (pFormInfo->termList == NULL) return;
5010
5011 keepGoing = TRUE;
5012 while (keepGoing) {
5013 keepGoing = FALSE;
5014 for (sdp = pFormInfo->termList; sdp->next != NULL; sdp = sdp->next) {
5015 next = sdp->next;
5016 if (sdp->group == GROUP_FIRST || sdp->group == GROUP_MIDDLE) {
5017 compare = MeshStringICmp (sdp->term, next->term);
5018 if (compare > 0) {
5019 tmp.term = next->term;
5020 tmp.field = next->field;
5021 tmp.count = next->count;
5022 tmp.db = next->db;
5023 tmp.fld = next->fld;
5024 next->term = sdp->term;
5025 next->field = sdp->field;
5026 next->count = sdp->count;
5027 next->db = sdp->db;
5028 next->fld = sdp->fld;
5029 sdp->term = tmp.term;
5030 sdp->field = tmp.field;
5031 sdp->count = tmp.count;
5032 sdp->db = tmp.db;
5033 sdp->fld = tmp.fld;
5034 keepGoing = TRUE;
5035 }
5036 }
5037 }
5038 }
5039 }
5040
5041 /*==================================================================*/
5042 /* */
5043 /* Query_ClearUnusedTerms () - Remove any terms that have been */
5044 /* turned off. */
5045 /* */
5046 /*==================================================================*/
5047
5048 static void Query_ClearUnusedTerms (IteM i)
5049
5050 {
5051 StateDataPtr next;
5052 StateDataPtr sdp;
5053 FormInfoPtr pFormInfo;
5054
5055 pFormInfo = (FormInfoPtr) GetObjectExtra (i);
5056
5057 WatchCursor ();
5058 Update ();
5059
5060 /* Iterate through the list, removing all */
5061 /* terms that are marked as unused. */
5062
5063 sdp = pFormInfo->termList;
5064
5065 while (sdp != NULL) {
5066 next = sdp->next;
5067 if (sdp->state == STATE_OFF) {
5068 RemoveTermFromList (pFormInfo, sdp, FALSE, FALSE);
5069 FreeTerm (sdp);
5070 }
5071 sdp = next;
5072 }
5073
5074 /* Adjust the display accordingly */
5075
5076 AlphabetizeGroups (pFormInfo);
5077 RepopulateChosen (pFormInfo);
5078 RecalculateChosen (pFormInfo);
5079 ArrowCursor ();
5080 }
5081
5082 /*==================================================================*/
5083 /* */
5084 /* SetupMenus () - Create and initialize the pulldown menus. */
5085 /* */
5086 /*==================================================================*/
5087
5088 static void SetupMenus (WindoW w, FormInfoPtr pFormInfo, Boolean explodeToggle, Boolean advancedQueryToggle)
5089
5090 {
5091 IteM clearUnusedItem;
5092 MenU m;
5093 MenU s;
5094
5095 /*-----------*/
5096 /* File menu */
5097 /*-----------*/
5098
5099 m = PulldownMenu (w, "File");
5100 CommandItem (m, "Import UID List.../I", ImportUIDs_Callback);
5101 CommandItem (m, "Export UID List.../E", ExportUIDs_Callback);
5102 SeparatorItem (m);
5103 CommandItem (m, "Quit/Q", Quit_Callback);
5104
5105 /*-----------*/
5106 /* Edit menu */
5107 /*-----------*/
5108
5109 m = PulldownMenu (w, "Edit");
5110 FormCommandItem (m, CUT_MENU_ITEM, (BaseFormPtr) pFormInfo, VIB_MSG_CUT);
5111 FormCommandItem (m, COPY_MENU_ITEM, (BaseFormPtr) pFormInfo, VIB_MSG_COPY);
5112 FormCommandItem (m, PASTE_MENU_ITEM, (BaseFormPtr) pFormInfo, VIB_MSG_PASTE);
5113 FormCommandItem (m, CLEAR_MENU_ITEM, (BaseFormPtr) pFormInfo, VIB_MSG_DELETE);
5114
5115 /*--------------*/
5116 /* Options menu */
5117 /*--------------*/
5118
5119 m = PulldownMenu (w, "Options");
5120
5121 clearUnusedItem = CommandItem (m, "Clear Unused Query Terms", Query_ClearUnusedTerms);
5122 SetObjectExtra (clearUnusedItem, pFormInfo, NULL);
5123 pFormInfo->advancedQueryItem = StatusItem (m, "Advanced Queries", AdvancedQueryToggle_Callback);
5124 SetStatus (pFormInfo->advancedQueryItem, advancedQueryToggle);
5125 SetObjectExtra (pFormInfo->advancedQueryItem, pFormInfo, NULL);
5126
5127 pFormInfo->explodeItem = StatusItem (m, "Explode Terms", ExplodeTermsToggle_Callback);
5128 SetStatus (pFormInfo->explodeItem, explodeToggle);
5129 SetObjectExtra (pFormInfo->explodeItem, pFormInfo, NULL);
5130
5131 s = SubMenu (m, "Show ASN.1");
5132 s_showASNItem = ChoiceGroup (s, NULL);
5133 ChoiceItem (s_showASNItem, "OFF");
5134 ChoiceItem (s_showASNItem, "1");
5135 ChoiceItem (s_showASNItem, "2");
5136 ChoiceItem (s_showASNItem, "3");
5137 ChoiceItem (s_showASNItem, "4");
5138 ChoiceItem (s_showASNItem, "5");
5139 ChoiceItem (s_showASNItem, "6");
5140 ChoiceItem (s_showASNItem, "7");
5141 ChoiceItem (s_showASNItem, "8");
5142 ChoiceItem (s_showASNItem, "9");
5143 ChoiceItem (s_showASNItem, "ON");
5144 ChoiceItem (s_showASNItem, "LOG");
5145 SetValue (s_showASNItem, 1);
5146
5147 /*------------*/
5148 /* Help menu */
5149 /*------------*/
5150
5151 m = PulldownMenu (w, "Help");
5152 CommandItem (m, "Databases...", DatabaseView_Callback);
5153 CommandItem (m, "Fields...", FieldView_Callback);
5154 CommandItem (m, "Modes...", ModeView_Callback);
5155 }
5156
5157 /*==================================================================*/
5158 /* */
5159 /* SetupAdvQueryGroup () - Create and initialize the Advanced */
5160 /* Query Form. */
5161 /* */
5162 /*==================================================================*/
5163
5164 static GrouP SetupAdvQueryGroup (FormInfoPtr pFormInfo, GrouP mainGroup)
5165
5166 {
5167 GrouP advQueryGroup;
5168 GrouP buttonGroup;
5169 GrouP instructionGroup;
5170 Char tempStr [256];
5171
5172 advQueryGroup = HiddenGroup (mainGroup, -1, 0, NULL);
5173 SetGroupSpacing (advQueryGroup, 5, 5);
5174
5175 /*----------------------------------*/
5176 /* Set up alternative boolean query */
5177 /* refinement text edit box. */
5178 /*----------------------------------*/
5179
5180 pFormInfo->advQueryText = ScrollText (advQueryGroup, ADV_TEXT_WIDTH, ADV_TEXT_HEIGHT, programFont, TRUE, AdvancedQueryText_Callback);
5181 SetObjectExtra (pFormInfo->advQueryText, pFormInfo, NULL);
5182
5183 /*------------------------------------------*/
5184 /* Create a group for the Retrieve/Evaluate */
5185 /* combined button and the Reset button. */
5186 /*------------------------------------------*/
5187
5188 buttonGroup = HiddenGroup (advQueryGroup, 5, 0, NULL);
5189 SetGroupSpacing (buttonGroup, 10, 10);
5190
5191 pFormInfo->advRetrieveButton = PushButton (buttonGroup, "Retrieve 000000000 Documents", EvaluateRetrieve_Callback);
5192 SetObjectExtra (pFormInfo->advRetrieveButton, pFormInfo, NULL);
5193 SetTitle (pFormInfo->advRetrieveButton, "Evaluate");
5194 Disable (pFormInfo->advRetrieveButton);
5195 pFormInfo->advQueryState = ADV_QUERY_INVALID_STATE;
5196
5197 pFormInfo->advResetButton = PushButton (buttonGroup, "Reset", Reset_Callback);
5198 SetObjectExtra (pFormInfo->advResetButton, pFormInfo, NULL);
5199
5200 /*----------------------------------------------*/
5201 /* Create instructions for using advanced query */
5202 /*----------------------------------------------*/
5203
5204 instructionGroup = HiddenGroup (advQueryGroup, 1, 0, NULL);
5205 StaticPrompt (instructionGroup, "Operators:", 0, 0, programFont, 'l');
5206 StaticPrompt (instructionGroup, "", 0, 0, programFont, 'l');
5207 StaticPrompt (instructionGroup, " & (and)", 0, 0, programFont, 'l');
5208 StaticPrompt (instructionGroup, " | (or)", 0, 0, programFont, 'l');
5209 StaticPrompt (instructionGroup, " - (butnot)", 0, 0, programFont, 'l');
5210 StaticPrompt (instructionGroup, " : (range)", 0, 0, programFont, 'l');
5211 StaticPrompt (instructionGroup, "", 0, 0, programFont, 'l');
5212 StaticPrompt (instructionGroup, "Example:", 0, 0, programFont, 'l');
5213 StaticPrompt (instructionGroup, "", 0, 0, programFont, 'l');
5214 tempStr [0] = '\0';
5215 StringCat (tempStr, " ((\"glucagon\" [WORD] | \"insulin\" ");
5216 StringCat (tempStr, "[MESH]) & (\"1995\" : \"1996\" [PDAT]))");
5217 StaticPrompt (instructionGroup, tempStr, 0, 0, programFont, 'l');
5218 StaticPrompt (instructionGroup, "", 0, 0, programFont, 'l');
5219 StaticPrompt (instructionGroup, "Use [*] to search all fields.", 0, 0, programFont, 'l');
5220
5221 /*--------------------------------*/
5222 /* Return the newly created group */
5223 /*--------------------------------*/
5224
5225 return advQueryGroup;
5226 }
5227
5228 /*==================================================================*/
5229 /* */
5230 /* GetValueFromField () - */
5231 /* */
5232 /*==================================================================*/
5233
5234 static Int4 GetValueFromField (DoC d, Int2 item, Int2 row, Int2 col)
5235
5236 {
5237 CharPtr str;
5238 Int4 value;
5239
5240 value = -1;
5241 str = GetDocText (d, item, row, col);
5242 if (str != NULL) {
5243 if (! StrToLong (str, &value)) {
5244 value = -1;
5245 }
5246 }
5247
5248 MemFree (str);
5249 return value;
5250 }
5251
5252 /*==================================================================*/
5253 /* */
5254 /* DrawAvailLeaf () - */
5255 /* */
5256 /*==================================================================*/
5257
5258 static void DrawAvailLeaf (DoC d, RectPtr r, Int2 item, Int2 frst)
5259
5260 {
5261 RecT q;
5262 Int2 value;
5263
5264 if (r == NULL || frst != 0) return;
5265
5266 value = GetValueFromField (d, item, 1, 3);
5267 if (value != 1) return;
5268
5269 q = *r;
5270 q.left++;
5271 q.right = q.left + 4;
5272 q.top += stdLineHeight / 2 - 2;
5273 q.bottom = q.top + 4;
5274 value = GetValueFromField (d, item, 1, 3);
5275 if (value == STATE_ON) {
5276 /*
5277 InvertColors ();
5278 */
5279 EraseRect (&q);
5280 PaintRect (&q);
5281 /*
5282 InvertColors ();
5283 */
5284 } else
5285 PaintRect (&q);
5286 }
5287
5288 /*==================================================================*/
5289 /* */
5290 /* HighlightAvail () - */
5291 /* */
5292 /*==================================================================*/
5293
5294 static Boolean HighlightAvail (DoC d, Int2 item, Int2 row, Int2 col)
5295
5296 {
5297 FormInfoPtr pFormInfo;
5298
5299 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5300
5301 if (item == pFormInfo->availItem && row == pFormInfo->availRow) return TRUE;
5302
5303 return FALSE;
5304 }
5305
5306 /*==================================================================*/
5307 /* */
5308 /* ClickAvail () - */
5309 /* */
5310 /*==================================================================*/
5311
5312 static void ClickAvail (DoC d, PoinT pt)
5313
5314 {
5315 Int2 item;
5316 Int2 row;
5317 FormInfoPtr pFormInfo;
5318
5319 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5320
5321 MapDocPoint (d, pt, &item, &row, NULL, NULL);
5322 pFormInfo->availClickItem = item;
5323 pFormInfo->availClickRow = row;
5324 pFormInfo->wasDoubleClick = dblClick;
5325
5326 SafeEnable (pFormInfo->acceptButton);
5327 }
5328
5329 /*==================================================================*/
5330 /* */
5331 /* ReleaseAvail () - This is called whenever the mouse button is */
5332 /* realeased in the term selection window. */
5333 /* */
5334 /*==================================================================*/
5335
5336 static void ReleaseAvail (DoC d, PoinT pt)
5337
5338 {
5339 Char ch;
5340 Int2 item;
5341 Int2 olditem;
5342 Int2 oldrow;
5343 CharPtr ptr;
5344 Int2 row;
5345 CharPtr text;
5346 Int4 iTermCount;
5347 CharPtr sTermCount;
5348 FormInfoPtr pFormInfo;
5349
5350 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5351
5352 /*------------------------------------*/
5353 /* Convert the screen location of the */
5354 /* release into an item and a row. */
5355 /*------------------------------------*/
5356
5357 MapDocPoint (d, pt, &item, &row, NULL, NULL);
5358
5359 /* ---------------------------------------- */
5360 /* There's no dragging in the avail window */
5361 /* ---------------------------------------- */
5362
5363 if (pFormInfo->availClickItem != item || pFormInfo->availClickRow != row) return;
5364
5365 text = GetDocText (pFormInfo->availDoc, item, row, 1);
5366 if (StringHasNoText (text)) {
5367 text = MemFree (text);
5368 }
5369
5370 olditem = pFormInfo->availItem;
5371 oldrow = pFormInfo->availRow;
5372 if (text != NULL) {
5373 pFormInfo->availItem = item;
5374 pFormInfo->availRow = row;
5375 } else {
5376 pFormInfo->availItem = 0;
5377 pFormInfo->availRow = 0;
5378 }
5379 if (olditem > 0 && oldrow > 0)
5380 InvalDocRows (pFormInfo->availDoc, olditem, oldrow, oldrow);
5381 if (text != NULL && item > 0 && row > 0)
5382 InvalDocRows (pFormInfo->availDoc, item, row, row);
5383
5384 if (text != NULL) {
5385 ptr = text;
5386 ch = *ptr;
5387 while (ch != '\0' && ch >= ' ') {
5388 ptr++;
5389 ch = *ptr;
5390 }
5391 *ptr = '\0';
5392 if (pFormInfo->currMode == RANGE_MODE) {
5393 if (CurrentText () == pFormInfo->fromText) {
5394 SafeSetTitle (pFormInfo->fromText, text);
5395 Select (pFormInfo->fromText);
5396 } else if (CurrentText () == pFormInfo->toText) {
5397 SafeSetTitle (pFormInfo->toText, text);
5398 Select (pFormInfo->toText);
5399 }
5400 } else {
5401 SafeSetTitle (pFormInfo->termText, text);
5402 Select (pFormInfo->termText);
5403 }
5404 Update ();
5405 } else {
5406 if (pFormInfo->currMode == RANGE_MODE) {
5407 SafeSetTitle (pFormInfo->fromText, "");
5408 SafeSetTitle (pFormInfo->toText, "");
5409 Select (pFormInfo->fromText);
5410 } else {
5411 SafeSetTitle (pFormInfo->termText, "");
5412 Select (pFormInfo->termText);
5413 }
5414 Update ();
5415 }
5416
5417 if (text != NULL && pFormInfo->wasDoubleClick) {
5418 WatchCursor ();
5419 Update ();
5420
5421 if ((pFormInfo->currMode == TAXONOMY_MODE) || (pFormInfo->currMode == MESH_TREE_MODE)) {
5422 Update ();
5423 ResetClip (); /* clipped to panel, need to update popup */
5424 RepopulateTaxonomy (pFormInfo, text);
5425 } else if (pFormInfo->currMode == RANGE_MODE) {
5426 ResetClip ();
5427 sTermCount = GetDocText (pFormInfo->availDoc, pFormInfo->availItem,
5428 pFormInfo->availRow, E2_COUNT_COL);
5429 TrimSpacesAroundString (sTermCount);
5430 iTermCount = atoi (sTermCount);
5431 MemFree (sTermCount);
5432 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb,
5433 pFormInfo->currField, text, STATE_ON, iTermCount);
5434 Update ();
5435 RecalculateChosen (pFormInfo);
5436 } else {
5437 ResetClip ();
5438 sTermCount = GetDocText (pFormInfo->availDoc, pFormInfo->availItem,
5439 pFormInfo->availRow, E2_COUNT_COL);
5440 TrimSpacesAroundString (sTermCount);
5441 iTermCount = atoi (sTermCount);
5442 MemFree (sTermCount);
5443 Query_AddBoolTerm (pFormInfo->form, pFormInfo->currDb,
5444 pFormInfo->currField, text, STATE_ON, iTermCount);
5445 Update ();
5446 RecalculateChosen (pFormInfo);
5447 }
5448
5449 ArrowCursor ();
5450 }
5451 MemFree (text);
5452 }
5453
5454 /*==================================================================*/
5455 /* */
5456 /* AvailTimerProc () - */
5457 /* */
5458 /*==================================================================*/
5459
5460 static void AvailTimerProc (WindoW w)
5461
5462 {
5463 FormInfoPtr pFormInfo;
5464
5465 pFormInfo = (FormInfoPtr) GetObjectExtra (w);
5466 pFormInfo->okayToAccept = TRUE;
5467 }
5468
5469 /*==================================================================*/
5470 /* */
5471 /* InitAvailPanel () - Set up the Term List Panel. */
5472 /* */
5473 /*==================================================================*/
5474
5475 static void InitAvailPanel (FormInfoPtr pFormInfo)
5476
5477 {
5478 RecT r;
5479
5480 pFormInfo->availItem = 0;
5481 pFormInfo->availRow = 0;
5482 SetDocShade (pFormInfo->availDoc, DrawAvailLeaf, NULL, HighlightAvail, NULL);
5483 SetDocProcs (pFormInfo->availDoc, ClickAvail, NULL, ReleaseAvail, NULL);
5484 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
5485
5486 ObjectRect (pFormInfo->availDoc, &r);
5487 InsetRect (&r, 4, 4);
5488 SelectFont (systemFont);
5489
5490 availColFmt [1].pixWidth = StringWidth ("0000000") + 10;
5491 availColFmt [0].pixWidth = (r.right - r.left) - availColFmt [1].pixWidth;
5492 availColFmt [2].pixWidth = 0;
5493
5494 SetDocAutoAdjust (pFormInfo->availDoc, FALSE);
5495
5496 InvalDocument (pFormInfo->availDoc);
5497 }
5498
5499 /*==================================================================*/
5500 /* */
5501 /* DrawChosenBrackets () - This is the draw callback for the */
5502 /* Chosen document panel. It gets called */
5503 /* every time the panel is drawn. */
5504 /* */
5505 /*==================================================================*/
5506
5507 static void DrawChosenBrackets (DoC d, RectPtr r, Int2 item, Int2 frst)
5508
5509 {
5510 FormInfoPtr pFormInfo;
5511 RecT s;
5512 StateDataPtr sdp;
5513 static Uint1 andsign [] = { 0x30, 0x48, 0x50, 0x20, 0x50, 0x8A, 0x84, 0x8A, 0x71, 0x00 };
5514 static Uint1 notsign [] = { 0x00, 0x00, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00 };
5515
5516 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5517
5518 sdp = pFormInfo->termList;
5519 while (sdp != NULL && item > 1) {
5520 sdp = sdp->next;
5521 item--;
5522 }
5523 if (sdp == NULL) return;
5524
5525 switch (sdp->group) {
5526 case GROUP_SINGLE:
5527 break;
5528 case GROUP_FIRST:
5529 MoveTo (r->left + 16 + 1, r->top + 1);
5530 LineTo (r->left + 16 + 3, r->top + 1);
5531 MoveTo (r->left + 16 + 1, r->top + 2);
5532 LineTo (r->left + 16 + 3, r->top + 2);
5533 MoveTo (r->left + 16 + 1, r->top + 1);
5534 LineTo (r->left + 16 + 1, r->bottom);
5535 break;
5536 case GROUP_MIDDLE:
5537 MoveTo (r->left + 16 + 1, r->top);
5538 LineTo (r->left + 16 + 1, r->bottom);
5539 break;
5540 case GROUP_LAST:
5541 MoveTo (r->left + 16 + 1, r->top);
5542 LineTo (r->left + 16 + 1, r->bottom - 1);
5543 MoveTo (r->left + 16 + 1, r->bottom - 2);
5544 LineTo (r->left + 16 + 3, r->bottom - 2);
5545 MoveTo (r->left + 16 + 1, r->bottom - 1);
5546 LineTo (r->left + 16 + 3, r->bottom - 1);
5547 break;
5548 default:
5549 break;
5550 }
5551
5552 switch (sdp->above) {
5553 case ENTREZ_OP_NONE:
5554 break;
5555 case ENTREZ_OP_AND:
5556 LoadRect (&s, r->left + 6, r->top, r->left + 14, r->top + 5);
5557 CopyBits (&s, andsign + 5);
5558 break;
5559 case ENTREZ_OP_BUTNOT:
5560 LoadRect (&s, r->left, r->top, r->left + 8, r->top + 5);
5561 CopyBits (&s, notsign + 5);
5562 break;
5563 default:
5564 break;
5565 }
5566
5567 switch (sdp->below) {
5568 case ENTREZ_OP_NONE:
5569 break;
5570 case ENTREZ_OP_AND:
5571 LoadRect (&s, r->left + 6, r->bottom - 5, r->left + 14, r->bottom);
5572 CopyBits (&s, andsign);
5573 break;
5574 case ENTREZ_OP_BUTNOT:
5575 LoadRect (&s, r->left, r->bottom - 5, r->left + 8, r->bottom);
5576 CopyBits (&s, notsign);
5577 break;
5578 default:
5579 break;
5580 }
5581 }
5582
5583 /*==================================================================*/
5584 /* */
5585 /* HighlightChosen () - */
5586 /* */
5587 /*==================================================================*/
5588
5589 static Boolean HighlightChosen (DoC d, Int2 item, Int2 row, Int2 col)
5590
5591 {
5592 StateDataPtr sdp;
5593 FormInfoPtr pFormInfo;
5594
5595 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5596
5597 if (col == 1 || col == 2) {
5598 if (pFormInfo->chosenInAboveBox || pFormInfo->chosenInBelowBox) return FALSE;
5599 /* if (item == pFormInfo->chosenItem) return TRUE; */
5600 return FALSE;
5601 } else if (col == 3) {
5602 sdp = pFormInfo->termList;
5603 while (sdp != NULL && item > 1) {
5604 sdp = sdp->next;
5605 item--;
5606 }
5607 if (sdp == NULL) return FALSE;
5608 return (Boolean) (sdp->state == STATE_ON);
5609 } else
5610 return FALSE;
5611 }
5612
5613 /*==================================================================*/
5614 /* */
5615 /* FrameChosen () - */
5616 /* */
5617 /*==================================================================*/
5618
5619 static void FrameChosen (FormInfoPtr pFormInfo)
5620
5621 {
5622 RecT sr;
5623
5624 ObjectRect (pFormInfo->chosenDoc, &sr);
5625 InsetRect (&sr, 4, 4);
5626
5627 if (RectInRect (&(pFormInfo->trackRect), &sr)) {
5628 Dotted ();
5629 FrameRect (&(pFormInfo->trackRect));
5630 }
5631 }
5632
5633 /*==================================================================*/
5634 /* */
5635 /* ClickChosen () - */
5636 /* */
5637 /*==================================================================*/
5638
5639 static void ClickChosen (DoC d, PoinT pt)
5640
5641 {
5642 Int2 col;
5643 Int2 item;
5644 RecT r;
5645 Int2 row;
5646 RecT s;
5647 FormInfoPtr pFormInfo;
5648
5649 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5650
5651 MapDocPoint (d, pt, &item, &row, &col, &r);
5652 if (item > 0 && row == 0 && col > 0)
5653 row = 1;
5654
5655 pFormInfo->chosenClickItem = item;
5656 pFormInfo->chosenClickRow = row;
5657 pFormInfo->chosenClickCol = col;
5658 pFormInfo->wasDoubleClick = dblClick;
5659 pFormInfo->chosenInAboveBox = FALSE;
5660 pFormInfo->chosenInBelowBox = FALSE;
5661
5662 if ((col == 1 || col == 2) && (item > 0) && (item <= pFormInfo->chosenNumLines) && (row > 0)) {
5663 pFormInfo->chosenItem = item;
5664 LoadRect (&s, r.left, r.top, r.left + 16, r.top + 5);
5665 if (PtInRect (pt, &s))
5666 pFormInfo->chosenInAboveBox = TRUE;
5667 LoadRect (&s, r.left, r.bottom - 5, r.left + 16, r.bottom);
5668 if (PtInRect (pt, &s))
5669 pFormInfo->chosenInBelowBox = TRUE;
5670 if (pFormInfo->chosenInAboveBox || pFormInfo->chosenInBelowBox)
5671 return;
5672 InvalDocCols (pFormInfo->chosenDoc, item, 1, 2);
5673 Update ();
5674 r.right = r.left + chosenColFmt [0].pixWidth + chosenColFmt [1].pixWidth;
5675 LoadRect (&(pFormInfo->trackRect), r.left + 22, r.top, r.right - 2, r.bottom);
5676 pFormInfo->trackPt = pt;
5677 InvertMode ();
5678 FrameChosen (pFormInfo);
5679 } else
5680 pFormInfo->chosenItem = 0;
5681 }
5682
5683 /*==================================================================*/
5684 /* */
5685 /* DragChosen () - */
5686 /* */
5687 /*==================================================================*/
5688
5689 static void DragChosen (DoC d, PoinT pt)
5690
5691 {
5692 Int4 off;
5693 BaR sb;
5694 RecT sr;
5695 FormInfoPtr pFormInfo;
5696
5697 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5698
5699 if (pFormInfo->chosenItem == 0) return;
5700 if (pFormInfo->chosenInAboveBox || pFormInfo->chosenInBelowBox) return;
5701 InvertMode ();
5702 FrameChosen (pFormInfo);
5703 Update ();
5704 ObjectRect (pFormInfo->chosenDoc, &sr);
5705 InsetRect (&sr, 4, 4);
5706 if (PtInRect (pt, &sr)) {
5707 OffsetRect (&(pFormInfo->trackRect), 0, pt.y - pFormInfo->trackPt.y);
5708 pFormInfo->trackPt = pt;
5709 }
5710 sb = GetSlateVScrollBar ((SlatE) pFormInfo->chosenDoc);
5711 off = GetBarValue (sb);
5712 ResetClip ();
5713 if (pt.y < sr.top)
5714 SetBarValue (sb, off - 1);
5715 else if (pt.y > sr.bottom)
5716 SetBarValue (sb, off + 1);
5717 Update ();
5718 InvertMode ();
5719 FrameChosen (pFormInfo);
5720 Update ();
5721 }
5722
5723 /*==================================================================*/
5724 /* */
5725 /* FlipOperatorBelow () - */
5726 /* */
5727 /*==================================================================*/
5728
5729 static void FlipOperatorBelow (FormInfoPtr pFormInfo, Int2 item)
5730
5731 {
5732 StateDataPtr next;
5733 RecT r;
5734 StateDataPtr sdp;
5735
5736 sdp = pFormInfo->termList;
5737 while (item > 1 && sdp != NULL) {
5738 item--;
5739 sdp = sdp->next;
5740 }
5741 if (sdp != NULL) {
5742 next = sdp->next;
5743 if (next != NULL) {
5744 if (sdp->below != next->above)
5745 Beep ();
5746 if (sdp->below == ENTREZ_OP_AND) {
5747 sdp->below = ENTREZ_OP_BUTNOT;
5748 next->above = ENTREZ_OP_BUTNOT;
5749 } else if (sdp->below == ENTREZ_OP_BUTNOT) {
5750 sdp->below = ENTREZ_OP_AND;
5751 next->above = ENTREZ_OP_AND;
5752 }
5753 ObjectRect (pFormInfo->chosenDoc, &r);
5754 InsetRect (&r, 4, 4);
5755 r.right = r.left + 16;
5756 Select (pFormInfo->chosenDoc);
5757 InvalRect (&r);
5758 ResetClip ();
5759 WatchCursor ();
5760 Update ();
5761 RecalculateChosen (pFormInfo);
5762 ArrowCursor ();
5763 }
5764 }
5765 }
5766
5767 /*==================================================================*/
5768 /* */
5769 /* RemoveTermFromList () - Removes the given term from the given */
5770 /* doubly-linked list of terms, and */
5771 /* adjusts the surrounding terms */
5772 /* accordingly. */
5773 /* */
5774 /*==================================================================*/
5775
5776 static Boolean RemoveTermFromList (FormInfoPtr pFormInfo, StateDataPtr sdp, Boolean goingDown, Boolean lastDraggedDown)
5777
5778 {
5779 StateDataPtr prev;
5780 StateDataPtr next;
5781 Int2 op;
5782
5783 /*-----------------------------*/
5784 /* Sanity check - can't remove */
5785 /* term from an empty list. */
5786 /*-----------------------------*/
5787
5788 if (sdp == NULL) return E2_LIST_NOT_MODIFIED;
5789
5790 /*------------------------------------*/
5791 /* Detach term from surrounding terms */
5792 /*------------------------------------*/
5793
5794 next = sdp->next;
5795 prev = sdp->prev;
5796 switch (sdp->group) {
5797 case GROUP_SINGLE:
5798 if (lastDraggedDown)
5799 return E2_LIST_NOT_MODIFIED;
5800 break;
5801 case GROUP_FIRST:
5802 if (next != NULL) {
5803 if (next->group == GROUP_MIDDLE)
5804 next->group = GROUP_FIRST;
5805 else if (next->group == GROUP_LAST)
5806 next->group = GROUP_SINGLE;
5807 }
5808 break;
5809 case GROUP_MIDDLE:
5810 break;
5811 case GROUP_LAST:
5812 if (prev != NULL) {
5813 if (prev->group == GROUP_MIDDLE)
5814 prev->group = GROUP_LAST;
5815 else if (prev->group == GROUP_FIRST)
5816 prev->group = GROUP_SINGLE;
5817 }
5818 break;
5819 default:
5820 break;
5821 }
5822
5823 /*-------------------------*/
5824 /* Adjust the state of the */
5825 /* surrounding terms. */
5826 /*-------------------------*/
5827
5828 sdp->prev = NULL;
5829 sdp->next = NULL;
5830 if (prev != NULL)
5831 prev->next = next;
5832 if (next != NULL)
5833 next->prev = prev;
5834 if (prev == NULL)
5835 pFormInfo->termList = next;
5836 op = ENTREZ_OP_NONE;
5837 switch (sdp->group) {
5838 case GROUP_SINGLE:
5839 if (goingDown) {
5840 if (prev != NULL)
5841 op = prev->below;
5842 } else {
5843 if (next != NULL)
5844 op = next->above;
5845 }
5846 if (prev != NULL)
5847 prev->below = op;
5848 if (next != NULL)
5849 next->above = op;
5850 break;
5851 case GROUP_FIRST:
5852 if (prev != NULL)
5853 op = prev->below;
5854 if (next != NULL)
5855 next->above = op;
5856 break;
5857 case GROUP_MIDDLE:
5858 break;
5859 case GROUP_LAST:
5860 if (next != NULL)
5861 op = next->above;
5862 if (prev != NULL)
5863 prev->below = op;
5864 break;
5865 default:
5866 break;
5867 }
5868
5869 /*---------------------*/
5870 /* Return successfully */
5871 /*---------------------*/
5872
5873 return E2_LIST_MODIFIED;
5874 }
5875
5876 /*====================================================================*/
5877 /* */
5878 /* AddTermToList () - Adds a given term to the given doubly-linked */
5879 /* list of terms, and adjusts the surrounding */
5880 /* terms accordingly. */
5881 /* */
5882 /*====================================================================*/
5883
5884 static void AddTermToList (FormInfoPtr pFormInfo, StateDataPtr newTerm, Int2 item, Boolean merge)
5885
5886 {
5887 StateDataPtr prev;
5888 StateDataPtr next;
5889 StateDataPtr currTerm;
5890 Int2 op;
5891
5892 /*-------------------------------------*/
5893 /* Add the new term into the term list */
5894 /*-------------------------------------*/
5895
5896 currTerm = pFormInfo->termList;
5897 if (currTerm == NULL)
5898 pFormInfo->termList = newTerm;
5899 else {
5900 while (item > 1 && currTerm->next != NULL) {
5901 item--;
5902 currTerm = currTerm->next;
5903 }
5904 next = currTerm->next;
5905 prev = currTerm->prev;
5906 currTerm->next = newTerm;
5907 newTerm->next = next;
5908 newTerm->prev = currTerm;
5909 if (next != NULL)
5910 next->prev = newTerm;
5911 op = ENTREZ_OP_NONE;
5912 if (prev != NULL)
5913 op = prev->below;
5914 currTerm->above = op;
5915 newTerm->below = currTerm->below;
5916 currTerm->below = ENTREZ_OP_NONE;
5917 newTerm->above = ENTREZ_OP_NONE;
5918 }
5919
5920 /*----------------------------------*/
5921 /* Do adding to group, if necessary */
5922 /*----------------------------------*/
5923
5924 newTerm->group = GROUP_SINGLE;
5925 if (merge && currTerm != NULL) {
5926 switch (currTerm->group) {
5927 case GROUP_SINGLE:
5928 currTerm->group = GROUP_FIRST;
5929 newTerm->group = GROUP_LAST;
5930 break;
5931 case GROUP_FIRST:
5932 newTerm->group = GROUP_MIDDLE;
5933 break;
5934 case GROUP_MIDDLE:
5935 newTerm->group = GROUP_MIDDLE;
5936 break;
5937 case GROUP_LAST:
5938 currTerm->group = GROUP_MIDDLE;
5939 newTerm->group = GROUP_LAST;
5940 break;
5941 default:
5942 break;
5943 }
5944 }
5945
5946 /*-----------------------------------------*/
5947 /* If it's not in a group, then by default */
5948 /* it's AND'd with the neighboring terms. */
5949 /*-----------------------------------------*/
5950
5951 else {
5952 prev = newTerm->prev;
5953 if (prev != NULL) {
5954 prev->below = ENTREZ_OP_AND;
5955 newTerm->above = ENTREZ_OP_AND;
5956 }
5957 }
5958 }
5959
5960 /*==================================================================*/
5961 /* */
5962 /* ReleaseChosen () - This is the callback function that gets */
5963 /* when the mouse button is released after */
5964 /* dragging a term in the Query Refinement */
5965 /* panel. */
5966 /* */
5967 /*==================================================================*/
5968
5969 static void ReleaseChosen (DoC d, PoinT pt)
5970
5971 {
5972 Int2 col;
5973 Boolean goingDown;
5974 Int2 inval;
5975 Int2 item;
5976 Boolean lastDraggedDown;
5977 Boolean merge;
5978 Int2 oldItem;
5979 RecT r;
5980 Int2 row;
5981 RecT s;
5982 StateDataPtr sdp;
5983 RecT sr;
5984 FormInfoPtr pFormInfo;
5985
5986 pFormInfo = (FormInfoPtr) GetObjectExtra (d);
5987
5988 /*---------------------------------------*/
5989 /* Map the current cursor position to an */
5990 /* item in the Query Refinement panel. */
5991 /*---------------------------------------*/
5992
5993 MapDocPoint (d, pt, &item, &row, &col, &r);
5994 if (item > 0 && row == 0 && col > 0)
5995 row = 1;
5996
5997 /*-------------*/
5998 /*-------------*/
5999
6000 if (pFormInfo->chosenInAboveBox || pFormInfo->chosenInBelowBox) {
6001 LoadRect (&s, r.left, r.top, r.left + 16, r.top + 5);
6002 if (PtInRect (pt, &s)) {
6003 if ((pFormInfo->chosenInAboveBox) && (item == pFormInfo->chosenItem))
6004 FlipOperatorBelow (pFormInfo, pFormInfo->chosenItem - 1);
6005 else if ((pFormInfo->chosenInBelowBox) && (item == pFormInfo->chosenItem - 1))
6006 FlipOperatorBelow (pFormInfo, pFormInfo->chosenItem - 1);
6007 }
6008 LoadRect (&s, r.left, r.bottom - 5, r.left + 16, r.bottom);
6009 if (PtInRect (pt, &s)) {
6010 if ((pFormInfo->chosenInBelowBox) && (item == pFormInfo->chosenItem))
6011 FlipOperatorBelow (pFormInfo, pFormInfo->chosenItem);
6012 else if ((pFormInfo->chosenInAboveBox) && (item == pFormInfo->chosenItem + 1))
6013 FlipOperatorBelow (pFormInfo, pFormInfo->chosenItem);
6014 }
6015 return;
6016 }
6017
6018 /*-----------------------*/
6019 /*-----------------------*/
6020
6021 if (pFormInfo->chosenItem > 0) {
6022
6023 oldItem = pFormInfo->chosenItem;
6024 pFormInfo->chosenItem = 0;
6025 InvertMode ();
6026 FrameChosen (pFormInfo);
6027 Update ();
6028 InvalDocCols (pFormInfo->chosenDoc, oldItem, 1, 2);
6029 Update ();
6030 if (item == oldItem) return;
6031 if (pFormInfo->chosenNumLines < 2) return;
6032
6033 /*-----------------------------------------------*/
6034 /* Are we dragging the last item 'past' the end? */
6035 /*-----------------------------------------------*/
6036
6037 lastDraggedDown = FALSE;
6038 if (oldItem == pFormInfo->chosenNumLines && item > pFormInfo->chosenNumLines)
6039 lastDraggedDown = TRUE;
6040
6041 /*-----------*/
6042 /*-----------*/
6043
6044 merge = TRUE;
6045 ObjectRect (pFormInfo->chosenDoc, &sr);
6046 InsetRect (&sr, 4, 4);
6047 /*
6048 if (item > pFormInfo->chosenNumLines && PtInRect (pt, &sr))
6049 */
6050 if (item == 0 && PtInRect (pt, &sr)) {
6051 merge = FALSE;
6052 item = INT2_MAX;
6053 }
6054
6055 /*-------*/
6056 /*-------*/
6057
6058 if ((item <= 0) || (pFormInfo->termList == NULL))
6059 return;
6060
6061 /*--------------------------------------*/
6062 /* Are we moving an item down the list? */
6063 /*--------------------------------------*/
6064
6065 goingDown = FALSE;
6066 if (item > oldItem) {
6067 item--;
6068 goingDown = TRUE;
6069 }
6070
6071 /*--------------------------------*/
6072 /* Find the item being dragged in */
6073 /* the state list. */
6074 /*--------------------------------*/
6075
6076 sdp = pFormInfo->termList;
6077 while (oldItem > 1 && sdp != NULL) {
6078 oldItem--;
6079 sdp = sdp->next;
6080 }
6081
6082 /*----------------------------------------*/
6083 /* Remove the term from the term list and */
6084 /* then re-add it in it's new position. */
6085 /*----------------------------------------*/
6086
6087 if (RemoveTermFromList (pFormInfo, sdp, goingDown, lastDraggedDown) ==
6088 E2_LIST_NOT_MODIFIED) return;
6089
6090 AddTermToList (pFormInfo, sdp, item, merge);
6091
6092 /*---------------------------*/
6093 /* Recalculate the new query */
6094 /* and redisplay it. */
6095 /*---------------------------*/
6096
6097 ResetClip ();
6098 WatchCursor ();
6099 Update ();
6100 AlphabetizeGroups (pFormInfo);
6101 RepopulateChosen (pFormInfo);
6102 RecalculateChosen (pFormInfo);
6103 ArrowCursor ();
6104 }
6105
6106 /*------------------------------------*/
6107 /* If the count column was clicked on */
6108 /* then toggle rows state on or off. */
6109 /*------------------------------------*/
6110
6111 if ((pFormInfo->chosenClickItem == item) &&
6112 (pFormInfo->chosenClickRow == row) &&
6113 (pFormInfo->chosenClickCol == col) &&
6114 (col == 3)) {
6115 inval = item;
6116 sdp = pFormInfo->termList;
6117 while (sdp != NULL && item > 1) {
6118 sdp = sdp->next;
6119 item--;
6120 }
6121 if (sdp == NULL) return;
6122 switch (sdp->state) {
6123 case STATE_OFF:
6124 sdp->state = STATE_ON;
6125 break;
6126 case STATE_ON:
6127 sdp->state = STATE_OFF;
6128 break;
6129 default:
6130 sdp->state = STATE_OFF;
6131 break;
6132 }
6133 ResetClip ();
6134 WatchCursor ();
6135 InvalDocCols (pFormInfo->chosenDoc, inval, 3, 3);
6136 Update ();
6137 RecalculateChosen (pFormInfo);
6138 ArrowCursor ();
6139 }
6140 }
6141
6142 /*==================================================================*/
6143 /* */
6144 /* InitChosenPanel () - */
6145 /* */
6146 /*==================================================================*/
6147
6148 static void InitChosenPanel (FormInfoPtr pFormInfo)
6149
6150 {
6151 Entrez2InfoPtr e2ip;
6152 Entrez2DbInfoPtr e2db;
6153 Entrez2FieldInfoPtr e2fd;
6154 Int2 maxWidth = 0;
6155 RecT r;
6156 Char str [32];
6157
6158 SetDocProcs (pFormInfo->chosenDoc, ClickChosen, DragChosen, ReleaseChosen, NULL);
6159 SetDocShade (pFormInfo->chosenDoc, DrawChosenBrackets, NULL, HighlightChosen, NULL);
6160 pFormInfo->chosenNumLines = 0;
6161
6162 ObjectRect (pFormInfo->chosenDoc, &r);
6163 InsetRect (&r, 4, 4);
6164
6165 SelectFont (systemFont);
6166 chosenColFmt [2].pixWidth = StringWidth ("0000000") + 10;
6167 chosenColFmt [1].pixWidth = StringWidth ("0000000") + 10;
6168
6169 /* more accurate calculation of chosenColFmt [1].pixWidth */
6170
6171 e2ip = Query_GetInfo ();
6172 if (e2ip != NULL) {
6173 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
6174 for (e2fd = e2db->fields; e2fd != NULL; e2fd = e2fd->next) {
6175 if (e2fd->field_name == NULL || StringLen (e2fd->field_name) > 20) continue;
6176 sprintf (str, " [%s]", e2fd->field_name);
6177 maxWidth = MAX (maxWidth, StringWidth (str));
6178 }
6179 }
6180 chosenColFmt [1].pixWidth = maxWidth + 10;
6181 }
6182
6183 chosenColFmt [0].pixWidth = (r.right - r.left) - chosenColFmt [1].pixWidth - chosenColFmt [2].pixWidth;
6184 SetDocAutoAdjust (pFormInfo->chosenDoc, FALSE);
6185
6186 InvalDocument (pFormInfo->chosenDoc);
6187 }
6188
6189 /*==================================================================*/
6190 /* */
6191 /* SetupStdQueryGroup () - Create and initialize the Standard */
6192 /* Query Form. */
6193 /* */
6194 /*==================================================================*/
6195
6196 static GrouP SetupStdQueryGroup (FormInfoPtr pFormInfo, GrouP mainGroup)
6197
6198 {
6199 Entrez2DbInfoPtr e2db;
6200 Entrez2InfoPtr e2ip;
6201 GrouP stdQueryGroup;
6202 GrouP enumlistGroup;
6203 EnumFieldAssocPtr alist;
6204 Int2 idx;
6205 Int2 db;
6206 Int2 wid;
6207 GrouP c;
6208 GrouP j;
6209 GrouP q1;
6210 GrouP q2;
6211 GrouP q3;
6212 PrompT ppt1;
6213 PrompT ppt2;
6214 ModeChoice mc;
6215 ModeIndex md;
6216 RecT r;
6217
6218 /*---------------------------------*/
6219 /* Get info about the DB server(s) */
6220 /*---------------------------------*/
6221
6222 e2ip = Query_GetInfo ();
6223 if (e2ip == NULL) return NULL;
6224
6225 /*---------------------------------*/
6226 /* Create the Standard Query Group */
6227 /*---------------------------------*/
6228
6229 stdQueryGroup = HiddenGroup (mainGroup, -1, 0, NULL);
6230 SetGroupSpacing (stdQueryGroup, 5, 5);
6231
6232 /*---------------------------------*/
6233 /* Create a group for the pulldown */
6234 /* lists and the accept button. */
6235 /*---------------------------------*/
6236
6237 enumlistGroup = HiddenGroup (stdQueryGroup, 0, 2, NULL);
6238 SetGroupSpacing (enumlistGroup, 15, 2);
6239
6240 /*-------------------------------*/
6241 /* Set up database pulldown list */
6242 /*-------------------------------*/
6243
6244 StaticPrompt (enumlistGroup, "Database:", 0, 0, programFont, 'l');
6245 q1 = HiddenGroup (enumlistGroup, 0, 0, NULL);
6246 alist = CreateDatabaseAlist (e2ip);
6247 idx = DBGetIDFromName ("PubMed");
6248
6249 pFormInfo->databasePopup = CreateEnumPopupDialog (q1, TRUE, ChangeDatabase_Callback, alist, (UIEnum) idx, NULL);
6250 SetObjectExtra (pFormInfo->databasePopup, pFormInfo, NULL);
6251 FreeEnumFieldAlist (alist);
6252 pFormInfo->currDb = idx;
6253
6254 /*-------------------------------*/
6255 /* Set up field pulldown list(s) */
6256 /*-------------------------------*/
6257
6258 StaticPrompt (enumlistGroup, "Field:", 0, 0, programFont, 'l');
6259 q2 = HiddenGroup (enumlistGroup, 0, 0, NULL);
6260 pFormInfo->fieldsPopup = MemNew (sizeof (PopuP) * (e2ip->db_count + 2));
6261 idx = FieldGetIDFromName (pFormInfo->currDb, "ALL");
6262 for (e2db = e2ip->db_info; e2db != NULL; e2db = e2db->next) {
6263 db = DBGetIDFromName (e2db->db_name);
6264 alist = CreateFieldAlist (e2db);
6265 pFormInfo->fieldsPopup [db] = CreateEnumPopupDialog (q2, TRUE, ChangeField_Callback, alist, (UIEnum) idx, pFormInfo);
6266 FreeEnumFieldAlist (alist);
6267 Hide (pFormInfo->fieldsPopup [db]);
6268 }
6269 pFormInfo->currField = idx;
6270 db = DBGetIDFromName ("PubMed");
6271 Show (pFormInfo->fieldsPopup [db]);
6272
6273 /*---------------------------*/
6274 /* Set up mode pulldown list */
6275 /*---------------------------*/
6276
6277 StaticPrompt (enumlistGroup, "Mode:", 0, 0, programFont, 'l');
6278 q3 = HiddenGroup (enumlistGroup, 0, 0, NULL);
6279 for (md = POPUP_MULT; md <= POPUP_UID; md++) {
6280 alist = mode_alists [md];
6281 mc = SELECTION_MODE;
6282 if (md == POPUP_MULT)
6283 mc = AUTOMATIC_MODE;
6284 else if (md == POPUP_AUTO)
6285 mc = TRANSLATE_MODE;
6286 else if (md == POPUP_UID)
6287 mc = LOOKUP_UID_MODE;
6288 pFormInfo->modesPopup [md] = CreateEnumPopupDialog (q3, TRUE, ChangeMode_Callback, alist, (UIEnum) mc, pFormInfo);
6289 Hide (pFormInfo->modesPopup [md]);
6290 }
6291 pFormInfo->currMode = AUTOMATIC_MODE;
6292 md = POPUP_MULT;
6293 Show (pFormInfo->modesPopup [md]);
6294
6295 /*----------------------*/
6296 /* Set up accept button */
6297 /*----------------------*/
6298
6299 StaticPrompt (enumlistGroup, "", 0, 0, programFont, 'l');
6300 pFormInfo->acceptButton = DefaultButton (enumlistGroup, "Accept", Accept_Callback);
6301 SetObjectExtra (pFormInfo->acceptButton, pFormInfo, NULL);
6302 Disable (pFormInfo->acceptButton);
6303
6304 AlignObjects (ALIGN_MIDDLE, (HANDLE) q1, (HANDLE) q2, (HANDLE) q3, (HANDLE) pFormInfo->acceptButton, NULL);
6305
6306 /*------------------------------*/
6307 /* Create a group to contain: */
6308 /* */
6309 /* Term entry */
6310 /* From/To Range entry */
6311 /* Taxonomy 'Lineage' popup */
6312 /* */
6313 /* These are mutually exclusive */
6314 /* and only one of these will */
6315 /* be visible at a time. */
6316 /*------------------------------*/
6317
6318 c = HiddenGroup (stdQueryGroup, 0, 0, NULL);
6319
6320 GetPosition (pFormInfo->acceptButton, &r);
6321 SelectFont (programFont);
6322 wid = r.right - (StringWidth ("From:") + StringWidth ("To:")) - 30;
6323 SelectFont (systemFont);
6324 wid /= 2 * stdCharWidth;
6325
6326 pFormInfo->termGroup = HiddenGroup (c, 2, 0, NULL);
6327 StaticPrompt (pFormInfo->termGroup, "Term:", 0, dialogTextHeight, programFont, 'l');
6328 pFormInfo->termText = DialogText (pFormInfo->termGroup, "", 20, TextAction);
6329 SetObjectExtra (pFormInfo->termText, pFormInfo, NULL);
6330
6331 pFormInfo->rangeGroup = HiddenGroup (c, 4, 0, NULL);
6332 StaticPrompt (pFormInfo->rangeGroup, "From:", 0, dialogTextHeight, programFont, 'l');
6333 pFormInfo->fromText = DialogText (pFormInfo->rangeGroup, "", wid, FromTextAction);
6334 pFormInfo->isValidFrom = FALSE;
6335 SetObjectExtra (pFormInfo->fromText, pFormInfo, NULL);
6336
6337 StaticPrompt (pFormInfo->rangeGroup, "To:", 0, dialogTextHeight, programFont, 'l');
6338 pFormInfo->toText = DialogText (pFormInfo->rangeGroup, "", wid, ToTextAction);
6339 pFormInfo->isValidTo = FALSE;
6340 SetObjectExtra (pFormInfo->toText, pFormInfo, NULL);
6341 Hide (pFormInfo->rangeGroup);
6342
6343 pFormInfo->taxLineagePopup = PopupList (c, TRUE, ChangeTaxParents_Callback);
6344 Hide (pFormInfo->taxLineagePopup);
6345 SetObjectExtra (pFormInfo->taxLineagePopup, pFormInfo, NULL);
6346 pFormInfo->taxStrings = NULL;
6347
6348 /*------------------------------------*/
6349 /* Create the Avail and Chosen panels */
6350 /*------------------------------------*/
6351
6352 c = HiddenGroup (stdQueryGroup, -1, 0, NULL);
6353 ppt1 = StaticPrompt (c, "Term Selection", 0, 0, programFont, 'c');
6354 pFormInfo->availDoc = DocumentPanel (c, 10 * stdCharWidth, 7 * stdLineHeight);
6355 SetObjectExtra (pFormInfo->availDoc, pFormInfo, NULL);
6356
6357 ppt2 = StaticPrompt (c, "Query Refinement", 0, 0, programFont, 'c');
6358 j = HiddenGroup (c, 0, 0, NULL);
6359 pFormInfo->chosenDoc = DocumentPanel (j, 10 * stdCharWidth, 7 * stdLineHeight);
6360 SetObjectExtra (pFormInfo->chosenDoc, pFormInfo, NULL);
6361
6362 /*-------------------*/
6363 /* Align the objects */
6364 /*-------------------*/
6365
6366 AlignObjects (ALIGN_CENTER, (HANDLE) pFormInfo->taxLineagePopup, (HANDLE) pFormInfo->termGroup, NULL);
6367 AlignObjects (ALIGN_MIDDLE, (HANDLE) pFormInfo->taxLineagePopup, (HANDLE) pFormInfo->termGroup, (HANDLE) pFormInfo->rangeGroup, NULL);
6368 AlignObjects (ALIGN_RIGHT,
6369 (HANDLE) pFormInfo->acceptButton,
6370 (HANDLE) pFormInfo->termText,
6371 (HANDLE) pFormInfo->availDoc, (HANDLE) pFormInfo->chosenDoc, (HANDLE) pFormInfo->toText, (HANDLE) ppt1, (HANDLE) ppt2, NULL);
6372
6373 /*---------------------------------*/
6374 /* Create a group for the Retrieve */
6375 /* and Reset buttons. */
6376 /*---------------------------------*/
6377
6378 c = HiddenGroup (stdQueryGroup, 5, 0, NULL);
6379 SetGroupSpacing (c, 10, 10);
6380
6381 pFormInfo->retrieveButton = PushButton (c, "Retrieve 000000000 Documents", pFormInfo->retrieveDocsProc);
6382 SetObjectExtra (pFormInfo->retrieveButton, pFormInfo, NULL);
6383 SetTitle (pFormInfo->retrieveButton, "Retrieve 0 Documents");
6384 Disable (pFormInfo->retrieveButton);
6385
6386 pFormInfo->resetButton = PushButton (c, "Reset", Reset_Callback);
6387 SetObjectExtra (pFormInfo->resetButton, pFormInfo, NULL);
6388
6389 /*----------------------------------------*/
6390 /* Initialize the Avail and Chosen panels */
6391 /*----------------------------------------*/
6392
6393 InitChosenPanel (pFormInfo);
6394 InitAvailPanel (pFormInfo);
6395
6396 /*---------------------*/
6397 /* Return successfully */
6398 /*---------------------*/
6399
6400 return stdQueryGroup;
6401 }
6402
6403 /*==================================================================*/
6404 /* */
6405 /* CreateTermlistForm() - */
6406 /* */
6407 /* The object hierarchy is: */
6408 /* */
6409 /* MainWindow */
6410 /* MainGroup */
6411 /* */
6412 /* PulldownMenus */
6413 /* */
6414 /* StdQueryGroup */
6415 /* EnumListGroup */
6416 /* DbPopup */
6417 /* FieldPopup */
6418 /* ModePopup(s) */
6419 /* AcceptButton */
6420 /* MiscGroup */
6421 /* TermDialogText */
6422 /* FromDialogText */
6423 /* ToDialogText */
6424 /* TaxLineagePopup */
6425 /* AvailGroup */
6426 /* AvailPrompt */
6427 /* AvailPanel */
6428 /* ChosenGroup */
6429 /* ChosenPrompt */
6430 /* ChosenPanel */
6431 /* ButtonGroup */
6432 /* RetrieveButton */
6433 /* ResetButton */
6434 /* */
6435 /* AdvQueryGroup */
6436 /* AdvQueryTextBox */
6437 /* ButtonGroup */
6438 /* EvaluateButton */
6439 /* RetrieveButton */
6440 /* ResetButton */
6441 /* */
6442 /*==================================================================*/
6443
6444 NLM_EXTERN ForM CreateTermlistForm (
6445 Int2 left,
6446 Int2 top,
6447 CharPtr title,
6448 WndActnProc activateCallback,
6449 FormMessageFunc messagesCallback,
6450 E2RetrieveDocsProc retrieveCallback,
6451 E2RetrieveUidProc retrieveUidCallback,
6452 Boolean explodeToggle,
6453 Boolean advancedQueryToggle
6454 )
6455
6456 {
6457 WindoW mainWindow;
6458 GrouP mainGroup;
6459 FormInfoPtr pFormInfo;
6460
6461 /*-----------------------------------*/
6462 /* Create a formInfo structure to be */
6463 /* filled in by this function. */
6464 /*-----------------------------------*/
6465
6466 pFormInfo = (FormInfoPtr) MemNew (sizeof (FormInfo));
6467 if (pFormInfo == NULL) return NULL;
6468
6469 /*-----------------------------*/
6470 /* Fill in some default values */
6471 /*-----------------------------*/
6472
6473 pFormInfo->advQueryLexPos = 0;
6474 pFormInfo->advQueryLexStr = NULL;
6475 pFormInfo->advQueryLexState = LEXSTATE_IDLE;
6476 pFormInfo->advQueryNextToken = NULL;
6477 pFormInfo->form = NULL;
6478 pFormInfo->termList = NULL;
6479
6480 /*----------------------------*/
6481 /* Create the Main Window and */
6482 /* set up basic callbacks. */
6483 /*----------------------------*/
6484
6485 mainWindow = FixedWindow (left, top, -10, -10, title, StdSendCloseWindowMessageProc);
6486 if (mainWindow == NULL) return NULL;
6487
6488 pFormInfo->formmessage = EditMessage_Callback;
6489 pFormInfo->appmessage = messagesCallback;
6490 pFormInfo->activate = activateCallback;
6491 pFormInfo->retrieveDocsProc = retrieveCallback;
6492 pFormInfo->retrieveUidProc = retrieveUidCallback;
6493 SetActivate (mainWindow, TermListActivate_Callback);
6494
6495 /*---------------------------------------*/
6496 /* Set up the menus and an overall group */
6497 /* for everything in the termlist window */
6498 /*---------------------------------------*/
6499
6500 SetupMenus (mainWindow, pFormInfo, explodeToggle, advancedQueryToggle);
6501
6502 mainGroup = HiddenGroup (mainWindow, 0, 0, NULL);
6503
6504 pFormInfo->stdQueryGroup = SetupStdQueryGroup (pFormInfo, mainGroup);
6505 pFormInfo->advQueryGroup = SetupAdvQueryGroup (pFormInfo, mainGroup);
6506
6507 AlignObjects (ALIGN_RIGHT, (HANDLE) pFormInfo->availDoc, (HANDLE) pFormInfo->advQueryText, NULL);
6508
6509 /*----------------------------------*/
6510 /* Show the advanced query group if */
6511 /* we're in advanced query mode. */
6512 /*----------------------------------*/
6513
6514 if (advancedQueryToggle == TRUE)
6515 SafeHide (pFormInfo->stdQueryGroup);
6516 else
6517 SafeHide (pFormInfo->advQueryGroup);
6518
6519 /*--------------------------------------*/
6520 /* Select the default starting database */
6521 /*--------------------------------------*/
6522
6523 ChangeDatabase (pFormInfo->databasePopup);
6524
6525 /*--------------------------------*/
6526 /* Fill in the FormInfo structure */
6527 /*--------------------------------*/
6528
6529 pFormInfo->form = (ForM) mainWindow;
6530
6531 /*---------------------*/
6532 /* Return successfully */
6533 /*---------------------*/
6534
6535 SetObjectExtra ((ForM) mainWindow, (BaseFormPtr) pFormInfo, TermListCleanup_Callback);
6536
6537 RealizeWindow (mainWindow);
6538 SetWindowTimer (mainWindow, AvailTimerProc);
6539
6540 return pFormInfo->form;
6541 }
6542
6543 /*==================================================================*/
6544 /* */
6545 /* Query_GetInfo () - Connect to the Entrez2 server and get DB */
6546 /* info -- db names, field names, etc. */
6547 /* */
6548 /*==================================================================*/
6549
6550 NLM_EXTERN Entrez2InfoPtr Query_GetInfo (void)
6551
6552 {
6553 Entrez2RequestPtr e2rq;
6554 Entrez2ReplyPtr e2ry;
6555 FILE *fp;
6556 ValNodePtr head = NULL;
6557 Char path [PATH_MAX];
6558 CharPtr str;
6559 ValNodePtr vnp;
6560
6561 /*---------------------------------*/
6562 /* Only query the server once, use */
6563 /* stored version afterwards. */
6564 /*---------------------------------*/
6565
6566 if (s_masterE2ip != NULL) return s_masterE2ip;
6567
6568 /*----------------------------------*/
6569 /* Request the data from the server */
6570 /*----------------------------------*/
6571
6572 e2rq = EntrezCreateGetInfoRequest ();
6573 if (e2rq == NULL) return NULL;
6574
6575 if (ShowASN () == TRUE)
6576 DisplayEntrezRequest (e2rq);
6577
6578 e2ry = SpecialEntrezSynchronousQuery (e2rq);
6579 if (e2ry == NULL) return NULL;
6580
6581 if (ShowASN () == TRUE)
6582 DisplayEntrezReply (e2ry);
6583
6584 s_masterE2ip = EntrezExtractInfoReply (e2ry);
6585
6586 Entrez2RequestFree (e2rq);
6587
6588 /*------------------------------*/
6589 /* Validate EntrezInfo contents */
6590 /*------------------------------*/
6591
6592 if (! ValidateEntrez2InfoPtr (s_masterE2ip, &head)) {
6593 TmpNam (path);
6594 fp = FileOpen (path, "w");
6595 if (fp != NULL) {
6596 fprintf (fp, "Entrez2Info Validation Errors\n\n");
6597 for (vnp = head; vnp != NULL; vnp = vnp->next) {
6598 str = (CharPtr) vnp->data.ptrvalue;
6599 if (str == NULL) continue;
6600 fprintf (fp, "%s\n", str);
6601 }
6602 FileClose (fp);
6603 LaunchGeneralTextViewer (path, "ValidateEntrez2InfoPtr");
6604 }
6605 FileRemove (path);
6606 ValNodeFreeData (head);
6607 }
6608
6609 /*---------------------*/
6610 /* Return successfully */
6611 /*---------------------*/
6612
6613 return s_masterE2ip;
6614 }
6615
6616 /*==================================================================*/
6617 /* */
6618 /* TermlistToRequestCloseGroup () - Builds a boolean request from */
6619 /* the info in the given TermFormPtr. */
6620 /* */
6621 /*==================================================================*/
6622
6623 static Boolean TermlistToRequestCloseGroup (FormInfoPtr pFormInfo, Entrez2RequestPtr e2RequestPtr)
6624
6625 {
6626 Int2 group;
6627 Int2 last;
6628 StateDataPtr sdp;
6629 Boolean isEmpty = TRUE;
6630 Boolean doNotExplode;
6631 Boolean doNotTranslate = FALSE;
6632 CharPtr rangeStr;
6633 CharPtr fromTerm;
6634 CharPtr toTerm;
6635 Entrez2FieldInfoPtr fieldInfo;
6636 CharPtr dbName;
6637
6638 group = 0;
6639 last = 0;
6640 doNotExplode = ! GetStatus (pFormInfo->explodeItem);
6641 sdp = pFormInfo->termList;
6642
6643 /* Loop through all the terms in the linked list */
6644
6645 for (sdp = pFormInfo->termList; sdp != NULL; sdp = sdp->next) {
6646
6647 /* Do not translate if DB is PubMed */
6648 /* and the field is ALL. */
6649
6650 fieldInfo = FieldGetInfo (sdp->db, sdp->fld);
6651 dbName = DBGetNameFromID (sdp->db);
6652
6653 if ((StrICmp(dbName, "PubMed") == 0) &&
6654 (StrICmp(fieldInfo->field_name, "ALL") == 0))
6655 doNotTranslate = doNotExplode; /* doNotTranslate = TRUE; */
6656 else
6657 doNotTranslate = doNotExplode;
6658
6659 if (sdp->group == GROUP_SINGLE || sdp->group == GROUP_FIRST)
6660 group++;
6661 if (sdp->state == STATE_ON) {
6662 isEmpty = FALSE;
6663
6664 /* Add opening parens at beginning */
6665
6666 if (last == 0) {
6667 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_LEFT_PAREN,
6668 NULL, NULL, NULL, 0, 0, NULL, NULL,
6669 doNotExplode, doNotTranslate);
6670 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_LEFT_PAREN,
6671 NULL, NULL, NULL, 0, 0, NULL, NULL,
6672 doNotExplode, doNotTranslate);
6673 }
6674
6675 /* Put an 'OR' operator between groups */
6676
6677 else if (last == group) {
6678 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_OR,
6679 NULL, NULL, NULL, 0, 0, NULL, NULL,
6680 doNotExplode, doNotTranslate);
6681 }
6682
6683 /* Put 'BUTNOT' operator where requested */
6684
6685 else if (sdp->above == ENTREZ_OP_BUTNOT) {
6686 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RIGHT_PAREN,
6687 NULL, NULL, NULL, 0, 0, NULL, NULL,
6688 doNotExplode, doNotTranslate);
6689 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RIGHT_PAREN,
6690 NULL, NULL, NULL, 0, 0, NULL, NULL,
6691 doNotExplode, doNotTranslate);
6692 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_BUTNOT,
6693 NULL, NULL, NULL, 0, 0, NULL, NULL,
6694 doNotExplode, doNotTranslate);
6695 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_LEFT_PAREN,
6696 NULL, NULL, NULL, 0, 0, NULL, NULL,
6697 doNotExplode, doNotTranslate);
6698 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_LEFT_PAREN,
6699 NULL, NULL, NULL, 0, 0, NULL, NULL,
6700 doNotExplode, doNotTranslate);
6701 }
6702
6703 /* Otherwise default operator is 'AND' */
6704
6705 else {
6706 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RIGHT_PAREN,
6707 NULL, NULL, NULL, 0, 0, NULL, NULL,
6708 doNotExplode, doNotTranslate);
6709 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_AND,
6710 NULL, NULL, NULL, 0, 0, NULL, NULL,
6711 doNotExplode, doNotTranslate);
6712 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_LEFT_PAREN,
6713 NULL, NULL, NULL, 0, 0, NULL, NULL,
6714 doNotExplode, doNotTranslate);
6715 }
6716
6717 /* Add in the term itself */
6718
6719 if (sdp->key == NULL) {
6720
6721 /* If it is a range, then split out the to and from */
6722
6723 if (StringChr (sdp->term, ':') != 0) {
6724 rangeStr = (CharPtr) MemNew (strlen (sdp->term) + 1);
6725 StringCpy (rangeStr, sdp->term);
6726 fromTerm = StringTokMT(rangeStr, ":", &rangeStr);
6727 toTerm = StringTokMT(rangeStr, ":", &rangeStr);
6728 if ((fromTerm != NULL) && (toTerm != NULL)) {
6729 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, sdp->field,
6730 fromTerm, NULL, 0, 0, NULL, NULL,
6731 doNotExplode, doNotTranslate);
6732 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RANGE,
6733 NULL, NULL, NULL, 0, 0, NULL, NULL,
6734 doNotExplode, doNotTranslate);
6735 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, sdp->field,
6736 toTerm, NULL, 0, 0, NULL, NULL,
6737 doNotExplode, doNotTranslate);
6738 }
6739 MemFree (rangeStr);
6740 }
6741 else
6742 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, sdp->field,
6743 sdp->term, NULL, 0, 0, NULL, NULL,
6744 doNotExplode, doNotTranslate);
6745 } else {
6746 EntrezAddToBooleanRequest (e2RequestPtr, NULL, 0, NULL, NULL,
6747 sdp->key, 0, 0, NULL, NULL,
6748 doNotExplode, doNotTranslate);
6749 EntrezSetUseHistoryFlag (e2RequestPtr);
6750 }
6751 last = group;
6752 }
6753 }
6754
6755 if (isEmpty == TRUE) return FALSE;
6756
6757 /* Add on the closing parens */
6758
6759 if (group > 0 && last > 0) {
6760 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RIGHT_PAREN,
6761 NULL, NULL, NULL, 0, 0, NULL, NULL,
6762 doNotExplode, doNotTranslate);
6763 EntrezAddToBooleanRequest (e2RequestPtr, NULL, ENTREZ_OP_RIGHT_PAREN,
6764 NULL, NULL, NULL, 0, 0, NULL, NULL,
6765 doNotExplode, doNotTranslate);
6766 }
6767
6768 /* Return successfully */
6769
6770 return TRUE;
6771 }
6772
6773 /*==================================================================*/
6774 /* */
6775 /* Query_FetchUIDs () - Use the linked list of terms stored in */
6776 /* the TermFormPtr to generate a query that */
6777 /* returns all matching UIDs. */
6778 /* */
6779 /*==================================================================*/
6780
6781 NLM_EXTERN Entrez2BooleanReplyPtr Query_FetchUIDs (ForM f)
6782
6783 {
6784 CharPtr dbName;
6785 Entrez2RequestPtr e2RequestPtr;
6786 Entrez2ReplyPtr e2ReplyPtr;
6787 Entrez2BooleanReplyPtr e2BooleanPtr;
6788 FormInfoPtr pFormInfo;
6789
6790 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
6791
6792 /*------------------------------------*/
6793 /* Make sure that we have at hand all */
6794 /* the ingredients for the query. */
6795 /*------------------------------------*/
6796
6797 if (pFormInfo->termList == NULL || pFormInfo->chosenNumLines < 1 || pFormInfo->termList->db < 0) return 0;
6798
6799 /*--------------------------------*/
6800 /* Get the name of the current DB */
6801 /*--------------------------------*/
6802
6803 dbName = DBGetNameFromID (pFormInfo->currDb);
6804 if (StringHasNoText (dbName)) return 0;
6805
6806 /*---------------------------------*/
6807 /* Create an empty Boolean request */
6808 /*---------------------------------*/
6809
6810 e2RequestPtr = EntrezCreateBooleanRequest (TRUE, FALSE, dbName, NULL, 0, 0, NULL, 0, 0);
6811 if (e2RequestPtr == NULL) return 0;
6812
6813 /*------------------------------------*/
6814 /* Convert the linked list of boolean */
6815 /* terms into a boolean request and */
6816 /* send the request to the server. */
6817 /*------------------------------------*/
6818
6819 if (! TermlistToRequestCloseGroup (pFormInfo, e2RequestPtr)) return 0;
6820
6821 if (ShowASN () == TRUE)
6822 DisplayEntrezRequest (e2RequestPtr);
6823
6824 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
6825 if (e2ReplyPtr == NULL) return 0;
6826
6827 if (ShowASN () == TRUE)
6828 DisplayEntrezReply (e2ReplyPtr);
6829
6830 /*----------------------------------*/
6831 /* Parse the count out of the reply */
6832 /*----------------------------------*/
6833
6834 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
6835
6836 /*----------------------------------*/
6837 /* Clean up and return successfully */
6838 /*----------------------------------*/
6839
6840 Entrez2RequestFree (e2RequestPtr);
6841
6842 return e2BooleanPtr;
6843 }
6844
6845 /*==================================================================*/
6846 /* */
6847 /* Query_FetchSeveralCounts () - */
6848 /* */
6849 /*==================================================================*/
6850
6851 NLM_EXTERN Entrez2TermListPtr Query_FetchSeveralCounts (CharPtr dbName, CharPtr fieldName, CharPtr searchStr, Int2 count)
6852
6853 {
6854 Entrez2RequestPtr e2RequestPtr;
6855 Entrez2ReplyPtr e2ReplyPtr;
6856 Entrez2TermListPtr e2TermListPtr;
6857 Int4 termPos;
6858
6859 /*-----------------------------------------*/
6860 /* Find the position of the requested term */
6861 /*-----------------------------------------*/
6862
6863 e2RequestPtr = EntrezCreateGetTermPositionRequest (dbName, fieldName, searchStr);
6864 if (ShowASN () == TRUE)
6865 DisplayEntrezRequest (e2RequestPtr);
6866
6867 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
6868
6869 if (ShowASN () == TRUE)
6870 DisplayEntrezReply (e2ReplyPtr);
6871
6872 if (e2ReplyPtr == NULL) return NULL;
6873
6874 termPos = EntrezExtractTermPosReply (e2ReplyPtr);
6875
6876 /*---------------------------------*/
6877 /* Retrieve the requested term and */
6878 /* several following terms. */
6879 /*---------------------------------*/
6880
6881 e2RequestPtr = EntrezCreateGetTermListRequest (dbName, fieldName, termPos, count);
6882 if (ShowASN () == TRUE)
6883 DisplayEntrezRequest (e2RequestPtr);
6884
6885 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
6886
6887 if (ShowASN () == TRUE)
6888 DisplayEntrezReply (e2ReplyPtr);
6889
6890 if (e2ReplyPtr == NULL) return NULL;
6891
6892 e2TermListPtr = EntrezExtractTermListReply (e2ReplyPtr);
6893
6894 /*---------------------*/
6895 /* Return successfully */
6896 /*---------------------*/
6897
6898 return e2TermListPtr;
6899 }
6900
6901 /*==================================================================*/
6902 /* */
6903 /* Query_FetchCount () - */
6904 /* */
6905 /*==================================================================*/
6906
6907 NLM_EXTERN Int4 Query_FetchCount (ForM f)
6908
6909 {
6910 CharPtr dbName;
6911 Int4 count;
6912 Entrez2RequestPtr e2RequestPtr;
6913 Entrez2ReplyPtr e2ReplyPtr;
6914 Entrez2BooleanReplyPtr e2BooleanPtr;
6915 FormInfoPtr pFormInfo;
6916
6917 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
6918
6919 /*------------------------------------*/
6920 /* Make sure that we have at hand all */
6921 /* the ingredients for the query. */
6922 /*------------------------------------*/
6923
6924 if (pFormInfo->termList == NULL || pFormInfo->chosenNumLines < 1 || pFormInfo->termList->db < 0) return 0;
6925
6926 /*--------------------------------*/
6927 /* Get the name of the current DB */
6928 /*--------------------------------*/
6929
6930 dbName = DBGetNameFromID (pFormInfo->currDb);
6931 if (StringHasNoText (dbName)) return 0;
6932
6933 /*---------------------------------*/
6934 /* Create an empty Boolean request */
6935 /*---------------------------------*/
6936
6937 e2RequestPtr = EntrezCreateBooleanRequest (FALSE, FALSE, dbName, NULL, 0, 0, NULL, 0, 0);
6938 if (e2RequestPtr == NULL) return 0;
6939
6940 /*------------------------------------*/
6941 /* Convert the linked list of boolean */
6942 /* terms into a boolean request and */
6943 /* send the request to the server. */
6944 /*------------------------------------*/
6945
6946 if (! TermlistToRequestCloseGroup (pFormInfo, e2RequestPtr)) return 0;
6947
6948 if (ShowASN () == TRUE)
6949 DisplayEntrezRequest (e2RequestPtr);
6950
6951 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
6952
6953 if (ShowASN () == TRUE)
6954 DisplayEntrezReply (e2ReplyPtr);
6955
6956 if (e2ReplyPtr == NULL) return 0;
6957
6958 /*----------------------------------*/
6959 /* Parse the count out of the reply */
6960 /*----------------------------------*/
6961
6962 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
6963 if (e2BooleanPtr == NULL) return 0;
6964
6965 count = e2BooleanPtr->count;
6966
6967 /*----------------------------------*/
6968 /* Clean up and return successfully */
6969 /*----------------------------------*/
6970
6971 Entrez2BooleanReplyFree (e2BooleanPtr);
6972 Entrez2RequestFree (e2RequestPtr);
6973
6974 return count;
6975 }
6976
6977 /*==================================================================*/
6978 /* */
6979 /* RemoveExtraQuotes () - */
6980 /* */
6981 /*==================================================================*/
6982
6983 static CharPtr RemoveExtraQuotes (CharPtr origString)
6984
6985 {
6986 Int2 charNum = 0;
6987 Int2 length;
6988 CharPtr newString;
6989 Int2 newCharNum = 0;
6990
6991 length = StringLen (origString);
6992 newString = MemNew (length + 1);
6993 for (charNum = 0; charNum < length; charNum++) {
6994 if (origString [charNum] != '"') {
6995 newString [newCharNum] = origString [charNum];
6996 newCharNum++;
6997 }
6998 }
6999
7000 return newString;
7001 }
7002
7003 /*==================================================================*/
7004 /* */
7005 /* Query_FetchParsedCount () - */
7006 /* */
7007 /*==================================================================*/
7008
7009 NLM_EXTERN Int4 Query_FetchParsedCount (ForM f)
7010
7011 {
7012 CharPtr dbName;
7013 Entrez2RequestPtr e2RequestPtr;
7014 Entrez2ReplyPtr e2ReplyPtr;
7015 Int4 count;
7016 Entrez2BooleanReplyPtr e2BooleanPtr;
7017 FormInfoPtr pFormInfo;
7018 Entrez2BooleanTermPtr tmpTerm;
7019 StateDataPtr currentTerm;
7020 Boolean found;
7021 ValNodePtr valNodeTermList;
7022 CharPtr cleanedUpTerm;
7023
7024 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
7025
7026 /*------------------------------------*/
7027 /* Make sure that we have at hand all */
7028 /* the ingredients for the query. */
7029 /*------------------------------------*/
7030
7031 if (pFormInfo->termList == NULL ||
7032 pFormInfo->chosenNumLines < 1 ||
7033 pFormInfo->termList->db < 0)
7034 return -1;
7035
7036 /*--------------------------------*/
7037 /* Get the name of the current DB */
7038 /*--------------------------------*/
7039
7040 dbName = DBGetNameFromID (pFormInfo->currDb);
7041 if (StringHasNoText (dbName)) return -1;
7042
7043 /*---------------------------------*/
7044 /* Create an empty Boolean request */
7045 /*---------------------------------*/
7046
7047 e2RequestPtr = EntrezCreateBooleanRequest (FALSE, TRUE, dbName, NULL,
7048 0, 0, NULL, 0, 0);
7049 if (e2RequestPtr == NULL) return -1;
7050
7051 /*------------------------------------*/
7052 /* Convert the linked list of boolean */
7053 /* terms into a boolean request and */
7054 /* send the request to the server. */
7055 /*------------------------------------*/
7056
7057 if (! TermlistToRequestCloseGroup (pFormInfo, e2RequestPtr)) return -1;
7058
7059 if (ShowASN () == TRUE)
7060 DisplayEntrezRequest (e2RequestPtr);
7061
7062 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
7063
7064 if (ShowASN () == TRUE)
7065 DisplayEntrezReply (e2ReplyPtr);
7066
7067 if (e2ReplyPtr == NULL) return -1;
7068
7069 /*--------------------------------*/
7070 /* Parse the counts for each term */
7071 /* out of the reply. */
7072 /*--------------------------------*/
7073
7074 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
7075 if (e2BooleanPtr == NULL) return -1;
7076
7077 count = e2BooleanPtr->count;
7078
7079 if (e2BooleanPtr->query != NULL) {
7080 valNodeTermList = e2BooleanPtr->query->exp;
7081
7082 while (valNodeTermList != NULL) {
7083 if (valNodeTermList->choice == 3) {
7084 tmpTerm = (Entrez2BooleanTermPtr) valNodeTermList->data.ptrvalue;
7085 cleanedUpTerm = RemoveExtraQuotes (tmpTerm->term);
7086 StringCpy (tmpTerm->term, cleanedUpTerm);
7087 currentTerm = pFormInfo->termList;
7088 found = FALSE;
7089 while ((currentTerm != NULL) && (! found)) {
7090 if ((StrICmp (currentTerm->field, tmpTerm->field) == 0) &&
7091 (StrICmp (currentTerm->term, tmpTerm->term) == 0)) {
7092 currentTerm->count = tmpTerm->term_count;
7093 found = TRUE;
7094 }
7095 currentTerm = currentTerm->next;
7096 }
7097 }
7098 valNodeTermList = valNodeTermList->next;
7099 }
7100 }
7101
7102 /*----------------------------------*/
7103 /* Clean up and return successfully */
7104 /*----------------------------------*/
7105
7106 Entrez2BooleanReplyFree (e2BooleanPtr);
7107 Entrez2RequestFree (e2RequestPtr);
7108
7109 return count;
7110 }
7111
7112 /*==================================================================*/
7113 /* */
7114 /* Query_GetTranslatedCount () - */
7115 /* */
7116 /*==================================================================*/
7117
7118 static Int4 Query_GetTranslatedTermCount (FormInfoPtr pFormInfo, CharPtr dbName, CharPtr fieldName, CharPtr term)
7119
7120 {
7121 Char displayStr [256];
7122 Entrez2RequestPtr e2RequestPtr;
7123 Entrez2ReplyPtr e2ReplyPtr;
7124 Entrez2TermListPtr e2TermListPtr;
7125 Int2 row;
7126 Int4 termPos;
7127 Entrez2TermPtr termPtr;
7128
7129 /*-----------------------------------------*/
7130 /* Find the position of the requested term */
7131 /*-----------------------------------------*/
7132
7133 e2RequestPtr = EntrezCreateGetTermPositionRequest (dbName, fieldName, term);
7134
7135 if (ShowASN () == TRUE)
7136 DisplayEntrezRequest (e2RequestPtr);
7137
7138 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
7139
7140 if (ShowASN () == TRUE)
7141 DisplayEntrezReply (e2ReplyPtr);
7142
7143 if (e2ReplyPtr == NULL) return -1;
7144
7145 termPos = EntrezExtractTermPosReply (e2ReplyPtr);
7146
7147 /*---------------------------------*/
7148 /* Retrieve the requested term and */
7149 /* several following terms. */
7150 /*---------------------------------*/
7151
7152 e2RequestPtr = EntrezCreateGetTermListRequest (dbName, fieldName, termPos, AVAIL_WINDOW_ROWS);
7153
7154 if (ShowASN () == TRUE)
7155 DisplayEntrezRequest (e2RequestPtr);
7156
7157 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
7158
7159 if (ShowASN () == TRUE)
7160 DisplayEntrezReply (e2ReplyPtr);
7161
7162 if (e2ReplyPtr == NULL) return -1;
7163
7164 e2TermListPtr = EntrezExtractTermListReply (e2ReplyPtr);
7165
7166 if (e2TermListPtr == NULL) return -1;
7167
7168 pFormInfo->availItem = 0;
7169 pFormInfo->availRow = 0;
7170 Reset (pFormInfo->availDoc);
7171 SetDocCache (pFormInfo->availDoc, NULL, NULL, NULL);
7172 Update ();
7173
7174 for (row = 1, termPtr = e2TermListPtr->list; row <= AVAIL_WINDOW_ROWS && termPtr != NULL; row++, termPtr = termPtr->next) {
7175 sprintf (displayStr, "%s\t%ld\t%d\n", termPtr->term, (long) (termPtr->count), (int) (termPtr->is_leaf_node ? 1 : 0));
7176 AppendText (pFormInfo->availDoc, displayStr, &availParFmt, availColFmt, systemFont);
7177 }
7178
7179 InvalDocument (pFormInfo->availDoc);
7180 Update ();
7181
7182 if (StringICmp (e2TermListPtr->list->term, term) == 0) return e2TermListPtr->list->count;
7183
7184 return -1;
7185 }
7186
7187 /*==================================================================*/
7188 /* */
7189 /* Query_TranslateAndAddBoolTerm () - */
7190 /* Have the server translate a single term */
7191 /* into multiple terms, each with their own */
7192 /* count. Then add each of these terms to the */
7193 /* the termlist (in an OR'd group) and display */
7194 /* them. */
7195 /* */
7196 /*==================================================================*/
7197
7198 static Boolean Query_TranslateAndAddBoolTerm (
7199 ForM f,
7200 Int2 currDb,
7201 Int2 currFld,
7202 CharPtr strs,
7203 Int2 state,
7204 Int4 num
7205 )
7206
7207 {
7208 StateDataPtr sdp = NULL;
7209 Entrez2RequestPtr e2RequestPtr;
7210 Entrez2ReplyPtr e2ReplyPtr;
7211 Entrez2BooleanReplyPtr e2BooleanPtr;
7212 CharPtr dbName;
7213 Entrez2BooleanTermPtr tmpTerm;
7214 ValNodePtr valNodeTermList;
7215 CharPtr cleanedUpTerm;
7216 Boolean firstTerm;
7217 StateDataPtr prev = NULL;
7218 CharPtr fieldName;
7219 Int2 fieldId;
7220 Entrez2FieldInfoPtr fieldInfo;
7221 FormInfoPtr pFormInfo;
7222 Int2 nextOperator = ENTREZ_OP_NONE;
7223 Int2 nextGroup;
7224 Int2 tmpOp;
7225 Boolean allowDuplicates;
7226 Boolean doNotTranslate;
7227
7228 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
7229
7230 /*-------------------------------------------*/
7231 /* Get the names of the current db and field */
7232 /*-------------------------------------------*/
7233
7234 dbName = DBGetNameFromID (currDb);
7235 if (StringHasNoText (dbName)) return FALSE;
7236
7237 fieldInfo = FieldGetInfo (currDb, currFld);
7238 if (fieldInfo == NULL) return FALSE;
7239
7240 /*------------------------------------------*/
7241 /* Allow duplicates if the DB is PubMed and */
7242 /* the field is All. */
7243 /*------------------------------------------*/
7244
7245 if ((StringICmp (dbName, "PubMed") == 0) &&
7246 (StringICmp (fieldInfo->field_name, "All") == 0))
7247 allowDuplicates = TRUE;
7248 else
7249 allowDuplicates = FALSE;
7250
7251 /*-----------------------------------*/
7252 /* Create and send a boolean request */
7253 /* to return a translated list */
7254 /* of terms for the given term. */
7255 /*-----------------------------------*/
7256
7257 doNotTranslate = TRUE;
7258 e2RequestPtr = EntrezCreateBooleanRequest (FALSE, TRUE, dbName, NULL, 0, 0, NULL, 0, 0);
7259 EntrezAddToBooleanRequest (e2RequestPtr, strs, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, TRUE, doNotTranslate);
7260 if (ShowASN () == TRUE)
7261 DisplayEntrezRequest (e2RequestPtr);
7262
7263 e2ReplyPtr = SpecialEntrezSynchronousQuery (e2RequestPtr);
7264
7265 if (ShowASN () == TRUE)
7266 DisplayEntrezReply (e2ReplyPtr);
7267
7268 if (e2ReplyPtr == NULL) return FALSE;
7269
7270 e2BooleanPtr = EntrezExtractBooleanReply (e2ReplyPtr);
7271 if (e2BooleanPtr == NULL) return FALSE;
7272
7273 if (e2BooleanPtr->query == NULL) return FALSE;
7274
7275 /*------------------------------------------------*/
7276 /* Parse the resulting terms out of the query and */
7277 /* add them one at a time to the current list of */
7278 /* terms and to the chosen window. */
7279 /*------------------------------------------------*/
7280
7281 valNodeTermList = e2BooleanPtr->query->exp;
7282
7283 firstTerm = TRUE;
7284 nextGroup = GROUP_SINGLE;
7285 while (valNodeTermList != NULL) {
7286 if (valNodeTermList->choice == TERMLIST_OPERATOR) {
7287 tmpOp = (Int2) valNodeTermList->data.intvalue;
7288 switch (tmpOp) {
7289 case ENTREZ_OP_AND:
7290 if (sdp != NULL) {
7291 if (sdp->group == GROUP_MIDDLE) {
7292 sdp->group = GROUP_LAST;
7293 } else if (sdp->group == GROUP_FIRST) {
7294 sdp->group = GROUP_SINGLE;
7295 }
7296 }
7297 nextOperator = tmpOp;
7298 nextGroup = GROUP_SINGLE;
7299 break;
7300 case ENTREZ_OP_OR:
7301 case ENTREZ_OP_BUTNOT:
7302 nextOperator = tmpOp;
7303 break;
7304 case ENTREZ_OP_LEFT_PAREN:
7305 nextGroup = GROUP_FIRST;
7306 break;
7307 case ENTREZ_OP_RIGHT_PAREN:
7308 break;
7309 }
7310 } else if (valNodeTermList->choice == TERMLIST_TERM) {
7311
7312 /*---------------------*/
7313 /* Parse the term info */
7314 /*---------------------*/
7315
7316 tmpTerm = (Entrez2BooleanTermPtr) valNodeTermList->data.ptrvalue;
7317 cleanedUpTerm = RemoveExtraQuotes (tmpTerm->term);
7318 StringCpy (tmpTerm->term, cleanedUpTerm);
7319 if (IsValidFieldName (currDb, tmpTerm->field) == FALSE)
7320 fieldName = FieldGetNameFromMenuName (currDb, tmpTerm->field);
7321 else
7322 fieldName = tmpTerm->field;
7323
7324 fieldId = -1;
7325 if (StringDoesHaveText (fieldName)) {
7326 fieldId = FieldGetIDFromName (currDb, fieldName);
7327 }
7328
7329 if (fieldId != -1) {
7330
7331 /*-----------------------------------*/
7332 /* Replace -1 with actual term count */
7333 /* Note -- this also creates the */
7334 /* desired 'flashing' effect in */
7335 /* the termlist window. */
7336 /*-----------------------------------*/
7337
7338 tmpTerm->term_count = Query_GetTranslatedTermCount (pFormInfo, dbName, fieldName, tmpTerm->term);
7339
7340 /*-------------------------------*/
7341 /* Add the term to the term list */
7342 /*-------------------------------*/
7343
7344 if (NULL != sdp)
7345 prev = sdp;
7346 sdp = CreateTerm (f, currDb, fieldId, tmpTerm->term, state,
7347 tmpTerm->term_count, allowDuplicates);
7348 if (NULL == sdp) {
7349 valNodeTermList = valNodeTermList->next;
7350 sdp = prev;
7351 continue;
7352 }
7353
7354 /*-------------------------------*/
7355 /* Make all the translated terms */
7356 /* an or'd group of terms. */
7357 /*-------------------------------*/
7358
7359 switch (nextGroup) {
7360 case GROUP_SINGLE:
7361 sdp->group = GROUP_SINGLE;
7362 break;
7363 case GROUP_FIRST:
7364 sdp->group = GROUP_FIRST;
7365 nextGroup = GROUP_MIDDLE;
7366 break;
7367 case GROUP_MIDDLE:
7368 sdp->group = GROUP_MIDDLE;
7369 break;
7370 case GROUP_LAST:
7371 sdp->group = GROUP_LAST;
7372 break;
7373 }
7374
7375 if (firstTerm == TRUE) {
7376 prev = sdp->prev;
7377 if (prev != NULL) {
7378 sdp->above = ENTREZ_OP_AND;
7379 prev->below = ENTREZ_OP_AND;
7380 }
7381 firstTerm = FALSE;
7382 } else {
7383 prev = sdp->prev;
7384 sdp->above = nextOperator;
7385 prev->below = nextOperator;
7386 }
7387
7388 /*--------------------------------------*/
7389 /* Display the term in the chosen panel */
7390 /*--------------------------------------*/
7391
7392 DisplayTerm (pFormInfo, tmpTerm->term, fieldName, tmpTerm->term_count);
7393
7394 } else {
7395 if (StringDoesHaveText (tmpTerm->field)) {
7396 Message (MSG_POSTERR, "Bad field name %s ignored in expanded query", tmpTerm->field);
7397 } else {
7398 Message (MSG_POSTERR, "Empty field name ignored in expanded query");
7399 }
7400 }
7401 }
7402 valNodeTermList = valNodeTermList->next;
7403 }
7404
7405 /*---------------------------*/
7406 /* Mark the last term as the */
7407 /* last in the group. */
7408 /*---------------------------*/
7409
7410 if (NULL != sdp)
7411 if (sdp->group != GROUP_SINGLE) {
7412 if (sdp->group == GROUP_FIRST)
7413 sdp->group = GROUP_SINGLE;
7414 else
7415 sdp->group = GROUP_LAST;
7416 }
7417
7418 /*--------------------------------*/
7419 /* Flatten out nested 'OR' groups */
7420 /* (A OR (B OR C)) */
7421 /* becomes */
7422 /* (A OR B OR C) */
7423 /*--------------------------------*/
7424
7425 sdp = pFormInfo->termList;
7426 while (sdp != NULL) {
7427 if ((sdp->group == GROUP_FIRST) &&
7428 (sdp->above == ENTREZ_OP_OR) &&
7429 (sdp->below == ENTREZ_OP_OR))
7430 sdp->group = GROUP_MIDDLE;
7431 sdp = sdp->next;
7432 }
7433
7434 /*------------------------*/
7435 /* Recalculate and redraw */
7436 /*------------------------*/
7437
7438 AlphabetizeGroups (pFormInfo);
7439 RepopulateChosen (pFormInfo);
7440 RecalculateChosen (pFormInfo);
7441
7442 /*---------------------*/
7443 /* Return successfully */
7444 /*---------------------*/
7445
7446 return TRUE;
7447 }
7448
7449 /*==================================================================*/
7450 /* */
7451 /* RefineUIDs () - */
7452 /* */
7453 /*==================================================================*/
7454
7455 NLM_EXTERN Boolean RefineUIDs (ForM f, CharPtr term, Int4 num, Int4Ptr uids, Int2 db)
7456
7457 {
7458 CharPtr advQueryStr;
7459 EnumFieldAssocPtr alist;
7460 Entrez2InfoPtr e2ip;
7461 FormInfoPtr pFormInfo;
7462 Char str [64];
7463 WindoW tempPort;
7464
7465 pFormInfo = (FormInfoPtr) GetObjectExtra (f);
7466
7467 /*-------------------------------*/
7468 /* Set the query window settings */
7469 /*-------------------------------*/
7470
7471 e2ip = Query_GetInfo ();
7472 if (e2ip == NULL) return FALSE;
7473
7474 alist = CreateDatabaseAlist (e2ip);
7475 if (pFormInfo->currDb != db) {
7476 SetEnumPopup (pFormInfo->databasePopup, alist, (UIEnum) db);
7477 ChangeDatabase (pFormInfo->databasePopup);
7478 } else
7479 DoResetAvail (pFormInfo, TRUE);
7480
7481 SafeSetTitle (pFormInfo->termText, "");
7482 SafeSetTitle (pFormInfo->fromText, "");
7483 SafeSetTitle (pFormInfo->toText, "");
7484 SafeDisable (pFormInfo->acceptButton);
7485 if (StringHasNoText (term))
7486 term = "*Current_Documents";
7487 if (term [0] == '*')
7488 term++;
7489 StringCpy (str, "*");
7490 StringNCpy (str + 1, term, sizeof (str) - 3);
7491
7492 /*-----------------------------------*/
7493 /* Add the term to the current query */
7494 /* in the query window. */
7495 /*-----------------------------------*/
7496
7497 tempPort = SavePort (pFormInfo->chosenDoc);
7498 Query_AddUidsTerm (pFormInfo->form, str, num, uids, db);
7499 RecalculateChosen (pFormInfo);
7500 RestorePort (tempPort);
7501
7502 if (! GetStatus (pFormInfo->advancedQueryItem)) {
7503 Show (pFormInfo->termText);
7504 Select (pFormInfo->termText);
7505 } else {
7506 advQueryStr = Query_ConvertToString (pFormInfo->form);
7507 SetAdvancedText (pFormInfo->advQueryText, advQueryStr);
7508 MemFree (advQueryStr);
7509 SafeShow (pFormInfo->advQueryGroup);
7510 }
7511
7512 /*---------------------*/
7513 /* Return successfully */
7514 /*---------------------*/
7515
7516 return TRUE;
7517 }
7518
7519 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |