Introduce POLYGONHOLE_MODE for creating holes in polygons
[geda-pcb/gde.git] / src / select.c
blob5240837fab340f30501d23a9435cd35e13ef0e88
1 /* $Id$ */
3 /*
4 * COPYRIGHT
6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
30 /* select routines
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
37 #include "global.h"
39 #include "data.h"
40 #include "draw.h"
41 #include "error.h"
42 #include "search.h"
43 #include "select.h"
44 #include "undo.h"
45 #include "rats.h"
46 #include "misc.h"
48 #include <sys/types.h>
49 #ifdef HAVE_REGEX_H
50 #include <regex.h>
51 #else
52 #ifdef HAVE_UNISTD_H
53 #include <unistd.h>
54 #endif
55 #endif
57 #ifdef HAVE_LIBDMALLOC
58 #include <dmalloc.h>
59 #endif
61 RCSID ("$Id$");
65 /* ---------------------------------------------------------------------------
66 * toggle selection of pin
67 * This SelectPin function was moved to here from the original netlist.c
68 * as part of the gui code separation for the Gtk port. SelectPin() is
69 * written by and is Copyright (C) 1998, 1999, 2000, 2001 harry eaton
71 void
72 SelectPin (LibraryEntryTypePtr entry, bool toggle)
74 ConnectionType conn;
76 if (SeekPad (entry, &conn, false))
78 switch (conn.type)
80 case PIN_TYPE:
82 PinTypePtr pin = (PinTypePtr) conn.ptr2;
84 AddObjectToFlagUndoList (PIN_TYPE, conn.ptr1, conn.ptr2,
85 conn.ptr2);
86 if (toggle)
88 TOGGLE_FLAG (SELECTEDFLAG, pin);
89 CenterDisplay (pin->X, pin->Y, false);
91 else
92 SET_FLAG (SELECTEDFLAG, pin);
93 DrawPin (pin, 0);
94 break;
96 case PAD_TYPE:
98 PadTypePtr pad = (PadTypePtr) conn.ptr2;
100 AddObjectToFlagUndoList (PAD_TYPE, conn.ptr1, conn.ptr2,
101 conn.ptr2);
102 if (toggle)
104 TOGGLE_FLAG (SELECTEDFLAG, pad);
105 CenterDisplay (pad->Point1.X, pad->Point1.Y, false);
107 else
108 SET_FLAG (SELECTEDFLAG, pad);
109 DrawPad (pad, 0);
110 break;
117 /* ---------------------------------------------------------------------------
118 * toggles the selection of any kind of object
119 * the different types are defined by search.h
121 bool
122 SelectObject (void)
124 void *ptr1, *ptr2, *ptr3;
125 LayerTypePtr layer;
126 int type;
128 bool changed = true;
130 type = SearchScreen (Crosshair.X, Crosshair.Y, SELECT_TYPES,
131 &ptr1, &ptr2, &ptr3);
132 if (type == NO_TYPE || TEST_FLAG (LOCKFLAG, (PinTypePtr) ptr2))
133 return (false);
134 switch (type)
136 case VIA_TYPE:
137 AddObjectToFlagUndoList (VIA_TYPE, ptr1, ptr1, ptr1);
138 TOGGLE_FLAG (SELECTEDFLAG, (PinTypePtr) ptr1);
139 DrawVia ((PinTypePtr) ptr1, 0);
140 break;
142 case LINE_TYPE:
144 LineType *line = (LineTypePtr) ptr2;
146 layer = (LayerTypePtr) ptr1;
147 AddObjectToFlagUndoList (LINE_TYPE, ptr1, ptr2, ptr2);
148 TOGGLE_FLAG (SELECTEDFLAG, line);
149 DrawLine (layer, line, 0);
150 break;
153 case RATLINE_TYPE:
155 RatTypePtr rat = (RatTypePtr) ptr2;
157 AddObjectToFlagUndoList (RATLINE_TYPE, ptr1, ptr1, ptr1);
158 TOGGLE_FLAG (SELECTEDFLAG, rat);
159 DrawRat (rat, 0);
160 break;
163 case ARC_TYPE:
165 ArcType *arc = (ArcTypePtr) ptr2;
167 layer = (LayerTypePtr) ptr1;
168 AddObjectToFlagUndoList (ARC_TYPE, ptr1, ptr2, ptr2);
169 TOGGLE_FLAG (SELECTEDFLAG, arc);
170 DrawArc (layer, arc, 0);
171 break;
174 case TEXT_TYPE:
176 TextType *text = (TextTypePtr) ptr2;
178 layer = (LayerTypePtr) ptr1;
179 AddObjectToFlagUndoList (TEXT_TYPE, ptr1, ptr2, ptr2);
180 TOGGLE_FLAG (SELECTEDFLAG, text);
181 DrawText (layer, text, 0);
182 break;
185 case POLYGON_TYPE:
187 PolygonType *poly = (PolygonTypePtr) ptr2;
189 layer = (LayerTypePtr) ptr1;
190 AddObjectToFlagUndoList (POLYGON_TYPE, ptr1, ptr2, ptr2);
191 TOGGLE_FLAG (SELECTEDFLAG, poly);
192 DrawPolygon (layer, poly, 0);
193 /* changing memory order no longer effects draw order */
194 break;
197 case PIN_TYPE:
198 AddObjectToFlagUndoList (PIN_TYPE, ptr1, ptr2, ptr2);
199 TOGGLE_FLAG (SELECTEDFLAG, (PinTypePtr) ptr2);
200 DrawPin ((PinTypePtr) ptr2, 0);
201 break;
203 case PAD_TYPE:
204 AddObjectToFlagUndoList (PAD_TYPE, ptr1, ptr2, ptr2);
205 TOGGLE_FLAG (SELECTEDFLAG, (PadTypePtr) ptr2);
206 DrawPad ((PadTypePtr) ptr2, 0);
207 break;
209 case ELEMENTNAME_TYPE:
211 ElementTypePtr element = (ElementTypePtr) ptr1;
213 /* select all names of the element */
214 ELEMENTTEXT_LOOP (element);
216 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
217 TOGGLE_FLAG (SELECTEDFLAG, text);
219 END_LOOP;
220 DrawElementName (element, 0);
221 break;
224 case ELEMENT_TYPE:
226 ElementTypePtr element = (ElementTypePtr) ptr1;
228 /* select all pins and names of the element */
229 PIN_LOOP (element);
231 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
232 TOGGLE_FLAG (SELECTEDFLAG, pin);
234 END_LOOP;
235 PAD_LOOP (element);
237 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
238 TOGGLE_FLAG (SELECTEDFLAG, pad);
240 END_LOOP;
241 ELEMENTTEXT_LOOP (element);
243 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
244 TOGGLE_FLAG (SELECTEDFLAG, text);
246 END_LOOP;
247 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
248 TOGGLE_FLAG (SELECTEDFLAG, element);
249 if (PCB->ElementOn &&
250 ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT ||
251 PCB->InvisibleObjectsOn))
252 if (PCB->ElementOn)
254 DrawElementName (element, 0);
255 DrawElementPackage (element, 0);
257 if (PCB->PinOn)
258 DrawElementPinsAndPads (element, 0);
259 break;
262 Draw ();
263 IncrementUndoSerialNumber ();
264 return (changed);
267 /* ----------------------------------------------------------------------
268 * selects/unselects all visible objects within the passed box
269 * Flag determines if the block is to be selected or unselected
270 * returns true if the state of any object has changed
272 bool
273 SelectBlock (BoxTypePtr Box, bool Flag)
275 bool changed = false;
277 if (PCB->RatOn || !Flag)
278 RAT_LOOP (PCB->Data);
280 if (LINE_IN_BOX ((LineTypePtr) line, Box) &&
281 !TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != Flag)
283 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
284 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
285 if (PCB->RatOn)
286 DrawRat (line, 0);
287 changed = true;
290 END_LOOP;
292 /* check layers */
293 LAYER_LOOP(PCB->Data, max_layer + 2);
295 if (! (layer->On || !Flag))
296 continue;
298 LINE_LOOP (layer);
300 if (LINE_IN_BOX (line, Box)
301 && !TEST_FLAG (LOCKFLAG, line)
302 && TEST_FLAG (SELECTEDFLAG, line) != Flag)
304 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
305 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
306 if (layer->On)
307 DrawLine (layer, line, 0);
308 changed = true;
311 END_LOOP;
312 ARC_LOOP (layer);
314 if (ARC_IN_BOX (arc, Box)
315 && !TEST_FLAG (LOCKFLAG, arc)
316 && TEST_FLAG (SELECTEDFLAG, arc) != Flag)
318 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
319 ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
320 if (layer->On)
321 DrawArc (layer, arc, 0);
322 changed = true;
325 END_LOOP;
326 TEXT_LOOP (layer);
328 if (!Flag || TEXT_IS_VISIBLE(PCB, layer, text))
330 if (TEXT_IN_BOX (text, Box)
331 && !TEST_FLAG (LOCKFLAG, text)
332 && TEST_FLAG (SELECTEDFLAG, text) != Flag)
334 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
335 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
336 if (TEXT_IS_VISIBLE(PCB, layer, text))
337 DrawText (layer, text, 0);
338 changed = true;
342 END_LOOP;
343 POLYGON_LOOP (layer);
345 if (POLYGON_IN_BOX (polygon, Box)
346 && !TEST_FLAG (LOCKFLAG, polygon)
347 && TEST_FLAG (SELECTEDFLAG, polygon) != Flag)
349 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
350 ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
351 if (layer->On)
352 DrawPolygon (layer, polygon, 0);
353 changed = true;
356 END_LOOP;
358 END_LOOP;
360 /* elements */
361 ELEMENT_LOOP (PCB->Data);
364 bool gotElement = false;
365 if ((PCB->ElementOn || !Flag)
366 && !TEST_FLAG (LOCKFLAG, element)
367 && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
368 || PCB->InvisibleObjectsOn))
370 if (BOX_IN_BOX
371 (&ELEMENT_TEXT (PCB, element).BoundingBox, Box)
372 && !TEST_FLAG (LOCKFLAG, &ELEMENT_TEXT (PCB, element))
373 && TEST_FLAG (SELECTEDFLAG,
374 &ELEMENT_TEXT (PCB, element)) != Flag)
376 /* select all names of element */
377 ELEMENTTEXT_LOOP (element);
379 AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
380 element, text, text);
381 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
383 END_LOOP;
384 if (PCB->ElementOn)
385 DrawElementName (element, 0);
386 changed = true;
388 if ((PCB->PinOn || !Flag) && ELEMENT_IN_BOX (element, Box))
389 if (TEST_FLAG (SELECTEDFLAG, element) != Flag)
391 AddObjectToFlagUndoList (ELEMENT_TYPE,
392 element, element, element);
393 ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
394 PIN_LOOP (element);
396 if (TEST_FLAG (SELECTEDFLAG, pin) != Flag)
398 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
399 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
400 if (PCB->PinOn)
401 DrawPin (pin, 0);
402 changed = true;
405 END_LOOP;
406 PAD_LOOP (element);
408 if (TEST_FLAG (SELECTEDFLAG, pad) != Flag)
410 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
411 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
412 if (PCB->PinOn)
413 DrawPad (pad, 0);
414 changed = true;
417 END_LOOP;
418 if (PCB->PinOn)
419 DrawElement (element, 0);
420 changed = true;
421 gotElement = true;
424 if ((PCB->PinOn || !Flag) && !TEST_FLAG (LOCKFLAG, element) && !gotElement)
426 PIN_LOOP (element);
428 if ((VIA_OR_PIN_IN_BOX (pin, Box)
429 && TEST_FLAG (SELECTEDFLAG, pin) != Flag))
431 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
432 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
433 if (PCB->PinOn)
434 DrawPin (pin, 0);
435 changed = true;
438 END_LOOP;
439 PAD_LOOP (element);
441 if (PAD_IN_BOX (pad, Box)
442 && TEST_FLAG (SELECTEDFLAG, pad) != Flag)
444 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
445 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
446 if (PCB->PinOn)
447 DrawPad (pad, 0);
448 changed = true;
451 END_LOOP;
455 END_LOOP;
456 /* end with vias */
457 if (PCB->ViaOn || !Flag)
458 VIA_LOOP (PCB->Data);
460 if (VIA_OR_PIN_IN_BOX (via, Box)
461 && !TEST_FLAG (LOCKFLAG, via)
462 && TEST_FLAG (SELECTEDFLAG, via) != Flag)
464 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
465 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
466 if (PCB->ViaOn)
467 DrawVia (via, 0);
468 changed = true;
471 END_LOOP;
472 if (changed)
474 Draw ();
475 IncrementUndoSerialNumber ();
477 return (changed);
480 /* ----------------------------------------------------------------------
481 * performs several operations on the passed object
483 void *
484 ObjectOperation (ObjectFunctionTypePtr F,
485 int Type, void *Ptr1, void *Ptr2, void *Ptr3)
487 switch (Type)
489 case LINE_TYPE:
490 if (F->Line)
491 return (F->Line ((LayerTypePtr) Ptr1, (LineTypePtr) Ptr2));
492 break;
494 case ARC_TYPE:
495 if (F->Arc)
496 return (F->Arc ((LayerTypePtr) Ptr1, (ArcTypePtr) Ptr2));
497 break;
499 case LINEPOINT_TYPE:
500 if (F->LinePoint)
501 return (F->LinePoint ((LayerTypePtr) Ptr1, (LineTypePtr) Ptr2,
502 (PointTypePtr) Ptr3));
503 break;
505 case TEXT_TYPE:
506 if (F->Text)
507 return (F->Text ((LayerTypePtr) Ptr1, (TextTypePtr) Ptr2));
508 break;
510 case POLYGON_TYPE:
511 if (F->Polygon)
512 return (F->Polygon ((LayerTypePtr) Ptr1, (PolygonTypePtr) Ptr2));
513 break;
515 case POLYGONPOINT_TYPE:
516 if (F->Point)
517 return (F->Point ((LayerTypePtr) Ptr1, (PolygonTypePtr) Ptr2,
518 (PointTypePtr) Ptr3));
519 break;
521 case VIA_TYPE:
522 if (F->Via)
523 return (F->Via ((PinTypePtr) Ptr1));
524 break;
526 case ELEMENT_TYPE:
527 if (F->Element)
528 return (F->Element ((ElementTypePtr) Ptr1));
529 break;
531 case PIN_TYPE:
532 if (F->Pin)
533 return (F->Pin ((ElementTypePtr) Ptr1, (PinTypePtr) Ptr2));
534 break;
536 case PAD_TYPE:
537 if (F->Pad)
538 return (F->Pad ((ElementTypePtr) Ptr1, (PadTypePtr) Ptr2));
539 break;
541 case ELEMENTNAME_TYPE:
542 if (F->ElementName)
543 return (F->ElementName ((ElementTypePtr) Ptr1));
544 break;
546 case RATLINE_TYPE:
547 if (F->Rat)
548 return (F->Rat ((RatTypePtr) Ptr1));
549 break;
551 return (NULL);
554 /* ----------------------------------------------------------------------
555 * performs several operations on selected objects which are also visible
556 * The lowlevel procedures are passed together with additional information
557 * resets the selected flag if requested
558 * returns true if anything has changed
560 bool
561 SelectedOperation (ObjectFunctionTypePtr F, bool Reset, int type)
563 bool changed = false;
565 /* check lines */
566 if (type & LINE_TYPE && F->Line)
567 VISIBLELINE_LOOP (PCB->Data);
569 if (TEST_FLAG (SELECTEDFLAG, line))
571 if (Reset)
573 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
574 CLEAR_FLAG (SELECTEDFLAG, line);
576 F->Line (layer, line);
577 changed = true;
580 ENDALL_LOOP;
582 /* check arcs */
583 if (type & ARC_TYPE && F->Arc)
584 VISIBLEARC_LOOP (PCB->Data);
586 if (TEST_FLAG (SELECTEDFLAG, arc))
588 if (Reset)
590 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
591 CLEAR_FLAG (SELECTEDFLAG, arc);
593 F->Arc (layer, arc);
594 changed = true;
597 ENDALL_LOOP;
599 /* check text */
600 if (type & TEXT_TYPE && F->Text)
601 ALLTEXT_LOOP (PCB->Data);
603 if (TEST_FLAG (SELECTEDFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text))
605 if (Reset)
607 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
608 CLEAR_FLAG (SELECTEDFLAG, text);
610 F->Text (layer, text);
611 changed = true;
614 ENDALL_LOOP;
616 /* check polygons */
617 if (type & POLYGON_TYPE && F->Polygon)
618 VISIBLEPOLYGON_LOOP (PCB->Data);
620 if (TEST_FLAG (SELECTEDFLAG, polygon))
622 if (Reset)
624 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
625 CLEAR_FLAG (SELECTEDFLAG, polygon);
627 F->Polygon (layer, polygon);
628 changed = true;
631 ENDALL_LOOP;
633 /* elements silkscreen */
634 if (type & ELEMENT_TYPE && PCB->ElementOn && F->Element)
635 ELEMENT_LOOP (PCB->Data);
637 if (TEST_FLAG (SELECTEDFLAG, element))
639 if (Reset)
641 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
642 CLEAR_FLAG (SELECTEDFLAG, element);
644 F->Element (element);
645 changed = true;
648 END_LOOP;
649 if (type & ELEMENTNAME_TYPE && PCB->ElementOn && F->ElementName)
650 ELEMENT_LOOP (PCB->Data);
652 if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element)))
654 if (Reset)
656 AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
657 element,
658 &ELEMENT_TEXT (PCB, element),
659 &ELEMENT_TEXT (PCB, element));
660 CLEAR_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element));
662 F->ElementName (element);
663 changed = true;
666 END_LOOP;
668 if (type & PIN_TYPE && PCB->PinOn && F->Pin)
669 ELEMENT_LOOP (PCB->Data);
671 PIN_LOOP (element);
673 if (TEST_FLAG (SELECTEDFLAG, pin))
675 if (Reset)
677 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
678 CLEAR_FLAG (SELECTEDFLAG, pin);
680 F->Pin (element, pin);
681 changed = true;
684 END_LOOP;
686 END_LOOP;
688 if (type & PAD_TYPE && PCB->PinOn && F->Pad)
689 ELEMENT_LOOP (PCB->Data);
691 PAD_LOOP (element);
693 if (TEST_FLAG (SELECTEDFLAG, pad))
695 if (Reset)
697 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
698 CLEAR_FLAG (SELECTEDFLAG, pad);
700 F->Pad (element, pad);
701 changed = true;
704 END_LOOP;
706 END_LOOP;
708 /* process vias */
709 if (type & VIA_TYPE && PCB->ViaOn && F->Via)
710 VIA_LOOP (PCB->Data);
712 if (TEST_FLAG (SELECTEDFLAG, via))
714 if (Reset)
716 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
717 CLEAR_FLAG (SELECTEDFLAG, via);
719 F->Via (via);
720 changed = true;
723 END_LOOP;
724 /* and rat-lines */
725 if (type & RATLINE_TYPE && PCB->RatOn && F->Rat)
726 RAT_LOOP (PCB->Data);
728 if (TEST_FLAG (SELECTEDFLAG, line))
730 if (Reset)
732 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
733 CLEAR_FLAG (SELECTEDFLAG, line);
735 F->Rat (line);
736 changed = true;
739 END_LOOP;
740 if (Reset && changed)
741 IncrementUndoSerialNumber ();
742 return (changed);
745 /* ----------------------------------------------------------------------
746 * selects/unselects all objects which were found during a connection scan
747 * Flag determines if they are to be selected or unselected
748 * returns true if the state of any object has changed
750 * text objects and elements cannot be selected by this routine
752 bool
753 SelectConnection (bool Flag)
755 bool changed = false;
757 if (PCB->RatOn)
758 RAT_LOOP (PCB->Data);
760 if (TEST_FLAG (FOUNDFLAG, line))
762 AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
763 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
764 DrawRat (line, 0);
765 changed = true;
768 END_LOOP;
770 VISIBLELINE_LOOP (PCB->Data);
772 if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
774 AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
775 ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
776 DrawLine (layer, line, 0);
777 changed = true;
780 ENDALL_LOOP;
781 VISIBLEARC_LOOP (PCB->Data);
783 if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
785 AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
786 ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
787 DrawArc (layer, arc, 0);
788 changed = true;
791 ENDALL_LOOP;
792 VISIBLEPOLYGON_LOOP (PCB->Data);
794 if (TEST_FLAG (FOUNDFLAG, polygon) && !TEST_FLAG (LOCKFLAG, polygon))
796 AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
797 ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
798 DrawPolygon (layer, polygon, 0);
799 changed = true;
802 ENDALL_LOOP;
804 if (PCB->PinOn && PCB->ElementOn)
806 ALLPIN_LOOP (PCB->Data);
808 if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pin))
810 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
811 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
812 DrawPin (pin, 0);
813 changed = true;
816 ENDALL_LOOP;
817 ALLPAD_LOOP (PCB->Data);
819 if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pad))
821 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
822 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
823 DrawPad (pad, 0);
824 changed = true;
827 ENDALL_LOOP;
830 if (PCB->ViaOn)
831 VIA_LOOP (PCB->Data);
833 if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
835 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
836 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
837 DrawVia (via, 0);
838 changed = true;
841 END_LOOP;
842 Draw ();
843 return (changed);
846 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
847 /* ---------------------------------------------------------------------------
848 * selects objects as defined by Type by name;
849 * it's a case insensitive match
850 * returns true if any object has been selected
853 #if defined (HAVE_REGCOMP)
854 static int
855 regexec_match_all (const regex_t *preg, const char *string)
857 regmatch_t match;
859 if (regexec (preg, string, 1, &match, 0) != 0)
860 return 0;
861 if (match.rm_so != 0)
862 return 0;
863 if (match.rm_eo != strlen(string))
864 return 0;
865 return 1;
867 #endif
869 bool
870 SelectObjectByName (int Type, char *Pattern, bool Flag)
872 bool changed = false;
874 #if defined(HAVE_REGCOMP)
875 #define REGEXEC(arg) (regexec_match_all(&compiled, (arg)))
877 int result;
878 regex_t compiled;
880 /* compile the regular expression */
881 result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE);
882 if (result)
884 char errorstring[128];
886 regerror (result, &compiled, errorstring, 128);
887 Message (_("regexp error: %s\n"), errorstring);
888 regfree (&compiled);
889 return (false);
891 #else
892 #define REGEXEC(arg) (re_exec((arg)) == 1)
894 char *compiled;
896 /* compile the regular expression */
897 if ((compiled = re_comp (Pattern)) != NULL)
899 Message (_("re_comp error: %s\n"), compiled);
900 return (false);
902 #endif
904 /* loop over all visible objects with names */
905 if (Type & TEXT_TYPE)
906 ALLTEXT_LOOP (PCB->Data);
908 if (!TEST_FLAG (LOCKFLAG, text)
909 && TEXT_IS_VISIBLE (PCB, layer, text)
910 && text->TextString
911 && REGEXEC (text->TextString)
912 && TEST_FLAG (SELECTEDFLAG, text) != Flag)
914 AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
915 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
916 DrawText (layer, text, 0);
917 changed = true;
920 ENDALL_LOOP;
922 if (PCB->ElementOn && (Type & ELEMENT_TYPE))
923 ELEMENT_LOOP (PCB->Data);
925 if (!TEST_FLAG (LOCKFLAG, element)
926 && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
927 || PCB->InvisibleObjectsOn)
928 && TEST_FLAG (SELECTEDFLAG, element) != Flag)
930 String name = ELEMENT_NAME (PCB, element);
931 if (name && REGEXEC (name))
933 AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
934 ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
935 PIN_LOOP (element);
937 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
938 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
940 END_LOOP;
941 PAD_LOOP (element);
943 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
944 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
946 END_LOOP;
947 ELEMENTTEXT_LOOP (element);
949 AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
950 ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
952 END_LOOP;
953 DrawElementName (element, 0);
954 DrawElement (element, 0);
955 changed = true;
959 END_LOOP;
960 if (PCB->PinOn && (Type & PIN_TYPE))
961 ALLPIN_LOOP (PCB->Data);
963 if (!TEST_FLAG (LOCKFLAG, element)
964 && pin->Name && REGEXEC (pin->Name)
965 && TEST_FLAG (SELECTEDFLAG, pin) != Flag)
967 AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
968 ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
969 DrawPin (pin, 0);
970 changed = true;
973 ENDALL_LOOP;
974 if (PCB->PinOn && (Type & PAD_TYPE))
975 ALLPAD_LOOP (PCB->Data);
977 if (!TEST_FLAG (LOCKFLAG, element)
978 && ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT
979 || PCB->InvisibleObjectsOn)
980 && TEST_FLAG (SELECTEDFLAG, pad) != Flag)
981 if (pad->Name && REGEXEC (pad->Name))
983 AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
984 ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
985 DrawPad (pad, 0);
986 changed = true;
989 ENDALL_LOOP;
990 if (PCB->ViaOn && (Type & VIA_TYPE))
991 VIA_LOOP (PCB->Data);
993 if (!TEST_FLAG (LOCKFLAG, via)
994 && via->Name
995 && REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag)
997 AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
998 ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
999 DrawVia (via, 0);
1000 changed = true;
1003 END_LOOP;
1005 #if defined(HAVE_REGCOMP)
1006 #if !defined(sgi)
1007 regfree (&compiled);
1008 #endif
1009 #endif
1011 if (changed)
1013 IncrementUndoSerialNumber ();
1014 Draw ();
1016 return (changed);
1018 #endif /* defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP) */