1 /*!
2 * \file src/change.c
3 *
4 * \brief Functions used to change object properties.
5 *
6 * <hr>
7 *
8 * <h1><b>Copyright.</b></h1>\n
9 *
10 * PCB, interactive printed circuit board design
11 *
12 * Copyright (C) 1994,1995,1996, 2005 Thomas Nau
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 *
28 * Contact addresses for paper mail and Email:
29 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
30 * Thomas.Nau@rz.uni-ulm.de
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include <stdlib.h>
38 #include <stdio.h>
39
40 #include "global.h"
41
42 #include "change.h"
43 #include "create.h"
44 #include "crosshair.h"
45 #include "data.h"
46 #include "draw.h"
47 #include "error.h"
48 #include "mymem.h"
49 #include "misc.h"
50 #include "mirror.h"
51 #include "polygon.h"
52 #include "rats.h"
53 #include "remove.h"
54 #include "rtree.h"
55 #include "search.h"
56 #include "select.h"
57 #include "set.h"
58 #include "thermal.h"
59 #include "undo.h"
60
61 #ifdef HAVE_LIBDMALLOC
62 #include <dmalloc.h>
63 #endif
64
65 /* ---------------------------------------------------------------------------
66 * some local prototypes
67 */
68 static void *ChangePinSize (ElementType *, PinType *);
69 static void *ChangePinClearSize (ElementType *, PinType *);
70 static void *ChangePinMaskSize (ElementType *, PinType *);
71 static void *ChangePadSize (ElementType *, PadType *);
72 static void *ChangePadClearSize (ElementType *, PadType *);
73 static void *ChangePadMaskSize (ElementType *, PadType *);
74 static void *ChangePin2ndSize (ElementType *, PinType *);
75 static void *ChangeElement2ndSize (ElementType *);
76 static void *ChangeViaSize (PinType *);
77 static void *ChangeVia2ndSize (PinType *);
78 static void *ChangeViaClearSize (PinType *);
79 static void *ChangeViaMaskSize (PinType *);
80 static void *ChangeLineSize (LayerType *, LineType *);
81 static void *ChangeLineClearSize (LayerType *, LineType *);
82 static void *ChangePolygonClearSize (LayerType *, PolygonType *);
83 static void *ChangeArcSize (LayerType *, ArcType *);
84 static void *ChangeArcClearSize (LayerType *, ArcType *);
85 static void *ChangeTextSize (LayerType *, TextType *);
86 static void *ChangeElementSize (ElementType *);
87 static void *ChangeElementNameSize (ElementType *);
88 static void *ChangePinName (ElementType *, PinType *);
89 static void *ChangePadName (ElementType *, PadType *);
90 static void *ChangeViaName (PinType *);
91 static void *ChangeLineName (LayerType *, LineType *);
92 static void *ChangeElementName (ElementType *);
93 static void *ChangeTextName (LayerType *, TextType *);
94 static void *ChangeElementSquare (ElementType *);
95 static void *SetElementSquare (ElementType *);
96 static void *ClrElementSquare (ElementType *);
97 static void *ChangeElementOctagon (ElementType *);
98 static void *SetElementOctagon (ElementType *);
99 static void *ClrElementOctagon (ElementType *);
100 static void *ChangePinSquare (ElementType *, PinType *);
101 static void *SetPinSquare (ElementType *, PinType *);
102 static void *ClrPinSquare (ElementType *, PinType *);
103 static void *ChangePinOctagon (ElementType *, PinType *);
104 static void *SetPinOctagon (ElementType *, PinType *);
105 static void *ClrPinOctagon (ElementType *, PinType *);
106 static void *ChangeViaOctagon (PinType *);
107 static void *SetViaOctagon (PinType *);
108 static void *ClrViaOctagon (PinType *);
109 static void *ChangePadSquare (ElementType *, PadType *);
110 static void *SetPadSquare (ElementType *, PadType *);
111 static void *ClrPadSquare (ElementType *, PadType *);
112 static void *ChangeViaThermal (PinType *);
113 static void *ChangePinThermal (ElementType *, PinType *);
114 static void *ChangeLineJoin (LayerType *, LineType *);
115 static void *SetLineJoin (LayerType *, LineType *);
116 static void *ClrLineJoin (LayerType *, LineType *);
117 static void *ChangeArcJoin (LayerType *, ArcType *);
118 static void *SetArcJoin (LayerType *, ArcType *);
119 static void *ClrArcJoin (LayerType *, ArcType *);
120 static void *ChangeTextJoin (LayerType *, TextType *);
121 static void *SetTextJoin (LayerType *, TextType *);
122 static void *ClrTextJoin (LayerType *, TextType *);
123 static void *ChangePolyClear (LayerType *, PolygonType *);
124
125 /* ---------------------------------------------------------------------------
126 * some local identifiers
127 */
128 /*! Either the new value or the change in value */
129 static int Value;
130 /*! Used as boolean to indicate that Value is an absolute or delta */
131 static int Absolute;
132 static char *NewName; /* new name */
133 static ObjectFunctionType ChangeSizeFunctions = {
134 ChangeLineSize,
135 ChangeTextSize,
136 ChangePolyClear,
137 ChangeViaSize,
138 ChangeElementSize, /* changes silk screen line width */
139 ChangeElementNameSize,
140 ChangePinSize,
141 ChangePadSize,
142 NULL,
143 NULL,
144 ChangeArcSize,
145 NULL
146 };
147 static ObjectFunctionType Change2ndSizeFunctions = {
148 NULL,
149 NULL,
150 NULL,
151 ChangeVia2ndSize,
152 ChangeElement2ndSize,
153 NULL,
154 ChangePin2ndSize,
155 NULL,
156 NULL,
157 NULL,
158 NULL,
159 NULL
160 };
161 static ObjectFunctionType ChangeThermalFunctions = {
162 NULL,
163 NULL,
164 NULL,
165 ChangeViaThermal,
166 NULL,
167 NULL,
168 ChangePinThermal,
169 NULL,
170 NULL,
171 NULL,
172 NULL,
173 NULL
174 };
175 static ObjectFunctionType ChangeClearSizeFunctions = {
176 ChangeLineClearSize,
177 NULL,
178 ChangePolygonClearSize, /* just to tell the user not to :-) */
179 ChangeViaClearSize,
180 NULL,
181 NULL,
182 ChangePinClearSize,
183 ChangePadClearSize,
184 NULL,
185 NULL,
186 ChangeArcClearSize,
187 NULL
188 };
189 static ObjectFunctionType ChangeNameFunctions = {
190 ChangeLineName,
191 ChangeTextName,
192 NULL,
193 ChangeViaName,
194 ChangeElementName,
195 NULL,
196 ChangePinName,
197 ChangePadName,
198 NULL,
199 NULL,
200 NULL,
201 NULL
202 };
203 static ObjectFunctionType ChangeSquareFunctions = {
204 NULL,
205 NULL,
206 NULL,
207 NULL,
208 ChangeElementSquare,
209 NULL,
210 ChangePinSquare,
211 ChangePadSquare,
212 NULL,
213 NULL,
214 NULL,
215 NULL
216 };
217 static ObjectFunctionType ChangeJoinFunctions = {
218 ChangeLineJoin,
219 ChangeTextJoin,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL,
227 NULL,
228 ChangeArcJoin,
229 NULL
230 };
231 static ObjectFunctionType ChangeOctagonFunctions = {
232 NULL,
233 NULL,
234 NULL,
235 ChangeViaOctagon,
236 ChangeElementOctagon,
237 NULL,
238 ChangePinOctagon,
239 NULL,
240 NULL,
241 NULL,
242 NULL,
243 NULL
244 };
245 static ObjectFunctionType ChangeMaskSizeFunctions = {
246 NULL,
247 NULL,
248 NULL,
249 ChangeViaMaskSize,
250 #if 0
251 ChangeElementMaskSize,
252 #else
253 NULL,
254 #endif
255 NULL,
256 ChangePinMaskSize,
257 ChangePadMaskSize,
258 NULL,
259 NULL,
260 NULL,
261 NULL
262 };
263 static ObjectFunctionType SetSquareFunctions = {
264 NULL,
265 NULL,
266 NULL,
267 NULL,
268 SetElementSquare,
269 NULL,
270 SetPinSquare,
271 SetPadSquare,
272 NULL,
273 NULL,
274 NULL,
275 NULL
276 };
277 static ObjectFunctionType SetJoinFunctions = {
278 SetLineJoin,
279 SetTextJoin,
280 NULL,
281 NULL,
282 NULL,
283 NULL,
284 NULL,
285 NULL,
286 NULL,
287 NULL,
288 SetArcJoin,
289 NULL
290 };
291 static ObjectFunctionType SetOctagonFunctions = {
292 NULL,
293 NULL,
294 NULL,
295 SetViaOctagon,
296 SetElementOctagon,
297 NULL,
298 SetPinOctagon,
299 NULL,
300 NULL,
301 NULL,
302 NULL,
303 NULL
304 };
305 static ObjectFunctionType ClrSquareFunctions = {
306 NULL,
307 NULL,
308 NULL,
309 NULL,
310 ClrElementSquare,
311 NULL,
312 ClrPinSquare,
313 ClrPadSquare,
314 NULL,
315 NULL,
316 NULL,
317 NULL
318 };
319 static ObjectFunctionType ClrJoinFunctions = {
320 ClrLineJoin,
321 ClrTextJoin,
322 NULL,
323 NULL,
324 NULL,
325 NULL,
326 NULL,
327 NULL,
328 NULL,
329 NULL,
330 ClrArcJoin,
331 NULL
332 };
333 static ObjectFunctionType ClrOctagonFunctions = {
334 NULL,
335 NULL,
336 NULL,
337 ClrViaOctagon,
338 ClrElementOctagon,
339 NULL,
340 ClrPinOctagon,
341 NULL,
342 NULL,
343 NULL,
344 NULL,
345 NULL
346 };
347
348 /*!
349 * \brief Changes the thermal on a via.
350 *
351 * \return TRUE if changed.
352 */
353 static void *
ChangeViaThermal(PinType * Via)354 ChangeViaThermal (PinType *Via)
355 {
356 AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, false);
357 RestoreToPolygon (PCB->Data, VIA_TYPE, CURRENT, Via);
358 AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
359 if (!Value) /* remove the thermals */
360 CLEAR_THERM (INDEXOFCURRENT, Via);
361 else
362 ASSIGN_THERM (INDEXOFCURRENT, Value, Via);
363 AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, true);
364 ClearFromPolygon (PCB->Data, VIA_TYPE, CURRENT, Via);
365 DrawVia (Via);
366 return Via;
367 }
368
369 /*!
370 * \brief Changes the thermal on a pin.
371 *
372 * \return TRUE if changed.
373 */
374 static void *
ChangePinThermal(ElementType * element,PinType * Pin)375 ChangePinThermal (ElementType *element, PinType *Pin)
376 {
377 AddObjectToClearPolyUndoList (PIN_TYPE, element, Pin, Pin, false);
378 RestoreToPolygon (PCB->Data, VIA_TYPE, CURRENT, Pin);
379 AddObjectToFlagUndoList (PIN_TYPE, element, Pin, Pin);
380 if (!Value) /* remove the thermals */
381 CLEAR_THERM (INDEXOFCURRENT, Pin);
382 else
383 ASSIGN_THERM (INDEXOFCURRENT, Value, Pin);
384 AddObjectToClearPolyUndoList (PIN_TYPE, element, Pin, Pin, true);
385 ClearFromPolygon (PCB->Data, VIA_TYPE, CURRENT, Pin);
386 DrawPin (Pin);
387 return Pin;
388 }
389
390 /*!
391 * \brief Changes the size of a via.
392 *
393 * \return TRUE if changed.
394 */
395 static void *
ChangeViaSize(PinType * Via)396 ChangeViaSize (PinType *Via)
397 {
398 Coord new_value = Absolute ? Value : Via->Thickness + Value;
399
400 if (TEST_FLAG (LOCKFLAG, Via))
401 return (NULL);
402 if (!TEST_FLAG (HOLEFLAG, Via) && new_value <= MAX_PINORVIASIZE &&
403 new_value >= MIN_PINORVIASIZE &&
404 new_value > Via->DrillingHole &&
405 new_value != Via->Thickness)
406 {
407 AddObjectToSizeUndoList (VIA_TYPE, Via, Via, Via);
408 EraseVia (Via);
409 r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
410 RestoreToPolygon (PCB->Data, PIN_TYPE, Via, Via);
411 if (Via->Mask)
412 {
413 AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
414 Via->Mask += new_value - Via->Thickness;
415 }
416 Via->Thickness = new_value;
417 SetPinBoundingBox (Via);
418 r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
419 ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
420 DrawVia (Via);
421 return (Via);
422 }
423 return (NULL);
424 }
425
426 /*!
427 * \brief Changes the drilling hole of a via.
428 *
429 * \return TRUE if changed.
430 */
431 static void *
ChangeVia2ndSize(PinType * Via)432 ChangeVia2ndSize (PinType *Via)
433 {
434 Coord new_value = (Absolute) ? Value : Via->DrillingHole + Value;
435
436 if (TEST_FLAG (LOCKFLAG, Via))
437 return (NULL);
438 if (new_value <= MAX_PINORVIASIZE &&
439 new_value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, Via) ||
440 new_value < Via->Thickness)
441 && new_value != Via->DrillingHole)
442 {
443 AddObjectTo2ndSizeUndoList (VIA_TYPE, Via, Via, Via);
444 EraseVia (Via);
445 RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
446 Via->DrillingHole = new_value;
447 if (TEST_FLAG (HOLEFLAG, Via))
448 {
449 AddObjectToSizeUndoList (VIA_TYPE, Via, Via, Via);
450 Via->Thickness = new_value;
451 }
452 ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
453 DrawVia (Via);
454 return (Via);
455 }
456 return (NULL);
457 }
458
459 /*!
460 * \brief Changes the clearance size of a via.
461 *
462 * \return TRUE if changed.
463 */
464 static void *
ChangeViaClearSize(PinType * Via)465 ChangeViaClearSize (PinType *Via)
466 {
467 Coord new_value = (Absolute) ? Value : Via->Clearance + Value;
468
469 if (TEST_FLAG (LOCKFLAG, Via))
470 return (NULL);
471 new_value = MIN (MAX_LINESIZE, new_value);
472 if (new_value < 0)
473 new_value = 0;
474 if (Value < 0 && new_value < PCB->Bloat * 2)
475 new_value = 0;
476 if ((Value > 0 || Absolute) && new_value < PCB->Bloat * 2)
477 new_value = PCB->Bloat * 2 + 2;
478 if (Via->Clearance == new_value)
479 return NULL;
480 RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
481 AddObjectToClearSizeUndoList (VIA_TYPE, Via, Via, Via);
482 EraseVia (Via);
483 r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
484 Via->Clearance = new_value;
485 SetPinBoundingBox (Via);
486 r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
487 ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
488 DrawVia (Via);
489 Via->Element = NULL;
490 return (Via);
491 }
492
493
494 /*!
495 * \brief Changes the size of a pin.
496 *
497 * \return TRUE if changed.
498 */
499 static void *
ChangePinSize(ElementType * Element,PinType * Pin)500 ChangePinSize (ElementType *Element, PinType *Pin)
501 {
502 Coord new_value = (Absolute) ? Value : Pin->Thickness + Value;
503
504 if (TEST_FLAG (LOCKFLAG, Pin))
505 return (NULL);
506 if (!TEST_FLAG (HOLEFLAG, Pin) && new_value <= MAX_PINORVIASIZE &&
507 new_value >= MIN_PINORVIASIZE &&
508 new_value > Pin->DrillingHole &&
509 new_value != Pin->Thickness)
510 {
511 AddObjectToSizeUndoList (PIN_TYPE, Element, Pin, Pin);
512 AddObjectToMaskSizeUndoList (PIN_TYPE, Element, Pin, Pin);
513 ErasePin (Pin);
514 r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
515 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
516 Pin->Mask += new_value - Pin->Thickness;
517 Pin->Thickness = new_value;
518 /* SetElementBB updates all associated rtrees */
519 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
520 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
521 DrawPin (Pin);
522 return (Pin);
523 }
524 return (NULL);
525 }
526
527 /*!
528 * \brief Changes the clearance size of a pin.
529 *
530 * \return TRUE if changed.
531 */
532 static void *
ChangePinClearSize(ElementType * Element,PinType * Pin)533 ChangePinClearSize (ElementType *Element, PinType *Pin)
534 {
535 Coord new_value = (Absolute) ? Value : Pin->Clearance + Value;
536
537 if (TEST_FLAG (LOCKFLAG, Pin))
538 return (NULL);
539 new_value = MIN (MAX_LINESIZE, new_value);
540 if (new_value < 0)
541 new_value = 0;
542 if (Value < 0 && new_value < PCB->Bloat * 2)
543 new_value = 0;
544 if ((Value > 0 || Absolute) && new_value < PCB->Bloat * 2)
545 new_value = PCB->Bloat * 2 + 2;
546 if (Pin->Clearance == new_value)
547 return NULL;
548 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
549 AddObjectToClearSizeUndoList (PIN_TYPE, Element, Pin, Pin);
550 ErasePin (Pin);
551 r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
552 Pin->Clearance = new_value;
553 /* SetElementBB updates all associated rtrees */
554 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
555 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
556 DrawPin (Pin);
557 return (Pin);
558 }
559
560 /*!
561 * \brief Changes the size of a pad.
562 *
563 * \return TRUE if changed.
564 */
565 static void *
ChangePadSize(ElementType * Element,PadType * Pad)566 ChangePadSize (ElementType *Element, PadType *Pad)
567 {
568 Coord new_value = (Absolute) ? Value : Pad->Thickness + Value;
569
570 if (TEST_FLAG (LOCKFLAG, Pad))
571 return (NULL);
572 if (new_value <= MAX_PADSIZE && new_value >= MIN_PADSIZE && new_value != Pad->Thickness)
573 {
574 AddObjectToSizeUndoList (PAD_TYPE, Element, Pad, Pad);
575 AddObjectToMaskSizeUndoList (PAD_TYPE, Element, Pad, Pad);
576 RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
577 ErasePad (Pad);
578 r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
579 Pad->Mask += new_value - Pad->Thickness;
580 Pad->Thickness = new_value;
581 /* SetElementBB updates all associated rtrees */
582 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
583 ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
584 DrawPad (Pad);
585 return (Pad);
586 }
587 return (NULL);
588 }
589
590 /*!
591 * \brief Changes the clearance size of a pad.
592 *
593 * \return TRUE if changed.
594 */
595 static void *
ChangePadClearSize(ElementType * Element,PadType * Pad)596 ChangePadClearSize (ElementType *Element, PadType *Pad)
597 {
598 Coord new_value = (Absolute) ? Value : Pad->Clearance + Value;
599
600 if (TEST_FLAG (LOCKFLAG, Pad))
601 return (NULL);
602 new_value = MIN (MAX_LINESIZE, new_value);
603 if (new_value < 0)
604 new_value = 0;
605 if (Value < 0 && new_value < PCB->Bloat * 2)
606 new_value = 0;
607 if ((Value > 0 || Absolute) && new_value < PCB->Bloat * 2)
608 new_value = PCB->Bloat * 2 + 2;
609 if (new_value == Pad->Clearance)
610 return NULL;
611 AddObjectToClearSizeUndoList (PAD_TYPE, Element, Pad, Pad);
612 RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
613 ErasePad (Pad);
614 r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
615 Pad->Clearance = new_value;
616 /* SetElementBB updates all associated rtrees */
617 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
618 ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
619 DrawPad (Pad);
620 return Pad;
621 }
622
623 /*!
624 * \brief Changes the drilling hole of all pins of an element.
625 *
626 * \return TRUE if changed.
627 */
628 static void *
ChangeElement2ndSize(ElementType * Element)629 ChangeElement2ndSize (ElementType *Element)
630 {
631 bool changed = false;
632 Coord new_value;
633
634 if (TEST_FLAG (LOCKFLAG, Element))
635 return (NULL);
636 PIN_LOOP (Element);
637 {
638 new_value = (Absolute) ? Value : pin->DrillingHole + Value;
639 if (new_value <= MAX_PINORVIASIZE &&
640 new_value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, pin) ||
641 new_value <= pin->Thickness)
642 && new_value != pin->DrillingHole)
643 {
644 changed = true;
645 AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, pin, pin);
646 ErasePin (pin);
647 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, pin);
648 pin->DrillingHole = new_value;
649 if (TEST_FLAG (HOLEFLAG, pin))
650 {
651 AddObjectToSizeUndoList (PIN_TYPE, Element, pin, pin);
652 pin->Thickness = new_value;
653 }
654 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, pin);
655 DrawPin (pin);
656 }
657 }
658 END_LOOP;
659 if (changed)
660 return (Element);
661 else
662 return (NULL);
663 }
664
665 /*!
666 * \brief Changes the drilling hole of a pin.
667 *
668 * \return TRUE if changed.
669 */
670 static void *
ChangePin2ndSize(ElementType * Element,PinType * Pin)671 ChangePin2ndSize (ElementType *Element, PinType *Pin)
672 {
673 Coord new_value = (Absolute) ? Value : Pin->DrillingHole + Value;
674
675 if (TEST_FLAG (LOCKFLAG, Pin))
676 return (NULL);
677 if (new_value <= MAX_PINORVIASIZE &&
678 new_value >= MIN_PINORVIAHOLE && (TEST_FLAG (HOLEFLAG, Pin) ||
679 new_value < Pin->Thickness)
680 && new_value != Pin->DrillingHole)
681 {
682 AddObjectTo2ndSizeUndoList (PIN_TYPE, Element, Pin, Pin);
683 ErasePin (Pin);
684 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
685 Pin->DrillingHole = new_value;
686 if (TEST_FLAG (HOLEFLAG, Pin))
687 {
688 AddObjectToSizeUndoList (PIN_TYPE, Element, Pin, Pin);
689 Pin->Thickness = new_value;
690 }
691 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
692 DrawPin (Pin);
693 return (Pin);
694 }
695 return (NULL);
696 }
697
698 /*!
699 * \brief Changes the size of a line.
700 *
701 * \return TRUE if changed.
702 */
703 static void *
ChangeLineSize(LayerType * Layer,LineType * Line)704 ChangeLineSize (LayerType *Layer, LineType *Line)
705 {
706 Coord new_value = (Absolute) ? Value : Line->Thickness + Value;
707
708 if (TEST_FLAG (LOCKFLAG, Line))
709 return (NULL);
710 if (new_value <= MAX_LINESIZE && new_value >= MIN_LINESIZE &&
711 new_value != Line->Thickness)
712 {
713 AddObjectToSizeUndoList (LINE_TYPE, Layer, Line, Line);
714 EraseLine (Line);
715 r_delete_entry (Layer->line_tree, (BoxType *) Line);
716 RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
717 Line->Thickness = new_value;
718 SetLineBoundingBox (Line);
719 r_insert_entry (Layer->line_tree, (BoxType *) Line, 0);
720 ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
721 DrawLine (Layer, Line);
722 return (Line);
723 }
724 return (NULL);
725 }
726
727 /*!
728 * \brief Changes the clearance size of a line.
729 *
730 * \return TRUE if changed.
731 */
732 static void *
ChangeLineClearSize(LayerType * Layer,LineType * Line)733 ChangeLineClearSize (LayerType *Layer, LineType *Line)
734 {
735 Coord new_value = (Absolute) ? Value : Line->Clearance + Value;
736
737 if (TEST_FLAG (LOCKFLAG, Line) || !TEST_FLAG (CLEARLINEFLAG, Line))
738 return (NULL);
739 new_value = MIN (MAX_LINESIZE, MAX (new_value, PCB->Bloat * 2 + 2));
740 if (new_value != Line->Clearance)
741 {
742 AddObjectToClearSizeUndoList (LINE_TYPE, Layer, Line, Line);
743 RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
744 EraseLine (Line);
745 r_delete_entry (Layer->line_tree, (BoxType *) Line);
746 Line->Clearance = new_value;
747 if (Line->Clearance == 0)
748 {
749 CLEAR_FLAG (CLEARLINEFLAG, Line);
750 Line->Clearance = MIL_TO_COORD(10);
751 }
752 SetLineBoundingBox (Line);
753 r_insert_entry (Layer->line_tree, (BoxType *) Line, 0);
754 ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
755 DrawLine (Layer, Line);
756 return (Line);
757 }
758 return (NULL);
759 }
760
761 /*!
762 * \brief Handle attempts to change the clearance of a polygon.
763 */
764 static void *
ChangePolygonClearSize(LayerType * Layer,PolygonType * poly)765 ChangePolygonClearSize (LayerType *Layer, PolygonType *poly)
766 {
767 static int shown_this_message = 0;
768 if (!shown_this_message)
769 {
770 gui->confirm_dialog (_("To change the clearance of objects in a polygon, "
771 "change the objects, not the polygon.\n"
772 "Hint: To set a minimum clearance for a group of objects, "
773 "select them all then :MinClearGap(Selected,=10,mil)"),
774 "Ok", NULL);
775 shown_this_message = 1;
776 }
777
778 return (NULL);
779 }
780
781 /*!
782 * \brief Changes the size of an arc.
783 *
784 * \return TRUE if changed.
785 */
786 static void *
ChangeArcSize(LayerType * Layer,ArcType * Arc)787 ChangeArcSize (LayerType *Layer, ArcType *Arc)
788 {
789 Coord new_value = (Absolute) ? Value : Arc->Thickness + Value;
790
791 if (TEST_FLAG (LOCKFLAG, Arc))
792 return (NULL);
793 if (new_value <= MAX_LINESIZE && new_value >= MIN_LINESIZE &&
794 new_value != Arc->Thickness)
795 {
796 AddObjectToSizeUndoList (ARC_TYPE, Layer, Arc, Arc);
797 EraseArc (Arc);
798 r_delete_entry (Layer->arc_tree, (BoxType *) Arc);
799 RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
800 Arc->Thickness = new_value;
801 SetArcBoundingBox (Arc);
802 r_insert_entry (Layer->arc_tree, (BoxType *) Arc, 0);
803 ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
804 DrawArc (Layer, Arc);
805 return (Arc);
806 }
807 return (NULL);
808 }
809
810 /*!
811 * \brief Changes the clearance size of an arc.
812 *
813 * \return TRUE if changed.
814 */
815 static void *
ChangeArcClearSize(LayerType * Layer,ArcType * Arc)816 ChangeArcClearSize (LayerType *Layer, ArcType *Arc)
817 {
818 Coord new_value = (Absolute) ? Value : Arc->Clearance + Value;
819
820 if (TEST_FLAG (LOCKFLAG, Arc) || !TEST_FLAG (CLEARLINEFLAG, Arc))
821 return (NULL);
822 new_value = MIN (MAX_LINESIZE, MAX (new_value, PCB->Bloat * 2 + 2));
823 if (new_value != Arc->Clearance)
824 {
825 AddObjectToClearSizeUndoList (ARC_TYPE, Layer, Arc, Arc);
826 EraseArc (Arc);
827 r_delete_entry (Layer->arc_tree, (BoxType *) Arc);
828 RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
829 Arc->Clearance = new_value;
830 if (Arc->Clearance == 0)
831 {
832 CLEAR_FLAG (CLEARLINEFLAG, Arc);
833 Arc->Clearance = MIL_TO_COORD(10);
834 }
835 SetArcBoundingBox (Arc);
836 r_insert_entry (Layer->arc_tree, (BoxType *) Arc, 0);
837 ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
838 DrawArc (Layer, Arc);
839 return (Arc);
840 }
841 return (NULL);
842 }
843
844 /*!
845 * \brief Changes the scaling factor of a text object.
846 *
847 * \return TRUE if changed.
848 */
849 static void *
ChangeTextSize(LayerType * Layer,TextType * Text)850 ChangeTextSize (LayerType *Layer, TextType *Text)
851 {
852 int new_value = (Absolute != 0 ? 0 : Text->Scale) +
853 (double)(Absolute != 0 ? Value : Value)
854 / (double)FONT_CAPHEIGHT * 100.;
855
856 if (TEST_FLAG (LOCKFLAG, Text))
857 return (NULL);
858 if (new_value <= MAX_TEXTSCALE && new_value >= MIN_TEXTSCALE &&
859 new_value != Text->Scale)
860 {
861 AddObjectToSizeUndoList (TEXT_TYPE, Layer, Text, Text);
862 EraseText (Layer, Text);
863 r_delete_entry (Layer->text_tree, (BoxType *) Text);
864 RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
865 Text->Scale = new_value;
866 SetTextBoundingBox (&PCB->Font, Text);
867 r_insert_entry (Layer->text_tree, (BoxType *) Text, 0);
868 ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
869 DrawText (Layer, Text);
870 return (Text);
871 }
872 return (NULL);
873 }
874
875 /*!
876 * \brief Changes the scaling factor of an element's outline.
877 *
878 * \return TRUE if changed.
879 */
880 static void *
ChangeElementSize(ElementType * Element)881 ChangeElementSize (ElementType *Element)
882 {
883 Coord new_value;
884 bool changed = false;
885
886 if (TEST_FLAG (LOCKFLAG, Element))
887 return (NULL);
888 if (PCB->ElementOn)
889 EraseElement (Element);
890 ELEMENTLINE_LOOP (Element);
891 {
892 new_value = (Absolute) ? Value : line->Thickness + Value;
893 if (new_value <= MAX_LINESIZE && new_value >= MIN_LINESIZE &&
894 new_value != line->Thickness)
895 {
896 AddObjectToSizeUndoList (ELEMENTLINE_TYPE, Element, line, line);
897 line->Thickness = new_value;
898 changed = true;
899 }
900 }
901 END_LOOP;
902 ARC_LOOP (Element);
903 {
904 new_value = (Absolute) ? Value : arc->Thickness + Value;
905 if (new_value <= MAX_LINESIZE && new_value >= MIN_LINESIZE &&
906 new_value != arc->Thickness)
907 {
908 AddObjectToSizeUndoList (ELEMENTARC_TYPE, Element, arc, arc);
909 arc->Thickness = new_value;
910 changed = true;
911 }
912 }
913 END_LOOP;
914 if (PCB->ElementOn)
915 {
916 DrawElement (Element);
917 }
918 if (changed)
919 return (Element);
920 return (NULL);
921 }
922
923 /*!
924 * \brief Changes the scaling factor of a elementname object.
925 *
926 * \return TRUE if changed.
927 */
928 static void *
ChangeElementNameSize(ElementType * Element)929 ChangeElementNameSize (ElementType *Element)
930 {
931 int new_value = (Absolute != 0 ? 0 : DESCRIPTION_TEXT (Element).Scale) +
932 (double)(Absolute != 0 ? Value : Value)
933 / (double)FONT_CAPHEIGHT * 100.;
934
935 if (TEST_FLAG (LOCKFLAG, &Element->Name[0]))
936 return (NULL);
937 if (new_value <= MAX_TEXTSCALE && new_value >= MIN_TEXTSCALE)
938 {
939 EraseElementName (Element);
940 ELEMENTTEXT_LOOP (Element);
941 {
942 AddObjectToSizeUndoList (ELEMENTNAME_TYPE, Element, text, text);
943 r_delete_entry (PCB->Data->name_tree[n], (BoxType *) text);
944 text->Scale = new_value;
945 SetTextBoundingBox (&PCB->Font, text);
946 r_insert_entry (PCB->Data->name_tree[n], (BoxType *) text, 0);
947 }
948 END_LOOP;
949 DrawElementName (Element);
950 return (Element);
951 }
952 return (NULL);
953 }
954
955 /*!
956 * \brief Changes the name of a via.
957 */
958 static void *
ChangeViaName(PinType * Via)959 ChangeViaName (PinType *Via)
960 {
961 char *old = Via->Name;
962
963 if (TEST_FLAG (DISPLAYNAMEFLAG, Via))
964 {
965 ErasePinName (Via);
966 Via->Name = NewName;
967 DrawPinName (Via);
968 }
969 else
970 Via->Name = NewName;
971 return (old);
972 }
973
974 /*!
975 * \brief Changes the name of a pin.
976 */
977 static void *
ChangePinName(ElementType * Element,PinType * Pin)978 ChangePinName (ElementType *Element, PinType *Pin)
979 {
980 char *old = Pin->Name;
981
982 (void) Element; /* get rid of 'unused...' warnings */
983 if (TEST_FLAG (DISPLAYNAMEFLAG, Pin))
984 {
985 ErasePinName (Pin);
986 Pin->Name = NewName;
987 DrawPinName (Pin);
988 }
989 else
990 Pin->Name = NewName;
991 return (old);
992 }
993
994 /*!
995 * \brief Changes the name of a pad.
996 */
997 static void *
ChangePadName(ElementType * Element,PadType * Pad)998 ChangePadName (ElementType *Element, PadType *Pad)
999 {
1000 char *old = Pad->Name;
1001
1002 (void) Element; /* get rid of 'unused...' warnings */
1003 if (TEST_FLAG (DISPLAYNAMEFLAG, Pad))
1004 {
1005 ErasePadName (Pad);
1006 Pad->Name = NewName;
1007 DrawPadName (Pad);
1008 }
1009 else
1010 Pad->Name = NewName;
1011 return (old);
1012 }
1013
1014 /*!
1015 * \brief Changes the name of a line.
1016 */
1017 static void *
ChangeLineName(LayerType * Layer,LineType * Line)1018 ChangeLineName (LayerType *Layer, LineType *Line)
1019 {
1020 char *old = Line->Number;
1021
1022 (void) Layer;
1023 Line->Number = NewName;
1024 return (old);
1025 }
1026
1027 /*!
1028 * \brief Changes the layout-name of an element.
1029 *
1030 * Change the specified text on an element, either on the board (give
1031 * PCB, PCB->Data) or in a buffer (give NULL, Buffer->Data).
1032 *
1033 * \return The old string is returned, and must be properly freed by the
1034 * caller.
1035 */
1036 char *
ChangeElementText(PCBType * pcb,DataType * data,ElementType * Element,int which,char * new_name)1037 ChangeElementText (PCBType *pcb, DataType *data, ElementType *Element, int which, char *new_name)
1038 {
1039 char *old = Element->Name[which].TextString;
1040
1041 #ifdef DEBUG
1042 printf("In ChangeElementText, updating old TextString %s to %s\n", old, new_name);
1043 #endif
1044
1045 if (pcb && which == NAME_INDEX (pcb))
1046 EraseElementName (Element);
1047
1048 r_delete_entry (data->name_tree[which],
1049 & Element->Name[which].BoundingBox);
1050
1051 Element->Name[which].TextString = new_name;
1052 SetTextBoundingBox (&PCB->Font, &Element->Name[which]);
1053
1054 r_insert_entry (data->name_tree[which],
1055 & Element->Name[which].BoundingBox, 0);
1056
1057 if (pcb && which == NAME_INDEX (pcb))
1058 DrawElementName (Element);
1059
1060 return old;
1061 }
1062
1063 static void *
ChangeElementName(ElementType * Element)1064 ChangeElementName (ElementType *Element)
1065 {
1066 if (TEST_FLAG (LOCKFLAG, &Element->Name[0]))
1067 return (NULL);
1068 if (NAME_INDEX (PCB) == NAMEONPCB_INDEX)
1069 {
1070 if (TEST_FLAG (UNIQUENAMEFLAG, PCB) &&
1071 UniqueElementName (PCB->Data, NewName) != NewName)
1072 {
1073 Message (_("Error: The name \"%s\" is not unique!\n"), NewName);
1074 return ((char *) -1);
1075 }
1076 }
1077
1078 return ChangeElementText (PCB, PCB->Data, Element, NAME_INDEX (PCB), NewName);
1079 }
1080
1081 /*!
1082 * \brief Sets data of a text object and calculates bounding box.
1083 *
1084 * Memory must have already been allocated.
1085 * The one for the new string is allocated.
1086 *
1087 * \return True if the string has been changed.
1088 */
1089 static void *
ChangeTextName(LayerType * Layer,TextType * Text)1090 ChangeTextName (LayerType *Layer, TextType *Text)
1091 {
1092 char *old = Text->TextString;
1093
1094 if (TEST_FLAG (LOCKFLAG, Text))
1095 return (NULL);
1096 EraseText (Layer, Text);
1097 r_delete_entry (Layer->text_tree, (BoxType *) Text);
1098 RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
1099 Text->TextString = NewName;
1100
1101 /* calculate size of the bounding box */
1102 SetTextBoundingBox (&PCB->Font, Text);
1103 r_insert_entry(Layer->text_tree, (BoxType *) Text, 0);
1104 ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
1105 DrawText (Layer, Text);
1106 return (old);
1107 }
1108
1109 /*!
1110 * \brief Changes the name of a layout; memory has to be already
1111 * allocated.
1112 */
1113 bool
ChangeLayoutName(char * Name)1114 ChangeLayoutName (char *Name)
1115 {
1116 free (PCB->Name);
1117 PCB->Name = Name;
1118 hid_action ("PCBChanged");
1119 return (true);
1120 }
1121
1122 /*!
1123 * \brief Changes the side of the board an element is on.
1124 *
1125 * \return TRUE if done.
1126 */
1127 bool
ChangeElementSide(ElementType * Element,Coord yoff)1128 ChangeElementSide (ElementType *Element, Coord yoff)
1129 {
1130 if (TEST_FLAG (LOCKFLAG, Element))
1131 return (false);
1132 EraseElement (Element);
1133 AddObjectToMirrorUndoList (ELEMENT_TYPE, Element, Element, Element, yoff);
1134 MirrorElementCoordinates (PCB->Data, Element, yoff);
1135 DrawElement (Element);
1136 return (true);
1137 }
1138
1139 /*!
1140 * \brief Changes the name of a layer; memory has to be already
1141 * allocated.
1142 */
1143 bool
ChangeLayerName(LayerType * Layer,char * Name)1144 ChangeLayerName (LayerType *Layer, char *Name)
1145 {
1146 free (CURRENT->Name);
1147 CURRENT->Name = Name;
1148 hid_action ("LayersChanged");
1149 return (true);
1150 }
1151
1152 /*!
1153 * \brief Changes the clearance flag of a line.
1154 */
1155 static void *
ChangeLineJoin(LayerType * Layer,LineType * Line)1156 ChangeLineJoin (LayerType *Layer, LineType *Line)
1157 {
1158 if (TEST_FLAG (LOCKFLAG, Line))
1159 return (NULL);
1160 EraseLine (Line);
1161 if (TEST_FLAG(CLEARLINEFLAG, Line))
1162 {
1163 AddObjectToClearPolyUndoList (LINE_TYPE, Layer, Line, Line, false);
1164 RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
1165 }
1166 AddObjectToFlagUndoList (LINE_TYPE, Layer, Line, Line);
1167 TOGGLE_FLAG (CLEARLINEFLAG, Line);
1168 if (TEST_FLAG(CLEARLINEFLAG, Line))
1169 {
1170 AddObjectToClearPolyUndoList (LINE_TYPE, Layer, Line, Line, true);
1171 ClearFromPolygon (PCB->Data, LINE_TYPE, Layer, Line);
1172 }
1173 DrawLine (Layer, Line);
1174 return (Line);
1175 }
1176
1177 /*!
1178 * \brief Sets the clearance flag of a line.
1179 */
1180 static void *
SetLineJoin(LayerType * Layer,LineType * Line)1181 SetLineJoin (LayerType *Layer, LineType *Line)
1182 {
1183 if (TEST_FLAG (LOCKFLAG, Line) || TEST_FLAG (CLEARLINEFLAG, Line))
1184 return (NULL);
1185 return ChangeLineJoin (Layer, Line);
1186 }
1187
1188 /*!
1189 * \brief Clears the clearance flag of a line.
1190 */
1191 static void *
ClrLineJoin(LayerType * Layer,LineType * Line)1192 ClrLineJoin (LayerType *Layer, LineType *Line)
1193 {
1194 if (TEST_FLAG (LOCKFLAG, Line) || !TEST_FLAG (CLEARLINEFLAG, Line))
1195 return (NULL);
1196 return ChangeLineJoin (Layer, Line);
1197 }
1198
1199 /*!
1200 * \brief Changes the clearance flag of an arc.
1201 */
1202 static void *
ChangeArcJoin(LayerType * Layer,ArcType * Arc)1203 ChangeArcJoin (LayerType *Layer, ArcType *Arc)
1204 {
1205 if (TEST_FLAG (LOCKFLAG, Arc))
1206 return (NULL);
1207 EraseArc (Arc);
1208 if (TEST_FLAG (CLEARLINEFLAG, Arc))
1209 {
1210 RestoreToPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
1211 AddObjectToClearPolyUndoList (ARC_TYPE, Layer, Arc, Arc, false);
1212 }
1213 AddObjectToFlagUndoList (ARC_TYPE, Layer, Arc, Arc);
1214 TOGGLE_FLAG (CLEARLINEFLAG, Arc);
1215 if (TEST_FLAG (CLEARLINEFLAG, Arc))
1216 {
1217 ClearFromPolygon (PCB->Data, ARC_TYPE, Layer, Arc);
1218 AddObjectToClearPolyUndoList (ARC_TYPE, Layer, Arc, Arc, true);
1219 }
1220 DrawArc (Layer, Arc);
1221 return (Arc);
1222 }
1223
1224 /*!
1225 * \brief Sets the clearance flag of an arc.
1226 */
1227 static void *
SetArcJoin(LayerType * Layer,ArcType * Arc)1228 SetArcJoin (LayerType *Layer, ArcType *Arc)
1229 {
1230 if (TEST_FLAG (LOCKFLAG, Arc) || TEST_FLAG (CLEARLINEFLAG, Arc))
1231 return (NULL);
1232 return ChangeArcJoin (Layer, Arc);
1233 }
1234
1235 /*!
1236 * \brief Clears the clearance flag of an arc.
1237 */
1238 static void *
ClrArcJoin(LayerType * Layer,ArcType * Arc)1239 ClrArcJoin (LayerType *Layer, ArcType *Arc)
1240 {
1241 if (TEST_FLAG (LOCKFLAG, Arc) || !TEST_FLAG (CLEARLINEFLAG, Arc))
1242 return (NULL);
1243 return ChangeArcJoin (Layer, Arc);
1244 }
1245
1246 /*!
1247 * \brief Changes the clearance flag of a text.
1248 */
1249 static void *
ChangeTextJoin(LayerType * Layer,TextType * Text)1250 ChangeTextJoin (LayerType *Layer, TextType *Text)
1251 {
1252 if (TEST_FLAG (LOCKFLAG, Text))
1253 return (NULL);
1254 EraseText (Layer, Text);
1255 if (TEST_FLAG(CLEARLINEFLAG, Text))
1256 {
1257 AddObjectToClearPolyUndoList (TEXT_TYPE, Layer, Text, Text, false);
1258 RestoreToPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
1259 }
1260 AddObjectToFlagUndoList (TEXT_TYPE, Layer, Text, Text);
1261 TOGGLE_FLAG (CLEARLINEFLAG, Text);
1262 if (TEST_FLAG(CLEARLINEFLAG, Text))
1263 {
1264 AddObjectToClearPolyUndoList (TEXT_TYPE, Layer, Text, Text, true);
1265 ClearFromPolygon (PCB->Data, TEXT_TYPE, Layer, Text);
1266 }
1267 DrawText (Layer, Text);
1268 return (Text);
1269 }
1270
1271 /*!
1272 * \brief Sets the clearance flag of a text.
1273 */
1274 static void *
SetTextJoin(LayerType * Layer,TextType * Text)1275 SetTextJoin (LayerType *Layer, TextType *Text)
1276 {
1277 if (TEST_FLAG (LOCKFLAG, Text) || TEST_FLAG (CLEARLINEFLAG, Text))
1278 return (NULL);
1279 return ChangeTextJoin (Layer, Text);
1280 }
1281
1282 /*!
1283 * \brief Clears the clearance flag of a text.
1284 */
1285 static void *
ClrTextJoin(LayerType * Layer,TextType * Text)1286 ClrTextJoin (LayerType *Layer, TextType *Text)
1287 {
1288 if (TEST_FLAG (LOCKFLAG, Text) || !TEST_FLAG (CLEARLINEFLAG, Text))
1289 return (NULL);
1290 return ChangeTextJoin (Layer, Text);
1291 }
1292
1293 /*!
1294 * \brief Changes the square flag of all pins on an element.
1295 */
1296 static void *
ChangeElementSquare(ElementType * Element)1297 ChangeElementSquare (ElementType *Element)
1298 {
1299 void *ans = NULL;
1300
1301 if (TEST_FLAG (LOCKFLAG, Element))
1302 return (NULL);
1303 PIN_LOOP (Element);
1304 {
1305 ans = ChangePinSquare (Element, pin);
1306 }
1307 END_LOOP;
1308 PAD_LOOP (Element);
1309 {
1310 ans = ChangePadSquare (Element, pad);
1311 }
1312 END_LOOP;
1313 return (ans);
1314 }
1315
1316 /*!
1317 * \brief Sets the square flag of all pins on an element.
1318 */
1319 static void *
SetElementSquare(ElementType * Element)1320 SetElementSquare (ElementType *Element)
1321 {
1322 void *ans = NULL;
1323
1324 if (TEST_FLAG (LOCKFLAG, Element))
1325 return (NULL);
1326 PIN_LOOP (Element);
1327 {
1328 ans = SetPinSquare (Element, pin);
1329 }
1330 END_LOOP;
1331 PAD_LOOP (Element);
1332 {
1333 ans = SetPadSquare (Element, pad);
1334 }
1335 END_LOOP;
1336 return (ans);
1337 }
1338
1339 /*!
1340 * \brief Clears the square flag of all pins on an element.
1341 */
1342 static void *
ClrElementSquare(ElementType * Element)1343 ClrElementSquare (ElementType *Element)
1344 {
1345 void *ans = NULL;
1346
1347 if (TEST_FLAG (LOCKFLAG, Element))
1348 return (NULL);
1349 PIN_LOOP (Element);
1350 {
1351 ans = ClrPinSquare (Element, pin);
1352 }
1353 END_LOOP;
1354 PAD_LOOP (Element);
1355 {
1356 ans = ClrPadSquare (Element, pad);
1357 }
1358 END_LOOP;
1359 return (ans);
1360 }
1361
1362 /*!
1363 * \brief Changes the octagon flags of all pins of an element.
1364 */
1365 static void *
ChangeElementOctagon(ElementType * Element)1366 ChangeElementOctagon (ElementType *Element)
1367 {
1368 void *result = NULL;
1369
1370 if (TEST_FLAG (LOCKFLAG, Element))
1371 return (NULL);
1372 PIN_LOOP (Element);
1373 {
1374 ChangePinOctagon (Element, pin);
1375 result = Element;
1376 }
1377 END_LOOP;
1378 return (result);
1379 }
1380
1381 /*!
1382 * \brief Sets the octagon flags of all pins of an element.
1383 */
1384 static void *
SetElementOctagon(ElementType * Element)1385 SetElementOctagon (ElementType *Element)
1386 {
1387 void *result = NULL;
1388
1389 if (TEST_FLAG (LOCKFLAG, Element))
1390 return (NULL);
1391 PIN_LOOP (Element);
1392 {
1393 SetPinOctagon (Element, pin);
1394 result = Element;
1395 }
1396 END_LOOP;
1397 return (result);
1398 }
1399
1400 /*!
1401 * \brief Clears the octagon flags of all pins of an element.
1402 */
1403 static void *
ClrElementOctagon(ElementType * Element)1404 ClrElementOctagon (ElementType *Element)
1405 {
1406 void *result = NULL;
1407
1408 if (TEST_FLAG (LOCKFLAG, Element))
1409 return (NULL);
1410 PIN_LOOP (Element);
1411 {
1412 ClrPinOctagon (Element, pin);
1413 result = Element;
1414 }
1415 END_LOOP;
1416 return (result);
1417 }
1418
1419 /*!
1420 * \brief Changes the square flag of a pad.
1421 */
1422 static void *
ChangePadSquare(ElementType * Element,PadType * Pad)1423 ChangePadSquare (ElementType *Element, PadType *Pad)
1424 {
1425 if (TEST_FLAG (LOCKFLAG, Pad))
1426 return (NULL);
1427 ErasePad (Pad);
1428 AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, false);
1429 RestoreToPolygon (PCB->Data, PAD_TYPE, Element, Pad);
1430 AddObjectToFlagUndoList (PAD_TYPE, Element, Pad, Pad);
1431 TOGGLE_FLAG (SQUAREFLAG, Pad);
1432 AddObjectToClearPolyUndoList (PAD_TYPE, Element, Pad, Pad, true);
1433 ClearFromPolygon (PCB->Data, PAD_TYPE, Element, Pad);
1434 DrawPad (Pad);
1435 return (Pad);
1436 }
1437
1438 /*!
1439 * \brief Sets the square flag of a pad.
1440 */
1441 static void *
SetPadSquare(ElementType * Element,PadType * Pad)1442 SetPadSquare (ElementType *Element, PadType *Pad)
1443 {
1444
1445 if (TEST_FLAG (LOCKFLAG, Pad) || TEST_FLAG (SQUAREFLAG, Pad))
1446 return (NULL);
1447
1448 return (ChangePadSquare (Element, Pad));
1449 }
1450
1451
1452 /*!
1453 * \brief Clears the square flag of a pad.
1454 */
1455 static void *
ClrPadSquare(ElementType * Element,PadType * Pad)1456 ClrPadSquare (ElementType *Element, PadType *Pad)
1457 {
1458
1459 if (TEST_FLAG (LOCKFLAG, Pad) || !TEST_FLAG (SQUAREFLAG, Pad))
1460 return (NULL);
1461
1462 return (ChangePadSquare (Element, Pad));
1463 }
1464
1465
1466 /*!
1467 * \brief Changes the square flag of a pin.
1468 */
1469 static void *
ChangePinSquare(ElementType * Element,PinType * Pin)1470 ChangePinSquare (ElementType *Element, PinType *Pin)
1471 {
1472 if (TEST_FLAG (LOCKFLAG, Pin))
1473 return (NULL);
1474 ErasePin (Pin);
1475 AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, false);
1476 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
1477 AddObjectToFlagUndoList (PIN_TYPE, Element, Pin, Pin);
1478 TOGGLE_FLAG (SQUAREFLAG, Pin);
1479 AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, true);
1480 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
1481 DrawPin (Pin);
1482 return (Pin);
1483 }
1484
1485 /*!
1486 * \brief Sets the square flag of a pin.
1487 */
1488 static void *
SetPinSquare(ElementType * Element,PinType * Pin)1489 SetPinSquare (ElementType *Element, PinType *Pin)
1490 {
1491 if (TEST_FLAG (LOCKFLAG, Pin) || TEST_FLAG (SQUAREFLAG, Pin))
1492 return (NULL);
1493
1494 return (ChangePinSquare (Element, Pin));
1495 }
1496
1497 /*!
1498 * \brief Clears the square flag of a pin.
1499 */
1500 static void *
ClrPinSquare(ElementType * Element,PinType * Pin)1501 ClrPinSquare (ElementType *Element, PinType *Pin)
1502 {
1503 if (TEST_FLAG (LOCKFLAG, Pin) || !TEST_FLAG (SQUAREFLAG, Pin))
1504 return (NULL);
1505
1506 return (ChangePinSquare (Element, Pin));
1507 }
1508
1509 /*!
1510 * \brief Changes the octagon flag of a via.
1511 */
1512 static void *
ChangeViaOctagon(PinType * Via)1513 ChangeViaOctagon (PinType *Via)
1514 {
1515 if (TEST_FLAG (LOCKFLAG, Via))
1516 return (NULL);
1517 EraseVia (Via);
1518 AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, false);
1519 RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
1520 AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
1521 TOGGLE_FLAG (OCTAGONFLAG, Via);
1522 AddObjectToClearPolyUndoList (VIA_TYPE, Via, Via, Via, true);
1523 ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
1524 DrawVia (Via);
1525 return (Via);
1526 }
1527
1528 /*!
1529 * \brief Sets the octagon flag of a via.
1530 */
1531 static void *
SetViaOctagon(PinType * Via)1532 SetViaOctagon (PinType *Via)
1533 {
1534 if (TEST_FLAG (LOCKFLAG, Via) || TEST_FLAG (OCTAGONFLAG, Via))
1535 return (NULL);
1536
1537 return (ChangeViaOctagon (Via));
1538 }
1539
1540 /*!
1541 * \brief Clears the octagon flag of a via.
1542 */
1543 static void *
ClrViaOctagon(PinType * Via)1544 ClrViaOctagon (PinType *Via)
1545 {
1546 if (TEST_FLAG (LOCKFLAG, Via) || !TEST_FLAG (OCTAGONFLAG, Via))
1547 return (NULL);
1548
1549 return (ChangeViaOctagon (Via));
1550 }
1551
1552 /*!
1553 * \brief Changes the octagon flag of a pin.
1554 */
1555 static void *
ChangePinOctagon(ElementType * Element,PinType * Pin)1556 ChangePinOctagon (ElementType *Element, PinType *Pin)
1557 {
1558 if (TEST_FLAG (LOCKFLAG, Pin))
1559 return (NULL);
1560 ErasePin (Pin);
1561 AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, false);
1562 RestoreToPolygon (PCB->Data, PIN_TYPE, Element, Pin);
1563 AddObjectToFlagUndoList (PIN_TYPE, Element, Pin, Pin);
1564 TOGGLE_FLAG (OCTAGONFLAG, Pin);
1565 AddObjectToClearPolyUndoList (PIN_TYPE, Element, Pin, Pin, true);
1566 ClearFromPolygon (PCB->Data, PIN_TYPE, Element, Pin);
1567 DrawPin (Pin);
1568 return (Pin);
1569 }
1570
1571 /*!
1572 * \brief Sets the octagon flag of a pin.
1573 */
1574 static void *
SetPinOctagon(ElementType * Element,PinType * Pin)1575 SetPinOctagon (ElementType *Element, PinType *Pin)
1576 {
1577 if (TEST_FLAG (LOCKFLAG, Pin) || TEST_FLAG (OCTAGONFLAG, Pin))
1578 return (NULL);
1579
1580 return (ChangePinOctagon (Element, Pin));
1581 }
1582
1583 /*!
1584 * \brief Clears the octagon flag of a pin.
1585 */
1586 static void *
ClrPinOctagon(ElementType * Element,PinType * Pin)1587 ClrPinOctagon (ElementType *Element, PinType *Pin)
1588 {
1589 if (TEST_FLAG (LOCKFLAG, Pin) || !TEST_FLAG (OCTAGONFLAG, Pin))
1590 return (NULL);
1591
1592 return (ChangePinOctagon (Element, Pin));
1593 }
1594
1595 /*!
1596 * \brief Changes the hole flag of a via.
1597 */
1598 bool
ChangeHole(PinType * Via)1599 ChangeHole (PinType *Via)
1600 {
1601 if (TEST_FLAG (LOCKFLAG, Via))
1602 return (false);
1603 EraseVia (Via);
1604 AddObjectToFlagUndoList (VIA_TYPE, Via, Via, Via);
1605 AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
1606 r_delete_entry (PCB->Data->via_tree, (BoxType *) Via);
1607 RestoreToPolygon (PCB->Data, VIA_TYPE, Via, Via);
1608 TOGGLE_FLAG (HOLEFLAG, Via);
1609
1610 if (TEST_FLAG (HOLEFLAG, Via))
1611 {
1612 /* A tented via becomes an minimally untented hole. An untented
1613 via retains its mask clearance. */
1614 if (Via->Mask > Via->Thickness)
1615 {
1616 Via->Mask = (Via->DrillingHole
1617 + (Via->Mask - Via->Thickness));
1618 }
1619 else if (Via->Mask < Via->DrillingHole)
1620 {
1621 Via->Mask = Via->DrillingHole + 2 * MASKFRAME;
1622 }
1623 }
1624 else
1625 {
1626 Via->Mask = (Via->Thickness
1627 + (Via->Mask - Via->DrillingHole));
1628 }
1629
1630 SetPinBoundingBox (Via);
1631 r_insert_entry (PCB->Data->via_tree, (BoxType *) Via, 0);
1632 ClearFromPolygon (PCB->Data, VIA_TYPE, Via, Via);
1633 DrawVia (Via);
1634 Draw ();
1635 return (true);
1636 }
1637
1638 /*!
1639 * \brief Changes the nopaste flag of a pad.
1640 */
1641 bool
ChangePaste(PadType * Pad)1642 ChangePaste (PadType *Pad)
1643 {
1644 if (TEST_FLAG (LOCKFLAG, Pad))
1645 return (false);
1646 ErasePad (Pad);
1647 AddObjectToFlagUndoList (PAD_TYPE, Pad, Pad, Pad);
1648 TOGGLE_FLAG (NOPASTEFLAG, Pad);
1649 DrawPad (Pad);
1650 Draw ();
1651 return (true);
1652 }
1653
1654 /*!
1655 * \brief Changes the CLEARPOLY flag of a polygon.
1656 */
1657 static void *
ChangePolyClear(LayerType * Layer,PolygonType * Polygon)1658 ChangePolyClear (LayerType *Layer, PolygonType *Polygon)
1659 {
1660 if (TEST_FLAG (LOCKFLAG, Polygon))
1661 return (NULL);
1662 AddObjectToClearPolyUndoList (POLYGON_TYPE, Layer, Polygon, Polygon, true);
1663 AddObjectToFlagUndoList (POLYGON_TYPE, Layer, Polygon, Polygon);
1664 TOGGLE_FLAG (CLEARPOLYFLAG, Polygon);
1665 InitClip (PCB->Data, Layer, Polygon);
1666 DrawPolygon (Layer, Polygon);
1667 return (Polygon);
1668 }
1669
1670 /*!
1671 * \brief Changes the side of all selected and visible elements.
1672 *
1673 * \return True if anything has changed.
1674 */
1675 bool
ChangeSelectedElementSide(void)1676 ChangeSelectedElementSide (void)
1677 {
1678 bool change = false;
1679
1680 /* setup identifiers */
1681 if (PCB->PinOn && PCB->ElementOn)
1682 ELEMENT_LOOP (PCB->Data);
1683 {
1684 if (TEST_FLAG (SELECTEDFLAG, element))
1685 {
1686 change |= ChangeElementSide (element, 0);
1687 }
1688 }
1689 END_LOOP;
1690 if (change)
1691 {
1692 Draw ();
1693 IncrementUndoSerialNumber ();
1694 }
1695 return (change);
1696 }
1697
1698 /*!
1699 * \brief Changes the thermals on all selected and visible pins and/or
1700 * vias.
1701 *
1702 * \return True if anything has changed.
1703 */
1704 bool
ChangeSelectedThermals(int types,int therm_style)1705 ChangeSelectedThermals (int types, int therm_style)
1706 {
1707 bool change = false;
1708
1709 Value = therm_style;
1710 change = SelectedOperation (&ChangeThermalFunctions, false, types);
1711 if (change)
1712 {
1713 Draw ();
1714 IncrementUndoSerialNumber ();
1715 }
1716 return (change);
1717 }
1718
1719
1720 /*!
1721 * \brief Changes the thermals on all selected and visible pins and/or
1722 * vias.
1723 *
1724 * \return True if anything has changed.
1725 */
1726 bool
ChangeSelectedViaLayers(int from,int to)1727 ChangeSelectedViaLayers (int from, int to)
1728 {
1729 bool change = false;
1730 int new_from;
1731 int new_to;
1732 int i;
1733
1734 VIA_LOOP (PCB->Data);
1735 {
1736 if (TEST_FLAG (LOCKFLAG, via))
1737 continue;
1738 if (TEST_FLAG (SELECTEDFLAG, via))
1739 {
1740
1741 new_from = (from != -1)?from:via->BuriedFrom;
1742 new_to = (to != -1)?to:via->BuriedTo;
1743
1744 if (new_from == new_to)
1745 continue;
1746
1747 /* special case - changing TH via "from" layer sets "to" layer to bottom layer */
1748 if (!VIA_IS_BURIED (via)
1749 && (to == -1))
1750 new_to = GetMaxBottomLayer ();
1751
1752 for (i=0; i < max_copper_layer; i++)
1753 {
1754 /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, false); not needed? */
1755 RestoreToPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
1756 }
1757
1758 AddObjectToSetViaLayersUndoList (via, via, via);
1759 via->BuriedFrom = new_from;
1760 via->BuriedTo = new_to;
1761
1762 if (VIA_IS_BURIED (via))
1763 {
1764 SanitizeBuriedVia (via);
1765 for (i=0; i < max_copper_layer; i++)
1766 {
1767 /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, true); not needed? */
1768 ClearFromPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
1769 }
1770 DrawVia (via);
1771 }
1772 change = true;
1773 }
1774 }
1775 END_LOOP;
1776 if (change)
1777 {
1778 Draw ();
1779 IncrementUndoSerialNumber ();
1780 }
1781 return (change);
1782 }
1783
1784 /*!
1785 * \brief Changes the size of all selected and visible object types.
1786 *
1787 * \return True if anything has changed.
1788 */
1789 bool
ChangeSelectedSize(int types,Coord Difference,bool fixIt)1790 ChangeSelectedSize (int types, Coord Difference, bool fixIt)
1791 {
1792 bool change = false;
1793
1794 /* setup identifiers */
1795 Absolute = (fixIt) ? 1 : 0;
1796 Value = Difference;
1797
1798 change = SelectedOperation (&ChangeSizeFunctions, false, types);
1799 if (change)
1800 {
1801 Draw ();
1802 IncrementUndoSerialNumber ();
1803 }
1804 return (change);
1805 }
1806
1807 /*!
1808 * \brief Changes the clearance size of all selected and visible objects.
1809 *
1810 * \return True if anything has changed.
1811 */
1812 bool
ChangeSelectedClearSize(int types,Coord Difference,bool fixIt)1813 ChangeSelectedClearSize (int types, Coord Difference, bool fixIt)
1814 {
1815 bool change = false;
1816
1817 /* setup identifiers */
1818 Absolute = (fixIt) ? 1 : 0;
1819 Value = Difference;
1820 if (TEST_FLAG (SHOWMASKFLAG, PCB))
1821 change = SelectedOperation (&ChangeMaskSizeFunctions, false, types);
1822 else
1823 change = SelectedOperation (&ChangeClearSizeFunctions, false, types);
1824 if (change)
1825 {
1826 Draw ();
1827 IncrementUndoSerialNumber ();
1828 }
1829 return (change);
1830 }
1831
1832 /*!
1833 * \brief Changes the 2nd size (drilling hole) of all selected and
1834 * visible objects.
1835 *
1836 * \return True if anything has changed.
1837 */
1838 bool
ChangeSelected2ndSize(int types,Coord Difference,bool fixIt)1839 ChangeSelected2ndSize (int types, Coord Difference, bool fixIt)
1840 {
1841 bool change = false;
1842
1843 /* setup identifiers */
1844 Absolute = (fixIt) ? 1 : 0;
1845 Value = Difference;
1846 change = SelectedOperation (&Change2ndSizeFunctions, false, types);
1847 if (change)
1848 {
1849 Draw ();
1850 IncrementUndoSerialNumber ();
1851 }
1852 return (change);
1853 }
1854
1855 /*!
1856 * \brief Changes the clearance flag (join) of all selected and visible
1857 * lines and/or arcs.
1858 *
1859 * \return True if anything has changed.
1860 */
1861 bool
ChangeSelectedJoin(int types)1862 ChangeSelectedJoin (int types)
1863 {
1864 bool change = false;
1865
1866 change = SelectedOperation (&ChangeJoinFunctions, false, types);
1867 if (change)
1868 {
1869 Draw ();
1870 IncrementUndoSerialNumber ();
1871 }
1872 return (change);
1873 }
1874
1875 /*!
1876 * \brief Changes the clearance flag (join) of all selected and visible
1877 * lines and/or arcs.
1878 *
1879 * \return True if anything has changed.
1880 */
1881 bool
SetSelectedJoin(int types)1882 SetSelectedJoin (int types)
1883 {
1884 bool change = false;
1885
1886 change = SelectedOperation (&SetJoinFunctions, false, types);
1887 if (change)
1888 {
1889 Draw ();
1890 IncrementUndoSerialNumber ();
1891 }
1892 return (change);
1893 }
1894
1895 /*!
1896 * \brief Changes the clearance flag (join) of all selected and visible
1897 * lines and/or arcs.
1898 *
1899 * \return True if anything has changed.
1900 */
1901 bool
ClrSelectedJoin(int types)1902 ClrSelectedJoin (int types)
1903 {
1904 bool change = false;
1905
1906 change = SelectedOperation (&ClrJoinFunctions, false, types);
1907 if (change)
1908 {
1909 Draw ();
1910 IncrementUndoSerialNumber ();
1911 }
1912 return (change);
1913 }
1914
1915 /*!
1916 * \brief Changes the square-flag of all selected and visible pins or
1917 * pads.
1918 *
1919 * \return True if anything has changed.
1920 */
1921 bool
ChangeSelectedSquare(int types)1922 ChangeSelectedSquare (int types)
1923 {
1924 bool change = false;
1925
1926 change = SelectedOperation (&ChangeSquareFunctions, false, types);
1927 if (change)
1928 {
1929 Draw ();
1930 IncrementUndoSerialNumber ();
1931 }
1932 return (change);
1933 }
1934
1935 /*!
1936 * \brief Sets the square-flag of all selected and visible pins or pads.
1937 *
1938 * \return True if anything has changed.
1939 */
1940 bool
SetSelectedSquare(int types)1941 SetSelectedSquare (int types)
1942 {
1943 bool change = false;
1944
1945 change = SelectedOperation (&SetSquareFunctions, false, types);
1946 if (change)
1947 {
1948 Draw ();
1949 IncrementUndoSerialNumber ();
1950 }
1951 return (change);
1952 }
1953
1954 /*!
1955 * \brief Clears the square-flag of all selected and visible pins or
1956 * pads.
1957 *
1958 * \return True if anything has changed.
1959 */
1960 bool
ClrSelectedSquare(int types)1961 ClrSelectedSquare (int types)
1962 {
1963 bool change = false;
1964
1965 change = SelectedOperation (&ClrSquareFunctions, false, types);
1966 if (change)
1967 {
1968 Draw ();
1969 IncrementUndoSerialNumber ();
1970 }
1971 return (change);
1972 }
1973
1974 /*!
1975 * \brief Changes the octagon-flag of all selected and visible pins and
1976 * vias.
1977 *
1978 * \return True if anything has changed.
1979 */
1980 bool
ChangeSelectedOctagon(int types)1981 ChangeSelectedOctagon (int types)
1982 {
1983 bool change = false;
1984
1985 change = SelectedOperation (&ChangeOctagonFunctions, false, types);
1986 if (change)
1987 {
1988 Draw ();
1989 IncrementUndoSerialNumber ();
1990 }
1991 return (change);
1992 }
1993
1994 /*!
1995 * \brief Sets the octagon-flag of all selected and visible pins and
1996 * vias.
1997 *
1998 * \return True if anything has changed.
1999 */
2000 bool
SetSelectedOctagon(int types)2001 SetSelectedOctagon (int types)
2002 {
2003 bool change = false;
2004
2005 change = SelectedOperation (&SetOctagonFunctions, false, types);
2006 if (change)
2007 {
2008 Draw ();
2009 IncrementUndoSerialNumber ();
2010 }
2011 return (change);
2012 }
2013
2014 /*!
2015 * \brief Clears the octagon-flag of all selected and visible pins and
2016 * vias.
2017 *
2018 * \return True if anything has changed.
2019 */
2020 bool
ClrSelectedOctagon(int types)2021 ClrSelectedOctagon (int types)
2022 {
2023 bool change = false;
2024
2025 change = SelectedOperation (&ClrOctagonFunctions, false, types);
2026 if (change)
2027 {
2028 Draw ();
2029 IncrementUndoSerialNumber ();
2030 }
2031 return (change);
2032 }
2033
2034 /*!
2035 * \brief Changes the hole-flag of all selected and visible vias.
2036 *
2037 * \return True if anything has changed.
2038 */
2039 bool
ChangeSelectedHole(void)2040 ChangeSelectedHole (void)
2041 {
2042 bool change = false;
2043
2044 if (PCB->ViaOn)
2045 VIA_LOOP (PCB->Data);
2046 {
2047 if (TEST_FLAG (SELECTEDFLAG, via))
2048 change |= ChangeHole (via);
2049 }
2050 END_LOOP;
2051 if (change)
2052 {
2053 Draw ();
2054 IncrementUndoSerialNumber ();
2055 }
2056 return (change);
2057 }
2058
2059 /*!
2060 * \brief Changes the no paste-flag of all selected and visible pads.
2061 *
2062 * \return True if anything has changed.
2063 */
2064 bool
ChangeSelectedPaste(void)2065 ChangeSelectedPaste (void)
2066 {
2067 bool change = false;
2068
2069 ALLPAD_LOOP (PCB->Data);
2070 {
2071 if (TEST_FLAG (SELECTEDFLAG, pad))
2072 change |= ChangePaste (pad);
2073 }
2074 ENDALL_LOOP;
2075 if (change)
2076 {
2077 Draw ();
2078 IncrementUndoSerialNumber ();
2079 }
2080 return (change);
2081 }
2082
2083
2084 /*!
2085 * \brief Changes the size of the passed object.
2086 *
2087 * \return True if anything is changed.
2088 */
2089 bool
ChangeObjectSize(int Type,void * Ptr1,void * Ptr2,void * Ptr3,Coord Difference,bool fixIt)2090 ChangeObjectSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
2091 Coord Difference, bool fixIt)
2092 {
2093 bool change;
2094
2095 /* setup identifier */
2096 Absolute = (fixIt) ? 1 : 0;
2097 Value = Difference;
2098 change =
2099 (ObjectOperation (&ChangeSizeFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL);
2100 if (change)
2101 {
2102 Draw ();
2103 IncrementUndoSerialNumber ();
2104 }
2105 return (change);
2106 }
2107
2108 /*!
2109 * \brief Changes the clearance size of the passed object.
2110 *
2111 * \return True if anything is changed.
2112 */
2113 bool
ChangeObjectClearSize(int Type,void * Ptr1,void * Ptr2,void * Ptr3,Coord Difference,bool fixIt)2114 ChangeObjectClearSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
2115 Coord Difference, bool fixIt)
2116 {
2117 bool change;
2118
2119 /* setup identifier */
2120 Absolute = (fixIt) ? 1 : 0;
2121 Value = Difference;
2122 if (TEST_FLAG (SHOWMASKFLAG, PCB))
2123 change =
2124 (ObjectOperation (&ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2125 NULL);
2126 else
2127 change =
2128 (ObjectOperation (&ChangeClearSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2129 NULL);
2130 if (change)
2131 {
2132 Draw ();
2133 IncrementUndoSerialNumber ();
2134 }
2135 return (change);
2136 }
2137
2138 /*!
2139 * \brief Changes the thermal of the passed object.
2140 *
2141 * \return True if anything is changed.
2142 *
2143 */
2144 bool
ChangeObjectThermal(int Type,void * Ptr1,void * Ptr2,void * Ptr3,int therm_type)2145 ChangeObjectThermal (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
2146 int therm_type)
2147 {
2148 bool change;
2149
2150 Value = Absolute = therm_type;
2151 change =
2152 (ObjectOperation (&ChangeThermalFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2153 NULL);
2154 if (change)
2155 {
2156 Draw ();
2157 IncrementUndoSerialNumber ();
2158 }
2159 return (change);
2160 }
2161
2162 /*!
2163 * \brief Changes the thermal of the passed object.
2164 *
2165 * \return True if anything is changed.
2166 *
2167 */
2168 bool
ChangeObjectViaLayers(void * Ptr1,void * Ptr2,void * Ptr3,int from,int to)2169 ChangeObjectViaLayers (void *Ptr1, void *Ptr2, void *Ptr3,
2170 int from, int to)
2171 {
2172 bool change = false;
2173 PinType *via = (PinType *) Ptr1;
2174 int new_from = (from != -1)?from:via->BuriedFrom;
2175 int new_to = (to != -1)?to:via->BuriedTo;
2176 int i;
2177
2178 if (TEST_FLAG (LOCKFLAG, via))
2179 return (NULL);
2180
2181 if ((new_from == new_to)
2182 && new_from != 0)
2183 return false;
2184
2185 /* special case - changing TH via "from" layer sets "to" layer to bottom layer */
2186 if (!VIA_IS_BURIED (via)
2187 && (to == -1))
2188 new_to = GetMaxBottomLayer ();
2189
2190 for (i=0; i < max_copper_layer; i++)
2191 {
2192 /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, false); not needed? */
2193 RestoreToPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
2194 }
2195
2196 if (from != -1 || to != -1)
2197 {
2198 AddObjectToSetViaLayersUndoList (via, via, via);
2199 change = true;
2200 }
2201
2202 via->BuriedFrom = new_from;
2203 via->BuriedTo = new_to;
2204
2205 if (VIA_IS_BURIED (via))
2206 {
2207 SanitizeBuriedVia (via);
2208 for (i=0; i < max_copper_layer; i++)
2209 {
2210 /* AddObjectToClearPolyUndoList (VIA_TYPE, &(PCB->Data->Layer[i]), via, via, true); not needed? */
2211 ClearFromPolygon (PCB->Data, VIA_TYPE, &(PCB->Data->Layer[i]), via);
2212 }
2213 DrawVia (via);
2214 }
2215
2216 if (change)
2217 {
2218 Draw ();
2219 IncrementUndoSerialNumber ();
2220 }
2221 return (change);
2222 }
2223
2224 /*!
2225 * \brief Changes the 2nd size of the passed object.
2226 *
2227 * \return True if anything is changed.
2228 */
2229 bool
ChangeObject2ndSize(int Type,void * Ptr1,void * Ptr2,void * Ptr3,Coord Difference,bool fixIt,bool incundo)2230 ChangeObject2ndSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
2231 Coord Difference, bool fixIt, bool incundo)
2232 {
2233 bool change;
2234
2235 /* setup identifier */
2236 Absolute = (fixIt) ? 1 : 0;
2237 Value = Difference;
2238 change =
2239 (ObjectOperation (&Change2ndSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2240 NULL);
2241 if (change)
2242 {
2243 Draw ();
2244 if (incundo)
2245 IncrementUndoSerialNumber ();
2246 }
2247 return (change);
2248 }
2249
2250 /*!
2251 * \brief Changes the mask size of the passed object.
2252 *
2253 * \return True if anything is changed.
2254 */
2255 bool
ChangeObjectMaskSize(int Type,void * Ptr1,void * Ptr2,void * Ptr3,Coord Difference,bool fixIt)2256 ChangeObjectMaskSize (int Type, void *Ptr1, void *Ptr2, void *Ptr3,
2257 Coord Difference, bool fixIt)
2258 {
2259 bool change;
2260
2261 /* setup identifier */
2262 Absolute = (fixIt) ? 1 : 0;
2263 Value = Difference;
2264 change =
2265 (ObjectOperation (&ChangeMaskSizeFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2266 NULL);
2267 if (change)
2268 {
2269 Draw ();
2270 IncrementUndoSerialNumber ();
2271 }
2272 return (change);
2273 }
2274
2275 /*!
2276 * \brief Changes the name of the passed object.
2277 *
2278 * \warning The allocated memory isn't freed because the old string is used
2279 * by the undo module.
2280 *
2281 * \return The old name.
2282 */
2283 void *
ChangeObjectName(int Type,void * Ptr1,void * Ptr2,void * Ptr3,char * Name)2284 ChangeObjectName (int Type, void *Ptr1, void *Ptr2, void *Ptr3, char *Name)
2285 {
2286 void *result;
2287 /* setup identifier */
2288 NewName = Name;
2289 result = ObjectOperation (&ChangeNameFunctions, Type, Ptr1, Ptr2, Ptr3);
2290 Draw ();
2291 return (result);
2292 }
2293
2294 /*!
2295 * \brief Changes the clearance-flag of the passed object.
2296 *
2297 * \return True if anything is changed.
2298 */
2299 bool
ChangeObjectJoin(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2300 ChangeObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2301 {
2302 if (ObjectOperation (&ChangeJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2303 {
2304 Draw ();
2305 IncrementUndoSerialNumber ();
2306 return (true);
2307 }
2308 return (false);
2309 }
2310
2311 /*!
2312 * \brief Sets the clearance-flag of the passed object.
2313 *
2314 * \return True if anything is changed.
2315 */
2316 bool
SetObjectJoin(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2317 SetObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2318 {
2319 if (ObjectOperation (&SetJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2320 {
2321 Draw ();
2322 IncrementUndoSerialNumber ();
2323 return (true);
2324 }
2325 return (false);
2326 }
2327
2328 /*!
2329 * \brief Clears the clearance-flag of the passed object.
2330 *
2331 * \return True if anything is changed.
2332 */
2333 bool
ClrObjectJoin(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2334 ClrObjectJoin (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2335 {
2336 if (ObjectOperation (&ClrJoinFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2337 {
2338 Draw ();
2339 IncrementUndoSerialNumber ();
2340 return (true);
2341 }
2342 return (false);
2343 }
2344
2345 /*!
2346 * \brief Changes the square-flag of the passed object.
2347 *
2348 * \return True if anything is changed.
2349 */
2350 bool
ChangeObjectSquare(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2351 ChangeObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2352 {
2353 if (ObjectOperation (&ChangeSquareFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2354 NULL)
2355 {
2356 Draw ();
2357 IncrementUndoSerialNumber ();
2358 return (true);
2359 }
2360 return (false);
2361 }
2362
2363 /*!
2364 * \brief Sets the square-flag of the passed object.
2365 *
2366 * \return True if anything is changed.
2367 */
2368 bool
SetObjectSquare(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2369 SetObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2370 {
2371 if (ObjectOperation (&SetSquareFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2372 {
2373 Draw ();
2374 IncrementUndoSerialNumber ();
2375 return (true);
2376 }
2377 return (false);
2378 }
2379
2380 /*!
2381 * \brief Clears the square-flag of the passed object.
2382 *
2383 * \return True if anything is changed.
2384 */
2385 bool
ClrObjectSquare(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2386 ClrObjectSquare (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2387 {
2388 if (ObjectOperation (&ClrSquareFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2389 {
2390 Draw ();
2391 IncrementUndoSerialNumber ();
2392 return (true);
2393 }
2394 return (false);
2395 }
2396
2397 /*!
2398 * \brief Changes the octagon-flag of the passed object.
2399 *
2400 * \return True if anything is changed.
2401 */
2402 bool
ChangeObjectOctagon(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2403 ChangeObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2404 {
2405 if (ObjectOperation (&ChangeOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) !=
2406 NULL)
2407 {
2408 Draw ();
2409 IncrementUndoSerialNumber ();
2410 return (true);
2411 }
2412 return (false);
2413 }
2414
2415 /*!
2416 * \brief Sets the octagon-flag of the passed object.
2417 *
2418 * \return True if anything is changed.
2419 */
2420 bool
SetObjectOctagon(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2421 SetObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2422 {
2423 if (ObjectOperation (&SetOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2424 {
2425 Draw ();
2426 IncrementUndoSerialNumber ();
2427 return (true);
2428 }
2429 return (false);
2430 }
2431
2432 /*!
2433 * \brief Clears the octagon-flag of the passed object.
2434 *
2435 * \return True if anything is changed.
2436 */
2437 bool
ClrObjectOctagon(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2438 ClrObjectOctagon (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2439 {
2440 if (ObjectOperation (&ClrOctagonFunctions, Type, Ptr1, Ptr2, Ptr3) != NULL)
2441 {
2442 Draw ();
2443 IncrementUndoSerialNumber ();
2444 return (true);
2445 }
2446 return (false);
2447 }
2448
2449 /*!
2450 * \bief Queries the user for a new object name and changes it.
2451 *
2452 * \warning The allocated memory isn't freed because the old string is used
2453 * by the undo module.
2454 */
2455 void *
QueryInputAndChangeObjectName(int Type,void * Ptr1,void * Ptr2,void * Ptr3)2456 QueryInputAndChangeObjectName (int Type, void *Ptr1, void *Ptr2, void *Ptr3)
2457 {
2458 char *name = NULL;
2459 char msg[513];
2460
2461 /* if passed an element name, make it an element reference instead */
2462 if (Type == ELEMENTNAME_TYPE)
2463 {
2464 Type = ELEMENT_TYPE;
2465 Ptr2 = Ptr1;
2466 Ptr3 = Ptr1;
2467 }
2468 switch (Type)
2469 {
2470 case LINE_TYPE:
2471 name = gui->prompt_for (_("Linename:"),
2472 EMPTY (((LineType *) Ptr2)->Number));
2473 break;
2474
2475 case VIA_TYPE:
2476 name = gui->prompt_for (_("Vianame:"),
2477 EMPTY (((PinType *) Ptr2)->Name));
2478 break;
2479
2480 case PIN_TYPE:
2481 sprintf (msg, _("%s Pin Name:"), EMPTY (((PinType *) Ptr2)->Number));
2482 name = gui->prompt_for (msg, EMPTY (((PinType *) Ptr2)->Name));
2483 break;
2484
2485 case PAD_TYPE:
2486 sprintf (msg, _("%s Pad Name:"), EMPTY (((PadType *) Ptr2)->Number));
2487 name = gui->prompt_for (msg, EMPTY (((PadType *) Ptr2)->Name));
2488 break;
2489
2490 case TEXT_TYPE:
2491 name = gui->prompt_for (_("Enter text:"),
2492 EMPTY (((TextType *) Ptr2)->TextString));
2493 break;
2494
2495 case ELEMENT_TYPE:
2496 name = gui->prompt_for (_("Elementname:"),
2497 EMPTY (ELEMENT_NAME
2498 (PCB, (ElementType *) Ptr2)));
2499 break;
2500 }
2501 if (name)
2502 {
2503 /* NB: ChangeObjectName takes ownership of the passed memory */
2504 char *old = (char *)ChangeObjectName (Type, Ptr1, Ptr2, Ptr3, name);
2505 if (old != (char *) -1)
2506 {
2507 AddObjectToChangeNameUndoList (Type, Ptr1, Ptr2, Ptr3, old);
2508 IncrementUndoSerialNumber ();
2509 }
2510 Draw ();
2511 return (Ptr3);
2512 }
2513 return (NULL);
2514 }
2515
2516 /*!
2517 * \brief Changes the maximum size of a layout, adjusts the scrollbars,
2518 * releases the saved pixmap if necessary and adjusts the cursor
2519 * confinement box.
2520 */
2521 void
ChangePCBSize(Coord Width,Coord Height)2522 ChangePCBSize (Coord Width, Coord Height)
2523 {
2524 PCB->MaxWidth = Width;
2525 PCB->MaxHeight = Height;
2526 hid_action ("PCBChanged");
2527 }
2528
2529 /*!
2530 * \brief Changes the mask size of a pad.
2531 *
2532 * \return TRUE if changed.
2533 */
2534 static void *
ChangePadMaskSize(ElementType * Element,PadType * Pad)2535 ChangePadMaskSize (ElementType *Element, PadType *Pad)
2536 {
2537 Coord new_value = (Absolute) ? Value : Pad->Mask + Value;
2538
2539 new_value = MAX (new_value, 0);
2540 if (new_value == Pad->Mask && Absolute == 0)
2541 new_value = Pad->Thickness;
2542 if (new_value != Pad->Mask)
2543 {
2544 AddObjectToMaskSizeUndoList (PAD_TYPE, Element, Pad, Pad);
2545 ErasePad (Pad);
2546 r_delete_entry (PCB->Data->pad_tree, &Pad->BoundingBox);
2547 Pad->Mask = new_value;
2548 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
2549 DrawPad (Pad);
2550 return (Pad);
2551 }
2552 return (NULL);
2553 }
2554
2555 /*!
2556 * \brief Changes the mask size of a pin.
2557 *
2558 * \return TRUE if changed.
2559 */
2560 static void *
ChangePinMaskSize(ElementType * Element,PinType * Pin)2561 ChangePinMaskSize (ElementType *Element, PinType *Pin)
2562 {
2563 Coord new_value = (Absolute) ? Value : Pin->Mask + Value;
2564
2565 new_value = MAX (new_value, 0);
2566 if (new_value == Pin->Mask && Absolute == 0)
2567 new_value = Pin->Thickness;
2568 if (new_value != Pin->Mask)
2569 {
2570 AddObjectToMaskSizeUndoList (PIN_TYPE, Element, Pin, Pin);
2571 ErasePin (Pin);
2572 r_delete_entry (PCB->Data->pin_tree, &Pin->BoundingBox);
2573 Pin->Mask = new_value;
2574 SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
2575 DrawPin (Pin);
2576 return (Pin);
2577 }
2578 return (NULL);
2579 }
2580
2581 /*!
2582 * \brief Changes the mask size of a via.
2583 *
2584 * \return TRUE if changed.
2585 */
2586 static void *
ChangeViaMaskSize(PinType * Via)2587 ChangeViaMaskSize (PinType *Via)
2588 {
2589 Coord new_value;
2590
2591 new_value = (Absolute) ? Value : Via->Mask + Value;
2592 new_value = MAX (new_value, 0);
2593 if (new_value != Via->Mask)
2594 {
2595 AddObjectToMaskSizeUndoList (VIA_TYPE, Via, Via, Via);
2596 EraseVia (Via);
2597 r_delete_entry (PCB->Data->via_tree, &Via->BoundingBox);
2598 Via->Mask = new_value;
2599 SetPinBoundingBox (Via);
2600 r_insert_entry (PCB->Data->via_tree, &Via->BoundingBox, 0);
2601 DrawVia (Via);
2602 return (Via);
2603 }
2604 return (NULL);
2605 }
2606