home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
hl10osrc.lzh
/
EditLibr
/
EditCard.cc
< prev
next >
Wrap
Text File
|
1994-04-23
|
13KB
|
499 lines
/* -*- Mode: C -*- */
/* EditCard.cc - Edit an existing card
* Created by Robert Heller on Wed Dec 11 20:41:43 1991
*
* ------------------------------------------------------------------
* Home Libarian by Deepwoods Software
* Edit a Librarian Card Catalog file
* ------------------------------------------------------------------
* Modification History:
* ------------------------------------------------------------------
* Contents:
* ------------------------------------------------------------------
*
*
* Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
* All Rights Reserved
*
*/
#include <stream.h>
#include <vBTree.h>
#include <ctype.h>
#ifdef MESSYDOS
#include <CardRec.h>
#include <ListRec.h>
#else
#include <CardRecord.h>
#include <ListRecord.h>
#endif
#include <Terminal.h>
#ifdef MESSYDOS
#include <CmdScren.h>
#else
#include <CommandScreen.h>
#endif
#include <EditForm.h>
#include "EditDefs.h"
#include "EditGlob.h"
const BuffSize = 1024;
const DescrSize = 4096;
static Key editkey;
static char Author[BuffSize],Title[BuffSize],Publisher[BuffSize],
City[BuffSize],Description[DescrSize],SubjList[DescrSize],
OrigSubjList[DescrSize];
static Card editcard(Book,Author,Title,Publisher,City,Description,0,0);
static char* TypeToString(void* f) {CardType ct = *((CardType*)f);return(TypeName(ct));}
static void StringToType(char* s,void* f){*((CardType*)f) = NameType(s);}
static Card* OrigCard;
static Boolean streqp(const char* s1,const char* s2)
{
register char c1,c2;
do {
c1 = *s1++;
if (islower(c1)) c1 = toupper(c1);
c2 = *s2++;
if (islower(c2)) c2 = toupper(c2);
if (c1 != c2) return(false);
} while (c1 != 0);
return(true);
}
static char* ReadQuotedStringFromBuffer(char* buffer,int buffsize,char* string)
{
Boolean inquote = false;
if (string == 0 || *string == 0) return((char*)0);
while (*string != 0 && (inquote || *string != ',')) {
if (*string == '"') inquote = ~inquote;
else if (*string == '\\') {
string++;
if (buffsize > 0) {
*buffer++ = *string;
buffsize--;
}
} else if (*string >= ' ') {
if (buffsize > 0) {
*buffer++ = *string;
buffsize--;
}
}
string++;
}
if (*string == ',') string++;
*buffer = 0;
return string;
}
static char* newelems[500];
void UpdateSubjs(const char* subjs,const char* osubjs,const Key key)
{
Key subj1;
Key subj2;
char* sl1;
char* sl2;
for (sl1 = (char*)osubjs;(sl1 = ReadQuotedStringFromBuffer((char*)subj1,sizeof(subj1),sl1)) != 0;) {
Boolean retain = false;
for (sl2 = (char*)subjs;(sl2 = ReadQuotedStringFromBuffer((char*)subj2,sizeof(subj2),sl2)) != 0;) {
if (streqp(subj2,subj1)) {
retain = true;
break;
}
}
if (!retain) {
CoreItem temp;
if (Tree->SearchSubj(subj1,&temp)) {
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
if (outitems == 0) Tree->DeleteSubj(subj1);
else {
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
Tree->InsertSubj(subj1,&rawrec);
}
}
}
}
for (sl1 = (char*)subjs;(sl1 = ReadQuotedStringFromBuffer((char*)subj1,sizeof(subj1),sl1)) != 0;) {
Boolean addnew = true;
for (sl2 = (char*)osubjs;(sl2 = ReadQuotedStringFromBuffer((char*)subj2,sizeof(subj2),sl2)) != 0;) {
if (streqp(subj2,subj1)) {
addnew = false;
break;
}
}
if (addnew) {
CoreItem temp;
if (Tree->SearchSubj(subj1,&temp)) {
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
newelems[outitems++] = (char*)key;
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
Tree->InsertSubj(subj1,&rawrec);
} else {
newelems[0] = (char*)key;
ListRecord newrec(1,newelems);
Record rawrec = newrec;
Tree->InsertSubj(subj1,&rawrec);
}
}
}
}
void UpdateAuthor(const char* auth,const char* oauth,const Key key)
{
Key authkey;
Key oauthkey;
strncpy(authkey,auth,KeySize);
authkey[KeySize-1] = 0;
strncpy(oauthkey,oauth,KeySize);
oauthkey[KeySize-1] = 0;
//cerr << "*** In UpdateAuthor: authkey = '" << authkey << "', oauthkey = '" << oauthkey << "'\n";
if (!streqp(authkey,oauthkey)) {
CoreItem temp;
//cerr << "Author changed, about to update old author\n";
if (Tree->SearchAuthor(oauthkey,&temp) &&
streqp(oauthkey,temp.key)) {
//cerr << "Updating old author...\n";
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
if (outitems == 0) Tree->DeleteAuthor(oauthkey);
else {
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
Tree->InsertAuthor(oauthkey,&rawrec);
}
//cerr << "Old author updated...\n";
}
//cerr << "About to fetch new author record\n";
if (Tree->SearchAuthor(authkey,&temp) &&
streqp(authkey,temp.key)) {
//cerr << "New author record fetched, about to update\n";
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
newelems[outitems++] = (char*)key;
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
//cerr << "Inserting new record for new author...\n";
Tree->InsertAuthor(authkey,&rawrec);
} else if (authkey[0] != 0) {
//cerr << "Creating new record for new author...\n";
newelems[0] = (char*)key;
ListRecord newrec(1,newelems);
Record rawrec = newrec;
Tree->InsertAuthor(authkey,&rawrec);
}
}
}
void UpdateTitle(const char* title,const char* otitle,const Key key)
{
Key titlekey;
Key otitlekey;
strncpy(titlekey,title,KeySize);
titlekey[KeySize-1] = 0;
strncpy(otitlekey,otitle,KeySize);
otitlekey[KeySize-1] = 0;
//cerr << "*** In UpdateTitle: titlekey = '" << titlekey << "', otitlekey = '" << otitlekey << "'\n";
if (!streqp(titlekey,otitlekey)) {
CoreItem temp;
if (Tree->SearchTitle(otitlekey,&temp) &&
streqp(otitlekey,temp.key)) {
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
if (outitems == 0) Tree->DeleteTitle(otitlekey);
else {
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
Tree->InsertTitle(otitlekey,&rawrec);
}
}
if (Tree->SearchTitle(titlekey,&temp) &&
streqp(titlekey,temp.key)) {
ListRecord rec(&temp.data);
int nitems = rec.ElementCount();
int outitems = 0;
for (int i = 0; i < nitems; i++) {
if (!streqp(rec[i],key)) {
newelems[outitems++] = rec[i];
}
}
newelems[outitems++] = (char*)key;
ListRecord newrec(outitems,newelems);
Record rawrec = newrec;
Tree->InsertTitle(titlekey,&rawrec);
} else if (titlekey[0] != 0) {
newelems[0] = (char*)key;
ListRecord newrec(1,newelems);
Record rawrec = newrec;
Tree->InsertTitle(titlekey,&rawrec);
}
}
}
void QuoteStringBuffer(char* buffer,char* string)
{
*buffer++ = '"';
while (*string != 0) {
if (*string == '"') *buffer++ = '\\';
*buffer++ = *string++;
}
*buffer++ = '"';
*buffer = 0;
}
static char *ptr;
static Key subjkey;
static void ExamineSubj(CoreItem* item,int level)
{
if (item->data.size <= 0) return;
ListRecord rec(&item->data);
int icount = rec.ElementCount();
for (int i = 0; i < icount; i++) {
if (streqp(subjkey,rec[i])) {
QuoteStringBuffer(ptr,item->key);
ptr += strlen(ptr);
*ptr++ = ',';
return;
}
}
}
void FetchSubjs(char* subjbuffer,const Key key)
{
ptr = subjbuffer;
strcpy(subjkey,key);
Tree->TraverseSubj(ExamineSubj);
if (ptr > subjbuffer && *(ptr-1) == ',') ptr--;
*ptr = '\0';
}
Boolean CardsAreDifferent(const Card *c1,const Card *c2)
{
if (c1->type != c2->type ||
c1->vol != c2->vol ||
c1->year != c2->year ||
strcmp(c1->author,c2->author) != 0 ||
strcmp(c1->title,c2->title) != 0 ||
strcmp(c1->publisher,c2->publisher) != 0 ||
strcmp(c1->city,c2->city) != 0 ||
strcmp(c1->description,c2->description) != 0) return(true);
else return(false);
}
static void SaveCard(EditForm& ef)
{
if (OrigCard != 0 && CardsAreDifferent(&editcard,OrigCard)) {
CardRecord rec(&editcard);
Record rawrec = rec;
Tree->InsertId(editkey,&rawrec);
UpdateAuthor(Author,OrigCard->author,editkey);
UpdateTitle(Title,OrigCard->title,editkey);
} else {
CardRecord rec(&editcard);
Record rawrec = rec;
Tree->InsertId(editkey,&rawrec);
UpdateAuthor(Author,"",editkey);
UpdateTitle(Title,"",editkey);
}
UpdateSubjs(SubjList,OrigSubjList,editkey);
strcpy(OrigSubjList,SubjList);
Term->Message("Saved");
ef.IsModified = false;
return;
}
static Field Fields[] = {
{"Id: ",Literal,0,0,3,1,4,1,0},
{editkey,Literal,0,0,3,5,KeySize,1,0},
{"Type: ",Literal,0,0,3,50,6,1,0},
{&editcard.type,Special,TypeToString,StringToType,3,56,14,1,0},
{"Title: ",Literal,0,0,4,1,7,1,0},
{Title,String,0,0,4,8,60,1,BuffSize},
{"Author: ",Literal,0,0,5,1,8,1,0},
{Author,String,0,0,5,9,60,1,BuffSize},
{"Publisher: ",Literal,0,0,6,1,11,1,0},
{Publisher,String,0,0,6,12,40,1,BuffSize},
{"Year: ",Literal,0,0,6,60,6,1,0},
{&editcard.year,Int,0,0,6,66,4,1,0},
{"City: ",Literal,0,0,7,1,6,1,0},
{City,String,0,0,7,7,40,1,BuffSize},
{"Vol: ",Literal,0,0,7,60,5,1,0},
{&editcard.vol,Int,0,0,7,65,4,1,0},
{"Description: ",Literal,0,0,8,1,13,1,0},
{Description,EditorString,0,0,8,14,50,10,DescrSize},
{"Subjects: ",Literal,0,0,19,1,10,1,0},
{SubjList,EditorString,0,0,19,11,50,3,DescrSize}
};
static const NumFields = sizeof(Fields) / sizeof(Field);
static void HelpField(EditForm& ef)
{
switch (ef.CurField()) {
case 4: // Type:
Term->Clear();
Term->PutStrAt(2,0,"Type field - enter one of:");
Term->PutStrAt(4,0,"Book, Magazine, CD, AudioCassette, Album, LaserDisk, VHSVideo,");
Term->PutStrAt(5,0,"BetaVideo, EightMM, EightTrack, DAT, or Other.");
Term->PutStrAt(7,0,"This is the type of item being cataloged.");
Term->PutStrAt(0,0,"Hit any key to resume editing:");
Term->GetKey();
ef.RePaint();
break;
case 6: // Title: (string)
Term->Message("Title field - enter the title as a string");
break;
case 8: // Author: (string)
Term->Message("Author field - enter the author as a string");
break;
case 10: // Publisher: (string)
Term->Message("Publisher field - enter the publisher as a string");
break;
case 12: // Year: (number)
Term->Message("Year field - enter the year as a number");
break;
case 14: // City: (string)
Term->Message("City field - enter the city as a string");
break;
case 16: // Volume: (number)
Term->Message("Volumn field - enter the volume number as a number");
break;
case 18: // Description (long string)
Term->Message("Description field - enter the description as a multi-line string");
break;
case 20: // Subjects (long string)
Term->Message("Subjects field - enter the subjects as a comma separated list of strings");
break;
}
}
static KeyBinding Bindings[] = {
{SaveCard,"^S - Save card",'S' - '@'},
{HelpField,"H - Give help for the current field",'H'},
{HelpField,"h - Give help for the current field",'h'}
};
static const NumBindings = sizeof(Bindings) / sizeof(KeyBinding);
int EditCard1(Key inkey)
{
#ifdef ILLEGAL_INSTR
static EditForm editform("Editing a Card",NumFields,Fields,
NumBindings,Bindings);
#else
EditForm *editform = new EditForm("Editing a Card",NumFields,Fields,
NumBindings,Bindings);
#endif
strcpy(editkey,inkey);
CoreItem item;
#ifdef ILLEGAL_INSTR
editform.ResetField();
#else
editform->ResetField();
#endif
if (Tree->SearchId(editkey,&item) &&
strlen(editkey) == strlen(item.key)) {
strcpy(editkey,item.key);
CardRecord crec(&item.data);
strcpy(Author,crec->author);
strcpy(Title,crec->title);
strcpy(Publisher,crec->publisher);
strcpy(City,crec->city);
strcpy(Description,crec->description);
editcard.year = crec->year;
editcard.vol = crec->vol;
editcard.type = crec->type;
FetchSubjs(SubjList,editkey);
strcpy(OrigSubjList,SubjList);
OrigCard = &crec;
#ifdef ILLEGAL_INSTR
if(editform.RunForm()) {
#else
if(editform->RunForm()) {
#endif
if (Term->YorNp(20,0,"Card modified - save it?"))
#ifdef ILLEGAL_INSTR
SaveCard(editform);
#else
SaveCard(*editform);
#endif
}
} else if (Term->YorNp(21,0,"Card not found, create it?")) {
Author[0] = 0;
Title[0] = 0;
Publisher[0] = 0;
City[0] = 0;
Description[0] = 0;
SubjList[0] = 0;
OrigSubjList[0] = 0;
OrigCard = 0;
editcard.type = Book;
editcard.vol = 0;
editcard.year = 0;
#ifdef ILLEGAL_INSTR
if(editform.RunForm()) {
#else
if(editform->RunForm()) {
#endif
if (Term->YorNp(20,0,"Card modified - save it?"))
#ifdef ILLEGAL_INSTR
SaveCard(editform);
#else
SaveCard(*editform);
#endif
}
}
#ifndef ILLEGAL_INSTR
delete editform;
#endif
return(-1);
}
int EditCard()
{
static Key tempkey;
Term->PromptLine(18,0,"Id of card to edit: ",tempkey,KeySize);
return(EditCard1(tempkey));
}