Index: trunk/scconfig/Rev.h =================================================================== --- trunk/scconfig/Rev.h (revision 31707) +++ trunk/scconfig/Rev.h (revision 31708) @@ -1 +1 @@ -static const int myrev = 31623; +static const int myrev = 31708; Index: trunk/scconfig/Rev.tab =================================================================== --- trunk/scconfig/Rev.tab (revision 31707) +++ trunk/scconfig/Rev.tab (revision 31708) @@ -1,3 +1,4 @@ +31708 configure query plugin: move the advanced search dialog from dialogs plugin to query to better access of internals 31623 configure query plugin: net length calculations 31519 configure io_tedax drc block upgrade for drc_query 31420 configure online support plugin (irc) and lib for IPv4/tcp Index: trunk/src/Makefile.dep =================================================================== --- trunk/src/Makefile.dep (revision 31707) +++ trunk/src/Makefile.dep (revision 31708) @@ -1094,7 +1094,7 @@ idpath.h obj_subc_list.h obj_subc.h ../src_3rd/libminuid/libminuid.h \ ht_subc.h ../src_3rd/genht/ht.h obj_pstk_list.h obj_pstk.h vtpadstack.h \ draw.h obj_term.h search.h search_r.h netlist.h \ - ../src_plugins/dialogs/dlg_search.h ../src_plugins/dialogs/dlg_undo.c \ + ../src_plugins/dialogs/dlg_undo.c \ ../src_3rd/libuundo/uundo.h event.h librnd/core/event.h undo.h \ undo_old.h ../src_plugins/dialogs/dlg_fpmap.c actions_pcb.h \ plug_footprint.h vtlibrary.h plug_io.h ../src_3rd/genvector/vts0.h \ @@ -1462,7 +1462,7 @@ ../src_plugins/lib_hid_common/dialogs_conf.h \ ../src_plugins/dialogs/dlg_pref_conf.c \ ../src_plugins/dialogs/dlg_pref_confedit.c librnd/core/hid_dad_unit.h -../src_plugins/dialogs/dlg_search.o: ../src_plugins/dialogs/dlg_search.c \ +../src_plugins/dialogs/dlg_search.o: \ ../config.h librnd/config.h ../src_3rd/genvector/gds_char.h \ ../src_3rd/genvector/genvector_impl.h \ ../src_3rd/genvector/genvector_undef.h librnd/core/actions.h \ @@ -1485,8 +1485,8 @@ obj_arc.h obj_line_list.h obj_line.h obj_poly_list.h obj_poly.h \ librnd/poly/polyarea.h obj_text_list.h obj_text.h font.h \ ../src_3rd/genht/htip.h obj_gfx_list.h obj_gfx.h layer_grp.h \ - rats_patch.h board.h ../src_plugins/dialogs/dlg_search_tab.h \ - ../src_plugins/dialogs/dlg_search_edit.c librnd/core/hid_dad_tree.h \ + rats_patch.h board.h \ + librnd/core/hid_dad_tree.h \ ../src_3rd/genht/hash.h ../src_plugins/dialogs/dlg_view.o: ../src_plugins/dialogs/dlg_view.c \ ../config.h librnd/config.h ../src_3rd/genht/htsp.h \ Index: trunk/src_plugins/dialogs/dlg_search_tab.h =================================================================== --- trunk/src_plugins/dialogs/dlg_search_tab.h (revision 31707) +++ trunk/src_plugins/dialogs/dlg_search_tab.h (nonexistent) @@ -1,203 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas - * - * 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 Street, 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") - */ - -/* advanced search dialog - expressioin wizard tables; intended to be - included from the search dialog only */ - -typedef enum { - RIGHT_STR, - RIGHT_INT, - RIGHT_DOUBLE, - RIGHT_COORD, - RIGHT_CONST, - RIGHT_max -} right_type; - -typedef enum { - OPS_ANY, - OPS_EQ, - OPS_STR -} op_type_t; - -static const char *ops_any[] = {"==", "!=", ">=", "<=", ">", "<", NULL}; -static const char *ops_eq[] = {"==", "!=", NULL}; -static const char *ops_str[] = {"==", "!=", "~", NULL}; - -typedef struct expr_wizard_op_s expr_wizard_op_t; -struct expr_wizard_op_s { - const char **ops; -}; - -static expr_wizard_op_t op_tab[] = { - {ops_any}, - {ops_eq}, - {ops_str}, - {NULL} -}; - -typedef struct expr_wizard_s expr_wizard_t; -struct expr_wizard_s { - const char *left_var; - const char *left_desc; - const expr_wizard_op_t *op; - right_type rtype; - const expr_wizard_op_t *right_const; -}; - -static const char *right_const_objtype[] = { "POINT", "LINE", "TEXT", "POLYGON", "ARC", "RAT", "NET", "LAYER", NULL }; -static const char *right_const_yesno[] = {"YES", "NO", NULL}; -static const char *right_const_10[] = {"1", "0", NULL}; -static const char *right_const_layerpos[] = {"TOP", "BOTTOM", "INTERNAL", NULL}; -static const char *right_const_layertype[] = {"COPPER", "SILK", "MASK", "PASTE", "BOUNDARY", "MECH", "DOC" , NULL}; -static const char *right_const_side[] = {"TOP", "BOTTOM", NULL}; - -enum { - RC_OBJTYPE, - RC_YESNO, - RC_10, - RC_LAYERPOS, - RC_LAYERTYPE, - RC_SIDE -}; - -static expr_wizard_op_t right_const_tab[] = { - {right_const_objtype}, - {right_const_yesno}, - {right_const_10}, - {right_const_layerpos}, - {right_const_layertype}, - {right_const_side}, - {NULL} -}; - -static const expr_wizard_t expr_tab[] = { - {"@.ID", "object ID", &op_tab[OPS_ANY], RIGHT_INT, NULL}, - {"@.type", "object type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_OBJTYPE]}, - - {NULL, "bounding box", NULL, 0, NULL}, - {"@.bbox.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.bbox.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.bbox.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.bbox.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.bbox.w", "width", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.bbox.h", "height", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - - - {NULL, "trace object's", NULL, 0, NULL}, - {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.clearance", "clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.length", "length", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - - {NULL, "line", NULL, 0, NULL}, - {"@.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - - {NULL, "arc", NULL, 0, NULL}, - {"@.x", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.angle.start", "start angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.angle.delta", "delta angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - - {NULL, "text", NULL, 0, NULL}, - {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.scale", "scale", &op_tab[OPS_ANY], RIGHT_INT, NULL}, - {"@.scale_x", "scale_x", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.scale_y", "scale_y", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.string", "string", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - - {NULL, "polygon", NULL, 0, NULL}, - {"@.points", "points", &op_tab[OPS_ANY], RIGHT_INT, NULL}, - - {NULL, "padstack", NULL, 0, NULL}, - {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.clearance", "global clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.xmirror", "x coords mirrored",&op_tab[OPS_ANY], RIGHT_INT, NULL}, - {"@.smirror", "stackup mirrored", &op_tab[OPS_ANY], RIGHT_INT, NULL}, - {"@.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.number", "number", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.hole", "proto: hole dia", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.plated", "proto: is plated?",&op_tab[OPS_ANY], RIGHT_INT, NULL}, - - {NULL, "subcircuit", NULL, 0, NULL}, - {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, - {"@.a.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.a.footprint", "footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.a.value", "value", &op_tab[OPS_STR], RIGHT_STR, NULL}, - - {NULL, "gfx", NULL, 0, NULL}, - {"@.cx", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.cy", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.sx", "size X (width)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.sy", "size Y (height)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.rot", "rotation angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - - {NULL, "host layer's", NULL, 0, NULL}, - {"@.layer.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.layer.visible", "visible", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_YESNO]}, - {"@.layer.position", "stack position", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERPOS]}, - {"@.layer.type", "type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERTYPE]}, - {"@.layer.purpose", "purpose", &op_tab[OPS_STR], RIGHT_STR, NULL}, - - {NULL, "host subcircuit's",NULL, 0, NULL}, - {"@.subc.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.subc.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, - {"@.subc.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, - {"@.subc.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, - {"@.subc.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.subc.footprint", "a.footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, - {"@.subc.value", "a.value", &op_tab[OPS_STR], RIGHT_STR, NULL}, - - {NULL, "flag", NULL, 0, NULL}, - {"@.p.flag.found", "found", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.hole", "hole", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.clearpoly","clearpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.clearline","clearline", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.selected", "selected", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.onsolder", "onsolder", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.auto", "auto", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.warn", "warn", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.drc", "drc", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.lock", "lock", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.fullpoly", "fullpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.nonetlist","nonetlist", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.termname", "termname", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.clearpolypoly","clearpolypoly",&op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.p.dyntext","dyntext", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - {"@.p.flag.p.floater","floater", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, - - {NULL, NULL, NULL, 0, NULL} -}; - Index: trunk/src_plugins/dialogs/dlg_search_edit.c =================================================================== --- trunk/src_plugins/dialogs/dlg_search_edit.c (revision 31707) +++ trunk/src_plugins/dialogs/dlg_search_edit.c (nonexistent) @@ -1,371 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * 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 Street, 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") - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -typedef struct{ - RND_DAD_DECL_NOINIT(dlg) - search_expr_t se; - int wleft, wop, wright[RIGHT_max]; - const expr_wizard_op_t *last_op; - right_type last_rtype; -} srchedit_ctx_t; - -static srchedit_ctx_t srchedit_ctx; - -/* Set the right side of the expression from the non-enum value of an widget attr */ -static void set_right(srchedit_ctx_t *ctx, rnd_hid_attribute_t *attr) -{ - free(ctx->se.right); - ctx->se.right = NULL; - - switch(ctx->se.expr->rtype) { - case RIGHT_STR: - ctx->se.right = rnd_strdup(attr->val.str); - break; - case RIGHT_INT: - ctx->se.right = rnd_strdup_printf("%d", attr->val.lng); - break; - case RIGHT_DOUBLE: - ctx->se.right = rnd_strdup_printf("%f", attr->val.dbl); - break; - case RIGHT_COORD: - ctx->se.right = rnd_strdup_printf("%$mm", attr->val.crd); - break; - case RIGHT_CONST: - case RIGHT_max: - break; - } -} - -static void srch_expr_set_ops(srchedit_ctx_t *ctx, const expr_wizard_op_t *op, int click) -{ - rnd_hid_tree_t *tree; - rnd_hid_attribute_t *attr; - rnd_hid_row_t *r, *cur = NULL; - char *cell[2], *cursor_path = NULL; - const char **o; - - if (op == ctx->last_op) - return; - - attr = &ctx->dlg[ctx->wop]; - tree = attr->wdata; - - /* remember cursor */ - if (click) { - r = rnd_dad_tree_get_selected(attr); - if (r != NULL) - cursor_path = rnd_strdup(r->cell[0]); - } - - /* remove existing items */ - rnd_dad_tree_clear(tree); - - /* add all items */ - cell[1] = NULL; - for(o = op->ops; *o != NULL; o++) { - cell[0] = rnd_strdup_printf(*o); - r = rnd_dad_tree_append(attr, NULL, cell); - r->user_data = (void *)(*o); /* will be casted back to const char * only */ - if ((!click) && (ctx->se.op == *o)) - cur = r; - } - - /* restore cursor */ - if (cursor_path != NULL) { - rnd_hid_attr_val_t hv; - hv.str = cursor_path; - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wop, &hv); - free(cursor_path); - } - if (cur != NULL) - rnd_dad_tree_jumpto(attr, cur); - ctx->last_op = op; -} - -static void srch_expr_fill_in_right_const(srchedit_ctx_t *ctx, const search_expr_t *s) -{ - rnd_hid_tree_t *tree; - rnd_hid_attribute_t *attr; - char *cell[2]; - const char **o; - - attr = &ctx->dlg[ctx->wright[RIGHT_CONST]]; - tree = attr->wdata; - - /* remove existing items */ - rnd_dad_tree_clear(tree); - - /* add all items */ - cell[1] = NULL; - for(o = s->expr->right_const->ops; *o != NULL; o++) { - cell[0] = rnd_strdup_printf(*o); - rnd_dad_tree_append(attr, NULL, cell); - } - - /* set cursor to last known value */ - if ((s != NULL) && (s->right != NULL)) { - rnd_hid_attr_val_t hv; - hv.str = s->right; - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], &hv); - } -} - -static void srch_expr_fill_in_right(srchedit_ctx_t *ctx, const search_expr_t *s) -{ - int n, empty = 0; - rnd_hid_attr_val_t hv; - - /* don't recalc if the same type; except for const, because there the same type means different set of values for each expr */ - if ((s->expr->rtype == ctx->last_rtype) && (s->expr->rtype != RIGHT_CONST)) - return; - - for(n = 0; n < RIGHT_max; n++) - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[n], 1); - - hv.str = ctx->se.right; - if (hv.str == NULL) { - hv.str = ""; - empty = 1; - } - - switch(s->expr->rtype) { - case RIGHT_STR: - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); - break; - case RIGHT_INT: - hv.lng = strtol(hv.str, NULL, 10); - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); - if (empty) - set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); - break; - case RIGHT_DOUBLE: - hv.dbl = strtod(hv.str, NULL); - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); - if (empty) - set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); - break; - case RIGHT_COORD: - hv.crd = rnd_get_value_ex(hv.str, NULL, NULL, NULL, "mm", NULL); - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); - if (empty) - set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); - break; - case RIGHT_CONST: srch_expr_fill_in_right_const(ctx, s); break; - case RIGHT_max: break; - } - - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], 0); - ctx->last_rtype = s->expr->rtype; -} - -static void srch_expr_left_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attrib->wdata; - srchedit_ctx_t *ctx = tree->user_ctx; - const expr_wizard_t *e; - - if (row == NULL) - return; - - e = row->user_data; - if (e->left_var == NULL) /* category */ - return; - - ctx->se.expr = e; - srch_expr_set_ops(ctx, e->op, 1); - srch_expr_fill_in_right(ctx, &ctx->se); -} - -static void srch_expr_op_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attrib->wdata; - srchedit_ctx_t *ctx = tree->user_ctx; - - if (row != NULL) - ctx->se.op = row->user_data; - else - ctx->se.op = NULL; -} - -/* the table on the left is static, needs to be filled in only once; - returns 1 if filled in op and right, else 0 */ -static int fill_in_left(srchedit_ctx_t *ctx) -{ - const expr_wizard_t *t; - rnd_hid_attribute_t *attr; - rnd_hid_row_t *r, *parent = NULL, *cur = NULL; - char *cell[2]; - - attr = &ctx->dlg[ctx->wleft]; - - cell[1] = NULL; - for(t = expr_tab; t->left_desc != NULL; t++) { - if (t->left_var == NULL) - parent = NULL; - cell[0] = rnd_strdup(t->left_desc); - if (parent != NULL) - r = rnd_dad_tree_append_under(attr, parent, cell); - else - r = rnd_dad_tree_append(attr, NULL, cell); - r->user_data = (void *)t; - if (t->left_var == NULL) - parent = r; - if (t == ctx->se.expr) - cur = r; - } - - if (cur != NULL) { - rnd_dad_tree_jumpto(attr, cur); - - /* clear all cache fields so a second window open won't inhibit refreshes */ - ctx->last_op = NULL; - ctx->last_rtype = RIGHT_max; - - srch_expr_set_ops(ctx, ctx->se.expr->op, 0); - srch_expr_fill_in_right(ctx, &ctx->se); - return 1; - } - return 0; -} - -static void srchexpr_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - srchedit_ctx_t *ctx = caller_data; - - set_right(ctx, attr); -} - -static void srch_expr_right_table_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) -{ - rnd_hid_tree_t *tree = attrib->wdata; - srchedit_ctx_t *ctx = tree->user_ctx; - - free(ctx->se.right); - ctx->se.right = NULL; - if (row != NULL) - ctx->se.right = rnd_strdup(row->cell[0]); -} - -static int srchedit_window(search_expr_t *expr) -{ - rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; - srchedit_ctx_t *ctx = &srchedit_ctx; - int res; - - ctx->se = *expr; - if (ctx->se.right != NULL) - ctx->se.right = rnd_strdup(ctx->se.right); - - /* clear all cache fields so a second window open won't inhibit refreshes */ - ctx->last_op = NULL; - ctx->last_rtype = RIGHT_max; - - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_TREE(ctx->dlg, 1, 1, NULL); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_SCROLL); - ctx->wleft = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_left_cb); - RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); - RND_DAD_END(ctx->dlg); - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_TREE(ctx->dlg, 1, 0, NULL); - ctx->wop = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_op_cb); - RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); - RND_DAD_END(ctx->dlg); - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - - RND_DAD_STRING(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wright[RIGHT_STR] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); - - RND_DAD_INTEGER(ctx->dlg, ""); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wright[RIGHT_INT] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); - RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); - - RND_DAD_REAL(ctx->dlg, ""); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wright[RIGHT_DOUBLE] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); - RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); - - RND_DAD_COORD(ctx->dlg, ""); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wright[RIGHT_COORD] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_MINMAX(ctx->dlg, -RND_MAX_COORD, RND_MAX_COORD); - RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); - - RND_DAD_TREE(ctx->dlg, 1, 0, NULL); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wright[RIGHT_CONST] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_right_table_cb); - RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); - - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_END(ctx->dlg); - RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); - RND_DAD_END(ctx->dlg); - RND_DAD_END(ctx->dlg); - - RND_DAD_DEFSIZE(ctx->dlg, 450, 450); - RND_DAD_NEW("search_expr", ctx->dlg, "pcb-rnd search expression", ctx, rnd_true, NULL); - - if (fill_in_left(ctx) != 1) { - srch_expr_set_ops(ctx, op_tab, 1); /* just to get the initial tree widget width */ - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], 0); /* just to get something harmless display on the right side after open */ - } - - res = RND_DAD_RUN(ctx->dlg); - if (res == 0) { - free(expr->right); - *expr = ctx->se; - if (ctx->se.op != NULL) - expr->valid = 1; - } - else - free(ctx->se.right); - - RND_DAD_FREE(ctx->dlg); - return res; -} - - Index: trunk/src_plugins/dialogs/dlg_search.c =================================================================== --- trunk/src_plugins/dialogs/dlg_search.c (revision 31707) +++ trunk/src_plugins/dialogs/dlg_search.c (nonexistent) @@ -1,429 +0,0 @@ -/* - * COPYRIGHT - * - * pcb-rnd, interactive printed circuit board design - * Copyright (C) 2019 Tibor 'Igor2' Palinkas - * - * 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 Street, 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") - */ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include "board.h" - -#define MAX_ROW 8 -#define MAX_COL 4 - -static const char *search_acts[] = { "select", "unselect", "view", NULL }; - -#define NEW_EXPR_LAB "" - -/* for debugging: */ -/*#define NEW_EXPR_LAB rnd_strdup_printf("%d:%d", row, col)*/ - -#include "dlg_search_tab.h" - -typedef struct { - int valid; - const expr_wizard_t *expr; - const char *op; - char *right; -} search_expr_t; - -typedef struct{ - RND_DAD_DECL_NOINIT(dlg) - int wexpr_str, wwizard, wact; - int wrowbox[MAX_ROW]; - int wexpr[MAX_ROW][MAX_COL]; /* expression framed box */ - int wexpr_lab[MAX_ROW][MAX_COL]; /* the label within the expression box */ - int wexpr_del[MAX_ROW][MAX_COL], wexpr_edit[MAX_ROW][MAX_COL]; /* expression buttons */ - int wor[MAX_ROW][MAX_COL]; /* before the current col */ - int wand[MAX_ROW]; /* before the current row */ - int wnew_or[MAX_ROW], wnew_and; - int visible[MAX_ROW][MAX_COL]; - search_expr_t expr[MAX_ROW][MAX_COL]; -} search_ctx_t; - -#define WIZ(ctx) (ctx->dlg[ctx->wwizard].val.lng) - -#include "dlg_search_edit.c" - -static void free_expr(search_expr_t *e) -{ - free(e->right); - memset(e, 0, sizeof(search_expr_t)); -} - -static void search_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) -{ - int r, c; - search_ctx_t *ctx = caller_data; - for(r = 0; r < MAX_ROW; r++) - for(c = 0; c < MAX_COL; c++) - free_expr(&ctx->expr[r][c]); - free(ctx); -} - -static void hspacer(search_ctx_t *ctx) -{ - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_END(ctx->dlg); -} - -static void vspacer(search_ctx_t *ctx) -{ - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_END(ctx->dlg); -} - -static void update_vis(search_ctx_t *ctx) -{ - int c, r, wen; - - wen = WIZ(ctx); - - for(r = 0; r < MAX_ROW; r++) { - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wrowbox[r],!ctx->visible[r][0]); - for(c = 0; c < MAX_COL; c++) { - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wexpr[r][c], !ctx->visible[r][c]); - if (c > 0) - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wor[r][c], !((ctx->visible[r][c-1] && ctx->visible[r][c]))); - rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_del[r][c], wen); - rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_edit[r][c], wen); - } - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnew_or[r], !ctx->visible[r][0]); - if (r > 0) - rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wand[r], !((ctx->visible[r-1][0] && ctx->visible[r][0]))); - rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_or[r], wen); - } - rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_and, wen); - rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_str, !wen); -} - -/* look up row and col for a widget attr in a [row][col] widget idx array; returns 0 on success */ -static int rc_lookup(search_ctx_t *ctx, int w[MAX_ROW][MAX_COL], rnd_hid_attribute_t *attr, int *row, int *col) -{ - int r, c, idx = attr - ctx->dlg; - for(r = 0; r < MAX_ROW; r++) { - for(c = 0; c < MAX_COL; c++) { - if (w[r][c] == idx) { - *row = r; - *col = c; - return 0; - } - } - } - return -1; -} - -/* look up row for a widget attr in a [row] widget idx array; returns 0 on success */ -static int r_lookup(search_ctx_t *ctx, int w[MAX_ROW], rnd_hid_attribute_t *attr, int *row) -{ - int r, idx = attr - ctx->dlg; - for(r = 0; r < MAX_ROW; r++) { - if (w[r] == idx) { - *row = r; - return 0; - } - } - return -1; -} - -static void append_expr(gds_t *dst, search_expr_t *e, int sepchar) -{ - gds_append_str(dst, e->expr->left_var); - gds_append(dst, sepchar); - gds_append_str(dst, e->op); - gds_append(dst, sepchar); - gds_append_str(dst, e->right); -} - -static void redraw_expr(search_ctx_t *ctx, int row, int col) -{ - rnd_hid_attr_val_t hv; - gds_t buf; - search_expr_t *e = &(ctx->expr[row][col]); - - if (e->valid) { - gds_init(&buf); - append_expr(&buf, e, '\n'); - hv.str = buf.array; - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); - gds_uninit(&buf); - } - else { - hv.str = NEW_EXPR_LAB; - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); - } -} - -static void search_recompile(search_ctx_t *ctx) -{ - rnd_hid_attr_val_t hv; - gds_t buf; - int row, col; - - gds_init(&buf); - for(row = 0; row < MAX_ROW; row++) { - if (!ctx->visible[row][0] || !ctx->expr[row][0].valid) - continue; - if (row > 0) - gds_append_str(&buf, " && "); - gds_append(&buf, '('); - for(col = 0; col < MAX_COL; col++) { - if (!ctx->visible[row][col] || !ctx->expr[row][col].valid) - continue; - if (col > 0) - gds_append_str(&buf, " || "); - gds_append(&buf, '('); - append_expr(&buf, &(ctx->expr[row][col]), ' '); - gds_append(&buf, ')'); - } - gds_append(&buf, ')'); - } - hv.str = buf.array; - rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_str, &hv); - gds_uninit(&buf); -} - -static void search_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - int row, col; - - if (rc_lookup(ctx, ctx->wexpr_del, attr, &row, &col) != 0) - return; - - free_expr(&(ctx->expr[row][col])); - for(;col < MAX_COL-1; col++) { - if (!ctx->visible[row][col+1]) { - ctx->visible[row][col] = 0; - memset(&ctx->expr[row][col], 0, sizeof(search_expr_t)); - break; - } - ctx->expr[row][col] = ctx->expr[row][col+1]; - redraw_expr(ctx, row, col); - } - update_vis(ctx); - search_recompile(ctx); -} - -static void search_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - int row, col; - search_expr_t *e; - - if (rc_lookup(ctx, ctx->wexpr_edit, attr, &row, &col) != 0) - return; - - e = &(ctx->expr[row][col]); - if (srchedit_window(e) == 0) { - redraw_expr(ctx, row, col); - search_recompile(ctx); - } -} - -static void search_enable_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - if (WIZ(ctx)) - search_recompile(ctx); /* overwrite the edit box just in case the user had something custom in it */ - update_vis(ctx); -} - -static void search_append_col_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - int row, col; - - if (r_lookup(ctx, ctx->wnew_or, attr, &row) != 0) - return; - - for(col = 0; col < MAX_COL; col++) { - if (!ctx->visible[row][col]) { - ctx->visible[row][col] = 1; - redraw_expr(ctx, row, col); - update_vis(ctx); - search_recompile(ctx); - return; - } - } - rnd_message(RND_MSG_ERROR, "Too many expressions in the row, can not add more\n"); -} - -static void search_append_row_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - int row; - - for(row = 0; row < MAX_ROW; row++) { - if (!ctx->visible[row][0]) { - ctx->visible[row][0] = 1; - redraw_expr(ctx, row, 0); - update_vis(ctx); - search_recompile(ctx); - return; - } - } - rnd_message(RND_MSG_ERROR, "Too many expression rows, can not add more\n"); -} - -static void search_apply_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) -{ - search_ctx_t *ctx = caller_data; - if (ctx->dlg[ctx->wexpr_str].val.str != NULL) - rnd_actionva(&PCB->hidlib, "query", search_acts[ctx->dlg[ctx->wact].val.lng], ctx->dlg[ctx->wexpr_str].val.str, NULL); -} - - -static const char *icon_del[] = { -"5 5 2 1", -" c None", -"+ c #FF0000", -"+ +", -" + + ", -" + ", -" + + ", -"+ +", -}; - -static const char *icon_edit[] = { -"5 5 2 1", -" c None", -"+ c #000000", -"++++ ", -"+ ", -"+++ ", -"+ ", -"++++ ", -}; - -static void search_window_create(void) -{ - rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; - search_ctx_t *ctx = calloc(sizeof(search_ctx_t), 1); - int row, col; - - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); - RND_DAD_LABEL(ctx->dlg, "Query expression:"); - RND_DAD_STRING(ctx->dlg); - RND_DAD_WIDTH_CHR(ctx->dlg, 64); - ctx->wexpr_str = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_LABEL(ctx->dlg, "Action on the results:"); - RND_DAD_ENUM(ctx->dlg, search_acts); - ctx->wact = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_END(ctx->dlg); - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_EXPFILL | RND_HATF_SCROLL); - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_LABEL(ctx->dlg, "Enable the wizard:"); - RND_DAD_BOOL(ctx->dlg, ""); - ctx->wwizard = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_DEFAULT_NUM(ctx->dlg, 1); - RND_DAD_CHANGE_CB(ctx->dlg, search_enable_cb); - RND_DAD_END(ctx->dlg); - for(row = 0; row < MAX_ROW; row++) { - if (row > 0) { - RND_DAD_BEGIN_HBOX(ctx->dlg); - ctx->wand[row] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_HIDE); - RND_DAD_LABEL(ctx->dlg, "AND"); - RND_DAD_END(ctx->dlg); - } - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, /*RND_HATF_EXPFILL | */RND_HATF_HIDE); - ctx->wrowbox[row] = RND_DAD_CURRENT(ctx->dlg); - for(col = 0; col < MAX_COL; col++) { - ctx->visible[row][col] = 0; - if (col > 0) { - RND_DAD_LABEL(ctx->dlg, " OR "); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wor[row][col] = RND_DAD_CURRENT(ctx->dlg); - } - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_TIGHT | RND_HATF_HIDE); - ctx->wexpr[row][col] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_LABEL(ctx->dlg, NEW_EXPR_LAB); - ctx->wexpr_lab[row][col] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_BEGIN_VBOX(ctx->dlg); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); - RND_DAD_PICBUTTON(ctx->dlg, icon_del); - RND_DAD_HELP(ctx->dlg, "Remove expression"); - ctx->wexpr_del[row][col] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_CHANGE_CB(ctx->dlg, search_del_cb); - RND_DAD_PICBUTTON(ctx->dlg, icon_edit); - RND_DAD_HELP(ctx->dlg, "Edit expression"); - ctx->wexpr_edit[row][col] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_CHANGE_CB(ctx->dlg, search_edit_cb); - RND_DAD_END(ctx->dlg); - RND_DAD_END(ctx->dlg); - } - hspacer(ctx); - RND_DAD_BUTTON(ctx->dlg, "append OR"); - RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); - ctx->wnew_or[row] = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_CHANGE_CB(ctx->dlg, search_append_col_cb); - RND_DAD_END(ctx->dlg); - } - vspacer(ctx); - RND_DAD_BUTTON(ctx->dlg, "append AND"); - ctx->wnew_and = RND_DAD_CURRENT(ctx->dlg); - RND_DAD_CHANGE_CB(ctx->dlg, search_append_row_cb); - RND_DAD_END(ctx->dlg); - RND_DAD_BEGIN_HBOX(ctx->dlg); - RND_DAD_BUTTON(ctx->dlg, "Apply"); - RND_DAD_CHANGE_CB(ctx->dlg, search_apply_cb); - RND_DAD_HELP(ctx->dlg, "Execute the search expression\nusing the selected action"); - hspacer(ctx); - RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); - RND_DAD_END(ctx->dlg); - RND_DAD_END(ctx->dlg); - - RND_DAD_DEFSIZE(ctx->dlg, 300, 350); - RND_DAD_NEW("search", ctx->dlg, "pcb-rnd search", ctx, rnd_false, search_close_cb); - - ctx->visible[0][0] = 1; - update_vis(ctx); - search_recompile(ctx); -} - - -const char pcb_acts_SearchDialog[] = "SearchDialog()\n"; -const char pcb_acth_SearchDialog[] = "Open the log dialog."; -fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) -{ - search_window_create(); - RND_ACT_IRES(0); - return 0; -} - - Index: trunk/src_plugins/dialogs/dlg_search.h =================================================================== --- trunk/src_plugins/dialogs/dlg_search.h (revision 31707) +++ trunk/src_plugins/dialogs/dlg_search.h (nonexistent) @@ -1,4 +0,0 @@ -extern const char pcb_acts_SearchDialog[]; -extern const char pcb_acth_SearchDialog[]; -fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); - Index: trunk/src_plugins/dialogs/Plug.tmpasm =================================================================== --- trunk/src_plugins/dialogs/Plug.tmpasm (revision 31707) +++ trunk/src_plugins/dialogs/Plug.tmpasm (revision 31708) @@ -13,7 +13,6 @@ $(PLUGDIR)/dialogs/dlg_loadsave.o $(PLUGDIR)/dialogs/dlg_padstack.o $(PLUGDIR)/dialogs/dlg_pref.o - $(PLUGDIR)/dialogs/dlg_search.o $(PLUGDIR)/dialogs/dlg_view.o @] Index: trunk/src_plugins/dialogs/dialogs.c =================================================================== --- trunk/src_plugins/dialogs/dialogs.c (revision 31707) +++ trunk/src_plugins/dialogs/dialogs.c (revision 31708) @@ -53,7 +53,6 @@ #include "dlg_loadsave.h" #include "dlg_padstack.h" #include "dlg_pinout.c" -#include "dlg_search.h" #include "dlg_undo.c" #include "dlg_fpmap.c" #include "dlg_obj_list.c" @@ -94,7 +93,6 @@ {"Load", pcb_act_Load, pcb_acth_Load, pcb_acts_Load}, {"Save", pcb_act_Save, pcb_acth_Save, pcb_acts_Save}, {"LibraryDialog", pcb_act_LibraryDialog, pcb_acth_LibraryDialog, pcb_acts_LibraryDialog}, - {"SearchDialog", pcb_act_SearchDialog, pcb_acth_SearchDialog, pcb_acts_SearchDialog}, {"InfoBarFileChanged", pcb_act_InfoBarFileChanged, pcb_acth_InfoBarFileChanged, pcb_acts_InfoBarFileChanged}, {"dlg_obj_list", pcb_act_dlg_obj_list, pcb_acth_dlg_obj_list, pcb_acts_dlg_obj_list}, {"gui_fpmap_choose", pcb_act_gui_fpmap_choose, pcb_acth_gui_fpmap_choose, pcb_acts_gui_fpmap_choose} Index: trunk/src_plugins/query/Plug.tmpasm =================================================================== --- trunk/src_plugins/query/Plug.tmpasm (revision 31707) +++ trunk/src_plugins/query/Plug.tmpasm (revision 31708) @@ -10,6 +10,7 @@ $(PLUGDIR)/query/net_int.o $(PLUGDIR)/query/net_len.o $(PLUGDIR)/query/fields_sphash.o + $(PLUGDIR)/query/dlg_search.o @] put /local/pcb/mod/YACC {$(PLUGDIR)/query/query_y} put /local/pcb/mod/LEX {$(PLUGDIR)/query/query_l} Index: trunk/src_plugins/query/dlg_search.c =================================================================== --- trunk/src_plugins/query/dlg_search.c (nonexistent) +++ trunk/src_plugins/query/dlg_search.c (revision 31708) @@ -0,0 +1,429 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * 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 Street, 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") + */ + +#include "config.h" + +#include + +#include +#include +#include +#include +#include +#include "board.h" + +#define MAX_ROW 8 +#define MAX_COL 4 + +static const char *search_acts[] = { "select", "unselect", "view", NULL }; + +#define NEW_EXPR_LAB "" + +/* for debugging: */ +/*#define NEW_EXPR_LAB rnd_strdup_printf("%d:%d", row, col)*/ + +#include "dlg_search_tab.h" + +typedef struct { + int valid; + const expr_wizard_t *expr; + const char *op; + char *right; +} search_expr_t; + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + int wexpr_str, wwizard, wact; + int wrowbox[MAX_ROW]; + int wexpr[MAX_ROW][MAX_COL]; /* expression framed box */ + int wexpr_lab[MAX_ROW][MAX_COL]; /* the label within the expression box */ + int wexpr_del[MAX_ROW][MAX_COL], wexpr_edit[MAX_ROW][MAX_COL]; /* expression buttons */ + int wor[MAX_ROW][MAX_COL]; /* before the current col */ + int wand[MAX_ROW]; /* before the current row */ + int wnew_or[MAX_ROW], wnew_and; + int visible[MAX_ROW][MAX_COL]; + search_expr_t expr[MAX_ROW][MAX_COL]; +} search_ctx_t; + +#define WIZ(ctx) (ctx->dlg[ctx->wwizard].val.lng) + +#include "dlg_search_edit.c" + +static void free_expr(search_expr_t *e) +{ + free(e->right); + memset(e, 0, sizeof(search_expr_t)); +} + +static void search_close_cb(void *caller_data, rnd_hid_attr_ev_t ev) +{ + int r, c; + search_ctx_t *ctx = caller_data; + for(r = 0; r < MAX_ROW; r++) + for(c = 0; c < MAX_COL; c++) + free_expr(&ctx->expr[r][c]); + free(ctx); +} + +static void hspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void vspacer(search_ctx_t *ctx) +{ + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); +} + +static void update_vis(search_ctx_t *ctx) +{ + int c, r, wen; + + wen = WIZ(ctx); + + for(r = 0; r < MAX_ROW; r++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wrowbox[r],!ctx->visible[r][0]); + for(c = 0; c < MAX_COL; c++) { + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wexpr[r][c], !ctx->visible[r][c]); + if (c > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wor[r][c], !((ctx->visible[r][c-1] && ctx->visible[r][c]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_del[r][c], wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_edit[r][c], wen); + } + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wnew_or[r], !ctx->visible[r][0]); + if (r > 0) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wand[r], !((ctx->visible[r-1][0] && ctx->visible[r][0]))); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_or[r], wen); + } + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wnew_and, wen); + rnd_gui->attr_dlg_widget_state(ctx->dlg_hid_ctx, ctx->wexpr_str, !wen); +} + +/* look up row and col for a widget attr in a [row][col] widget idx array; returns 0 on success */ +static int rc_lookup(search_ctx_t *ctx, int w[MAX_ROW][MAX_COL], rnd_hid_attribute_t *attr, int *row, int *col) +{ + int r, c, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + for(c = 0; c < MAX_COL; c++) { + if (w[r][c] == idx) { + *row = r; + *col = c; + return 0; + } + } + } + return -1; +} + +/* look up row for a widget attr in a [row] widget idx array; returns 0 on success */ +static int r_lookup(search_ctx_t *ctx, int w[MAX_ROW], rnd_hid_attribute_t *attr, int *row) +{ + int r, idx = attr - ctx->dlg; + for(r = 0; r < MAX_ROW; r++) { + if (w[r] == idx) { + *row = r; + return 0; + } + } + return -1; +} + +static void append_expr(gds_t *dst, search_expr_t *e, int sepchar) +{ + gds_append_str(dst, e->expr->left_var); + gds_append(dst, sepchar); + gds_append_str(dst, e->op); + gds_append(dst, sepchar); + gds_append_str(dst, e->right); +} + +static void redraw_expr(search_ctx_t *ctx, int row, int col) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + search_expr_t *e = &(ctx->expr[row][col]); + + if (e->valid) { + gds_init(&buf); + append_expr(&buf, e, '\n'); + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + gds_uninit(&buf); + } + else { + hv.str = NEW_EXPR_LAB; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_lab[row][col], &hv); + } +} + +static void search_recompile(search_ctx_t *ctx) +{ + rnd_hid_attr_val_t hv; + gds_t buf; + int row, col; + + gds_init(&buf); + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0] || !ctx->expr[row][0].valid) + continue; + if (row > 0) + gds_append_str(&buf, " && "); + gds_append(&buf, '('); + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col] || !ctx->expr[row][col].valid) + continue; + if (col > 0) + gds_append_str(&buf, " || "); + gds_append(&buf, '('); + append_expr(&buf, &(ctx->expr[row][col]), ' '); + gds_append(&buf, ')'); + } + gds_append(&buf, ')'); + } + hv.str = buf.array; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wexpr_str, &hv); + gds_uninit(&buf); +} + +static void search_del_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (rc_lookup(ctx, ctx->wexpr_del, attr, &row, &col) != 0) + return; + + free_expr(&(ctx->expr[row][col])); + for(;col < MAX_COL-1; col++) { + if (!ctx->visible[row][col+1]) { + ctx->visible[row][col] = 0; + memset(&ctx->expr[row][col], 0, sizeof(search_expr_t)); + break; + } + ctx->expr[row][col] = ctx->expr[row][col+1]; + redraw_expr(ctx, row, col); + } + update_vis(ctx); + search_recompile(ctx); +} + +static void search_edit_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + search_expr_t *e; + + if (rc_lookup(ctx, ctx->wexpr_edit, attr, &row, &col) != 0) + return; + + e = &(ctx->expr[row][col]); + if (srchedit_window(e) == 0) { + redraw_expr(ctx, row, col); + search_recompile(ctx); + } +} + +static void search_enable_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + if (WIZ(ctx)) + search_recompile(ctx); /* overwrite the edit box just in case the user had something custom in it */ + update_vis(ctx); +} + +static void search_append_col_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row, col; + + if (r_lookup(ctx, ctx->wnew_or, attr, &row) != 0) + return; + + for(col = 0; col < MAX_COL; col++) { + if (!ctx->visible[row][col]) { + ctx->visible[row][col] = 1; + redraw_expr(ctx, row, col); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expressions in the row, can not add more\n"); +} + +static void search_append_row_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + int row; + + for(row = 0; row < MAX_ROW; row++) { + if (!ctx->visible[row][0]) { + ctx->visible[row][0] = 1; + redraw_expr(ctx, row, 0); + update_vis(ctx); + search_recompile(ctx); + return; + } + } + rnd_message(RND_MSG_ERROR, "Too many expression rows, can not add more\n"); +} + +static void search_apply_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + search_ctx_t *ctx = caller_data; + if (ctx->dlg[ctx->wexpr_str].val.str != NULL) + rnd_actionva(&PCB->hidlib, "query", search_acts[ctx->dlg[ctx->wact].val.lng], ctx->dlg[ctx->wexpr_str].val.str, NULL); +} + + +static const char *icon_del[] = { +"5 5 2 1", +" c None", +"+ c #FF0000", +"+ +", +" + + ", +" + ", +" + + ", +"+ +", +}; + +static const char *icon_edit[] = { +"5 5 2 1", +" c None", +"+ c #000000", +"++++ ", +"+ ", +"+++ ", +"+ ", +"++++ ", +}; + +static void search_window_create(void) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Close", 0}, {NULL, 0}}; + search_ctx_t *ctx = calloc(sizeof(search_ctx_t), 1); + int row, col; + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_LABEL(ctx->dlg, "Query expression:"); + RND_DAD_STRING(ctx->dlg); + RND_DAD_WIDTH_CHR(ctx->dlg, 64); + ctx->wexpr_str = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Action on the results:"); + RND_DAD_ENUM(ctx->dlg, search_acts); + ctx->wact = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_EXPFILL | RND_HATF_SCROLL); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, "Enable the wizard:"); + RND_DAD_BOOL(ctx->dlg, ""); + ctx->wwizard = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_DEFAULT_NUM(ctx->dlg, 1); + RND_DAD_CHANGE_CB(ctx->dlg, search_enable_cb); + RND_DAD_END(ctx->dlg); + for(row = 0; row < MAX_ROW; row++) { + if (row > 0) { + RND_DAD_BEGIN_HBOX(ctx->dlg); + ctx->wand[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL | RND_HATF_HIDE); + RND_DAD_LABEL(ctx->dlg, "AND"); + RND_DAD_END(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, /*RND_HATF_EXPFILL | */RND_HATF_HIDE); + ctx->wrowbox[row] = RND_DAD_CURRENT(ctx->dlg); + for(col = 0; col < MAX_COL; col++) { + ctx->visible[row][col] = 0; + if (col > 0) { + RND_DAD_LABEL(ctx->dlg, " OR "); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wor[row][col] = RND_DAD_CURRENT(ctx->dlg); + } + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_FRAME | RND_HATF_TIGHT | RND_HATF_HIDE); + ctx->wexpr[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_LABEL(ctx->dlg, NEW_EXPR_LAB); + ctx->wexpr_lab[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_TIGHT); + RND_DAD_PICBUTTON(ctx->dlg, icon_del); + RND_DAD_HELP(ctx->dlg, "Remove expression"); + ctx->wexpr_del[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_del_cb); + RND_DAD_PICBUTTON(ctx->dlg, icon_edit); + RND_DAD_HELP(ctx->dlg, "Edit expression"); + ctx->wexpr_edit[row][col] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_edit_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + } + hspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append OR"); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wnew_or[row] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_col_cb); + RND_DAD_END(ctx->dlg); + } + vspacer(ctx); + RND_DAD_BUTTON(ctx->dlg, "append AND"); + ctx->wnew_and = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, search_append_row_cb); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_BUTTON(ctx->dlg, "Apply"); + RND_DAD_CHANGE_CB(ctx->dlg, search_apply_cb); + RND_DAD_HELP(ctx->dlg, "Execute the search expression\nusing the selected action"); + hspacer(ctx); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 300, 350); + RND_DAD_NEW("search", ctx->dlg, "pcb-rnd search", ctx, rnd_false, search_close_cb); + + ctx->visible[0][0] = 1; + update_vis(ctx); + search_recompile(ctx); +} + + +const char pcb_acts_SearchDialog[] = "SearchDialog()\n"; +const char pcb_acth_SearchDialog[] = "Open the log dialog."; +fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv) +{ + search_window_create(); + RND_ACT_IRES(0); + return 0; +} + + Index: trunk/src_plugins/query/dlg_search.h =================================================================== --- trunk/src_plugins/query/dlg_search.h (nonexistent) +++ trunk/src_plugins/query/dlg_search.h (revision 31708) @@ -0,0 +1,4 @@ +extern const char pcb_acts_SearchDialog[]; +extern const char pcb_acth_SearchDialog[]; +fgw_error_t pcb_act_SearchDialog(fgw_arg_t *res, int argc, fgw_arg_t *argv); + Index: trunk/src_plugins/query/dlg_search_edit.c =================================================================== --- trunk/src_plugins/query/dlg_search_edit.c (nonexistent) +++ trunk/src_plugins/query/dlg_search_edit.c (revision 31708) @@ -0,0 +1,371 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2019 Tibor 'Igor2' Palinkas + * + * 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 Street, 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") + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +typedef struct{ + RND_DAD_DECL_NOINIT(dlg) + search_expr_t se; + int wleft, wop, wright[RIGHT_max]; + const expr_wizard_op_t *last_op; + right_type last_rtype; +} srchedit_ctx_t; + +static srchedit_ctx_t srchedit_ctx; + +/* Set the right side of the expression from the non-enum value of an widget attr */ +static void set_right(srchedit_ctx_t *ctx, rnd_hid_attribute_t *attr) +{ + free(ctx->se.right); + ctx->se.right = NULL; + + switch(ctx->se.expr->rtype) { + case RIGHT_STR: + ctx->se.right = rnd_strdup(attr->val.str); + break; + case RIGHT_INT: + ctx->se.right = rnd_strdup_printf("%d", attr->val.lng); + break; + case RIGHT_DOUBLE: + ctx->se.right = rnd_strdup_printf("%f", attr->val.dbl); + break; + case RIGHT_COORD: + ctx->se.right = rnd_strdup_printf("%$mm", attr->val.crd); + break; + case RIGHT_CONST: + case RIGHT_max: + break; + } +} + +static void srch_expr_set_ops(srchedit_ctx_t *ctx, const expr_wizard_op_t *op, int click) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *cur = NULL; + char *cell[2], *cursor_path = NULL; + const char **o; + + if (op == ctx->last_op) + return; + + attr = &ctx->dlg[ctx->wop]; + tree = attr->wdata; + + /* remember cursor */ + if (click) { + r = rnd_dad_tree_get_selected(attr); + if (r != NULL) + cursor_path = rnd_strdup(r->cell[0]); + } + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = op->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)(*o); /* will be casted back to const char * only */ + if ((!click) && (ctx->se.op == *o)) + cur = r; + } + + /* restore cursor */ + if (cursor_path != NULL) { + rnd_hid_attr_val_t hv; + hv.str = cursor_path; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wop, &hv); + free(cursor_path); + } + if (cur != NULL) + rnd_dad_tree_jumpto(attr, cur); + ctx->last_op = op; +} + +static void srch_expr_fill_in_right_const(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + rnd_hid_tree_t *tree; + rnd_hid_attribute_t *attr; + char *cell[2]; + const char **o; + + attr = &ctx->dlg[ctx->wright[RIGHT_CONST]]; + tree = attr->wdata; + + /* remove existing items */ + rnd_dad_tree_clear(tree); + + /* add all items */ + cell[1] = NULL; + for(o = s->expr->right_const->ops; *o != NULL; o++) { + cell[0] = rnd_strdup_printf(*o); + rnd_dad_tree_append(attr, NULL, cell); + } + + /* set cursor to last known value */ + if ((s != NULL) && (s->right != NULL)) { + rnd_hid_attr_val_t hv; + hv.str = s->right; + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], &hv); + } +} + +static void srch_expr_fill_in_right(srchedit_ctx_t *ctx, const search_expr_t *s) +{ + int n, empty = 0; + rnd_hid_attr_val_t hv; + + /* don't recalc if the same type; except for const, because there the same type means different set of values for each expr */ + if ((s->expr->rtype == ctx->last_rtype) && (s->expr->rtype != RIGHT_CONST)) + return; + + for(n = 0; n < RIGHT_max; n++) + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[n], 1); + + hv.str = ctx->se.right; + if (hv.str == NULL) { + hv.str = ""; + empty = 1; + } + + switch(s->expr->rtype) { + case RIGHT_STR: + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + break; + case RIGHT_INT: + hv.lng = strtol(hv.str, NULL, 10); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_DOUBLE: + hv.dbl = strtod(hv.str, NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_COORD: + hv.crd = rnd_get_value_ex(hv.str, NULL, NULL, NULL, "mm", NULL); + rnd_gui->attr_dlg_set_value(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], &hv); + if (empty) + set_right(ctx, &ctx->dlg[ctx->wright[s->expr->rtype]]); + break; + case RIGHT_CONST: srch_expr_fill_in_right_const(ctx, s); break; + case RIGHT_max: break; + } + + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[s->expr->rtype], 0); + ctx->last_rtype = s->expr->rtype; +} + +static void srch_expr_left_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + const expr_wizard_t *e; + + if (row == NULL) + return; + + e = row->user_data; + if (e->left_var == NULL) /* category */ + return; + + ctx->se.expr = e; + srch_expr_set_ops(ctx, e->op, 1); + srch_expr_fill_in_right(ctx, &ctx->se); +} + +static void srch_expr_op_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + if (row != NULL) + ctx->se.op = row->user_data; + else + ctx->se.op = NULL; +} + +/* the table on the left is static, needs to be filled in only once; + returns 1 if filled in op and right, else 0 */ +static int fill_in_left(srchedit_ctx_t *ctx) +{ + const expr_wizard_t *t; + rnd_hid_attribute_t *attr; + rnd_hid_row_t *r, *parent = NULL, *cur = NULL; + char *cell[2]; + + attr = &ctx->dlg[ctx->wleft]; + + cell[1] = NULL; + for(t = expr_tab; t->left_desc != NULL; t++) { + if (t->left_var == NULL) + parent = NULL; + cell[0] = rnd_strdup(t->left_desc); + if (parent != NULL) + r = rnd_dad_tree_append_under(attr, parent, cell); + else + r = rnd_dad_tree_append(attr, NULL, cell); + r->user_data = (void *)t; + if (t->left_var == NULL) + parent = r; + if (t == ctx->se.expr) + cur = r; + } + + if (cur != NULL) { + rnd_dad_tree_jumpto(attr, cur); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + srch_expr_set_ops(ctx, ctx->se.expr->op, 0); + srch_expr_fill_in_right(ctx, &ctx->se); + return 1; + } + return 0; +} + +static void srchexpr_right_cb(void *hid_ctx, void *caller_data, rnd_hid_attribute_t *attr) +{ + srchedit_ctx_t *ctx = caller_data; + + set_right(ctx, attr); +} + +static void srch_expr_right_table_cb(rnd_hid_attribute_t *attrib, void *hid_ctx, rnd_hid_row_t *row) +{ + rnd_hid_tree_t *tree = attrib->wdata; + srchedit_ctx_t *ctx = tree->user_ctx; + + free(ctx->se.right); + ctx->se.right = NULL; + if (row != NULL) + ctx->se.right = rnd_strdup(row->cell[0]); +} + +static int srchedit_window(search_expr_t *expr) +{ + rnd_hid_dad_buttons_t clbtn[] = {{"Cancel", 1}, {"OK", 0}, {NULL, 0}}; + srchedit_ctx_t *ctx = &srchedit_ctx; + int res; + + ctx->se = *expr; + if (ctx->se.right != NULL) + ctx->se.right = rnd_strdup(ctx->se.right); + + /* clear all cache fields so a second window open won't inhibit refreshes */ + ctx->last_op = NULL; + ctx->last_rtype = RIGHT_max; + + RND_DAD_BEGIN_HBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_TREE(ctx->dlg, 1, 1, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_SCROLL); + ctx->wleft = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_left_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + ctx->wop = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_op_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + RND_DAD_END(ctx->dlg); + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + + RND_DAD_STRING(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_STR] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_INTEGER(ctx->dlg, ""); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_INT] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_REAL(ctx->dlg, ""); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_DOUBLE] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -(1L<<30), (1L<<30)); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_COORD(ctx->dlg, ""); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_COORD] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_MINMAX(ctx->dlg, -RND_MAX_COORD, RND_MAX_COORD); + RND_DAD_CHANGE_CB(ctx->dlg, srchexpr_right_cb); + + RND_DAD_TREE(ctx->dlg, 1, 0, NULL); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_HIDE); + ctx->wright[RIGHT_CONST] = RND_DAD_CURRENT(ctx->dlg); + RND_DAD_TREE_SET_CB(ctx->dlg, selected_cb, srch_expr_right_table_cb); + RND_DAD_TREE_SET_CB(ctx->dlg, ctx, ctx); + + RND_DAD_BEGIN_VBOX(ctx->dlg); + RND_DAD_COMPFLAG(ctx->dlg, RND_HATF_EXPFILL); + RND_DAD_END(ctx->dlg); + RND_DAD_BUTTON_CLOSES(ctx->dlg, clbtn); + RND_DAD_END(ctx->dlg); + RND_DAD_END(ctx->dlg); + + RND_DAD_DEFSIZE(ctx->dlg, 450, 450); + RND_DAD_NEW("search_expr", ctx->dlg, "pcb-rnd search expression", ctx, rnd_true, NULL); + + if (fill_in_left(ctx) != 1) { + srch_expr_set_ops(ctx, op_tab, 1); /* just to get the initial tree widget width */ + rnd_gui->attr_dlg_widget_hide(ctx->dlg_hid_ctx, ctx->wright[RIGHT_CONST], 0); /* just to get something harmless display on the right side after open */ + } + + res = RND_DAD_RUN(ctx->dlg); + if (res == 0) { + free(expr->right); + *expr = ctx->se; + if (ctx->se.op != NULL) + expr->valid = 1; + } + else + free(ctx->se.right); + + RND_DAD_FREE(ctx->dlg); + return res; +} + + Index: trunk/src_plugins/query/dlg_search_tab.h =================================================================== --- trunk/src_plugins/query/dlg_search_tab.h (nonexistent) +++ trunk/src_plugins/query/dlg_search_tab.h (revision 31708) @@ -0,0 +1,203 @@ +/* + * COPYRIGHT + * + * pcb-rnd, interactive printed circuit board design + * Copyright (C) 2016,2020 Tibor 'Igor2' Palinkas + * + * 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 Street, 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") + */ + +/* advanced search dialog - expressioin wizard tables; intended to be + included from the search dialog only */ + +typedef enum { + RIGHT_STR, + RIGHT_INT, + RIGHT_DOUBLE, + RIGHT_COORD, + RIGHT_CONST, + RIGHT_max +} right_type; + +typedef enum { + OPS_ANY, + OPS_EQ, + OPS_STR +} op_type_t; + +static const char *ops_any[] = {"==", "!=", ">=", "<=", ">", "<", NULL}; +static const char *ops_eq[] = {"==", "!=", NULL}; +static const char *ops_str[] = {"==", "!=", "~", NULL}; + +typedef struct expr_wizard_op_s expr_wizard_op_t; +struct expr_wizard_op_s { + const char **ops; +}; + +static expr_wizard_op_t op_tab[] = { + {ops_any}, + {ops_eq}, + {ops_str}, + {NULL} +}; + +typedef struct expr_wizard_s expr_wizard_t; +struct expr_wizard_s { + const char *left_var; + const char *left_desc; + const expr_wizard_op_t *op; + right_type rtype; + const expr_wizard_op_t *right_const; +}; + +static const char *right_const_objtype[] = { "POINT", "LINE", "TEXT", "POLYGON", "ARC", "RAT", "NET", "LAYER", NULL }; +static const char *right_const_yesno[] = {"YES", "NO", NULL}; +static const char *right_const_10[] = {"1", "0", NULL}; +static const char *right_const_layerpos[] = {"TOP", "BOTTOM", "INTERNAL", NULL}; +static const char *right_const_layertype[] = {"COPPER", "SILK", "MASK", "PASTE", "BOUNDARY", "MECH", "DOC" , NULL}; +static const char *right_const_side[] = {"TOP", "BOTTOM", NULL}; + +enum { + RC_OBJTYPE, + RC_YESNO, + RC_10, + RC_LAYERPOS, + RC_LAYERTYPE, + RC_SIDE +}; + +static expr_wizard_op_t right_const_tab[] = { + {right_const_objtype}, + {right_const_yesno}, + {right_const_10}, + {right_const_layerpos}, + {right_const_layertype}, + {right_const_side}, + {NULL} +}; + +static const expr_wizard_t expr_tab[] = { + {"@.ID", "object ID", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.type", "object type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_OBJTYPE]}, + + {NULL, "bounding box", NULL, 0, NULL}, + {"@.bbox.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.w", "width", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.bbox.h", "height", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + + {NULL, "trace object's", NULL, 0, NULL}, + {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.clearance", "clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.length", "length", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "line", NULL, 0, NULL}, + {"@.x1", "X1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y1", "Y1", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.x2", "X2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y2", "Y2", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "arc", NULL, 0, NULL}, + {"@.x", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.angle.start", "start angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.angle.delta", "delta angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "text", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.scale", "scale", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.scale_x", "scale_x", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.scale_y", "scale_y", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.string", "string", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.thickness", "thickness", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + + {NULL, "polygon", NULL, 0, NULL}, + {"@.points", "points", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + + {NULL, "padstack", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.clearance", "global clearance", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.xmirror", "x coords mirrored",&op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.smirror", "stackup mirrored", &op_tab[OPS_ANY], RIGHT_INT, NULL}, + {"@.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.number", "number", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.hole", "proto: hole dia", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.plated", "proto: is plated?",&op_tab[OPS_ANY], RIGHT_INT, NULL}, + + {NULL, "subcircuit", NULL, 0, NULL}, + {"@.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, + {"@.a.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.footprint", "footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.a.value", "value", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "gfx", NULL, 0, NULL}, + {"@.cx", "center X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.cy", "center Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.sx", "size X (width)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.sy", "size Y (height)", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.rot", "rotation angle", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + + {NULL, "host layer's", NULL, 0, NULL}, + {"@.layer.name", "name", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.layer.visible", "visible", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_YESNO]}, + {"@.layer.position", "stack position", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERPOS]}, + {"@.layer.type", "type", &op_tab[OPS_EQ], RIGHT_CONST, &right_const_tab[RC_LAYERTYPE]}, + {"@.layer.purpose", "purpose", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "host subcircuit's",NULL, 0, NULL}, + {"@.subc.x", "X", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.subc.y", "Y", &op_tab[OPS_ANY], RIGHT_COORD, NULL}, + {"@.subc.rotation", "rotation", &op_tab[OPS_ANY], RIGHT_DOUBLE, NULL}, + {"@.subc.side", "side", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_SIDE]}, + {"@.subc.refdes", "refdes", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.subc.footprint", "a.footprint", &op_tab[OPS_STR], RIGHT_STR, NULL}, + {"@.subc.value", "a.value", &op_tab[OPS_STR], RIGHT_STR, NULL}, + + {NULL, "flag", NULL, 0, NULL}, + {"@.p.flag.found", "found", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.hole", "hole", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearpoly","clearpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearline","clearline", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.selected", "selected", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.onsolder", "onsolder", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.auto", "auto", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.warn", "warn", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.drc", "drc", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.lock", "lock", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.fullpoly", "fullpoly", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.nonetlist","nonetlist", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.termname", "termname", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.clearpolypoly","clearpolypoly",&op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.p.dyntext","dyntext", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + {"@.p.flag.p.floater","floater", &op_tab[OPS_ANY], RIGHT_CONST, &right_const_tab[RC_10]}, + + {NULL, NULL, NULL, 0, NULL} +}; + Index: trunk/src_plugins/query/query_act.c =================================================================== --- trunk/src_plugins/query/query_act.c (revision 31707) +++ trunk/src_plugins/query/query_act.c (revision 31708) @@ -43,6 +43,7 @@ #include "view.h" #include "actions_pcb.h" #include "net_len.h" +#include "dlg_search.h" #include static const char pcb_acts_query[] = @@ -616,7 +617,8 @@ {"query", pcb_act_query, pcb_acth_query, pcb_acts_query}, {"QueryObj", pcb_act_QueryObj, pcb_acth_QueryObj, pcb_acts_QueryObj}, {"QueryCompileField", pcb_act_QueryCompileField, pcb_acth_QueryCompileField, pcb_acts_QueryCompileField}, - {"QueryCalcNetLen", pcb_act_QueryCalcNetLen, pcb_acth_QueryCalcNetLen, pcb_acts_QueryCalcNetLen} + {"QueryCalcNetLen", pcb_act_QueryCalcNetLen, pcb_acth_QueryCalcNetLen, pcb_acts_QueryCalcNetLen}, + {"SearchDialog", pcb_act_SearchDialog, pcb_acth_SearchDialog, pcb_acts_SearchDialog} }; void query_action_reg(const char *cookie)