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