executor/src/listAddDel.c

411 lines
12 KiB
C

/* Copyright 1989 - 2000 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_listAddDel[] =
"$Id: listAddDel.c 74 2004-12-30 03:38:55Z ctm $";
#endif
/* Forward declarations in ListMgr.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "ListMgr.h"
#include "MemoryMgr.h"
#include "rsys/list.h"
P3(PUBLIC pascal trap, INTEGER, LAddColumn, INTEGER, count, /* IMIV-271 */
INTEGER, coln, ListHandle, list)
{
Rect todraw;
Cell c;
INTEGER ncols, nrows, noffsets, offset;
Size nbefore, nafter;
Ptr ip, op;
int i;
Point p;
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
noffsets = count * nrows;
if (coln > Hx(list, dataBounds.right))
coln = Hx(list, dataBounds.right);
if (coln < Hx(list, dataBounds.left))
coln = Hx(list, dataBounds.left);
HxX(list, dataBounds.right) = CW(Hx(list, dataBounds.right) + count);
if (noffsets) {
TRAPBEGIN();
SetHandleSize((Handle) list,
GetHandleSize((Handle) list) + noffsets * sizeof(INTEGER));
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
nbefore = (coln - Hx(list, dataBounds.left)) * sizeof(INTEGER);
nafter = (ncols - count) * sizeof(INTEGER) - nbefore;
ip = (Ptr) (HxX(list, cellArray) + nrows * (ncols - count) + 1);
op = (Ptr) (HxX(list, cellArray) + nrows * ncols + 1);
op -= sizeof(INTEGER);
ip -= sizeof(INTEGER);
*(INTEGER *)op = *(INTEGER *)ip; /* sentinel */
/* SPEEDUP: merge the two BlockMoves ... (unroll begining and end) */
while (--nrows >= 0) {
ip -= nafter;
op -= nafter;
BlockMove(ip, op, nafter);
offset = CW(*(INTEGER *)op) & 0x7FFF;
for (i = 0; ++i <= count; )
{
op -= sizeof(INTEGER);
*(INTEGER *)op = CW(offset);
}
ip -= nbefore;
op -= nbefore;
BlockMove(ip, op, nbefore);
}
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
C_LCellSize(p, list); /* recalcs visible */
if (Hx(list, listFlags) & DODRAW) {
todraw = HxX(list, dataBounds);
todraw.left = CW(coln);
SectRect(&todraw, &HxX(list, visible), &todraw);
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
C_LDraw(c, list);
}
TRAPEND();
}
return coln;
}
P3(PUBLIC pascal trap, INTEGER, LAddRow, INTEGER, count, /* IMIV-271 */
INTEGER, rown, ListHandle, list)
{
Rect todraw;
Cell c;
INTEGER ncols, nrows, noffsets, offset;
Size nbefore, nafter;
INTEGER *ip, *op;
Point p;
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
noffsets = count * ncols;
if (rown > Hx(list, dataBounds.bottom))
rown = Hx(list, dataBounds.bottom);
if (rown < Hx(list, dataBounds.top))
rown = Hx(list, dataBounds.top);
HxX(list, dataBounds.bottom) = CW(Hx(list, dataBounds.bottom) + count);
if (noffsets) {
TRAPBEGIN();
SetHandleSize((Handle) list,
GetHandleSize((Handle) list) + noffsets * sizeof(INTEGER));
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
nbefore = (rown - Hx(list, dataBounds.top));
nafter = ((nrows - count) - nbefore) * ncols;
ip = HxX(list, cellArray) + (nrows - count) * ncols + 1;
op = HxX(list, cellArray) + nrows * ncols + 1;
*--op = *--ip; /* sentinel */
ip -= nafter;
op -= nafter;
offset = CW(*ip) & 0x7FFF;
BlockMove((Ptr) ip, (Ptr) op, nafter * sizeof(INTEGER));
/* move the after rows */
while (--noffsets >= 0)
*--op = CW(offset);
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
C_LCellSize(p, list); /* recalcs visible */
if (Hx(list, listFlags) & DODRAW) {
todraw = HxX(list, dataBounds);
todraw.top = CW(rown);
SectRect(&todraw, &HxX(list, visible), &todraw);
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
C_LDraw(c, list);
}
TRAPEND();
}
return rown;
}
PRIVATE void
compute_visible_rect (Rect *rp, ListHandle list, INTEGER top, INTEGER left,
INTEGER bottom, INTEGER right)
{
INTEGER h, v;
INTEGER new_top, new_left, new_bottom, new_right;
h = Hx (list, cellSize.h);
v = Hx (list, cellSize.v);
new_top = Hx (list, rView.top ) + (top - Hx (list, visible.top )) * v;
new_left = Hx (list, rView.left) + (left - Hx (list, visible.left)) * h;
new_bottom = new_top + (bottom - top ) * v;
new_right = new_left + (right - left) * h;
rp->top = CW (new_top);
rp->left = CW (new_left);
rp->bottom = CW (new_bottom);
rp->right = CW (new_right);
SectRect (rp, &HxX (list, rView), rp);
}
P3(PUBLIC pascal trap, void, LDelColumn, INTEGER, count, /* IMIV-271 */
INTEGER, coln, ListHandle, list)
{
Rect todraw;
Cell c;
INTEGER ncols, nrows, noffsets, delta;
Size nbefore, nafter, ntomove;
unsigned short int *ip, *op; /* unsigned INTEGER */
Ptr dataip, dataop;
INTEGER off1, off2, off3, off4, off5;
int i;
ControlHandle control;
Point p;
if (!list || coln >= Hx(list, dataBounds.right))
/*-->*/ return; /* invalid */
if (count == 0 || (coln == Hx(list, dataBounds.left) &&
count >= Hx(list, dataBounds.right) - Hx(list, dataBounds.left))) {
SetHandleSize((Handle) HxP(list, cells), (Size) 0);
SetHandleSize((Handle) list, sizeof(ListRec));
HxX(list, cellArray)[0] = 0;
HxX(list, dataBounds.right) = HxX(list, dataBounds.left);
HxX(list, visible.left) = HxX(list, dataBounds.left);
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
C_LCellSize(p, list); /* recalcs visible */
if (Hx(list, listFlags) & DODRAW)
EraseRect(&HxX(list, rView));
if ((control = HxP(list, hScroll)))
SetCtlMax(control, Hx(control, contrlMin));
/*-->*/ return; /* quick delete of everything */
}
if (coln + count > Hx(list, dataBounds.right))
count = Hx(list, dataBounds.right) - coln;
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
noffsets = count * nrows;
if (coln > Hx(list, dataBounds.right))
coln = Hx(list, dataBounds.right);
HxX(list, dataBounds.right) = CW(Hx(list, dataBounds.right) - count);
if (noffsets) {
INTEGER visible_right, bounds_right;
TRAPBEGIN();
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
nbefore = (coln - Hx(list, dataBounds.left));
nafter = ncols - nbefore;
ip = op = (unsigned short int *) HxX(list, cellArray);
dataip = dataop = (Ptr) STARH(HxP(list, cells));
delta = 0;
/* SPEEDUP: partial loop unrolling ... combine things and don't
bother adding delta when we know that it's zero */
while (--nrows >= 0) {
off1 = CW(*ip) & 0x7FFF;
for (i = nbefore; --i >= 0; ) /* copy before-offsets */
*op++ = CW(CW(*ip++) - delta);
off2 = CW(*ip) & 0x7FFF;
ntomove = off2 - off1;
BlockMove(dataip, dataop, ntomove); /* copy before-data */
dataip += ntomove;
dataop += ntomove;
ip += count; /* skip count offsets */
off3 = CW(*ip) & 0x7FFF;
ntomove = off3 - off2;
dataip += ntomove; /* skip appropriate data */
delta += ntomove; /* note this */
off4 = CW(*ip) & 0x7FFF;
for (i = nafter; --i >= 0; ) /* copy after-offsets */
*op++ = CW(CW(*ip++) - delta);
off5 = CW(*ip) & 0x7FFF;
ntomove = off5 - off4;
BlockMove(dataip, dataop, ntomove); /* copy before-data */
dataip += ntomove;
dataop += ntomove;
}
*op++ = CW(CW(*ip++) - delta); /* sentinel */
SetHandleSize((Handle) list,
GetHandleSize((Handle) list) - noffsets * sizeof(INTEGER));
SetHandleSize((Handle) HxP(list, cells),
GetHandleSize((Handle) HxP(list, cells)) - delta);
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
/* save visible_right and bounds_right now, because LCellSize
will adjust them and we won't be able to figure out if we
needed to force a scroll */
visible_right = Hx(list, visible.right);
bounds_right = Hx(list, dataBounds.right);
C_LCellSize(p, list); /* recalcs visible */
if ((control = HxP(list, hScroll))) {
INTEGER visible_left;
visible_left = Hx(list, visible.left);
/* Determine whether or not we need to scroll up one location
(because we were maximally scrolled down and we deleted
something that was visible) */
if (visible_left > 0 && visible_right > bounds_right) {
--visible_left;
HxX(list, visible.left) = CW (visible_left);
coln = visible_left;
}
}
if (Hx(list, listFlags) & DODRAW) {
Rect eraser;
compute_visible_rect (&eraser, list, Hx (list, visible.top),
Hx (list, visible.right),
Hx (list, visible.bottom),
visible_right);
EraseRect (&eraser);
todraw = HxX(list, dataBounds);
todraw.left = CW(coln);
SectRect(&todraw, &HxX(list, visible), &todraw);
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
C_LDraw(c, list);
}
TRAPEND();
}
}
P3(PUBLIC pascal trap, void, LDelRow, INTEGER, count, /* IMIV-272 */
INTEGER, rown, ListHandle, list)
{
Rect todraw;
Cell c;
INTEGER ncols, nrows, noffsets;
Size nbefore, nafter;
unsigned short int *ip, *op;
ControlHandle control;
INTEGER off1, off2, off3;
Size delta, ntomove;
Point p;
if (!list || rown >= Hx(list, dataBounds.bottom))
/*-->*/ return; /* invalid */
if (count == 0 || (rown == Hx(list, dataBounds.top) &&
count >= Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top))) {
SetHandleSize((Handle) HxP(list, cells), (Size) 0);
SetHandleSize((Handle) list, sizeof(ListRec));
HxX(list, cellArray)[0] = CWC(0);
HxX(list, dataBounds.bottom) = HxX(list, dataBounds.top);
HxX(list, visible.top) = HxX(list, dataBounds.top);
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
C_LCellSize(p, list); /* recalcs visible */
if (Hx(list, listFlags) & DODRAW)
EraseRect(&HxX(list, rView));
if ((control = HxP(list, vScroll)))
SetCtlMax(control, Hx(control, contrlMin));
/*-->*/ return; /* quick delete of all */
}
if (rown + count > Hx(list, dataBounds.bottom))
count = Hx(list, dataBounds.bottom) - rown;
ncols = Hx(list, dataBounds.right) - Hx(list, dataBounds.left);
noffsets = count * ncols;
HxX(list, dataBounds.bottom) = CW(Hx(list, dataBounds.bottom) - count);
if (noffsets) {
INTEGER visible_bottom, bounds_bottom;
TRAPBEGIN();
nrows = Hx(list, dataBounds.bottom) - Hx(list, dataBounds.top);
nbefore = (rown - Hx(list, dataBounds.top)) * ncols;
nafter = nrows * ncols - nbefore;
ip = op = (unsigned short int *) HxX(list, cellArray) + nbefore;
ip += noffsets;
off1 = CW(*op) & 0x7FFF;
off2 = CW(*ip) & 0x7FFF;
delta = off2 - off1;
while (--nafter >= 0)
*op++ = CW(CW(*ip++) - delta);
off3 = CW(*ip) & 0x7FFF;
*op = CW(CW(*ip) - delta); /* sentinel */
ntomove = off3 - off2;
BlockMove((Ptr) STARH(HxP(list, cells)) + off2,
(Ptr) STARH(HxP(list, cells)) + off1, ntomove);
SetHandleSize((Handle) list,
GetHandleSize((Handle) list) - noffsets * sizeof(INTEGER));
SetHandleSize((Handle) HxP(list, cells),
GetHandleSize((Handle) HxP(list, cells)) - delta);
p.h = Hx(list, cellSize.h);
p.v = Hx(list, cellSize.v);
/* save visible_bottom and bounds_bottom now, because LCellSize
will adjust them and we won't be able to figure out if we
needed to force a scroll */
visible_bottom = Hx(list, visible.bottom);
bounds_bottom = Hx(list, dataBounds.bottom);
C_LCellSize(p, list); /* recalcs visible */
if ((control = HxP(list, vScroll))) {
INTEGER visible_top;
visible_top = Hx(list, visible.top);
/* Determine whether or not we need to scroll up one location
(because we were maximally scrolled down and we deleted
something that was visible) */
if (visible_top > 0 && visible_bottom > bounds_bottom) {
--visible_top;
HxX(list, visible.top) = CW (visible_top);
rown = visible_top;
}
}
if (Hx(list, listFlags) & DODRAW) {
Rect eraser;
compute_visible_rect (&eraser, list, Hx (list, visible.bottom),
Hx (list, visible.left), visible_bottom,
Hx (list, visible.right));
EraseRect (&eraser);
todraw = HxX(list, dataBounds);
todraw.top = CW(rown);
SectRect(&todraw, &HxX(list, visible), &todraw);
for (c.v = CW(todraw.top) ; c.v < CW(todraw.bottom); c.v++)
for (c.h = CW(todraw.left) ; c.h < CW(todraw.right); c.h++)
C_LDraw(c, list);
}
TRAPEND();
}
}