Index: src/select.c =================================================================== --- src/select.c (revision 953) +++ src/select.c (revision 954) @@ -210,15 +210,40 @@ } /* ---------------------------------------------------------------------- - * selects/unselects all visible objects within the passed box - * Flag determines if the block is to be selected or unselected - * returns true if the state of any object has changed + * selects/unselects or lists visible objects within the passed box + * If len is NULL: + * Flag determines if the block is to be selected or unselected + * returns non-NULL if the state of any object has changed + * if len is non-NULLL + * returns a list of object IDs matched the search and loads len with the + * length of the list. Returns NULL on no match. */ -bool -SelectBlock (BoxTypePtr Box, bool Flag) +static long int * +ListBlock_ (BoxTypePtr Box, bool Flag, int *len) { - bool changed = false; + int changed = 0; + int used = 0, alloced = 0; + long int *list = NULL; +/* append an object to the return list OR set the flag if there's no list */ +#define append(undo_type, p1, obj) \ +do { \ + if (len == NULL) { \ + AddObjectToFlagUndoList (undo_type, p1, obj, obj); \ + ASSIGN_FLAG (SELECTEDFLAG, Flag, obj); \ + } \ + else { \ + if (used >= alloced) { \ + alloced += 64; \ + list = realloc(list, sizeof(*list) * alloced); \ + } \ + list[used] = obj->ID; \ + used++; \ + } \ + changed = 1; \ +} while(0) + + if (PCB->RatOn || !Flag) RAT_LOOP (PCB->Data); { @@ -225,11 +250,9 @@ if (LINE_IN_BOX ((LineTypePtr) line, Box) && !TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != Flag) { - AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line); - ASSIGN_FLAG (SELECTEDFLAG, Flag, line); + append(RATLINE_TYPE, line, line); if (PCB->RatOn) DrawRat (line); - changed = true; } } END_LOOP; @@ -257,11 +280,9 @@ && !TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != Flag) { - AddObjectToFlagUndoList (LINE_TYPE, layer, line, line); - ASSIGN_FLAG (SELECTEDFLAG, Flag, line); + append(LINE_TYPE, layer, line); if (layer->On) DrawLine (layer, line); - changed = true; } } END_LOOP; @@ -271,11 +292,9 @@ && !TEST_FLAG (LOCKFLAG, arc) && TEST_FLAG (SELECTEDFLAG, arc) != Flag) { - AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc); - ASSIGN_FLAG (SELECTEDFLAG, Flag, arc); + append(ARC_TYPE, layer, arc); if (layer->On) DrawArc (layer, arc); - changed = true; } } END_LOOP; @@ -287,11 +306,9 @@ && !TEST_FLAG (LOCKFLAG, text) && TEST_FLAG (SELECTEDFLAG, text) != Flag) { - AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text); - ASSIGN_FLAG (SELECTEDFLAG, Flag, text); + append(TEXT_TYPE, layer, text); if (TEXT_IS_VISIBLE(PCB, layer, text)) DrawText (layer, text); - changed = true; } } } @@ -302,11 +319,9 @@ && !TEST_FLAG (LOCKFLAG, polygon) && TEST_FLAG (SELECTEDFLAG, polygon) != Flag) { - AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon); - ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon); + append(POLYGON_TYPE, layer, polygon); if (layer->On) DrawPolygon (layer, polygon); - changed = true; } } END_LOOP; @@ -332,30 +347,23 @@ /* select all names of element */ ELEMENTTEXT_LOOP (element); { - AddObjectToFlagUndoList (ELEMENTNAME_TYPE, - element, text, text); - ASSIGN_FLAG (SELECTEDFLAG, Flag, text); + append(ELEMENTNAME_TYPE, element, text); } END_LOOP; if (PCB->ElementOn) DrawElementName (element); - changed = true; } if ((PCB->PinOn || !Flag) && ELEMENT_IN_BOX (element, Box)) if (TEST_FLAG (SELECTEDFLAG, element) != Flag) { - AddObjectToFlagUndoList (ELEMENT_TYPE, - element, element, element); - ASSIGN_FLAG (SELECTEDFLAG, Flag, element); + append(ELEMENT_TYPE, element, element); PIN_LOOP (element); { if (TEST_FLAG (SELECTEDFLAG, pin) != Flag) { - AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin); - ASSIGN_FLAG (SELECTEDFLAG, Flag, pin); + append(PIN_TYPE, element, pin); if (PCB->PinOn) DrawPin (pin); - changed = true; } } END_LOOP; @@ -363,17 +371,14 @@ { if (TEST_FLAG (SELECTEDFLAG, pad) != Flag) { - AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad); - ASSIGN_FLAG (SELECTEDFLAG, Flag, pad); + append(PAD_TYPE, element, pad); if (PCB->PinOn) DrawPad (pad); - changed = true; } } END_LOOP; if (PCB->PinOn) DrawElement (element); - changed = true; gotElement = true; } } @@ -384,11 +389,9 @@ if ((VIA_OR_PIN_IN_BOX (pin, Box) && TEST_FLAG (SELECTEDFLAG, pin) != Flag)) { - AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin); - ASSIGN_FLAG (SELECTEDFLAG, Flag, pin); + append(PIN_TYPE, element, pin); if (PCB->PinOn) DrawPin (pin); - changed = true; } } END_LOOP; @@ -400,11 +403,9 @@ || PCB->InvisibleObjectsOn || !Flag)) { - AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad); - ASSIGN_FLAG (SELECTEDFLAG, Flag, pad); + append(PAD_TYPE, element, pad); if (PCB->PinOn) DrawPad (pad); - changed = true; } } END_LOOP; @@ -420,23 +421,39 @@ && !TEST_FLAG (LOCKFLAG, via) && TEST_FLAG (SELECTEDFLAG, via) != Flag) { - AddObjectToFlagUndoList (VIA_TYPE, via, via, via); - ASSIGN_FLAG (SELECTEDFLAG, Flag, via); + append(VIA_TYPE, via, via); if (PCB->ViaOn) DrawVia (via); - changed = true; } } END_LOOP; + if (changed) { Draw (); IncrementUndoSerialNumber (); } - return (changed); + + if (len == NULL) { + static long int non_zero; + return (changed ? &non_zero : NULL); + } } +#undef append /* ---------------------------------------------------------------------- + * selects/unselects all visible objects within the passed box + * Flag determines if the block is to be selected or unselected + * returns true if the state of any object has changed + */ +bool +SelectBlock (BoxTypePtr Box, bool Flag) +{ + /* do not list, set flag */ + return (ListBlock_ (Box, Flag, NULL) == NULL) ? false : true; +} + +/* ---------------------------------------------------------------------- * performs several operations on the passed object */ void *