/* * COPYRIGHT * * pcb-rnd, interactive printed circuit board design * (this file is based on PCB, interactive printed circuit board design) * Copyright (C) 1994,1995,1996 Thomas Nau * Copyright (C) 1997, 1998, 1999, 2000, 2001 Harry Eaton * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Contact: * Project page: http://repo.hu/projects/pcb-rnd * lead developer: http://repo.hu/projects/pcb-rnd/contact.html * mailing list: pcb-rnd (at) list.repo.hu (send "subscribe") * * * Old contact info: * Harry Eaton, 6697 Buttonhole Ct, Columbia, MD 21044, USA * haceaton@aplcomm.jhuapl.edu * */ #include "config.h" #include "conf_core.h" #include "board.h" #include "data.h" #include #include "undo.h" #include "find.h" #include "remove.h" #include "funchash_core.h" #include "obj_rat.h" #include #include #include "netlist.h" #include "draw.h" #include "obj_rat_draw.h" static const char pcb_acts_AddRats[] = "AddRats(AllRats|SelectedRats|Close, [manhattan])"; static const char pcb_acth_AddRats[] = "Add one or more rat lines to the board."; /* DOC: addrats.html */ static fgw_error_t pcb_act_AddRats(fgw_arg_t *res, int argc, fgw_arg_t *argv) { int op, flgs = PCB_RATACC_PRECISE; const char *opts = NULL; pcb_rat_t *shorty; float len, small; RND_ACT_CONVARG(1, FGW_KEYWORD, AddRats, op = fgw_keyword(&argv[1])); TODO("toporouter: autorotuer: remove this when the old autorouter is removed"); /* temporary hack for the old autorouter */ RND_ACT_MAY_CONVARG(2, FGW_STR, AddRats, opts = argv[2].val.str); if ((opts != NULL) && (opts[0] == 'm')) flgs = PCB_RATACC_ONLY_MANHATTAN; if (conf_core.temp.rat_warn) { pcb_data_clear_flag(PCB->Data, PCB_FLAG_WARN, 1, 0); pcb_draw(); } switch (op) { case F_AllRats: if (pcb_net_add_all_rats(PCB, flgs | PCB_RATACC_INFO) > 0) pcb_board_set_changed_flag(PCB, rnd_true); break; case F_SelectedRats: case F_Selected: if (pcb_net_add_all_rats(PCB, flgs | PCB_RATACC_INFO | PCB_RATACC_ONLY_SELECTED) > 0) pcb_board_set_changed_flag(PCB, rnd_true); break; case F_Close: small = RND_SQUARE(RND_MAX_COORD); shorty = NULL; PCB_RAT_LOOP(PCB->Data); { if (PCB_FLAG_TEST(PCB_FLAG_SELECTED, line)) continue; len = RND_SQUARE(line->Point1.X - line->Point2.X) + RND_SQUARE(line->Point1.Y - line->Point2.Y); if (len < small) { small = len; shorty = line; } } PCB_END_LOOP; if (shorty) { pcb_undo_add_obj_to_flag(shorty); PCB_FLAG_SET(PCB_FLAG_SELECTED, shorty); pcb_rat_invalidate_draw(shorty); pcb_draw(); pcb_center_display(PCB, (shorty->Point2.X + shorty->Point1.X) / 2, (shorty->Point2.Y + shorty->Point1.Y) / 2); } break; default: RND_ACT_FAIL(AddRats); } RND_ACT_IRES(0); return 0; } static const char pcb_acts_Connection[] = "Connection(Find|ResetLinesAndPolygons|ResetPinsAndVias|Reset)"; static const char pcb_acth_Connection[] = "Searches connections of the object at the cursor position."; /* DOC: connection.html */ static fgw_error_t pcb_act_Connection(fgw_arg_t *res, int argc, fgw_arg_t *argv) { int op; RND_ACT_CONVARG(1, FGW_KEYWORD, Connection, op = fgw_keyword(&argv[1])); switch(op) { case F_Find: { rnd_coord_t x, y; unsigned long res; pcb_find_t fctx; rnd_hid_get_coords("Click on a connection", &x, &y, 0); memset(&fctx, 0, sizeof(fctx)); fctx.flag_set = PCB_FLAG_FOUND; fctx.flag_chg_undoable = 1; fctx.consider_rats = !!conf_core.editor.conn_find_rat; res = pcb_find_from_xy(&fctx, PCB->Data, x, y); if (res == -1) rnd_message(RND_MSG_INFO, "nothing found there\n"); else if (res == 1) rnd_message(RND_MSG_INFO, "found 1 object\n"); else rnd_message(RND_MSG_INFO, "found %ld objects\n", res); pcb_find_free(&fctx); break; } case F_ResetLinesAndPolygons: case F_ResetLayerObjects: if (pcb_data_clear_obj_flag(PCB->Data, PCB_OBJ_LINE | PCB_OBJ_ARC | PCB_OBJ_POLY | PCB_OBJ_TEXT, PCB_FLAG_FOUND, 1, 1) > 0) { pcb_undo_inc_serial(); pcb_draw(); } break; case F_ResetPinsViasAndPads: case F_ResetPadstacks: if (pcb_data_clear_obj_flag(PCB->Data, PCB_OBJ_PSTK, PCB_FLAG_FOUND, 1, 1) > 0) { pcb_undo_inc_serial(); pcb_draw(); } break; case F_Reset: if (pcb_data_clear_flag(PCB->Data, PCB_FLAG_FOUND, 1, 1) > 0) { pcb_undo_inc_serial(); pcb_draw(); } break; default: RND_ACT_FAIL(Connection); } RND_ACT_IRES(0); return 0; } static const char pcb_acts_DeleteRats[] = "DeleteRats(AllRats|Selected|SelectedRats)"; static const char pcb_acth_DeleteRats[] = "Delete rat lines."; static fgw_error_t pcb_act_DeleteRats(fgw_arg_t *res, int argc, fgw_arg_t *argv) { int op; RND_ACT_CONVARG(1, FGW_KEYWORD, DeleteRats, op = fgw_keyword(&argv[1])); if (conf_core.temp.rat_warn) { pcb_data_clear_flag(PCB->Data, PCB_FLAG_WARN, 1, 0); pcb_draw(); } switch(op) { case F_AllRats: if (pcb_rats_destroy(rnd_false)) pcb_board_set_changed_flag(PCB, rnd_true); break; case F_SelectedRats: case F_Selected: if (pcb_rats_destroy(rnd_true)) pcb_board_set_changed_flag(PCB, rnd_true); break; default: RND_ACT_FAIL(DeleteRats); } RND_ACT_IRES(0); return 0; } static rnd_action_t rats_action_list[] = { {"AddRats", pcb_act_AddRats, pcb_acth_AddRats, pcb_acts_AddRats}, {"Connection", pcb_act_Connection, pcb_acth_Connection, pcb_acts_Connection}, {"DeleteRats", pcb_act_DeleteRats, pcb_acth_DeleteRats, pcb_acts_DeleteRats} }; void pcb_rats_act_init2(void) { RND_REGISTER_ACTIONS(rats_action_list, NULL); }