From f76ffa11df19e97d019ae492bff3f0cd62f3c1c6 Mon Sep 17 00:00:00 2001 From: Dan White Date: Sat, 25 Feb 2012 07:52:03 -0600 Subject: [PATCH] action.c: new UpdatePackage(Selected|All) Action will attempt to update the selected packages to use the footprint in the currently-loaded Library instead of from the .pcb file. Assumes the footprint name (newlib filename) to load is contained in the current element's "Desc" field (internally as: DESCRIPTION_NAME(element)). The new footprint's mark is placed at the same location and in the same orientation as the old footprint. The element's name, refdes, and value are preserved. NO OTHER CHECKING is done (e.g. number of pins). Reports and does not touch missing footprints. --- src/action.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/src/action.c b/src/action.c index 21725124..c075d10d 100644 --- a/src/action.c +++ b/src/action.c @@ -7172,6 +7172,182 @@ ActionElementList (int argc, char **argv, Coord x, Coord y) return 0; } + + +/* ---------------------------------------------------------------- */ +static const char updatepackage_syntax[] = "UpdatePackage(Selected|All)"; + +static const char updatepackage_help[] = "Reloads the indicated element packages."; + +/* %start-doc actions UpdatePackage + +@table @code + +@item Selected +Only updates the footprint of the selected elements from the currently-loaded +library. + +@item All +Reloads from the currently-loaded library the packages of all elements in the +layout. + +@end table + +Extracts the footprint name to load from the element's @code{Desc} field. +Preserves the old element's Desc, Name, and Value fields. + +%end-doc */ + +static int update_footprints_not_found; + +static int +ActionUpdatePackage (int argc, char **argv, Coord x, Coord y) +{ + char *function = NULL; + int fnid; + int er, pr; + ElementType *pe = NULL; + Coord mx, my; + int i; + char *old; + + function = ARG(0); + update_footprints_not_found = 0; + +#ifdef DEBUG + printf("Entered ActionUpdatePackage, executing function %s\n", function); +#endif + + if (function) + { + fnid = GetFunctionID (function); + if ( !(fnid == F_All || fnid == F_Selected)) + AFAIL (updatepackage); + } + else + { + AFAIL (updatepackage); + } + + /* Select all elements for All mode */ + if (fnid == F_All) + SelectObjectByName (ELEMENT_TYPE, ".*", true); + + /* Flag all original elements, we are adding more but don't want to process + * the new ones*/ + ELEMENT_LOOP (PCB->Data); + { + SET_FLAG(VISITFLAG, element); + } + END_LOOP; + + + ELEMENT_LOOP (PCB->Data); + { + /* All elements (from here on ??) were added in previous iterations of this + * loop; we are done. */ + if (!TEST_FLAG(VISITFLAG, element)) + break; + + /* Only touch selected elements. */ + if (!TEST_FLAG (SELECTEDFLAG, element)) + continue; + + /* no element name, it's likely not something we wish to change skip */ + if (EMPTY_STRING_P (NAMEONPCB_NAME (element))) + continue; + + if (EMPTY_STRING_P (DESCRIPTION_NAME (element))) + { + Message (_("Skipping refdes %s, no footprint name\n"), NAMEONPCB_NAME (element)); + continue; + } + + if (EMPTY_STRING_P (VALUE_NAME (element))) + { + Message (_("For refdes %s, no value\n"), NAMEONPCB_NAME (element)); + } + + /* to get here, this is a footprint element (??) */ + + /* do not touch element if not in current library */ + if (LoadFootprint(1, &DESCRIPTION_NAME(element), x, y)) + { + update_footprints_not_found ++; + Message (_("Footprint not found: %s\n"), DESCRIPTION_NAME(element)); + continue; + } + + /* all good, now update the package */ + Message (_("Updating footprint for (%s, %s, %s).\n"), + NAMEONPCB_NAME(element), + VALUE_NAME(element), + DESCRIPTION_NAME(element) + ); + + /* in the method of ElementList(Need,...) */ + pe = PASTEBUFFER->Data->Element->data; + if (!FRONT (element)) + MirrorElementCoordinates (PASTEBUFFER->Data, pe, pe->MarkY*2 - PCB->MaxHeight); + + er = ElementOrientation (element); + pr = ElementOrientation (pe); + if (er != pr) + RotateElementLowLevel (PASTEBUFFER->Data, pe, pe->MarkX, pe->MarkY, (er-pr+4)%4); + + /* move element parts to their previous locations */ + mx = element->MarkX; + my = element->MarkY; + for (i=0; iName[i].X = element->Name[i].X - mx + pe->MarkX ; + pe->Name[i].Y = element->Name[i].Y - my + pe->MarkY ; + pe->Name[i].Direction = element->Name[i].Direction; + pe->Name[i].Scale = element->Name[i].Scale; + } + + /* preserve attributes */ + for (i=0; iAttributes.Number; i++) + { + CreateNewAttribute (& pe->Attributes, + element->Attributes.List[i].name, + element->Attributes.List[i].value); + } + + /* preserve name, refdes, and value */ + old = ChangeElementText (PCB, PASTEBUFFER->Data, pe, DESCRIPTION_INDEX, + strdup (DESCRIPTION_NAME(element))); + if (old) free(old); + old = ChangeElementText (PCB, PASTEBUFFER->Data, pe, NAMEONPCB_INDEX, + strdup (NAMEONPCB_NAME(element))); + if (old) free(old); + old = ChangeElementText (PCB, PASTEBUFFER->Data, pe, VALUE_INDEX, + strdup (VALUE_NAME(element))); + if (old) free(old); + + /* who needs old data? */ + RemoveElement (element); + + /* place in layout */ + if (CopyPastebufferToLayout (mx, my)) + SetChangedFlag (true); + + } + END_LOOP; + + if (update_footprints_not_found > 0) + { + gui->confirm_dialog (_("Not all requested footprints were found.\n" + "See the message log for details"), 0); + } + +#ifdef DEBUG + printf(" ... Leaving ActionUpdatePackage.\n"); +#endif + return 0; +} + + /* ---------------------------------------------------------------- */ static const char elementsetattr_syntax[] = "ElementSetAttr(refdes,name[,value])"; @@ -8187,6 +8363,9 @@ HID_Action action_action_list[] = { {"ElementSetAttr", 0, ActionElementSetAttr, elementsetattr_help, elementsetattr_syntax} , + {"UpdatePackage", 0, ActionUpdatePackage, + updatepackage_help, updatepackage_syntax} + , {"ExecCommand", 0, ActionExecCommand, execcommand_help, execcommand_syntax} , -- 2.11.4.GIT