Fixed the mess that is the "expand"/"unexpand" command set. This

had numerous problems, the main one being that each of the three
commands was inconsistent:  "expand toggle" inverts the expansion
of the selection and syncs with the layout.  But "expand" expands
the layout where instances overlap the box and does not sync to
the selection, and "unexpand" unexpands the layout where the box
completely surrounds instances.  Added a set of options to
"expand" and "unexpand" so that these functions can be made
consistent with each other.  All varieties of the function now
always sync the selection and the layout.
This commit is contained in:
R. Timothy Edwards 2026-04-04 20:47:04 -04:00
parent f7cceed5e3
commit ceba050a21
11 changed files with 427 additions and 136 deletions

View File

@ -1 +1 @@
8.3.631
8.3.632

View File

@ -781,39 +781,82 @@ cmdEraseCellsFunc(
* Implement the "expand" command.
*
* Usage:
* expand
* expand toggle
* expand [selection|surround|overlap|all] [toggle]
*
* "selection" expands cells in the selection. All other options
* expand cells in the layout. "all" expands all cells in the
* layout. "surround" expands cells which the cursor box
* surrounds completely, and "overlap" expands cells which the
* cursor box overlaps.
*
* If "toggle" is specified, flips the expanded/unexpanded status.
* Cells which were expanded are unexpanded, and cells which were
* unexpanded are expanded.
*
* For backwards compatibility:
* "expand" alone implements "expand overlap".
* "expand toggle" implements "expand selection toggle".
*
* Also see: CmdUnexpand
*
* Results:
* None.
*
* Side effects:
* If "toggle" is specified, flips the expanded/unexpanded status
* of all selected cells. Otherwise, aren't any unexpanded cells
* left under the box. May read cells in from disk, and updates
* bounding boxes that have changed.
* Expansion state of cells is changed. May read cells in from
* disk, and update bounding boxes that have changed.
*
* ----------------------------------------------------------------------------
*/
#define EXPAND_SELECTION 0
#define EXPAND_SURROUND 1
#define EXPAND_OVERLAP 2
#define EXPAND_ALL 3
#define EXPAND_HELP 4
void
CmdExpand(
MagWindow *w,
TxCommand *cmd)
{
int windowMask, boxMask, d;
int windowMask, boxMask, d, option;
bool doToggle = FALSE;
const char * const *msg;
Rect rootRect;
CellUse *rootBoxUse;
CellDef *rootBoxDef;
int cmdExpandFunc(CellUse *use, int windowMask); /* Forward reference. */
if (cmd->tx_argc > 2 || (cmd->tx_argc == 2
&& (strncmp(cmd->tx_argv[1], "toggle", strlen(cmd->tx_argv[1])) != 0)))
static const char * const cmdExpandOption[] = {
"selection expand cell instances in the selection",
"surround expand cell instances which the cursor box surrounds",
"overlap expand cell instances which the cursor box overlaps",
"all expand all cell instances",
NULL
};
if (cmd->tx_argc > 1)
{
TxError("Usage: %s or %s toggle\n", cmd->tx_argv[0], cmd->tx_argv[0]);
return;
if (!strncmp(cmd->tx_argv[cmd->tx_argc - 1], "toggle",
strlen(cmd->tx_argv[cmd->tx_argc - 1])))
{
doToggle = TRUE;
cmd->tx_argc--;
}
}
if (cmd->tx_argc > 1)
{
option = Lookup(cmd->tx_argv[1], cmdExpandOption);
if (option < 0) option = EXPAND_HELP;
}
else
option = EXPAND_OVERLAP;
if (option == EXPAND_HELP) goto badusage;
windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL)
{
@ -844,23 +887,95 @@ CmdExpand(
WindScale(d, 1);
TxPrintf("expand: rescaled by %d\n", d);
d = DBLambda[1];
if (cmd->tx_argc == 2) break; /* Don't toggle twice */
if (doToggle) break; /* Don't toggle twice */
}
(void) ToolGetBoxWindow(&rootRect, &boxMask);
if (cmd->tx_argc == 2)
SelectExpand(windowMask);
else
if (option != EXPAND_SELECTION)
{
if ((boxMask & windowMask) != windowMask)
{
TxError("The box isn't in the same window as the cursor.\n");
return;
}
DBExpandAll(rootBoxUse, &rootRect, windowMask,
TRUE, cmdExpandFunc, (ClientData)(pointertype) windowMask);
}
switch (option)
{
case EXPAND_SELECTION:
SelectExpand(windowMask,
(doToggle) ? DB_EXPAND_TOGGLE : DB_EXPAND,
(Rect *)NULL, FALSE);
break;
case EXPAND_OVERLAP:
if (doToggle)
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP,
&rootRect, FALSE);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
&rootRect, FALSE);
}
break;
case EXPAND_SURROUND:
if (doToggle)
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_SURROUND,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_SURROUND,
&rootRect, TRUE);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
&rootRect, TRUE);
}
break;
case EXPAND_ALL:
if (doToggle)
{
DBExpandAll(rootBoxUse, &TiPlaneRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL, FALSE);
}
else
{
DBExpandAll(rootBoxUse, &TiPlaneRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL, FALSE);
}
break;
}
} while (d != DBLambda[1]);
return;
badusage:
for (msg = &(cmdExpandOption[0]); *msg != NULL; msg++)
TxPrintf(" %s\n", *msg);
TxPrintf(" toggle Toggle the visibility of cell instances.\n");
}
/* This function is called for each cell whose expansion status changed.

View File

@ -517,14 +517,14 @@ CmdLoad(
DBExpandAll(topuse, &(topuse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask,
TRUE, keepGoing, NULL);
DB_EXPAND, keepGoing, NULL);
DBExpandAll(topuse, &(topuse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask,
FALSE, keepGoing, NULL);
DB_UNEXPAND, keepGoing, NULL);
DBExpand(topuse,
((DBWclientRec *)w->w_clientData)->dbw_bitmask,
TRUE);
DB_EXPAND);
/* We don't want to save and restore DBLambda, because */
/* loading the file may change their values. Instead, we */

View File

@ -1239,7 +1239,7 @@ cmdExpandOneLevel(
extern int cmdExpand1func(CellUse *cu, ClientData bitmask);
/* first, expand this cell use */
DBExpand(cu, bitmask, expand);
DBExpand(cu, bitmask, expand ? DB_EXPAND : DB_UNEXPAND);
/* now, unexpand its direct children (ONE LEVEL ONLY) */
if (expand)
@ -1251,7 +1251,7 @@ cmdExpand1func(
CellUse *cu,
ClientData bitmask)
{
DBExpand(cu, (int)CD2INT(bitmask), FALSE);
DBExpand(cu, (int)CD2INT(bitmask), DB_UNEXPAND);
return 0;
}

View File

@ -702,32 +702,62 @@ CmdTool(
* Implement the "unexpand" command.
*
* Usage:
* unexpand
* unexpand [selection|surround|overlap|all]
*
* "selection" unexpands (hides) cells in the selection. All
* other options unexpand cells in the layout. "all" unexpands
* all cells in the layout. "surround" unexpannds cells which
* the cursor box surrounds completely, and "overlap" unexpands
* cells which the cursor box overlaps.
*
* For backwards compatibility:
* "unexpand" alone implements "unexpand surround".
*
* Also see: CmdExpand
*
* Results:
* None.
*
* Side effects:
* Unexpands all cells under the box that don't completely
* contain the box.
* Changes the expansion state of cells.
*
* ----------------------------------------------------------------------------
*/
#define UNEXPAND_SELECTION 0
#define UNEXPAND_SURROUND 1
#define UNEXPAND_OVERLAP 2
#define UNEXPAND_ALL 3
#define UNEXPAND_HELP 4
void
CmdUnexpand(
MagWindow *w,
TxCommand *cmd)
{
int windowMask, boxMask;
int windowMask, boxMask, option;
const char * const *msg;
Rect rootRect;
int cmdUnexpandFunc(CellUse *use, int windowMask); /* Forward reference. */
if (cmd->tx_argc != 1)
static const char * const cmdUnexpandOption[] = {
"selection expand cell instances in the selection",
"surround expand cell instances which the cursor box surrounds",
"overlap expand cell instances which the cursor box overlaps",
"all expand all cell instances",
NULL
};
if (cmd->tx_argc > 1)
{
TxError("Usage: %s\n", cmd->tx_argv[0]);
return;
option = Lookup(cmd->tx_argv[1], cmdUnexpandOption);
if (option < 0) option = UNEXPAND_HELP;
}
else
option = UNEXPAND_SURROUND;
if (option == UNEXPAND_HELP) goto badusage;
windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL)
@ -743,8 +773,42 @@ CmdUnexpand(
TxError("The box isn't in the same window as the cursor.\n");
return;
}
DBExpandAll(((CellUse *) w->w_surfaceID), &rootRect, windowMask,
FALSE, cmdUnexpandFunc, (ClientData)(pointertype) windowMask);
switch (option)
{
case UNEXPAND_SELECTION:
SelectExpand(windowMask, DB_UNEXPAND, (Rect *)NULL, FALSE);
break;
case UNEXPAND_OVERLAP:
DBExpandAll(((CellUse *)w->w_surfaceID), &rootRect, windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
&rootRect, FALSE);
break;
case UNEXPAND_SURROUND:
DBExpandAll(((CellUse *)w->w_surfaceID), &rootRect, windowMask,
DB_UNEXPAND | DB_EXPAND_SURROUND,
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_SURROUND,
&rootRect, TRUE);
break;
case UNEXPAND_ALL:
DBExpandAll(((CellUse *)w->w_surfaceID), &TiPlaneRect, windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL);
break;
}
return;
badusage:
for (msg = &(cmdUnexpandOption[0]); *msg != NULL; msg++)
TxPrintf(" %s\n", *msg);
}
/* This function is called for each cell whose expansion status changed.

View File

@ -39,6 +39,7 @@ struct expandArg
{
bool ea_deref; /* TRUE if root def dereference flag is set */
int ea_xmask; /* Expand mask. */
int ea_type; /* Expand, unexpand, or toggle */
int (*ea_func)(); /* Function to call for each cell whose
* status is changed.
*/
@ -67,15 +68,22 @@ struct expandArg
*/
void
DBExpand(cellUse, expandMask, expandFlag)
DBExpand(cellUse, expandMask, expandType)
CellUse *cellUse;
int expandMask;
bool expandFlag;
int expandType;
{
CellDef *def;
if (DBDescendSubcell(cellUse, expandMask) == expandFlag)
return;
bool expandFlag, expandTest;
expandTest = DBDescendSubcell(cellUse, expandMask);
if ((expandType & DB_EXPAND_MASK) == DB_EXPAND_TOGGLE)
expandFlag = expandTest;
else
{
expandFlag = ((expandType & DB_EXPAND_MASK) == DB_EXPAND) ? TRUE : FALSE;
if (expandFlag == expandTest) return;
}
if (expandFlag)
{
@ -130,17 +138,17 @@ DBExpand(cellUse, expandMask, expandFlag)
*/
void
DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
DBExpandAll(rootUse, rootRect, expandMask, expandType, func, cdarg)
CellUse *rootUse; /* Root cell use from which search begins */
Rect *rootRect; /* Area to be expanded, in root coordinates */
int expandMask; /* Window mask in which cell is to be expanded */
bool expandFlag; /* TRUE => expand, FALSE => unexpand */
int expandType; /* DB_EXPAND, DB_UNEXPAND, DB_EXPAND_TOGGLE */
int (*func)(); /* Function to call for each cell whose expansion
* status is modified. NULL means don't call anyone.
*/
ClientData cdarg; /* Argument to pass to func. */
{
int dbExpandFunc(), dbUnexpandFunc();
int dbExpandFunc();
SearchContext scontext;
struct expandArg arg;
@ -148,29 +156,26 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
(void) DBCellRead(rootUse->cu_def, TRUE, TRUE, NULL);
/*
* Walk through the area and set the expansion state
* appropriately.
* Walk through the area and set the expansion state appropriately.
*/
arg.ea_xmask = expandMask;
arg.ea_func = func;
arg.ea_arg = cdarg;
arg.ea_type = expandType;
arg.ea_deref = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
scontext.scx_use = rootUse;
scontext.scx_trans = GeoIdentityTransform;
scontext.scx_area = *rootRect;
if (expandFlag)
DBCellSrArea(&scontext, dbExpandFunc, (ClientData) &arg);
else
DBCellSrArea(&scontext, dbUnexpandFunc, (ClientData) &arg);
DBCellSrArea(&scontext, dbExpandFunc, (ClientData) &arg);
}
/*
* dbExpandFunc --
*
* Filter function called by DBCellSrArea on behalf of DBExpandAll above
* when cells are being expanded.
* when cells are being expanded, unexpanded, or toggled.
*/
int
@ -184,68 +189,55 @@ dbExpandFunc(scx, arg)
{
CellUse *childUse = scx->scx_use;
int n = DBLambda[1];
int expandTest;
int expandType = (arg->ea_type & DB_EXPAND_MASK);
int expandSurround = (arg->ea_type & DB_EXPAND_SURROUND_MASK);
bool surround;
expandTest = DBDescendSubcell(childUse, arg->ea_xmask);
/*
* Change the expansion status of this cell if necessary. Call the
* client's function if the expansion status has changed.
*/
if (!DBDescendSubcell(childUse, arg->ea_xmask))
if (!expandTest && ((expandType == DB_EXPAND) || (expandType == DB_EXPAND_TOGGLE)))
{
/* If the cell is unavailable, then don't expand it.
*/
if ((childUse->cu_def->cd_flags & CDAVAILABLE) == 0)
surround = (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area)
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox));
if (surround || (expandSurround == DB_EXPAND_OVERLAP))
{
/* If the parent is dereferenced, then the child should be, too */
if (arg->ea_deref) childUse->cu_def->cd_flags |= CDDEREFERENCE;
if(!DBCellRead(childUse->cu_def, TRUE, TRUE, NULL))
/* If the cell is unavailable, then don't expand it.
*/
if ((childUse->cu_def->cd_flags & CDAVAILABLE) == 0)
{
TxError("Cell %s is unavailable. It could not be expanded.\n",
childUse->cu_def->cd_name);
return 2;
/* If the parent is dereferenced, then the child should be, too */
if (arg->ea_deref) childUse->cu_def->cd_flags |= CDDEREFERENCE;
if (!DBCellRead(childUse->cu_def, TRUE, TRUE, NULL))
{
TxError("Cell %s is unavailable. It could not be expanded.\n",
childUse->cu_def->cd_name);
return 2;
}
}
childUse->cu_expandMask |= arg->ea_xmask;
expandTest = TRUE;
if (arg->ea_func != NULL)
{
if ((*arg->ea_func)(childUse, arg->ea_arg) != 0) return 1;
}
}
childUse->cu_expandMask |= arg->ea_xmask;
if (arg->ea_func != NULL)
{
if ((*arg->ea_func)(childUse, arg->ea_arg) != 0) return 1;
}
}
if (DBCellSrArea(scx, dbExpandFunc, (ClientData) arg))
return 1;
return 2;
}
/*
* dbUnexpandFunc --
*
* Filter function called by DBCellSrArea on behalf of DBExpandAll above
* when cells are being unexpanded.
*/
int
dbUnexpandFunc(scx, arg)
SearchContext *scx; /* Pointer to search context containing
* child use, search area in coor-
* dinates of the child use, and
* transform back to "root".
*/
struct expandArg *arg; /* Client data from caller */
{
CellUse *childUse = scx->scx_use;
/*
* Change the expansion status of this cell if necessary.
*/
if (DBDescendSubcell(childUse, arg->ea_xmask))
else if (expandTest && ((expandType == DB_UNEXPAND) ||
(expandType == DB_EXPAND_TOGGLE)))
{
if (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area)
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox))
surround = (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area)
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox));
if (surround || (expandSurround == DB_EXPAND_OVERLAP))
{
childUse->cu_expandMask &= ~arg->ea_xmask;
expandTest = FALSE;
/* Call the client's function, if there is one. */
@ -256,11 +248,7 @@ dbUnexpandFunc(scx, arg)
}
}
/* Don't recursively search things that aren't already expanded. */
else return 2;
if (DBCellSrArea(scx, dbUnexpandFunc, (ClientData) arg))
if (DBCellSrArea(scx, dbExpandFunc, (ClientData) arg))
return 1;
return 2;
}

View File

@ -4418,7 +4418,7 @@ DBCellWriteCommandFile(cellDef, f)
}
else
{
fprintf(f, "label %s %s %d %d %d %d %s %s\n",
fprintf(f, "label %s %s %d %d %d %d %s %s%s\n",
lab->lab_text,
DBFontList[lab->lab_font]->mf_name,
lab->lab_size >> 3,
@ -4426,15 +4426,10 @@ DBCellWriteCommandFile(cellDef, f)
lab->lab_offset.p_x,
lab->lab_offset.p_y,
directionNames[lab->lab_just],
(lab->lab_flags & LABEL_STICKY) ? "-" : "",
DBTypeLongName(lab->lab_type));
}
if (lab->lab_flags & LABEL_STICKY)
{
fprintf(f, "select area label\n");
fprintf(f, "setlabel sticky true\n");
}
if (lab->lab_flags & PORT_DIR_MASK)
{
if (!(lab->lab_flags & LABEL_STICKY))

View File

@ -1062,6 +1062,19 @@ extern unsigned char DBVerbose; /* If 0, don't print any messages */
#define DB_VERBOSE_WARN 2
#define DB_VERBOSE_ALL 3
/* ---------- Definitions for expanding/unexpanding cells --------------*/
/* Selection expansion flags */
#define DB_EXPAND_MASK 3 /* 1 = expand, 0 = unexpand, 2 = toggle */
#define DB_EXPAND_SURROUND_MASK 4 /* 1 = surround, 0 = touch */
/* Selection expansion values */
#define DB_EXPAND 0
#define DB_UNEXPAND 1
#define DB_EXPAND_TOGGLE 2
#define DB_EXPAND_SURROUND 4
#define DB_EXPAND_OVERLAP 0
/* ------------------ Exported technology variables ------------------- */
/***

View File

@ -546,12 +546,12 @@ DBWloadWindow(window, name, flags)
newEditUse = DBCellNewUse(newEditDef, (char *) NULL);
(void) StrDup(&(newEditUse->cu_id), "Topmost cell in the window");
DBExpand(newEditUse,
((DBWclientRec *)window->w_clientData)->dbw_bitmask, TRUE);
((DBWclientRec *)window->w_clientData)->dbw_bitmask, DB_EXPAND);
if (expand)
DBExpandAll(newEditUse, &(newEditUse->cu_bbox),
((DBWclientRec *)window->w_clientData)->dbw_bitmask,
FALSE, UnexpandFunc,
DB_UNEXPAND, UnexpandFunc,
INT2CD(((DBWclientRec *)window->w_clientData)->dbw_bitmask));
if (newEdit)

View File

@ -1216,13 +1216,21 @@ SelectTransform(transform)
SelectAndCopy2(EditRootDef);
}
/* Client data used by SelectExpand */
typedef struct selExpData {
int sed_mask; /* window mask */
int sed_type; /* DB_EXPAND, etc. */
Rect *sed_box; /* selection box if used, or NULL */
} SelExpData;
/*
* ----------------------------------------------------------------------------
*
* SelectExpand --
*
* Expand all of the selected cells that are unexpanded, and
* unexpand all of those that are expanded.
* Expand or unexpand all of the selected cells according to
* expandType.
*
* Results:
* None.
@ -1230,58 +1238,166 @@ SelectTransform(transform)
* Side effects:
* The contents of the selected cells will become visible or
* invisible on the display in the indicated window(s).
* Both the cell in the layout and the selection are updated
* so that they are synchonized with respect to the state of
* visibility.
*
* ----------------------------------------------------------------------------
*/
void
SelectExpand(mask)
SelectExpand(mask, expandType, rootBox)
int mask; /* Bits of this word indicate which
* windows the selected cells will be
* expanded in.
*/
int expandType; /* Operation to perform: Expand,
* unexpand, or expand toggle.
*/
Rect *rootBox; /* Area of root box, if selecting by
* cursor box area.
*/
{
extern int selExpandFunc(); /* Forward reference. */
/* Forward references */
extern int selExpandFunc();
(void) SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
selExpandFunc, INT2CD(mask));
SelExpData sed;
sed.sed_type = expandType;
sed.sed_box = rootBox;
sed.sed_mask = mask;
if (rootBox != NULL)
{
SearchContext scx;
scx.scx_use = SelectUse;
scx.scx_area = *rootBox;
scx.scx_trans = GeoIdentityTransform;
SelEnumCells(FALSE, (bool *) NULL, &scx, selExpandFunc, &sed);
return;
}
SelEnumCells(FALSE, (bool *) NULL, (SearchContext *)NULL,
selExpandFunc, &sed);
}
/* ARGSUSED */
int
selExpandFunc(selUse, use, transform, mask)
selExpandFunc(selUse, use, transform, sed)
CellUse *selUse; /* Use from selection. */
CellUse *use; /* Use to expand (in actual layout). */
Transform *transform; /* Not used. */
int mask; /* Windows in which to expand. */
SelExpData *sed; /* Information for expansion */
{
/* Don't change expansion status of root cell: screws up
* DBWAreaChanged (need to always have at least top-level
* cell be expanded).
*/
int expandType = sed->sed_type;
int mask = sed->sed_mask;
Rect *rootBox = sed->sed_box;
if (use->cu_parent == NULL)
/* If a rootBox is provided, then we are here trying to sync the
* cells in the selection to those in the edit cell. Need to
* follow the policy of expandType: If DB_EXPAND_SURROUND, then
* selUse must be inside the rootBox. If DB_EXPAND_OVERLAP, then
* selUse must ovelap the rootBox.
*/
if (rootBox != NULL)
{
TxError("Can't unexpand root cell of window.\n");
return 0;
if ((expandType & DB_EXPAND_SURROUND_MASK) == DB_EXPAND_OVERLAP)
{
if (!GEO_OVERLAP(rootBox, &selUse->cu_bbox))
return 0;
}
else /* (expandType & DB_EXPAND_SURROUND_MASK) == DB_EXPAND_SURROUND */
{
if (!GEO_SURROUND(rootBox, &selUse->cu_bbox))
return 0;
}
}
/* Be sure to modify the expansion bit in the selection as well as
* the one in the layout in order to keep them consistent.
/* If a rootBox was given, then the expansion is being done in the
* edit cell, and the selection is being updated to reflect any
* changes there, so only handle the selection. Otherwise, we
* have to sync the corresponding cells in the edit def here.
*/
if (DBDescendSubcell(use, mask))
if ((expandType & DB_EXPAND_MASK) == DB_EXPAND)
{
DBExpand(selUse, mask, FALSE);
DBExpand(use, mask, FALSE);
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask,
(TileTypeBitMask *) NULL);
/* Be sure to modify the expansion bit in the selection as well as
* the one in the layout in order to keep them consistent.
*/
DBExpand(selUse, mask, DB_EXPAND);
if (!rootBox)
{
DBExpand(use, mask, DB_EXPAND);
if (use->cu_parent == NULL)
DBWAreaChanged(use->cu_def, &use->cu_bbox, mask, &DBAllButSpaceBits);
else
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask, &DBAllButSpaceBits);
}
}
else
else if ((expandType & DB_EXPAND_MASK) == DB_UNEXPAND)
{
DBExpand(selUse, mask, TRUE);
DBExpand(use, mask, TRUE);
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask, &DBAllButSpaceBits);
/* Don't change expansion status of root cell: screws up
* DBWAreaChanged (need to always have at least top-level
* cell be expanded).
*/
if ((use->cu_parent == NULL) && !rootBox)
{
TxError("Can't unexpand root cell of window.\n");
return 0;
}
if (use->cu_parent != NULL)
{
/* Be sure to modify the expansion bit in the selection as well as
* the one in the layout in order to keep them consistent.
*/
DBExpand(selUse, mask, DB_UNEXPAND);
if (!rootBox)
{
DBExpand(use, mask, DB_UNEXPAND);
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask,
(TileTypeBitMask *) NULL);
}
}
}
else /* (expandType & DB_EXPAND_MASK) == DB_EXPAND_TOGGLE */
{
/* Don't change expansion status of root cell: screws up
* DBWAreaChanged (need to always have at least top-level
* cell be expanded).
*/
if (use->cu_parent == NULL)
{
if (!rootBox) TxError("Can't unexpand root cell of window.\n");
return 0;
}
/* Be sure to modify the expansion bit in the selection as well as
* the one in the layout in order to keep them consistent.
*/
if (DBDescendSubcell(selUse, mask))
{
DBExpand(selUse, mask, DB_UNEXPAND);
if (!rootBox)
{
DBExpand(use, mask, DB_UNEXPAND);
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask,
(TileTypeBitMask *) NULL);
}
}
else
{
DBExpand(selUse, mask, DB_EXPAND);
if (!rootBox)
{
DBExpand(use, mask, DB_EXPAND);
DBWAreaChanged(use->cu_parent, &use->cu_bbox, mask, &DBAllButSpaceBits);
}
}
}
return 0;
}

View File

@ -954,7 +954,7 @@ windXviewCmd(w, cmd)
celluse = (CellUse *) (w->w_surfaceID);
DBExpandAll(celluse, &(celluse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask, FALSE,
((DBWclientRec *)w->w_clientData)->dbw_bitmask, DB_UNEXPAND,
ViewUnexpandFunc,
(ClientData)(pointertype) (((DBWclientRec *)w->w_clientData)->dbw_bitmask));