Category : Windows 3.X Files
Archive   : JWPSRC.ZIP
Filename : UNDO.C

 
Output of file : UNDO.C contained in archive : JWPSRC.ZIP
/* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */

#include "jwp.h"


static PARAGRAPH far *fpara = NULL;



void FreeUndo (UNDOBUF far *up)
{
switch (up->action) {
U_PARAFORMAT:
U_INSERT:
U_DELETE:
U_REPLACE: {
PARAGRAPH far *lp, far *lp2;

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}
}
}
FreeBlock(up);
}



void FreeUndoChain (UNDOBUF far *up)
{
UNDOBUF far *up1;

for (; up != NULL; ) {
up1 = up;
up = up->next;
FreeUndo(up1);
}
}



static int FindParaNum (FILEOPTIONS *f, PARAGRAPH far *p)
{
int n;
PARAGRAPH far *p1;

for (p1 = f->paragraph, n = 0; p1 != NULL; p1 = p1->next, n++) {
if (p1 == p) return (n);
}

return (-1);
}



void TrimUndoChain (FILEOPTIONS *f)
{
UNDOBUF far *up;

if (f->undo == NULL) return;

while (f->undolevels > global.undolevels) {
if (f->undo->next == NULL) {
FreeUndo(f->undo);
f->undo = f->undotail = NULL;
f->undolevels = 0;
return;
}

up = f->undotail->prev;
FreeUndo(f->undotail);
if (up == NULL) {
f->undo = f->undotail = NULL;
f->undolevels = 0;
} else {
up->next = NULL;
f->undotail = up;
f->undolevels--;
}
}
}



static UNDOBUF far *CreateUndo (int para, int start, int len, UNDOACTIONS action)
{
UNDOBUF far *up;

up = StructAlloc(UNDOBUF);

up->para1 = up->para2 = para;
up->start = start;
up->stop = start + len;
up->action = action;
up->data = NULL;
up->next = up->prev = NULL;

return (up);
}



void UndoAddTyping (FILEOPTIONS *f, POSITION p, int howmany, BOOL splitline)
{
int para, start;
UNDOBUF far *up;
time_t tm;


if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

para = FindParaNum(f, PARAOF(p));
start = POS2ABS(p);

up = f->undo;

if (splitline) {
if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, 0, U_INSERT);
up->para2 = para + 1;
up->stop = 0;
f->undolevels = 1;
} else if ((up->action == U_INSERT || up->action == U_REPLACE) &&
up->para2 == para && up->stop == start) {
up->para2 = para + 1;
up->stop = 0;
} else {
up = CreateUndo(para, start, 0, U_INSERT);
up->para2 = para + 1;
up->stop = 0;
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}
} else {
if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, howmany, U_INSERT);
f->undolevels = 1;
} else if ((up->action != U_INSERT && up->action != U_REPLACE) ||
up->para2 != para || up->stop != start) {

up = CreateUndo(para, start, howmany, U_INSERT);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
} else {
up->stop += howmany;
}
}

time(&tm);
up->time = tm;
}



void UndoFixConvert (FILEOPTIONS *f, POSITION p, int oldlen, int newlen)
{
UNDOBUF far *up;
time_t tm;

if (global.undolevels == 0) return;
if (f->undo == NULL) return;
if (!(f->type & FN_NORMAL)) return;

up = f->undo;
if (up->action != U_INSERT && up->action != U_REPLACE) return;
if (up->para2 != FindParaNum(f, PARAOF(p))) return;
//if (up->stop != POS2ABS(p) + oldlen) return;
if (up->stop <= POS2ABS(p)) return;

up->stop += newlen - oldlen;

time(&tm);
up->time = tm;
}



void UndoAddInsert (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
UNDOBUF far *up;
int para1, para2;
time_t tm;

if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

para1 = FindParaNum(f, PARAOF(p1));
para2 = FindParaNum(f, PARAOF(p2));

if (f->undo == NULL) {
up = f->undo = f->undotail = CreateUndo(para1, POS2ABS(p1), 0, U_INSERT);
up->para2 = para2;
up->stop = POS2ABS(p2);
f->undolevels = 1;
} else {
up = CreateUndo(para1, POS2ABS(p1), 0, U_INSERT);
up->para2 = para2;
up->stop = POS2ABS(p2);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}

time(&tm);
up->time = tm;
}



static PARAGRAPH far *SaveData (FILEOPTIONS *f, POSITION p1, POSITION p2)
{

unsigned int len;
PARAGRAPH far *data = NULL, far *p, far *lp;

if (PARAOF(p1) == PARAOF(p2)) {
lp = StructAlloc(PARAGRAPH);
_fmemcpy(lp, PARAOF(p1), sizeof(PARAGRAPH));

lp->lines = lp->lastline = NULL;
lp->next = lp->prev = NULL;
len = POSOF(p2) - POSOF(p1);

lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);

_fmemcpy(lp->text, PARAOF(p1)->text + POSOF(p1), len * sizeof(UNIT));
lp->text[len].kanji = 0;

return (lp);
}

for (p = PARAOF(p1); ; p = p->next) {
if (data == NULL) {
data = lp = StructAlloc(PARAGRAPH);
_fmemcpy(lp, p, sizeof(PARAGRAPH));
lp->prev = NULL;
} else {
lp->next = StructAlloc(PARAGRAPH);
_fmemcpy(lp->next, p, sizeof(PARAGRAPH));
lp->next->prev = lp;
lp = lp->next;
}

lp->next = NULL;
lp->lines = lp->lastline = NULL;

if (p == PARAOF(p1)) {
len = unitlen(p->text) - POSOF(p1);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text + POSOF(p1), len * sizeof(UNIT));
lp->text[len].kanji = 0;
} else if (p == PARAOF(p2)) {
len = POSOF(p2);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text, len * sizeof(UNIT));
lp->text[len].kanji = 0;
break;
} else {
len = unitlen(p->text);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text, len * sizeof(UNIT));
lp->text[len].kanji = 0;
}
}

return (data);
}



void UndoAddDelete (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
UNDOBUF far *up;
int para1, para2;
time_t tm;

if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

para1 = FindParaNum(f, PARAOF(p1));
POSOF(p1) = POS2ABS(p1);
para2 = FindParaNum(f, PARAOF(p2));
POSOF(p2) = POS2ABS(p2);

if (f->undo == NULL) {
up = f->undo = f->undotail = CreateUndo(para1, POSOF(p1), 0, U_DELETE);
up->para2 = para2;
up->stop = POSOF(p2);
f->undolevels = 1;
} else {
up = CreateUndo(para1, POSOF(p1), 0, U_DELETE);
up->para2 = para2;
up->stop = POSOF(p2);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}

up->data = SaveData(f, p1, p2);

time(&tm);
up->time = tm;
}



void UndoJoinLine (FILEOPTIONS *f, POSITION p)
{
int para, start;
UNDOBUF far *up;
PARAGRAPH far *pp;
time_t tm;


if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;


para = FindParaNum(f, PARAOF(p));
start = POS2ABS(p);

up = f->undo;

if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, 0, U_DELETE);
up->para2 = para + 1;
up->stop = 0;
f->undolevels = 1;

pp = StructAlloc(PARAGRAPH);
up->data = (void far *) pp;

_fmemcpy(pp, PARAOF(p), sizeof(PARAGRAPH));
pp->lines = pp->lastline = NULL;
pp->prev = NULL;
pp->text = NULL;
pp->next = StructAlloc(PARAGRAPH);
_fmemcpy(pp->next, PARAOF(p)->next, sizeof(PARAGRAPH));
pp->next->prev = pp;
pp = pp->next;
pp->next = NULL;
pp->text = NULL;
} else if (up->action == U_DELETE && up->para1 == para &&
up->start == start) {
up->para2 = para + 1;
up->stop = 0;

for (pp = (PARAGRAPH far *) up->data; pp->next != NULL; pp = pp->next);

pp->next = StructAlloc(PARAGRAPH);
_fmemcpy(pp->next, PARAOF(p)->next, sizeof(PARAGRAPH));
pp->next->prev = pp;
pp = pp->next;
pp->next = NULL;
pp->text = NULL;
} else if (up->action == U_DELETE && up->para1 == para + 1 &&
up->start == 0) {
up->para1 = para;
up->start = start;

pp = (PARAGRAPH far *) up->data;
pp->prev = StructAlloc(PARAGRAPH);
_fmemcpy(pp->prev, PARAOF(p), sizeof(PARAGRAPH));
pp->prev->next = pp;
pp = pp->prev;
pp->prev = NULL;
pp->text = NULL;

up->data = (void far *) pp;
} else {
up = CreateUndo(para, start, 0, U_DELETE);
up->para2 = para + 1;
up->stop = 0;
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);

pp = StructAlloc(PARAGRAPH);
up->data = (void far *) pp;

_fmemcpy(pp, PARAOF(p), sizeof(PARAGRAPH));
pp->lines = pp->lastline = NULL;
pp->prev = NULL;
pp->text = NULL;
pp->next = StructAlloc(PARAGRAPH);
_fmemcpy(pp->next, PARAOF(p)->next, sizeof(PARAGRAPH));
pp->next->prev = pp;
pp = pp->next;
pp->next = NULL;
pp->text = NULL;
}

time(&tm);
up->time = tm;
}



void UndoAddErase (FILEOPTIONS *f, POSITION p, int howmany)
{
int para, start;
unsigned int i, n, len;
UNDOBUF far *up;
POSITION p1, p2;
PARAGRAPH far *pp;
time_t tm;


if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

para = FindParaNum(f, PARAOF(p));
start = POS2ABS(p);
p1 = p;
POSOF(p1) = start;
p2 = p1;
POSOF(p2) += howmany;

up = f->undo;

if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, howmany, U_DELETE);
up->data = SaveData(f, p1, p2);
f->undolevels = 1;
} else if (up->action == U_DELETE && up->para1 == para && up->start == start) {
up->stop += howmany;

for (pp = (PARAGRAPH far *) up->data; pp->next != NULL; pp = pp->next);

if (pp->text == NULL) {
n = (howmany + 2) / UNDOTEXTSIZE;
n = (n + 1 ) * UNDOTEXTSIZE;
pp->text = (UNIT far *) BlockAlloc(n * sizeof(UNIT));
len = 0;
} else {
n = SegHeapGetSize(pp->text) / sizeof(UNIT);
len = unitlen(pp->text);
if (len + howmany + 2 > n) {
n = (len + howmany + 2) / UNDOTEXTSIZE;
n = (n + 1 ) * UNDOTEXTSIZE;

pp->text = (UNIT far *) SegHeapRealloc(pp->text, n * sizeof(UNIT));
}
}

for (i = 0; i < howmany; i++) {
pp->text[len + i] = PARAOF(p)->text[start + i];
}
pp->text[len + i].kanji = 0;
} else if (up->action == U_DELETE && up->para1 == para && up->start == start + howmany) {
up->start = start;

pp = (PARAGRAPH far *) up->data;

if (pp->text == NULL) {
n = (howmany + 2) / UNDOTEXTSIZE;
n = (n + 1 ) * UNDOTEXTSIZE;
pp->text = (UNIT far *) BlockAlloc(n * sizeof(UNIT));
len = 0;
} else {
n = SegHeapGetSize(pp->text) / sizeof(UNIT);
len = unitlen(pp->text);
if (len + howmany + 2 > n) {
n = (len + howmany + 2) / UNDOTEXTSIZE;
n = (n + 1 ) * UNDOTEXTSIZE;

pp->text = (UNIT far *) SegHeapRealloc(pp->text, n * sizeof(UNIT));
}
}

if (len >= 1) {
for (i = len - 1; i >= 0; i--) {
pp->text[i + howmany] = pp->text[i];
if (i == 0) break;
}
}
pp->text[len + howmany].kanji = 0;

for (i = 0; i < howmany; i++) {
pp->text[i] = PARAOF(p)->text[start + i];
}
} else {
up = CreateUndo(para, start, howmany, U_DELETE);
up->data = SaveData(f, p1, p2);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}

time(&tm);
up->time = tm;
}



void UndoAddReplace (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
UNDOBUF far *up;
int para1;
time_t tm;

if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

para1 = FindParaNum(f, PARAOF(p1));
POSOF(p1) = POS2ABS(p1);
POSOF(p2) = POS2ABS(p2);

if (f->undo == NULL) {
up = f->undo = f->undotail = CreateUndo(para1, POSOF(p1), 0, U_REPLACE);
f->undolevels = 1;
} else {
up = CreateUndo(para1, POSOF(p1), 0, U_REPLACE);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}

up->data = SaveData(f, p1, p2);

time(&tm);
up->time = tm;
}



void UndoFixReplace (FILEOPTIONS *f, POSITION p)
{
if (!(f->type & FN_NORMAL)) return;
if (f->undo == NULL) return;
if (f->undo->action != U_REPLACE) return;

f->undo->para2 = FindParaNum(f, PARAOF(p));
f->undo->stop = POS2ABS(p);
}



static PARAGRAPH far *SaveFormatting (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
PARAGRAPH far *pp, far *savepp = NULL, far *pp1;

for (pp = PARAOF(p1); ; pp = pp->next) {
if (savepp == NULL) {
pp1 = savepp = StructAlloc(PARAGRAPH);
_fmemcpy(savepp, pp, sizeof(PARAGRAPH));
savepp->next = savepp->prev = NULL;
} else {
pp1->next = StructAlloc(PARAGRAPH);
_fmemcpy(pp1->next, pp, sizeof(PARAGRAPH));
pp1->next->prev = pp1;
pp1 = pp1->next;
pp1->next = NULL;
}

pp1->text = NULL;
if (pp == PARAOF(p2)) break;
}

return (savepp);
}



void UndoAddFormatParagraph (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
int para;
UNDOBUF far *up;
PARAGRAPH far *savepp;
time_t tm;


if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;

FreeUndoChain(f->redo);
f->redo = NULL;

savepp = SaveFormatting(f, p1, p2);

para = FindParaNum(f, PARAOF(p1));
up = f->undo;

if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, 0, 0, U_PARAFORMAT);
up->para2 = FindParaNum(f, PARAOF(p2));
up->data = (void far *) savepp;
f->undolevels = 1;
} else {
up = CreateUndo(para, 0, 0, U_PARAFORMAT);
up->para2 = FindParaNum(f, PARAOF(p2));
up->data = (void far *) savepp;
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}

time(&tm);
up->time = tm;
}



static PARAGRAPH far *FindParaFromNum (FILEOPTIONS *f, int num)
{
int i;
PARAGRAPH far *p;

for (i = 0, p = f->paragraph; i < num && p != NULL; i++, p = p->next);

return (p);
}



static void MoveToPosition (FILEOPTIONS *f, POSITION p)
{
f->current = p;

//if (CURPARA(f) != global.cpospara) FillCPos(f, CURPARA(f), 0, -1);

if (!FindCaret(f, TRUE)) {
MoveIntoWindow(f);
InvalidateRect(f->hwnd, NULL, TRUE);
UpdateWindow(f->hwnd);
} else {
TurnOffSelection(f);
}

//f->pseudo = f->cursor;
//DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
//Triangles(f);
}



static BOOL ReformatProc (FILEOPTIONS *f, PARAGRAPH far *p, int n)
{
int i;
PARAGRAPH far *lp;

/* Find the paragraph */

for (i = 0, lp = fpara; i < n && lp != NULL; i++, lp = lp->next);

if (lp == NULL) return (FALSE);

p->spacemulti = lp->spacemulti;
p->spacing = (f->basefont->height + f->basefont->spacing) * p->spacemulti / 100;
p->spacing -= f->basefont->height;

p->firstindent = lp->firstindent;
p->leftindent = lp->leftindent;
p->rightindent = lp->rightindent;

return (TRUE);
}


static PARAGRAPH far *PackData (PARAGRAPH far *lp, KANJI far *buf, unsigned int size)
{
unsigned int i, j, k;

for (i = 0; lp != NULL; lp = lp->next) {
if (lp->text != NULL) {
j = unitlen(lp->text);

if (i + j > size + 5) break;

for (k = 0; k < j; k++) buf[i++] = lp->text[k].kanji;
}
buf[i++] = '\r';
}

if (i > 0) buf[--i] = 0; /* Get rid of last CR */
else buf[i] = 0;

return (lp);
}



void UndoOneStep (FILEOPTIONS *f)
{
int i, j;
UNDOBUF far *up;
POSITION p, p1, p2;
PARAGRAPH far *lp;
HCURSOR hcursor;
KANJI buf[MAXLINELEN];

if (f->undo == NULL) return;

PARAOF(p) = FindParaFromNum(f, f->undo->para1);
if (PARAOF(p) == NULL) return;

POSOF(p) = f->undo->start;

hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
ShowCursor(TRUE);

up = f->undo;

switch (up->action) {
case U_INSERT:
PARAOF(p2) = FindParaFromNum(f, up->para2);
POSOF(p2) = up->stop;
up->data = SaveData(f, p, p2);

AbsoluteToPosition(p, &p1);
PARAOF(p) = FindParaFromNum(f, up->para2);
POSOF(p) = up->stop - 1;
AbsoluteToPosition(p, &p2);

MoveToPosition(f, p1);

BlockDelete (f, p1, p2);
break;

case U_DELETE: {
unsigned int blocksize;
KANJI far *kp;
PARAGRAPH far *lp, far *lp2;

AbsoluteToPosition(p, &p1);
MoveToPosition(f, p1);

SetReformatProc(ReformatProc);
blocksize = C64K/sizeof(KANJI);
kp = (KANJI far *) BlockAlloc (C64K);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
fpara = lp;
lp = PackData(lp, kp, blocksize);
InsertString(f, f->current, kp, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND | OP_MINIMAL);
}

FreeBlock(kp);
SetReformatProc(NULL);

/* Free the data */

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}
up->data = NULL;
break;
}

case U_REPLACE: {
unsigned int blocksize;
KANJI far *kp;
BOOL replace = TRUE;
PARAGRAPH far *lp, far *lp2, far *savepp;

PARAOF(p2) = FindParaFromNum(f, up->para2);
POSOF(p2) = up->stop;
savepp = SaveData(f, p, p2);

AbsoluteToPosition(p, &p1);
PARAOF(p) = FindParaFromNum(f, up->para2);
POSOF(p) = up->stop - 1;
AbsoluteToPosition(p, &p2);

MoveToPosition(f, p1);

SetReformatProc(ReformatProc);
blocksize = C64K/sizeof(KANJI);
kp = (KANJI far *) BlockAlloc (C64K);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
fpara = lp;
lp = PackData(lp, kp, blocksize);
if (replace) {
f->current = p2;
CURCHAR(f)++;
BlockReplace(f, p1, p2, kp);
replace = FALSE;
} else {
InsertString(f, f->current, kp, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND | OP_MINIMAL);
}
}

FreeBlock(kp);
SetReformatProc(NULL);

up->para2 = FindParaNum(f, CURPARA(f));
up->stop = POS2ABS(f->current);

/* Free the data */

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}

up->data = savepp;
break;
}

case U_PARAFORMAT: {
PARAGRAPH far *lp, far *lp2, far *savepp;

LINEOF(p) = PARAOF(p)->lines;
POSOF(p) = 0;

PARAOF(p2) = FindParaFromNum(f, up->para2);

MoveToPosition(f, p);

/* Save the formatting */

savepp = SaveFormatting(f, p, p2);

fpara = (PARAGRAPH far *) up->data;
SetReformatProc(ReformatProc);
ReformatParagraph(f, p, PARAOF(p2)->next, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND);
SetReformatProc(NULL);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}

up->data = savepp;
break;
}
}

ShowCursor(FALSE);
SetCursor(hcursor);

f->undo = up->next;
if (up == NULL) {
f->undotail = NULL;
f->undolevels = 0;
} else {
f->undolevels--;
}

// FreeUndo(up);

up->next = f->redo;
if (f->redo != NULL) f->redo->prev = up;
f->redo = up;
}



void RedoOneStep (FILEOPTIONS *f)
{
int i, j;
UNDOBUF far *up;
POSITION p, p1, p2;
PARAGRAPH far *lp;
HCURSOR hcursor;
KANJI buf[MAXLINELEN];

if (f->redo == NULL) return;

PARAOF(p) = FindParaFromNum(f, f->redo->para1);
if (PARAOF(p) == NULL) return;

POSOF(p) = f->redo->start;

hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
ShowCursor(TRUE);

up = f->redo;

switch (up->action) {
case U_DELETE:
PARAOF(p2) = FindParaFromNum(f, up->para2);
POSOF(p2) = up->stop;
up->data = SaveData(f, p, p2);

AbsoluteToPosition(p, &p1);
PARAOF(p) = FindParaFromNum(f, up->para2);
POSOF(p) = up->stop - 1;
AbsoluteToPosition(p, &p2);

MoveToPosition(f, p1);

BlockDelete (f, p1, p2);
break;

case U_INSERT: {
unsigned int blocksize;
KANJI far *kp;
PARAGRAPH far *lp, far *lp2;

AbsoluteToPosition(p, &p1);
MoveToPosition(f, p1);

SetReformatProc(ReformatProc);
blocksize = C64K/sizeof(KANJI);
kp = (KANJI far *) BlockAlloc (C64K);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
fpara = lp;
lp = PackData(lp, kp, blocksize);
InsertString(f, f->current, kp, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND | OP_MINIMAL);
}

FreeBlock(kp);
SetReformatProc(NULL);

/* Free the data */

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}
up->data = NULL;
break;
}

case U_REPLACE: {
unsigned int blocksize;
KANJI far *kp;
BOOL replace = TRUE;
PARAGRAPH far *lp, far *lp2, far *savepp;

PARAOF(p2) = FindParaFromNum(f, up->para2);
POSOF(p2) = up->stop;
savepp = SaveData(f, p, p2);

AbsoluteToPosition(p, &p1);
PARAOF(p) = FindParaFromNum(f, up->para2);
POSOF(p) = up->stop - 1;
AbsoluteToPosition(p, &p2);

MoveToPosition(f, p1);

SetReformatProc(ReformatProc);
blocksize = C64K/sizeof(KANJI);
kp = (KANJI far *) BlockAlloc (C64K);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
fpara = lp;
lp = PackData(lp, kp, blocksize);
if (replace) {
f->current = p2;
CURCHAR(f)++;
BlockReplace(f, p1, p2, kp);
replace = FALSE;
} else {
InsertString(f, f->current, kp, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND | OP_MINIMAL);
}
}

FreeBlock(kp);
SetReformatProc(NULL);

up->para2 = FindParaNum(f, CURPARA(f));
up->stop = POS2ABS(f->current);

/* Free the data */

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}

up->data = savepp;
break;
}

case U_PARAFORMAT: {
PARAGRAPH far *lp, far *lp2, far *savepp;

LINEOF(p) = PARAOF(p)->lines;
POSOF(p) = 0;

PARAOF(p2) = FindParaFromNum(f, up->para2);

MoveToPosition(f, p);

/* Save the formatting */

savepp = SaveFormatting(f, p, p2);

fpara = (PARAGRAPH far *) up->data;
SetReformatProc(ReformatProc);
ReformatParagraph(f, p, PARAOF(p2)->next, OP_REFORMAT | OP_UPDATE | OP_MOVESEL | OP_MOVETOEND);
SetReformatProc(NULL);

for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}

up->data = savepp;
break;
}
}

ShowCursor(FALSE);
SetCursor(hcursor);

f->redo = up->next;

up->next = f->undo;
if (f->undo == NULL) {
f->undotail = up;
f->undolevels = 1;
} else {
f->undo->prev = up;
f->undolevels++;
}
f->undo = up;
}


  3 Responses to “Category : Windows 3.X Files
Archive   : JWPSRC.ZIP
Filename : UNDO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/