diff --git a/VERSION b/VERSION index 48221040..24bead74 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.631 +8.3.632 diff --git a/commands/CmdE.c b/commands/CmdE.c index b83b2b14..6d3c156e 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -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. diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index 349a1164..2c9006d2 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -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 */ diff --git a/commands/CmdSubrs.c b/commands/CmdSubrs.c index 5ff6d199..7a12c979 100644 --- a/commands/CmdSubrs.c +++ b/commands/CmdSubrs.c @@ -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; } diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index f14b6eab..b6c56300 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -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. diff --git a/database/DBexpand.c b/database/DBexpand.c index d1ba588a..d547cf5f 100644 --- a/database/DBexpand.c +++ b/database/DBexpand.c @@ -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; } diff --git a/database/DBio.c b/database/DBio.c index 22e81bdd..c8173d9f 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -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)) diff --git a/database/database.h.in b/database/database.h.in index b879aa71..d1e7385b 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -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 ------------------- */ /*** diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index cb3cdeb3..d9ef5945 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -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) diff --git a/select/selOps.c b/select/selOps.c index 59ce84be..91cbeeb2 100644 --- a/select/selOps.c +++ b/select/selOps.c @@ -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; } diff --git a/windows/windCmdSZ.c b/windows/windCmdSZ.c index 3190708d..63bd3e6e 100644 --- a/windows/windCmdSZ.c +++ b/windows/windCmdSZ.c @@ -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));