Пример #1
0
/* ---------------------------------------------------------------------------
 * rotates the contents of the pastebuffer
 */
void
RotateBuffer (BufferType *Buffer, BYTE Number)
{
  /* rotate vias */
  VIA_LOOP (Buffer->Data);
  {
    r_delete_entry (Buffer->Data->via_tree, (BoxType *)via);
    ROTATE_VIA_LOWLEVEL (via, Buffer->X, Buffer->Y, Number);
    SetPinBoundingBox (via);
    r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0);
  }
  END_LOOP;

  /* elements */
  ELEMENT_LOOP (Buffer->Data);
  {
    RotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y,
			   Number);
  }
  END_LOOP;

  /* all layer related objects */
  ALLLINE_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->line_tree, (BoxType *)line);
    RotateLineLowLevel (line, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->line_tree, (BoxType *)line, 0);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->arc_tree, (BoxType *)arc);
    RotateArcLowLevel (arc, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->text_tree, (BoxType *)text);
    RotateTextLowLevel (text, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->text_tree, (BoxType *)text, 0);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->polygon_tree, (BoxType *)polygon);
    RotatePolygonLowLevel (polygon, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0);
  }
  ENDALL_LOOP;

  /* finally the origin and the bounding box */
  ROTATE (Buffer->X, Buffer->Y, Buffer->X, Buffer->Y, Number);
  RotateBoxLowLevel (&Buffer->BoundingBox, Buffer->X, Buffer->Y, Number);
  SetCrosshairRangeToBuffer ();
}
Пример #2
0
/*!
 * \brief Move everything.
 *
 * Call our own 'MyMove*LowLevel' where they don't exist in move.c.
 * This gets very slow if there are large polygons present, since every
 * element move re-clears the poly, followed by the polys moving and
 * re-clearing everything again.
 */
static void
MoveAll(Coord dx, Coord dy)
{
  ELEMENT_LOOP (PCB->Data);
  {
    MoveElementLowLevel (PCB->Data, element, dx, dy);
    AddObjectToMoveUndoList (ELEMENT_TYPE, NULL, NULL, element, dx, dy);
  }
  END_LOOP;
  VIA_LOOP (PCB->Data);
  {
    MyMoveViaLowLevel (PCB->Data, via, dx, dy);
    AddObjectToMoveUndoList (VIA_TYPE, NULL, NULL, via, dx, dy);
  }
  END_LOOP;
  ALLLINE_LOOP (PCB->Data);
  {
    MyMoveLineLowLevel (PCB->Data, layer, line, dx, dy);
    AddObjectToMoveUndoList (LINE_TYPE, NULL, NULL, line, dx, dy);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (PCB->Data);
  {
    MyMoveArcLowLevel (PCB->Data, layer, arc, dx, dy);
    AddObjectToMoveUndoList (ARC_TYPE, NULL, NULL, arc, dx, dy);
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (PCB->Data);
  {
    MyMoveTextLowLevel (layer, text, dx, dy);
    AddObjectToMoveUndoList (TEXT_TYPE, NULL, NULL, text, dx, dy);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (PCB->Data);
  {
    /*
     * XXX MovePolygonLowLevel does not mean "no gui" like
     * XXX MoveElementLowLevel, it doesn't even handle layer
     * XXX tree activity.
     */
    MyMovePolygonLowLevel (PCB->Data, layer, polygon, dx, dy);
    AddObjectToMoveUndoList (POLYGON_TYPE, NULL, NULL, polygon, dx, dy);
  }
  ENDALL_LOOP;
}
Пример #3
0
/* ---------------------------------------------------------------------------
 * searches for a object by it's unique ID. It doesn't matter if
 * the object is visible or not. The search is performed on a PCB, a
 * buffer or on the remove list.
 * The calling routine passes two pointers to allocated memory for storing
 * the results. 
 * A type value is returned too which is NO_TYPE if no objects has been found.
 */
int
SearchObjectByID (DataTypePtr Base,
		  void **Result1, void **Result2, void **Result3, int ID,
		  int type)
{
  if (type == LINE_TYPE || type == LINEPOINT_TYPE)
    {
      ALLLINE_LOOP (Base);
      {
	if (line->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) line;
	    return (LINE_TYPE);
	  }
	if (line->Point1.ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point1;
	    return (LINEPOINT_TYPE);
	  }
	if (line->Point2.ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point2;
	    return (LINEPOINT_TYPE);
	  }
      }
      ENDALL_LOOP;
    }
  if (type == ARC_TYPE)
    {
      ALLARC_LOOP (Base);
      {
	if (arc->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) arc;
	    return (ARC_TYPE);
	  }
      }
      ENDALL_LOOP;
    }

  if (type == TEXT_TYPE)
    {
      ALLTEXT_LOOP (Base);
      {
	if (text->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) text;
	    return (TEXT_TYPE);
	  }
      }
      ENDALL_LOOP;
    }

  if (type == POLYGON_TYPE || type == POLYGONPOINT_TYPE)
    {
      ALLPOLYGON_LOOP (Base);
      {
	if (polygon->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) polygon;
	    return (POLYGON_TYPE);
	  }
	if (type == POLYGONPOINT_TYPE)
	  POLYGONPOINT_LOOP (polygon);
	{
	  if (point->ID == ID)
	    {
	      *Result1 = (void *) layer;
	      *Result2 = (void *) polygon;
	      *Result3 = (void *) point;
	      return (POLYGONPOINT_TYPE);
	    }
	}
	END_LOOP;
      }
      ENDALL_LOOP;
    }
  if (type == VIA_TYPE)
    {
      VIA_LOOP (Base);
      {
	if (via->ID == ID)
	  {
	    *Result1 = *Result2 = *Result3 = (void *) via;
	    return (VIA_TYPE);
	  }
      }
      END_LOOP;
    }

  if (type == RATLINE_TYPE || type == LINEPOINT_TYPE)
    {
      RAT_LOOP (Base);
      {
	if (line->ID == ID)
	  {
	    *Result1 = *Result2 = *Result3 = (void *) line;
	    return (RATLINE_TYPE);
	  }
	if (line->Point1.ID == ID)
	  {
	    *Result1 = (void *) NULL;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point1;
	    return (LINEPOINT_TYPE);
	  }
	if (line->Point2.ID == ID)
	  {
	    *Result1 = (void *) NULL;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point2;
	    return (LINEPOINT_TYPE);
	  }
      }
      END_LOOP;
    }

  if (type == ELEMENT_TYPE || type == PAD_TYPE || type == PIN_TYPE
      || type == ELEMENTLINE_TYPE || type == ELEMENTNAME_TYPE
      || type == ELEMENTARC_TYPE)
    /* check pins and elementnames too */
    ELEMENT_LOOP (Base);
  {
    if (element->ID == ID)
      {
	*Result1 = *Result2 = *Result3 = (void *) element;
	return (ELEMENT_TYPE);
      }
    if (type == ELEMENTLINE_TYPE)
      ELEMENTLINE_LOOP (element);
    {
      if (line->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) line;
	  return (ELEMENTLINE_TYPE);
	}
    }
    END_LOOP;
    if (type == ELEMENTARC_TYPE)
      ARC_LOOP (element);
    {
      if (arc->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) arc;
	  return (ELEMENTARC_TYPE);
	}
    }
    END_LOOP;
    if (type == ELEMENTNAME_TYPE)
      ELEMENTTEXT_LOOP (element);
    {
      if (text->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) text;
	  return (ELEMENTNAME_TYPE);
	}
    }
    END_LOOP;
    if (type == PIN_TYPE)
      PIN_LOOP (element);
    {
      if (pin->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) pin;
	  return (PIN_TYPE);
	}
    }
    END_LOOP;
    if (type == PAD_TYPE)
      PAD_LOOP (element);
    {
      if (pad->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) pad;
	  return (PAD_TYPE);
	}
    }
    END_LOOP;
  }
  END_LOOP;

  Message ("hace: Internal error, search for ID %d failed\n", ID);
  return (NO_TYPE);
}
Пример #4
0
/*
 * AlignText(X, [Lefts/Rights/Centers, [First/Last/Crosshair/Average[, Gridless]]])
 * AlignText(Y, [Tops/Bottoms/Centers, [First/Last/Crosshair/Average[, Gridless]]])
 *
 *	X or Y		- Select which axis will move, other is untouched
 *	Lefts, Rights,
 *	Tops, Bottoms,
 *	Centers         - Pick alignment point within each element.
 *	                  NB: text objects have no Mark
 *	First, Last, 
 *	Crosshair, 
 *	Average		- Alignment reference, First=Topmost/Leftmost,
 *			  Last=Bottommost/Rightmost, Average or Crosshair point
 *	Gridless	- Do not force results to align to prevailing grid
 *
 * Defaults are Lefts/Tops, First
 */
static int
aligntext(int argc, char **argv, Coord x, Coord y)
{
	int dir;
	int point;
	int reference;
	int gridless;
	Coord q;
	Coord p, dp, dx, dy;
	int changed = 0;

	if (argc < 1 || argc > 4) {
		AFAIL(aligntext);
	}

	/* parse direction arg */
	switch ((dir = keyword(ARG(0)))) {
	case K_X:
	case K_Y:
		break;
	default:
		AFAIL(aligntext);
	}

	/* parse point (within each element) which will be aligned */
	switch ((point = keyword(ARG(1)))) {
	case K_Centers:
		break;
	case K_Lefts:
	case K_Rights:
		if (dir == K_Y) {
			AFAIL(aligntext);
		}
		break;
	case K_Tops:
	case K_Bottoms:
		if (dir == K_X) {
			AFAIL(aligntext);
		}
		break;
	case K_none:
		/* default value */
		if (dir == K_X) {
			point = K_Lefts;
		} else {
			point = K_Tops;
		}
		break;
	default:
		AFAIL(aligntext);
	}

	/* parse reference which will determine alignment coordinates */
	switch ((reference = keyword(ARG(2)))) {
	case K_First:
	case K_Last:
	case K_Average:
	case K_Crosshair:
		break;
	case K_none:
		reference = K_First;	/* default value */
		break;
	default:
		AFAIL(aligntext);
	}

	/* optionally work off the grid (solar cells!) */
	switch (keyword(ARG(3))) {
	case K_Gridless:
		gridless = 1;
		break;
	case K_none:
		gridless = 0;
		break;
	default:
		AFAIL(aligntext);
	}

	SaveUndoSerialNumber();

	/* find the final alignment coordinate using the above options */
	q = reference_coord(K_aligntext, Crosshair.X, Crosshair.Y,
				dir, point, reference);

	/* move all selected elements to the new coordinate */

	/* selected text part of an element */
	ELEMENT_LOOP(PCB->Data);
	{
		TextType *text;
		text = &(element)->Name[NAME_INDEX(PCB)];
		if (! TEST_FLAG (SELECTEDFLAG, text))
			continue;
		/* find delta from reference point to reference point */
		p = coord(text, dir, point);
		dp = q - p;
		/* ...but if we're gridful, keep the mark on the grid */
		/* TODO re-enable for text, need textcoord()
		if (! gridless) {
			dp -= (coord(text, dir, K_Marks) + dp)
					% (long) (PCB->Grid);
		}
		*/
		if (dp) {
			/* move from generic to X or Y */
			dx = dy = dp;
			if (dir == K_X)
				dy = 0;
			else
				dx = 0;
			MoveObject(ELEMENTNAME_TYPE, element, text, text, dx, dy);
			changed = 1;
		}
	}
	END_LOOP;

	/* Selected bare text objects */
	ALLTEXT_LOOP (PCB->Data);
	{
	  if (TEST_FLAG (SELECTEDFLAG, text))
	    {
		/* find delta from reference point to reference point */
		p = coord(text, dir, point);
		dp = q - p;
		/* ...but if we're gridful, keep the mark on the grid */
		/* TODO re-enable for text, need textcoord()
		if (! gridless) {
			dp -= (coord(text, dir, K_Marks) + dp)
					% (long) (PCB->Grid);
		}
		*/
		if (dp) {
			/* move from generic to X or Y */
			dx = dy = dp;
			if (dir == K_X)
				dy = 0;
			else
				dx = 0;
			MoveObject(TEXT_TYPE, layer, text, text, dx, dy);
			changed = 1;
		}
	    }
	}
	ENDALL_LOOP;

	if (changed) {
		RestoreUndoSerialNumber();
		IncrementUndoSerialNumber();
		Redraw();
		SetChangedFlag(true);
	}

	free_texts_by_pos();

	return 0;
}
Пример #5
0
/*
 * Find all selected text objects, then order them in order by coordinate in
 * the 'dir' axis.  This is used to find the "First" and "Last" elements
 * and also to choose the distribution order.
 *
 * For alignment, first and last are in the orthogonal axis (imagine if
 * you were lining up letters in a sentence, aligning *vertically* to the
 * first letter means selecting the first letter *horizontally*).
 *
 * For distribution, first and last are in the distribution axis.
 */
static int
sort_texts_by_pos(int op, int dir, int point)
{
	int nsel = 0;

	if (ntexts_by_pos)
		return ntexts_by_pos;

	if (op == K_aligntext)
		dir = dir == K_X ? K_Y : K_X;	/* see above */

	ELEMENT_LOOP(PCB->Data);
	{
		TextType *text;
		text = &(element)->Name[NAME_INDEX(PCB)];
		if (! TEST_FLAG (SELECTEDFLAG, text))
			continue;
		nsel++;
	}
	END_LOOP;


	ALLTEXT_LOOP (PCB->Data);
	{
		if (! TEST_FLAG (SELECTEDFLAG, text))
			continue;
		nsel++;
	}
	ENDALL_LOOP;


	if (! nsel)
		return 0;

	texts_by_pos = malloc(nsel * sizeof(*texts_by_pos));
	ntexts_by_pos = nsel;


	nsel = 0;

	ELEMENT_LOOP(PCB->Data);
	{
		TextType *text;
		text = &(element)->Name[NAME_INDEX(PCB)];
		if (! TEST_FLAG (SELECTEDFLAG, text))
			continue;
		texts_by_pos[nsel].text = text;
		texts_by_pos[nsel].type = ELEMENTNAME_TYPE;
		texts_by_pos[nsel++].pos = coord(text, dir, point);
	}
	END_LOOP;


	ALLTEXT_LOOP (PCB->Data);
	{
		if (! TEST_FLAG (SELECTEDFLAG, text))
			continue;
		texts_by_pos[nsel].text = text;
		texts_by_pos[nsel].type = TEXT_TYPE;
		texts_by_pos[nsel++].pos = coord(text, dir, point);
	}
	ENDALL_LOOP;


	qsort(texts_by_pos, ntexts_by_pos,
		sizeof(*texts_by_pos), cmp_tbp);
	return ntexts_by_pos;
}
Пример #6
0
/* ---------------------------------------------------------------------------
 * flip components/tracks from one side to the other
 */
static void
SwapBuffer (BufferType *Buffer)
{
  int j, k;
  Cardinal sgroup, cgroup;
  LayerType swap;

  ELEMENT_LOOP (Buffer->Data);
  {
    r_delete_element (Buffer->Data, element);
    MirrorElementCoordinates (Buffer->Data, element, 0);
  }
  END_LOOP;
  /* set buffer offset to 'mark' position */
  Buffer->X = SWAP_X (Buffer->X);
  Buffer->Y = SWAP_Y (Buffer->Y);
  VIA_LOOP (Buffer->Data);
  {
    r_delete_entry (Buffer->Data->via_tree, (BoxType *)via);
    via->X = SWAP_X (via->X);
    via->Y = SWAP_Y (via->Y);
    SetPinBoundingBox (via);
    r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0);
  }
  END_LOOP;
  ALLLINE_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->line_tree, (BoxType *)line);
    line->Point1.X = SWAP_X (line->Point1.X);
    line->Point1.Y = SWAP_Y (line->Point1.Y);
    line->Point2.X = SWAP_X (line->Point2.X);
    line->Point2.Y = SWAP_Y (line->Point2.Y);
    SetLineBoundingBox (line);
    r_insert_entry (layer->line_tree, (BoxType *)line, 0);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->arc_tree, (BoxType *)arc);
    arc->X = SWAP_X (arc->X);
    arc->Y = SWAP_Y (arc->Y);
    arc->StartAngle = SWAP_ANGLE (arc->StartAngle);
    arc->Delta = SWAP_DELTA (arc->Delta);
    SetArcBoundingBox (arc);
    r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->polygon_tree, (BoxType *)polygon);
    POLYGONPOINT_LOOP (polygon);
    {
      point->X = SWAP_X (point->X);
      point->Y = SWAP_Y (point->Y);
    }
    END_LOOP;
    SetPolygonBoundingBox (polygon);
    r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0);
    /* hmmm, how to handle clip */
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->text_tree, (BoxType *)text);
    text->X = SWAP_X (text->X);
    text->Y = SWAP_Y (text->Y);
    TOGGLE_FLAG (ONSOLDERFLAG, text);
    SetTextBoundingBox (&PCB->Font, text);
    r_insert_entry (layer->text_tree, (BoxType *)text, 0);
  }
  ENDALL_LOOP;
  /* swap silkscreen layers */
  swap = Buffer->Data->Layer[solder_silk_layer];
  Buffer->Data->Layer[solder_silk_layer] =
    Buffer->Data->Layer[component_silk_layer];
  Buffer->Data->Layer[component_silk_layer] = swap;

  /* swap layer groups when balanced */
  sgroup = GetLayerGroupNumberByNumber (solder_silk_layer);
  cgroup = GetLayerGroupNumberByNumber (component_silk_layer);
  if (PCB->LayerGroups.Number[cgroup] == PCB->LayerGroups.Number[sgroup])
    {
      for (j = k = 0; j < PCB->LayerGroups.Number[sgroup]; j++)
	{
	  int t1, t2;
	  Cardinal cnumber = PCB->LayerGroups.Entries[cgroup][k];
	  Cardinal snumber = PCB->LayerGroups.Entries[sgroup][j];

	  if (snumber >= max_copper_layer)
	    continue;
	  swap = Buffer->Data->Layer[snumber];

	  while (cnumber >= max_copper_layer)
	    {
	      k++;
	      cnumber = PCB->LayerGroups.Entries[cgroup][k];
	    }
	  Buffer->Data->Layer[snumber] = Buffer->Data->Layer[cnumber];
	  Buffer->Data->Layer[cnumber] = swap;
	  k++;
	  /* move the thermal flags with the layers */
	  ALLPIN_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (snumber, pin);
	    t2 = TEST_THERM (cnumber, pin);
	    ASSIGN_THERM (snumber, t2, pin);
	    ASSIGN_THERM (cnumber, t1, pin);
	  }
	  ENDALL_LOOP;
	  VIA_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (snumber, via);
	    t2 = TEST_THERM (cnumber, via);
	    ASSIGN_THERM (snumber, t2, via);
	    ASSIGN_THERM (cnumber, t1, via);
	  }
	  END_LOOP;
	}
    }
  SetBufferBoundingBox (Buffer);
  SetCrosshairRangeToBuffer ();
}
Пример #7
0
bool
SelectObjectByName (int Type, char *Pattern, bool Flag)
{
  bool changed = false;

#if defined(HAVE_REGCOMP)
#define	REGEXEC(arg)	(regexec_match_all(&compiled, (arg)))

  int result;
  regex_t compiled;

  /* compile the regular expression */
  result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE);
  if (result)
    {
      char errorstring[128];

      regerror (result, &compiled, errorstring, 128);
      Message (_("regexp error: %s\n"), errorstring);
      regfree (&compiled);
      return (false);
    }
#else
#define	REGEXEC(arg)	(re_exec((arg)) == 1)

  char *compiled;

  /* compile the regular expression */
  if ((compiled = re_comp (Pattern)) != NULL)
    {
      Message (_("re_comp error: %s\n"), compiled);
      return (false);
    }
#endif

  /* loop over all visible objects with names */
  if (Type & TEXT_TYPE)
    ALLTEXT_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, text)
	&& TEXT_IS_VISIBLE (PCB, layer, text)
	&& text->TextString
	&& REGEXEC (text->TextString)
	&& TEST_FLAG (SELECTEDFLAG, text) != Flag)
      {
	AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	DrawText (layer, text, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;

  if (PCB->ElementOn && (Type & ELEMENT_TYPE))
    ELEMENT_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
	    || PCB->InvisibleObjectsOn)
	&& TEST_FLAG (SELECTEDFLAG, element) != Flag)
      {
	String name = ELEMENT_NAME (PCB, element);
	if (name && REGEXEC (name))
	  {
	    AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
	    ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
	    PIN_LOOP (element);
	    {
	      AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
	    }
	    END_LOOP;
	    PAD_LOOP (element);
	    {
	      AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
	    }
	    END_LOOP;
	    ELEMENTTEXT_LOOP (element);
	    {
	      AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	    }
	    END_LOOP;
	    DrawElementName (element, 0);
	    DrawElement (element, 0);
	    changed = true;
	  }
      }
  }
  END_LOOP;
  if (PCB->PinOn && (Type & PIN_TYPE))
    ALLPIN_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& pin->Name && REGEXEC (pin->Name)
	&& TEST_FLAG (SELECTEDFLAG, pin) != Flag)
      {
	AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
	DrawPin (pin, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;
  if (PCB->PinOn && (Type & PAD_TYPE))
    ALLPAD_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT
	    || PCB->InvisibleObjectsOn)
	&& TEST_FLAG (SELECTEDFLAG, pad) != Flag)
      if (pad->Name && REGEXEC (pad->Name))
	{
	  AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	  ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
	  DrawPad (pad, 0);
	  changed = true;
	}
  }
  ENDALL_LOOP;
  if (PCB->ViaOn && (Type & VIA_TYPE))
    VIA_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, via)
	&& via->Name
	&& REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag)
      {
	AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
	DrawVia (via, 0);
	changed = true;
      }
  }
  END_LOOP;

#if defined(HAVE_REGCOMP)
#if !defined(sgi)
  regfree (&compiled);
#endif
#endif

  if (changed)
    {
      IncrementUndoSerialNumber ();
      Draw ();
    }
  return (changed);
}
Пример #8
0
/* ----------------------------------------------------------------------
 * performs several operations on selected objects which are also visible
 * The lowlevel procedures are passed together with additional information
 * resets the selected flag if requested
 * returns true if anything has changed
 */
bool
SelectedOperation (ObjectFunctionTypePtr F, bool Reset, int type)
{
  bool changed = false;

  /* check lines */
  if (type & LINE_TYPE && F->Line)
    VISIBLELINE_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, line))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
	    CLEAR_FLAG (SELECTEDFLAG, line);
	  }
	F->Line (layer, line);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check arcs */
  if (type & ARC_TYPE && F->Arc)
    VISIBLEARC_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, arc))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
	    CLEAR_FLAG (SELECTEDFLAG, arc);
	  }
	F->Arc (layer, arc);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check text */
  if (type & TEXT_TYPE && F->Text)
    ALLTEXT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
	    CLEAR_FLAG (SELECTEDFLAG, text);
	  }
	F->Text (layer, text);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check polygons */
  if (type & POLYGON_TYPE && F->Polygon)
    VISIBLEPOLYGON_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, polygon))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
	    CLEAR_FLAG (SELECTEDFLAG, polygon);
	  }
	F->Polygon (layer, polygon);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* elements silkscreen */
  if (type & ELEMENT_TYPE && PCB->ElementOn && F->Element)
    ELEMENT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, element))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
	    CLEAR_FLAG (SELECTEDFLAG, element);
	  }
	F->Element (element);
	changed = true;
      }
  }
  END_LOOP;
  if (type & ELEMENTNAME_TYPE && PCB->ElementOn && F->ElementName)
    ELEMENT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element)))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
				     element,
				     &ELEMENT_TEXT (PCB, element),
				     &ELEMENT_TEXT (PCB, element));
	    CLEAR_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element));
	  }
	F->ElementName (element);
	changed = true;
      }
  }
  END_LOOP;

  if (type & PIN_TYPE && PCB->PinOn && F->Pin)
    ELEMENT_LOOP (PCB->Data);
  {
    PIN_LOOP (element);
    {
      if (TEST_FLAG (SELECTEDFLAG, pin))
	{
	  if (Reset)
	    {
	      AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	      CLEAR_FLAG (SELECTEDFLAG, pin);
	    }
	  F->Pin (element, pin);
	  changed = true;
	}
    }
    END_LOOP;
  }
  END_LOOP;

  if (type & PAD_TYPE && PCB->PinOn && F->Pad)
    ELEMENT_LOOP (PCB->Data);
  {
    PAD_LOOP (element);
    {
      if (TEST_FLAG (SELECTEDFLAG, pad))
	{
	  if (Reset)
	    {
	      AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	      CLEAR_FLAG (SELECTEDFLAG, pad);
	    }
	  F->Pad (element, pad);
	  changed = true;
	}
    }
    END_LOOP;
  }
  END_LOOP;

  /* process vias */
  if (type & VIA_TYPE && PCB->ViaOn && F->Via)
    VIA_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, via))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	    CLEAR_FLAG (SELECTEDFLAG, via);
	  }
	F->Via (via);
	changed = true;
      }
  }
  END_LOOP;
  /* and rat-lines */
  if (type & RATLINE_TYPE && PCB->RatOn && F->Rat)
    RAT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, line))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
	    CLEAR_FLAG (SELECTEDFLAG, line);
	  }
	F->Rat (line);
	changed = true;
      }
  }
  END_LOOP;
  if (Reset && changed)
    IncrementUndoSerialNumber ();
  return (changed);
}