home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / hl10osrc.lzh / Librarian / Librarian.cc < prev    next >
Text File  |  1994-04-23  |  11KB  |  412 lines

  1. /* -*- Mode: C -*- */
  2. /* Librarian.cc - Librarian - query program main line
  3.  * Created by Robert Heller on Tue Mar 17 16:57:42 1992
  4.  *
  5.  * ------------------------------------------------------------------
  6.  * Home Libarian by Deepwoods Software
  7.  * Librarian program - search a card catalog
  8.  * ------------------------------------------------------------------
  9.  * Modification History:
  10.  * ------------------------------------------------------------------
  11.  * Contents:
  12.  * ------------------------------------------------------------------
  13.  * 
  14.  * 
  15.  * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
  16.  *        All Rights Reserved
  17.  * 
  18.  */
  19.  
  20. #include <stream.h>
  21. #include <vBTree.h>
  22. #include <ctype.h>
  23. #ifdef MESSYDOS
  24. #include <CardRec.h>
  25. #include <ListRec.h>
  26. #else
  27. #include <CardRecord.h>
  28. #include <ListRecord.h>
  29. #endif
  30. #include <Terminal.h>
  31. #ifdef MESSYDOS
  32. #include <CmdScren.h>
  33. #include <ScrPmt.h>
  34. #include <LLScrPmt.h>
  35. #else
  36. #include <CommandScreen.h>
  37. #include <ScrollPrompt.h>
  38. #include <LLScrollPrompt.h>
  39. #endif
  40. #define VERSION "V1.0Beta"
  41. #ifdef MESSYDOS
  42. #include "Libraria.h"
  43. #else
  44. #include "Librarian.h"
  45. #endif
  46.  
  47. static vBTree *Tree;
  48. static Terminal *Term;
  49.  
  50. const DisplayBufferSize = 4096;
  51. const Margin = 256;
  52. static char DisplayBuffer[DisplayBufferSize];
  53.  
  54. void DispCard(Key inkey)
  55. {
  56.     int column;
  57.     int lines = 0;
  58.     ScrollPrompt CardOutput("",3,0,80,15,20);
  59.     static char answer[1];
  60.     CoreItem item;
  61.     if (!(Tree->SearchId(inkey,&item) &&
  62.           strlen(inkey) == strlen(item.key))) return;        
  63.     char* outptr = DisplayBuffer;
  64.     strcpy(outptr,item.key); outptr += strlen(item.key);
  65.     *outptr++ = '\n';
  66.     *outptr++ = '\n';
  67.     if (item.data.size > 0) {
  68.         CardRecord rec(&item.data);
  69.         register Card *c = &rec;
  70.         char* tn = TypeName(c->type);
  71.         strcpy(outptr,c->author); outptr += strlen(c->author);
  72.         *outptr++ = ',';
  73.         *outptr++ = ' ';
  74.         sprintf(outptr,"%d\n",c->year); outptr += strlen(outptr);
  75.         strcpy(outptr,"    "); outptr += strlen(outptr);
  76.         strcpy(outptr,c->title); outptr += strlen(outptr);
  77.         *outptr++ = '\n';
  78.         strcpy(outptr,"    "); outptr += strlen(outptr);
  79.         strcpy(outptr,tn); outptr += strlen(tn);
  80.         *outptr++ = '\n';
  81.         strcpy(outptr,"    Published by "); outptr += strlen(outptr);
  82.         strcpy(outptr,c->publisher); outptr += strlen(outptr);
  83.         *outptr++ = ' ';
  84.         strcpy(outptr,c->city); outptr += strlen(outptr);
  85.         *outptr++ = '\n';
  86.         if (c->vol != 0) {
  87.             sprintf(outptr,"    Volume: %d",c->vol);
  88.             outptr += strlen(outptr);
  89.         }
  90.         *outptr++ = '\n';
  91.         *outptr++ = '\n';
  92.         column = 0;
  93.         for (char* p = c->description; lines < 22 && *p != 0; p++) {
  94.             if (*p != '\n' && column < 4) {
  95.                 *outptr++ = ' ';
  96.                 *outptr++ = ' ';
  97.                 *outptr++ = ' ';
  98.                 *outptr++ = ' ';
  99.                 column = 4;
  100.             }
  101.             if (*p == '\n') {
  102.                 *outptr++ = '\n';
  103.                 lines++;
  104.                 column = 0;
  105.             } else if (column > 78) {
  106.                 *outptr++ = '\\';
  107.                 *outptr++ = '\n';
  108.                 lines++;
  109.                 column = 0;
  110.                 p--;
  111.             } else if (*p == '\t') {
  112.                 do {
  113.                     *outptr++ = ' ';
  114.                     column++;
  115.                 } while ((column % 8) != 0);
  116.             } else {
  117.                 *outptr++ = *p;
  118.                 column++;
  119.             }
  120.         }
  121.         if (column > 0) {
  122.             *outptr++ = '\n';
  123.             lines++;
  124.         }
  125.         *outptr = '\0';
  126.         CardOutput.Scroll(DisplayBuffer,"Hit RETURN to continue",answer,1);
  127.     }
  128. }
  129.  
  130. int ListCards()
  131. {
  132.     CoreItem item;
  133.     Key searchkey;
  134.     static char title[80], line[LineLength];
  135.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  136.     sprintf(title,"Ids matching %s",searchkey);
  137.     LLScrollPrompt IdList(title,3,0,80,15,20);
  138.     LineList* llist = (LineList*) 0;
  139.     LineList** ptr = &llist;
  140.     LineList* prev = (LineList*) 0;
  141.     if (Tree->SearchId(searchkey,&item)) {
  142.         do {
  143.             int fill;
  144.             char* p = line;
  145.             strcpy(p,item.key);
  146.             fill = KeySize - strlen(item.key);
  147.             p += strlen(item.key);
  148.             while (fill-- > 0) *p++ = ' ';
  149.             *p++ = ' ';
  150.             {
  151.                 CardRecord crec(&item.data);
  152.                 strcpy(p,crec->title);
  153.                 p += strlen(crec->title);
  154.             }
  155.             *p++ = 0;
  156.             LineList* newline = new LineList(line,0,prev);
  157.             *ptr = newline;
  158.             prev = newline;
  159.             ptr = &newline->nextline;
  160.             //cerr << "*** line = '" << line << "'\n";
  161.         } while (Tree->SearchIdAgain(&item));
  162.         if (llist != (LineList*) 0) {
  163.             if (IdList.Scroll(llist,"Card to view (RETURN for more, q to exit):",title,KeySize) > 0) 
  164.                 DispCard(title);
  165.             FreeLineList(llist);
  166.         }
  167.         return(-1);
  168.     } else {
  169.         Term->Message("No ids found");
  170.         return(1);
  171.     }
  172. }
  173.  
  174. int ListCardsFromList(char* title,ListRecord& list)
  175. {
  176.     CoreItem item;
  177.     static Key newkey;
  178.     static char line[LineLength];
  179.     LLScrollPrompt IdList(title,3,0,80,15,20);
  180.     LineList* llist = (LineList*) 0;
  181.     LineList** ptr = &llist;
  182.     LineList* prev = (LineList*) 0;
  183.     int numids = list.ElementCount();
  184.     for (int i = 0; i < numids; i++) {
  185.         if (Tree->SearchId(list[i],&item) && strlen(list[i]) == strlen(item.key)) {
  186.             int fill;
  187.             char* p = line;
  188.             strcpy(p,item.key);
  189.             fill = KeySize - strlen(item.key);
  190.             p += strlen(item.key);
  191.             while (fill-- > 0) *p++ = ' ';
  192.             *p++ = ' ';
  193.             {
  194.                 CardRecord crec(&item.data);
  195.                 strcpy(p,crec->title);
  196.                 p += strlen(crec->title);
  197.             }
  198.             *p++ = 0;
  199.             LineList* newline = new LineList(line,0,prev);
  200.             *ptr = newline;
  201.             prev = newline;
  202.             ptr = &newline->nextline;
  203.         }
  204.     }
  205.     if (llist != (LineList*) 0) {
  206.         if (IdList.Scroll(llist,"Card to view (RETURN for more, q to exit):",title,KeySize) > 0) 
  207.             DispCard(title);
  208.         FreeLineList(llist);
  209.     }
  210.     return(-1);
  211. }
  212.  
  213. int ListTitles()
  214. {
  215.     CoreItem item;
  216.     Key searchkey;
  217.     static char title[80],header[80],line[LineLength];
  218.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  219.     sprintf(title,"Titles matching %s",searchkey);
  220.     LLScrollPrompt TitleList(title,3,0,80,15,20);
  221.     LineList* llist = (LineList*) 0;
  222.     LineList** ptr = &llist;
  223.     LineList* prev = (LineList*) 0;
  224.     int i;
  225.     int refnum = 0;
  226.     if (Tree->SearchTitle(searchkey,&item)) {
  227.         do {
  228.             refnum++;
  229.             sprintf(line,"%3d: %s",refnum,item.key);
  230.             LineList* newline = new LineList(line,0,prev);
  231.             *ptr = newline;
  232.             prev = newline;
  233.             ptr = &newline->nextline;
  234.         } while (Tree->SearchTitleAgain(&item));
  235.         if (llist != (LineList*) 0) {
  236.             if (refnum == 1) {
  237.                 if (Tree->SearchTitle(llist->thisline+5,&item)) {
  238.                     sprintf(header,"Ids for title %s",item.key);
  239.                     ListRecord rec(&item.data);
  240.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  241.                     else if (rec.ElementCount() > 1)
  242.                         ListCardsFromList(header,rec);
  243.                 }
  244.             } else if (TitleList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  245.                 refnum = atoi(title);
  246.                 for (i = 1,prev = llist;
  247.                      prev != (LineList*)0 && i < refnum;
  248.                      prev = prev->nextline,i++) ;
  249.                 if (i == refnum) {
  250.                     if (Tree->SearchTitle(prev->thisline+5,&item)) {
  251.                         sprintf(header,"Ids for title %s",item.key);
  252.                         ListRecord rec(&item.data);
  253.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  254.                         else if (rec.ElementCount() > 1)
  255.                             ListCardsFromList(header,rec);
  256.                     }
  257.                 } else Term->Message("Bad reference number");
  258.             }
  259.             FreeLineList(llist);
  260.         }
  261.         return(-1);
  262.     } else {
  263.         Term->Message("No titles found");
  264.         return(1);
  265.     }
  266. }
  267.  
  268. int ListAuthors()
  269. {
  270.     CoreItem item;
  271.     Key searchkey;
  272.     static char title[80],header[80],line[LineLength];
  273.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  274.     sprintf(title,"Authors matching %s",searchkey);
  275.     LLScrollPrompt AuthorList(title,3,0,80,15,20);
  276.     LineList* llist = (LineList*) 0;
  277.     LineList** ptr = &llist;
  278.     LineList* prev = (LineList*) 0;
  279.     int refnum = 0;
  280.     int i;
  281.     if (Tree->SearchAuthor(searchkey,&item)) {
  282.         do {
  283.             refnum++;
  284.             sprintf(line,"%3d: %s",refnum,item.key);
  285.             LineList* newline = new LineList(line,0,prev);
  286.             *ptr = newline;
  287.             prev = newline;
  288.             ptr = &newline->nextline;
  289.         } while (Tree->SearchAuthorAgain(&item));
  290.         if (llist != (LineList*) 0) {
  291.             if (refnum == 1) {
  292.                 if (Tree->SearchAuthor(llist->thisline+5,&item)) {
  293.                     sprintf(header,"Ids for author %s",item.key);
  294.                     ListRecord rec(&item.data);
  295.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  296.                     else if (rec.ElementCount() > 1)
  297.                         ListCardsFromList(header,rec);
  298.                 }
  299.             } else if (AuthorList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  300.                 refnum = atoi(title);
  301.                 for (i = 1,prev = llist;
  302.                      prev != (LineList*)0 && i < refnum;
  303.                      prev = prev->nextline,i++) ;
  304.                 if (i == refnum) {
  305.                     if (Tree->SearchAuthor(prev->thisline+5,&item)) {
  306.                         sprintf(header,"Ids for author %s",item.key);
  307.                         ListRecord rec(&item.data);
  308.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  309.                         else if (rec.ElementCount() > 1)
  310.                             ListCardsFromList(header,rec);
  311.                     }
  312.                 } else Term->Message("Bad reference number");
  313.             }
  314.             FreeLineList(llist);
  315.         }
  316.         return(-1);
  317.     } else {
  318.         Term->Message("No authors found");
  319.         return(1);
  320.     }
  321. }
  322.  
  323. int ListSubjects()
  324. {
  325.     CoreItem item;
  326.     Key searchkey;
  327.     static char title[80],header[80],line[LineLength];
  328.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  329.     sprintf(title,"Subjects matching %s",searchkey);
  330.     LLScrollPrompt SubjectList(title,3,0,80,15,20);
  331.     LineList* llist = (LineList*) 0;
  332.     LineList** ptr = &llist;
  333.     LineList* prev = (LineList*) 0;
  334.     int refnum = 0;
  335.     int i;
  336.     if (Tree->SearchSubj(searchkey,&item)) {
  337.         do {
  338.             refnum++;
  339.             sprintf(line,"%3d: %s",refnum,item.key);
  340.             LineList* newline = new LineList(line,0,prev);
  341.             *ptr = newline;
  342.             prev = newline;
  343.             ptr = &newline->nextline;
  344.         } while (Tree->SearchSubjAgain(&item));
  345.         if (llist != (LineList*) 0) {
  346.             if (refnum == 1) {
  347.                 if (Tree->SearchSubj(llist->thisline+5,&item)) {
  348.                     sprintf(header,"Ids for subject %s",item.key);
  349.                     ListRecord rec(&item.data);
  350.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  351.                     else if (rec.ElementCount() > 1)
  352.                         ListCardsFromList(header,rec);
  353.                 }
  354.             } else if (SubjectList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  355.                 refnum = atoi(title);
  356.                 for (i = 1,prev = llist;
  357.                      prev != (LineList*)0 && i < refnum;
  358.                      prev = prev->nextline,i++) ;
  359.                 if (i == refnum) {
  360.                     if (Tree->SearchSubj(prev->thisline+5,&item)) {
  361.                         sprintf(header,"Ids for subject %s",item.key);
  362.                         ListRecord rec(&item.data);
  363.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  364.                         else if (rec.ElementCount() > 1)
  365.                             ListCardsFromList(header,rec);
  366.                     }
  367.                 } else Term->Message("Bad reference number");
  368.             }
  369.             FreeLineList(llist);
  370.         }
  371.         return(-1);
  372.     } else {
  373.         Term->Message("No subjects found");
  374.         return(1);
  375.     }
  376. }
  377.  
  378. static int Quit()
  379. {
  380.     return 0;
  381. }
  382.  
  383. static CommandDescr Main[] = {
  384.     { "Quit", Quit, 0 },
  385.     { "List Cards", ListCards, 0 },
  386.     { "List Titles", ListTitles, 0 },
  387.     { "List Authors", ListAuthors, 0 },
  388.     { "List Subjects", ListSubjects, 0 },
  389. };
  390.  
  391. const NumCommands = sizeof(Main) / sizeof(CommandDescr);
  392.  
  393. main(int argc,char** argv)
  394. {
  395.     static Librarian args(argc,argv);
  396.     vBTree tree(args.infile,ReadOnly,0);
  397.     if (tree.OpenStat() == failure) {
  398.         int error = errno;
  399.         cerr << "Could not open " << args.infile << ": "
  400.              << strerror(error) << "\n";
  401.         exit(error);
  402.     }
  403.     Terminal term;
  404.     Term = &term;
  405.     static CommandScreen mainScreen("Main Command Menu",NumCommands,Main);
  406.     Tree = &tree;
  407.  
  408.     mainScreen.RunScreen();
  409. }
  410.  
  411.  
  412.