1*11987Sslatteng /* @(#)undodb.c	1.2	04/18/83
211963Sslatteng  *
311963Sslatteng  * Copyright -C- 1982 Barry S. Roitblat
411963Sslatteng  *
511963Sslatteng  *
611963Sslatteng  *      This file contains routines for recording (remembering) database
711963Sslatteng  * activity to provide an undo capability for the gremlin picture editor.
811963Sslatteng  */
911963Sslatteng 
1011963Sslatteng #include "gremlin.h"
1111963Sslatteng #include "grem2.h"
1211963Sslatteng 
1311963Sslatteng /* The following are used to point to the undo database lists */
1411963Sslatteng 
1511963Sslatteng UNELT *unlist, *unback;
1611963Sslatteng 
1711963Sslatteng /* imports from point.c */
1811963Sslatteng 
1911963Sslatteng POINT *PTInit(), *PTMakePoint();
2011963Sslatteng 
2111963Sslatteng /* imports from c */
2211963Sslatteng 
2311963Sslatteng extern char *malloc();
2411963Sslatteng extern char *strcpy();
2511963Sslatteng 
2611963Sslatteng /* imports from db1.c */
2711963Sslatteng 
2811963Sslatteng extern DBClearElt();
2911963Sslatteng 
30*11987Sslatteng 
3111963Sslatteng UNRembAdd(element, db)
3211963Sslatteng ELT *element, *(*db);
3311963Sslatteng /*
3411963Sslatteng  *      This routine records an addition to the database by saving
3511963Sslatteng  * a pointer to the new element
3611963Sslatteng  */
3711963Sslatteng 
3811963Sslatteng {
3911963Sslatteng     UNELT *temp;
4011963Sslatteng 
4111963Sslatteng     temp = (UNELT *) malloc(sizeof(UNELT));
4211963Sslatteng     temp->action = ADD;
4311963Sslatteng     temp->dbase  = db;
4411963Sslatteng     temp->oldelt = NULL;
4511963Sslatteng     temp->newelt = element;
4611963Sslatteng     temp->nextun = unlist;
4711963Sslatteng     unlist = temp;
4811963Sslatteng }  /* end RembAdd */
4911963Sslatteng 
5011963Sslatteng UNRembDelete(element, db)
5111963Sslatteng ELT *element, *(*db);
5211963Sslatteng /*
5311963Sslatteng  *      This routine records a deletion from the database by saving
5411963Sslatteng  * a pointer to the deleted element
5511963Sslatteng  */
5611963Sslatteng 
5711963Sslatteng {
5811963Sslatteng     UNELT *temp;
5911963Sslatteng 
6011963Sslatteng     temp = (UNELT *) malloc(sizeof(UNELT));
6111963Sslatteng     temp->action = DELETE;
6211963Sslatteng     temp->dbase  = db;
6311963Sslatteng     temp->oldelt = element;
6411963Sslatteng     temp->newelt = NULL;
6511963Sslatteng     temp->nextun = unlist;
6611963Sslatteng     unlist = temp;
6711963Sslatteng }  /* end RembDelete */
6811963Sslatteng 
69*11987Sslatteng 
7011963Sslatteng UNRembMod(element, db)
7111963Sslatteng ELT *element, *(*db);
7211963Sslatteng /*
7311963Sslatteng  *      This routine records a modification to the database.  The
7411963Sslatteng  * element passed to it is the element which will be modified and it
7511963Sslatteng  * is therefore copied (copying the text and pointlist also)
7611963Sslatteng  * and save as oldelt.  A pointer of the element (which will be
7711963Sslatteng  * modified) is saved in newelt.
7811963Sslatteng  */
7911963Sslatteng 
8011963Sslatteng {
8111963Sslatteng     POINT *pt;
8211963Sslatteng     UNELT *temp;
8311963Sslatteng     ELT *hold;
8411963Sslatteng 
8511963Sslatteng     temp = (UNELT *) malloc(sizeof(UNELT));
8611963Sslatteng     temp->action = MOD;
8711963Sslatteng     temp->dbase = db;
8811963Sslatteng     temp->newelt = element;
8911963Sslatteng     temp->oldelt = hold = (ELT *) malloc(sizeof(ELT));
9011963Sslatteng     hold->type = element->type;
9111963Sslatteng     hold->brushf = element->brushf;
9211963Sslatteng     hold->size = element->size;
9311963Sslatteng     hold->textpt = malloc((unsigned) strlen(element->textpt) + 1);
9411963Sslatteng     (void) strcpy(hold->textpt, element->textpt);
9511963Sslatteng     pt = element->ptlist;
9611963Sslatteng     hold->ptlist = PTInit();
9711963Sslatteng     while ( !Nullpoint(pt) )
9811963Sslatteng     {
9911963Sslatteng         (void) PTMakePoint(pt->x, pt->y, &(hold->ptlist));
10011963Sslatteng         pt = PTNextPoint(pt);
10111963Sslatteng     }  /* end while */
10211963Sslatteng     temp->nextun = unlist;
10311963Sslatteng     unlist = temp;
10411963Sslatteng }  /* end RembMod */
10511963Sslatteng 
UNForget()10611963Sslatteng UNForget()
10711963Sslatteng /*
10811963Sslatteng  *      This routine clears the undo database.  The database is copied
10911963Sslatteng  * into the backup database and elements from the backup database
11011963Sslatteng  * are deleted and returned to free storage.  If nothing is in the undo
11111963Sslatteng  * database, the backup database is preserved.
11211963Sslatteng  */
11311963Sslatteng 
11411963Sslatteng {
11511963Sslatteng     UNELT *temp;
11611963Sslatteng 
11711963Sslatteng     if (unlist == nullun) return;
11811963Sslatteng     while (unback != nullun)
11911963Sslatteng     {
12011963Sslatteng         temp = unback->nextun;
12111963Sslatteng         switch (unback->action)
12211963Sslatteng         {
12311963Sslatteng                case ADD: free((char *) unback);
12411963Sslatteng                          break;
12511963Sslatteng 
12611963Sslatteng                case MOD:
12711963Sslatteng             case DELETE: DBClearElt(unback->oldelt);
12811963Sslatteng                          free((char *) unback);
12911963Sslatteng                          break;
13011963Sslatteng         }  /* end switch */;
13111963Sslatteng         unback = temp;
13211963Sslatteng     }  /* end while */;
13311963Sslatteng     unback = unlist;
13411963Sslatteng     unlist = nullun;
13511963Sslatteng }  /* end Forget */
136