예제 #1
0
static void
selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
{
    GtkTreeModel *model;
    GtkTreeIter iter;
    GhidDrcViolation *violation;
    int i;

    if (!gtk_tree_selection_get_selected (selection, &model, &iter))
    {
        if (ClearFlagOnAllObjects (true, FOUNDFLAG))
        {
            IncrementUndoSerialNumber ();
            Draw ();
        }
        return;
    }

    /* Check the selected node has children, if so; return. */
    if (gtk_tree_model_iter_has_child (model, &iter))
        return;

    gtk_tree_model_get (model, &iter, DRC_VIOLATION_OBJ_COL, &violation, -1);

    ClearFlagOnAllObjects (true, FOUNDFLAG);

    if (violation == NULL)
        return;

    /* Flag the objects listed against this DRC violation */
    for (i = 0; i < violation->object_count; i++)
    {
        int object_id = violation->object_id_list[i];
        int object_type = violation->object_type_list[i];
        int found_type;
        void *ptr1, *ptr2, *ptr3;

        found_type = SearchObjectByID (PCB->Data, &ptr1, &ptr2, &ptr3,
                                       object_id, object_type);
        if (found_type == NO_TYPE)
        {
            Message (_("Object ID %i identified during DRC was not found. Stale DRC window?\n"),
                     object_id);
            continue;
        }
        AddObjectToFlagUndoList (object_type, ptr1, ptr2, ptr3);
        SET_FLAG (FOUNDFLAG, (AnyObjectType *)ptr2);
        switch (violation->object_type_list[i])
        {
        case LINE_TYPE:
        case ARC_TYPE:
        case POLYGON_TYPE:
            ChangeGroupVisibility (GetLayerNumber (PCB->Data, (LayerType *) ptr1), true, true);
        }
        DrawObject (object_type, ptr1, ptr2);
    }
    SetChangedFlag (true);
    IncrementUndoSerialNumber ();
    Draw();
}
예제 #2
0
/*!
 * \brief Find the specified element.
 *
 * Usage: FindElement(Refdes)\n
 * If no argument is passed, no action is carried out.
 */
static int
find_element (int argc, char **argv, Coord x, Coord y)
{
  if (argc == 0 || strcasecmp (argv[0], "") == 0)
  {
    Message ("WARNING: in FindElement the argument should be a non-empty string value.\n");
      return 0;
  }
  else
  {
    SET_FLAG (NAMEONPCBFLAG, PCB);
    ELEMENT_LOOP(PCB->Data);
    {
      if (NAMEONPCB_NAME(element)
        && strcmp (argv[0], NAMEONPCB_NAME(element)) == 0)
      {
        gui->set_crosshair
        (
          element->MarkX,
          element->MarkY,
          HID_SC_PAN_VIEWPORT
        );
      }
    }
    END_LOOP;
    gui->invalidate_all ();
    IncrementUndoSerialNumber ();
    return 0;
  };
}
예제 #3
0
파일: move.c 프로젝트: fruoff/pcb-fruoff
/* ---------------------------------------------------------------------------
 * moves the object identified by its data pointers and the type
 * as well as all attached rubberband lines
 */
void *
MoveObjectAndRubberband (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
			 Coord DX, Coord DY)
{
  RubberbandTypePtr ptr;
  void *ptr2;

  /* setup offset */
  DeltaX = DX;
  DeltaY = DY;
  if (DX == 0 && DY == 0)
    return (NULL);

  /* move all the lines... and reset the counter */
  ptr = Crosshair.AttachedObject.Rubberband;
  while (Crosshair.AttachedObject.RubberbandN)
    {
      /* first clear any marks that we made in the line flags */
      CLEAR_FLAG (RUBBERENDFLAG, ptr->Line);
      AddObjectToMoveUndoList (LINEPOINT_TYPE,
			       ptr->Layer, ptr->Line, ptr->MovedPoint, DX,
			       DY);
      MoveLinePoint (ptr->Layer, ptr->Line, ptr->MovedPoint);
      Crosshair.AttachedObject.RubberbandN--;
      ptr++;
    }

  AddObjectToMoveUndoList (Type, Ptr1, Ptr2, Ptr3, DX, DY);
  ptr2 = ObjectOperation (&MoveFunctions, Type, Ptr1, Ptr2, Ptr3);
  IncrementUndoSerialNumber ();
  return (ptr2);
}
예제 #4
0
/* Select on the layout the current net treeview selection
 */
static void
netlist_select_cb (GtkWidget * widget, gpointer data)
{
  LibraryEntryType *entry;
  ConnectionType conn;
  gint i;
  gboolean select_flag = GPOINTER_TO_INT (data);

  if (!selected_net)
    return;
  if (selected_net == node_selected_net)
    node_selected_net = NULL;

  InitConnectionLookup ();
  ResetConnections (true);

  for (i = selected_net->EntryN, entry = selected_net->Entry; i; i--, entry++)
    if (SeekPad (entry, &conn, false))
      RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, true);

  SelectConnection (select_flag);
  ResetConnections (false);
  FreeConnectionLookupMemory ();
  IncrementUndoSerialNumber ();
  Draw ();
}
예제 #5
0
/*!
 * \brief Locking all or selected elements.
 *
 * Usage:\n
 * UnlockElements(All)\n
 * UE(All)\n       
 * If no argument is passed, no action is carried out.
 */
static int
unlock_elements (int argc, char **argv, Coord x, Coord y)
{
        int all = 0;
        if (strcasecmp (argv[0], "All") == 0)
                all = 1;
        else
        {
                Message ("ERROR: in UnlockElements argument should be All.\n");
                return 1;
        }
        SET_FLAG (NAMEONPCBFLAG, PCB);
        ELEMENT_LOOP(PCB->Data);
        {
                if (TEST_FLAG (LOCKFLAG, element))
                {
                        /* element is locked */
                        if (all)
                                CLEAR_FLAG(LOCKFLAG, element);
                }
        }
        END_LOOP;
        gui->invalidate_all ();
        IncrementUndoSerialNumber ();
        return 0;
}
예제 #6
0
int
footprint_update(int argc, char **argv, int x, int y)
{
  global_argc = argc;
  global_argv = argv;

  debug_log("footprint_update\n");
  debug_log("  argc: %d\n", argc);
  if (argc) {
    int i;
    for (i = 0; i < argc; i++) {
      debug_log("  argv[%d]: %s\n", i, argv[i]);
    }
  }
  if (argc >= 1) {
    if (strcasecmp(argv[0], "auto") == 0) {
      match_mode = MATCH_MODE_AUTO;
      style = STYLE_ALL;
    } else if (strcasecmp(argv[0], "manual") == 0) {
      match_mode = MATCH_MODE_MANUAL;
      style = STYLE_SELECTED;
    } else {
      base_log("Error: If given, the first argument must be "
               "\"auto\" or \"manual\".\n");
      return usage();
    }
    if (argc >= 2) {
      if (strcasecmp(argv[1], "selected") == 0) {
        style = STYLE_SELECTED;
      } else if (strcasecmp(argv[1], "named") == 0) {
        style = STYLE_NAMED;
      } else {
        base_log("Error: If given, the second argument must be "
                 "\"selected\", or \"named\".\n");
        return usage();
      }
    }
    
  }
  debug_log("match_mode: %d\n", match_mode);
  debug_log("style: %d\n", style);

  if (PASTEBUFFER->Data->ElementN != 1) {
    base_log("Error: Paste buffer should contain one element.\n");
    return usage();
  }

  ELEMENT_LOOP(PASTEBUFFER->Data);
  {
    int replaced = replace_footprints(element);
    if (replaced) {
      base_log("Replaced %d elements.\n", replaced);
      IncrementUndoSerialNumber();
    }
  }
  END_LOOP;

  return 0;
}
예제 #7
0
Boolean ClrObjectOctagon( int Type, void *Ptr1, void *Ptr2, void *Ptr3 )
{
  if ( ObjectOperation( &ClrOctagonFunctions, Type, Ptr1, Ptr2, Ptr3 ) )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return 1;
}
예제 #8
0
Boolean SetObjectSquare( int Type, void *Ptr1, void *Ptr2, void *Ptr3 )
{
  if ( ObjectOperation( &SetSquareFunctions, Type, Ptr1, Ptr2, Ptr3 ) )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return 1;
}
예제 #9
0
Boolean ChangeObjectJoin( int Type, void *Ptr1, void *Ptr2, void *Ptr3 )
{
  if ( ObjectOperation( &ChangeJoinFunctions, Type, Ptr1, Ptr2, Ptr3 ) )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return 1;
}
예제 #10
0
Boolean ClrSelectedOctagon( int types )
{
  Boolean change;
  if ( change & 255 )
  {
    Draw( );
    IncrementUndoSerialNumber( );
    return change;
  }
  return SelectedOperation( &ClrOctagonFunctions, 0, types );
}
예제 #11
0
Boolean SetSelectedSquare( int types )
{
  Boolean change;
  if ( change & 255 )
  {
    Draw( );
    IncrementUndoSerialNumber( );
    return change;
  }
  return SelectedOperation( &SetSquareFunctions, 0, types );
}
예제 #12
0
Boolean ChangeSelectedThermals( int types, int therm_style )
{
  Boolean change;
  Delta = therm_style;
  if ( change & 255 )
  {
    Draw( );
    IncrementUndoSerialNumber( );
    return change;
  }
  return SelectedOperation( &ChangeThermalFunctions, 0, types );
}
예제 #13
0
Boolean ChangeSelectedPaste( void )
{
  int eax;
  int edx;
  int ebp_36;
  Boolean change;
{
  Cardinal n;
  ElementTypePtr element;
  change = 0;
  n = PCB->Data->ElementN + -1;
  if ( PCB->Data->ElementN + -1 != -1 )
  {
    ebp_36 = ( PCB->Data->ElementN * 300 ) + -300;
    while ( 1 )
    {
      Cardinal n = 0;
      Cardinal sn;
      PadTypePtr pad;
      element += PCB->Data->Element / 300;
      sn = element->PadN;
      element->PadN = element->PadN;
      for ( ; sn && n < sn;  )
      {
        pad = element->Pad + ( n * 104 );
        if ( ( ( pad->Flags.f/*.1_1of4*/ & 64 ) & 255 ) == 0 )
          continue;
        else
        {
          sn = element->PadN;
          change |= ChangePaste( pad );
        }
        n += sn == sn;
      }
      n += -1;
      ebp_36 += -300;
      if ( n == -1 )
      {
        if ( change == 0 )
          break;
        Draw( );
        IncrementUndoSerialNumber( );
        break;
      }
      else
      {
      }
    }
  }
  return change;
}
}
예제 #14
0
파일: move.c 프로젝트: fruoff/pcb-fruoff
/* ---------------------------------------------------------------------------
 * moves the object identified by its data pointers and the type
 * to a new layer without changing it's position
 */
void *
MoveObjectToLayer (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
		   LayerTypePtr Target, bool enmasse)
{
  void *result;

  /* setup global identifiers */
  Dest = Target;
  MoreToCome = enmasse;
  result = ObjectOperation (&MoveToLayerFunctions, Type, Ptr1, Ptr2, Ptr3);
  IncrementUndoSerialNumber ();
  return (result);
}
예제 #15
0
Boolean ChangeObjectThermal( int Type, void *Ptr1, void *Ptr2, void *Ptr3, int therm_type )
{
  Boolean change;
  Absolute = therm_type;
  Delta = therm_type;
  change = ObjectOperation( &ChangeThermalFunctions, Type, Ptr1, Ptr2, Ptr3 ) != 0;
  if ( ObjectOperation( &ChangeThermalFunctions, Type, Ptr1, Ptr2, Ptr3 ) )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return change;
}
예제 #16
0
Boolean ChangeSelected2ndSize( int types, LocationType Difference, Boolean fixIt )
{
  Boolean change;
  Difference = 0;
  Absolute = fixIt != 0 ? Difference : Difference;
  Delta = Difference;
  if ( change & 255 )
  {
    Draw( );
    IncrementUndoSerialNumber( );
    return change;
  }
  return SelectedOperation( &Change2ndSizeFunctions, 0, types );
}
예제 #17
0
파일: remove.c 프로젝트: bert/pcb-rnd
/* ----------------------------------------------------------------------
 * removes all selected and visible objects
 * returns true if any objects have been removed
 */
bool
RemoveSelected (void)
{
  Bulk = true;
  if (SelectedOperation (&RemoveFunctions, false, ALL_TYPES))
    {
      IncrementUndoSerialNumber ();
      Draw ();
      Bulk = false;
      return (true);
    }
  Bulk = false;
  return (false);
}
예제 #18
0
Boolean ChangeObjectMaskSize( int Type, void *Ptr1, void *Ptr2, void *Ptr3, LocationType Difference, Boolean fixIt )
{
  Boolean change;
  Difference = 0;
  Absolute = fixIt != 0 ? Difference : Difference;
  Delta = Difference;
  change = ObjectOperation( &ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3 ) != 0;
  if ( ObjectOperation( &ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3 ) )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return change;
}
예제 #19
0
파일: autocrop.c 프로젝트: bert/pcb-plugins
static int
autocrop (int argc, char **argv, Coord x, Coord y)
{
//  int changed = 0;
  Coord dx, dy, pad;
  BoxType *box;

  box = GetDataBoundingBox (PCB->Data); /* handy! */
  if (!box || (box->X1 == box->X2 || box->Y1 == box->Y2))
  {
    /* board would become degenerate */
    return 0;
  }
  /*
   * Now X1/Y1 are the distance to move the left/top edge
   * (actually moving all components to the left/up) such that
   * the exact edge of the leftmost/topmost component would touch
   * the edge.  Reduce the move by the edge relief requirement XXX
   * and expand the board by the same amount.
   */
  pad = PCB->minWid * 5; /* XXX real edge clearance */
  dx = -box->X1 + pad;
  dy = -box->Y1 + pad;
  box->X2 += pad;
  box->Y2 += pad;
  /*
   * Round move to keep components grid-aligned, then translate the
   * upper coordinates into the new space.
   */
  dx -= dx % (long) PCB->Grid;
  dy -= dy % (long) PCB->Grid;
  box->X2 += dx;
  box->Y2 += dy;
  /*
   * Avoid touching any data if there's nothing to do.
   */
  if (dx == 0 && dy == 0 && PCB->MaxWidth == box->X2
    && PCB->MaxHeight == box->Y2)
  {
    return 0;
  }
  /* Resize -- XXX cannot be undone */
  PCB->MaxWidth = box->X2;
  PCB->MaxHeight = box->Y2;
  MoveAll (dx, dy);
  IncrementUndoSerialNumber ();
  Redraw ();
  SetChangedFlag (1);
  return 0;
}
예제 #20
0
파일: copy.c 프로젝트: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * copies the object identified by its data pointers and the type
 * the new objects is moved by DX,DY
 * I assume that the appropriate layer ... is switched on
 */
void *
CopyObject (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
	    Coord DX, Coord DY)
{
  void *ptr;

  /* setup movement vector */
  DeltaX = DX;
  DeltaY = DY;

  /* the subroutines add the objects to the undo-list */
  ptr = ObjectOperation (&CopyFunctions, Type, Ptr1, Ptr2, Ptr3);
  IncrementUndoSerialNumber ();
  return (ptr);
}
예제 #21
0
static int
renumber_block (int argc, char **argv, Coord x, Coord y)
{
  char num_buf[15];
  int old_base, new_base;

  if (argc < 2) {
    Message("Usage: RenumberBlock oldnum newnum");
    return 1;
  }

  old_base = atoi (argv[0]);
  new_base = atoi (argv[1]);

  SET_FLAG (NAMEONPCBFLAG, PCB);

  ELEMENT_LOOP (PCB->Data);
  {
    char *refdes_split, *cp;
    char *old_ref, *new_ref;
    int num;

    if (!TEST_FLAG (SELECTEDFLAG, element))
      continue;

    old_ref = element->Name[1].TextString;
    for (refdes_split=cp=old_ref; *cp; cp++)
      if (!isdigit(*cp))
        refdes_split = cp+1;

    num = atoi (refdes_split);
    num += (new_base - old_base);
    sprintf(num_buf, "%d" ,num);
    new_ref = (char *) malloc (refdes_split - old_ref + strlen(num_buf) + 1);
    memcpy (new_ref, old_ref, refdes_split - old_ref);
    strcpy (new_ref + (refdes_split - old_ref), num_buf);

    AddObjectToChangeNameUndoList (ELEMENT_TYPE, NULL, NULL,
                                   element,
                                   NAMEONPCB_NAME (element));

    ChangeObjectName (ELEMENT_TYPE, element, NULL, NULL, new_ref);
  }
  END_LOOP;
  IncrementUndoSerialNumber ();
  return 0;
}
예제 #22
0
Boolean ChangeObjectClearSize( int Type, void *Ptr1, void *Ptr2, void *Ptr3, LocationType Difference, Boolean fixIt )
{
  int ecx;
  int ebx;
  int esi;
  int edi;
  Boolean change;
  Difference = 0;
  Absolute = fixIt != 0 ? Difference : Difference;
  Delta = Difference;
  change = ObjectOperation( &ChangeClearSizeFunctions, Type, Ptr1, Ptr2, Ptr3 ) != 0;
  if ( change & 255 )
  {
    Draw( );
    IncrementUndoSerialNumber( );
  }
  return change;
}
예제 #23
0
Boolean ChangeObject2ndSize( int Type, void *Ptr1, void *Ptr2, void *Ptr3, LocationType Difference, Boolean fixIt, Boolean incundo )
{
  int eax;
  Boolean change;
  Difference = 0;
  Absolute = fixIt != 0 ? Difference : Difference;
  Delta = Difference;
  change = change != 0;
  if ( change )
  {
    Draw( );
    if ( incundo & 255 )
    {
      IncrementUndoSerialNumber( );
      return change;
    }
  }
  return ebp_12;
}
예제 #24
0
파일: insert.c 프로젝트: thequux/pcb
/* ---------------------------------------------------------------------------
 * inserts point into objects
 */
void *
InsertPointIntoObject (int Type, void *Ptr1, void *Ptr2, Cardinal * Ptr3,
		       LocationType DX, LocationType DY, bool Force,
		       bool insert_last)
{
  void *ptr;

  /* setup offset */
  InsertX = DX;
  InsertY = DY;
  InsertAt = *Ptr3;
  InsertLast = insert_last;
  Forcible = Force;

  /* the operation insert the points to the undo-list */
  ptr = ObjectOperation (&InsertFunctions, Type, Ptr1, Ptr2, Ptr3);
  if (ptr != NULL)
    IncrementUndoSerialNumber ();
  return (ptr);
}
예제 #25
0
파일: netlist.c 프로젝트: bert/pcb-rnd
/* Select on the layout the current net treeview selection
 */
static void
nbcb_select_common (LibraryMenuTypePtr net, int pos, int select_flag)
{
  LibraryEntryType *entry;
  ConnectionType conn;
  int i;

  InitConnectionLookup ();
  ResetConnections (true);

  for (i = net->EntryN, entry = net->Entry; i; i--, entry++)
    if (SeekPad (entry, &conn, false))
      RatFindHook (conn.type, conn.ptr1, conn.ptr2, conn.ptr2, true, true);

  SelectConnection (select_flag);
  ResetConnections (false);
  FreeConnectionLookupMemory ();
  IncrementUndoSerialNumber ();
  Draw ();
}
예제 #26
0
파일: remove.c 프로젝트: bert/pcb-rnd
bool
DeleteRats (bool selected)
{
  bool changed = false;
  Bulk = true;
  RAT_LOOP (PCB->Data);
  {
    if ((!selected) || TEST_FLAG (SELECTEDFLAG, line))
      {
	changed = true;
	RemoveRat (line);
      }
  }
  END_LOOP;
  Bulk = false;
  if (changed)
    {
      Draw ();
      IncrementUndoSerialNumber ();
    }
  return (changed);
}
예제 #27
0
/*!
 * \brief Locking all or selected elements.
 *
 * Usage:\n
 * LockElements([Selected|All])\n
 * LE([Selected|All])\n
 * If no argument is passed, no action is carried out.
 */
static int
lock_elements (int argc, char **argv, Coord x, Coord y)
{
        int selected = 0;
        int all = 0;
        if (argc > 0 && strcasecmp (argv[0], "Selected") == 0)
                selected = 1;
        else if (argc >0 && strcasecmp (argv[0], "All") == 0)
                all = 1;
        else
        {
                Message ("ERROR: in LockElements argument should be either Selected or All.\n");
                return 1;
        }
        SET_FLAG (NAMEONPCBFLAG, PCB);
        ELEMENT_LOOP(PCB->Data);
        {
                if (!TEST_FLAG (LOCKFLAG, element))
                {
                        /* element is not locked */
                        if (all)
                                SET_FLAG(LOCKFLAG, element);
                        if (selected)
                        {
                                if (TEST_FLAG (SELECTEDFLAG, element))
                                {
                                        /* better to unselect element first */
                                        CLEAR_FLAG(SELECTEDFLAG, element);
                                        SET_FLAG(LOCKFLAG, element);
                                }
                        }
                }
        }
        END_LOOP;
        gui->invalidate_all ();
        IncrementUndoSerialNumber ();
        return 0;
}
예제 #28
0
파일: move.c 프로젝트: fruoff/pcb-fruoff
int
MoveLayer (int old_index, int new_index)
{
  int groups[MAX_LAYER + 2], l, g;
  LayerType saved_layer;
  int saved_group;

  AddLayerChangeToUndoList (old_index, new_index);
  IncrementUndoSerialNumber ();

  if (old_index < -1 || old_index >= max_copper_layer)
    {
      Message ("Invalid old layer %d for move: must be -1..%d\n",
	       old_index, max_copper_layer - 1);
      return 1;
    }
  if (new_index < -1 || new_index > max_copper_layer || new_index >= MAX_LAYER)
    {
      Message ("Invalid new layer %d for move: must be -1..%d\n",
	       new_index, max_copper_layer);
      return 1;
    }
  if (old_index == new_index)
    return 0;

  if (new_index == -1
      && LastLayerInComponentGroup (old_index))
    {
      gui->confirm_dialog ("You can't delete the last top-side layer\n", "Ok", NULL);
      return 1;
    }

  if (new_index == -1
      && LastLayerInSolderGroup (old_index))
    {
      gui->confirm_dialog ("You can't delete the last bottom-side layer\n", "Ok", NULL);
      return 1;
    }

  for (g = 0; g < MAX_LAYER+2; g++)
    groups[g] = -1;

  for (g = 0; g < MAX_LAYER; g++)
    for (l = 0; l < PCB->LayerGroups.Number[g]; l++)
      groups[PCB->LayerGroups.Entries[g][l]] = g;

  if (old_index == -1)
    {
      LayerTypePtr lp;
      if (max_copper_layer == MAX_LAYER)
	{
	  Message ("No room for new layers\n");
	  return 1;
	}
      /* Create a new layer at new_index. */
      lp = &PCB->Data->Layer[new_index];
      memmove (&PCB->Data->Layer[new_index + 1],
	       &PCB->Data->Layer[new_index],
	       (max_copper_layer - new_index + 2) * sizeof (LayerType));
      memmove (&groups[new_index + 1],
	       &groups[new_index],
	       (max_copper_layer - new_index + 2) * sizeof (int));
      max_copper_layer++;
      memset (lp, 0, sizeof (LayerType));
      lp->On = 1;
      lp->Name = strdup ("New Layer");
      lp->Color = Settings.LayerColor[new_index];
      lp->SelectedColor = Settings.LayerSelectedColor[new_index];
      for (l = 0; l < max_copper_layer; l++)
	if (LayerStack[l] >= new_index)
	  LayerStack[l]++;
      LayerStack[max_copper_layer - 1] = new_index;
    }
  else if (new_index == -1)
    {
      /* Delete the layer at old_index */
      memmove (&PCB->Data->Layer[old_index],
	       &PCB->Data->Layer[old_index + 1],
	       (max_copper_layer - old_index + 2 - 1) * sizeof (LayerType));
      memset (&PCB->Data->Layer[max_copper_layer + 1], 0, sizeof (LayerType));
      memmove (&groups[old_index],
	       &groups[old_index + 1],
	       (max_copper_layer - old_index + 2 - 1) * sizeof (int));
      for (l = 0; l < max_copper_layer; l++)
	if (LayerStack[l] == old_index)
	  memmove (LayerStack + l,
		   LayerStack + l + 1,
		   (max_copper_layer - l - 1) * sizeof (LayerStack[0]));
      max_copper_layer--;
      for (l = 0; l < max_copper_layer; l++)
	if (LayerStack[l] > old_index)
	  LayerStack[l]--;
    }
  else
    {
      /* Move an existing layer */
      memcpy (&saved_layer, &PCB->Data->Layer[old_index], sizeof (LayerType));
      saved_group = groups[old_index];
      if (old_index < new_index)
	{
	  memmove (&PCB->Data->Layer[old_index],
		   &PCB->Data->Layer[old_index + 1],
		   (new_index - old_index) * sizeof (LayerType));
	  memmove (&groups[old_index],
		   &groups[old_index + 1],
		   (new_index - old_index) * sizeof (int));
	}
      else
	{
	  memmove (&PCB->Data->Layer[new_index + 1],
		   &PCB->Data->Layer[new_index],
		   (old_index - new_index) * sizeof (LayerType));
	  memmove (&groups[new_index + 1],
		   &groups[new_index],
		   (old_index - new_index) * sizeof (int));
	}
      memcpy (&PCB->Data->Layer[new_index], &saved_layer, sizeof (LayerType));
      groups[new_index] = saved_group;
    }

  move_all_thermals(old_index, new_index);

  for (g = 0; g < MAX_LAYER; g++)
    PCB->LayerGroups.Number[g] = 0;
  for (l = 0; l < max_copper_layer + 2; l++)
    {
      int i;
      g = groups[l];
      if (g >= 0)
	{
	  i = PCB->LayerGroups.Number[g]++;
	  PCB->LayerGroups.Entries[g][i] = l;
	}
    }

  for (g = 0; g < MAX_LAYER; g++)
    if (PCB->LayerGroups.Number[g] == 0)
      {
	memmove (&PCB->LayerGroups.Number[g],
		 &PCB->LayerGroups.Number[g + 1],
		 (MAX_LAYER - g - 1) * sizeof (PCB->LayerGroups.Number[g]));
	memmove (&PCB->LayerGroups.Entries[g],
		 &PCB->LayerGroups.Entries[g + 1],
		 (MAX_LAYER - g - 1) * sizeof (PCB->LayerGroups.Entries[g]));
      }

  hid_action ("LayersChanged");
  gui->invalidate_all ();
  return 0;
}
예제 #29
0
파일: report.c 프로젝트: veox/pcb
static int
ReportNetLengthByName (char *tofind, int x, int y)
{
  int result;
  char *netname = 0;
  Coord length = 0;
  int found = 0;
  int i;
  LibraryMenuType *net;
  ConnectionType conn;
  int net_found = 0;
#if defined(USE_RE)
  int use_re = 0;
#endif
#if defined(HAVE_REGCOMP)
  regex_t elt_pattern;
  regmatch_t match;
#endif
#if defined(HAVE_RE_COMP)
  char *elt_pattern;
#endif

  if (!PCB)
    return 1;

  if (!tofind)
    return 1;

#if defined(USE_RE)
      use_re = 1;
      for (i = 0; i < PCB->NetlistLib.MenuN; i++)
	{
	  net = PCB->NetlistLib.Menu + i;
	  if (strcasecmp (tofind, net->Name + 2) == 0)
	    use_re = 0;
	}
      if (use_re)
	{
#if defined(HAVE_REGCOMP)
	  result =
	    regcomp (&elt_pattern, tofind,
		     REG_EXTENDED | REG_ICASE | REG_NOSUB);
	  if (result)
	    {
	      char errorstring[128];

	      regerror (result, &elt_pattern, errorstring, 128);
	      Message (_("regexp error: %s\n"), errorstring);
	      regfree (&elt_pattern);
	      return (1);
	    }
#endif
#if defined(HAVE_RE_COMP)
	  if ((elt_pattern = re_comp (tofind)) != NULL)
	    {
	      Message (_("re_comp error: %s\n"), elt_pattern);
	      return (1);
	    }
#endif
	}
#endif

  for (i = 0; i < PCB->NetlistLib.MenuN; i++)
    {
      net = PCB->NetlistLib.Menu + i;

#if defined(USE_RE)
	  if (use_re)
	    {
#if defined(HAVE_REGCOMP)
	      if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0)
		continue;
#endif
#if defined(HAVE_RE_COMP)
	      if (re_exec (net->Name + 2) != 1)
		continue;
#endif
	    }
	  else
#endif
	  if (strcasecmp (net->Name + 2, tofind))
	    continue;

        if (SeekPad (net->Entry, &conn, false))
        {
          switch (conn.type)
          {
            case PIN_TYPE:
              x = ((PinType *) (conn.ptr2))->X;
              y = ((PinType *) (conn.ptr2))->Y;
              net_found=1;
	      break;
            case PAD_TYPE:
              x = ((PadType *) (conn.ptr2))->Point1.X;
              y = ((PadType *) (conn.ptr2))->Point1.Y;
              net_found=1;
	      break;
          }
	  if (net_found)
	    break;
        }
    }

  if (!net_found)
    {
      gui->log (_("No net named %s\n"), tofind);
      return 1;
    }

#ifdef HAVE_REGCOMP
  if (use_re)
    regfree (&elt_pattern);
#endif

  /* Reset all connection flags and save an undo-state to get back
   * to the state the board was in when we started.
   *
   * After this, we don't add any changes to the undo system, but
   * ensure we get back to a point where we can Undo() our changes
   * by resetting the connections with ClearFlagOnAllObjects() before
   * calling Undo() when we are finished.
   */
  ClearFlagOnAllObjects (true, FOUNDFLAG);
  IncrementUndoSerialNumber ();

  length = XYtoNetLength (x, y, &found);
  netname = net->Name + 2;

  ClearFlagOnAllObjects (false, FOUNDFLAG);
  Undo (true);

  if (!found)
    {
      if (net_found)
        gui->log (_("Net found, but no lines or arcs were flagged.\n"));
      else
        gui->log (_("Net not found.\n"));

      return 1;
    }

  {
    char buf[50];
    pcb_snprintf(buf, 50, _("%$m*"), Settings.grid_unit->suffix, length);
    if (netname)
      gui->log (_("Net \"%s\" length: %s\n"), netname, buf);
    else
      gui->log (_("Net length: %s\n"), buf);
  }

  return 0;
}
예제 #30
0
파일: report.c 프로젝트: veox/pcb
static int
ReportNetLength (int argc, char **argv, Coord x, Coord y)
{
  Coord length = 0;
  char *netname = 0;
  int found = 0;

  gui->get_coords (_("Click on a connection"), &x, &y);

  /* Reset all connection flags and save an undo-state to get back
   * to the state the board was in when we started this function.
   *
   * After this, we don't add any changes to the undo system, but
   * ensure we get back to a point where we can Undo() our changes
   * by resetting the connections with ClearFlagOnAllObjects() before
   * calling Undo() at the end of the procedure.
   */
  ClearFlagOnAllObjects (true, FOUNDFLAG);
  IncrementUndoSerialNumber ();

  length = XYtoNetLength (x, y, &found);

  if (!found)
    {
      ClearFlagOnAllObjects (false, FOUNDFLAG);
      Undo (true);
      gui->log (_("No net under cursor.\n"));
      return 1;
    }

  ELEMENT_LOOP (PCB->Data);
  {
    PIN_LOOP (element);
    {
      if (TEST_FLAG (FOUNDFLAG, pin))
	{
	  int ni, nei;
	  char *ename = element->Name[NAMEONPCB_INDEX].TextString;
	  char *pname = pin->Number;
	  char *n;

	  if (ename && pname)
	    {
	      n = Concat (ename, _("-"), pname, NULL);
	      for (ni = 0; ni < PCB->NetlistLib.MenuN; ni++)
		for (nei = 0; nei < PCB->NetlistLib.Menu[ni].EntryN; nei++)
		  {
		    if (strcmp (PCB->NetlistLib.Menu[ni].Entry[nei].ListEntry, n) == 0)
		      {
			netname = PCB->NetlistLib.Menu[ni].Name + 2;
			goto got_net_name; /* four for loops deep */
		      }
		  }
	    }
	}
    }
    END_LOOP;
    PAD_LOOP (element);
    {
      if (TEST_FLAG (FOUNDFLAG, pad))
	{
	  int ni, nei;
	  char *ename = element->Name[NAMEONPCB_INDEX].TextString;
	  char *pname = pad->Number;
	  char *n;

	  if (ename && pname)
	    {
	      n = Concat (ename, _("-"), pname, NULL);
	      for (ni = 0; ni < PCB->NetlistLib.MenuN; ni++)
		for (nei = 0; nei < PCB->NetlistLib.Menu[ni].EntryN; nei++)
		  {
		    if (strcmp (PCB->NetlistLib.Menu[ni].Entry[nei].ListEntry, n) == 0)
		      {
			netname = PCB->NetlistLib.Menu[ni].Name + 2;
			goto got_net_name; /* four for loops deep */
		      }
		  }
	    }
	}
    }
    END_LOOP;
  }
  END_LOOP;

got_net_name:
  ClearFlagOnAllObjects (false, FOUNDFLAG);
  Undo (true);

  {
    char buf[50];
    pcb_snprintf(buf, sizeof (buf), _("%$m*"), Settings.grid_unit->suffix, length);
    if (netname)
      gui->log (_("Net \"%s\" length: %s\n"), netname, buf);
    else
      gui->log (_("Net length: %s\n"), buf);
  }

  return 0;
}