Index: trunk/src_plugins/order/order.h =================================================================== --- trunk/src_plugins/order/order.h (revision 27479) +++ trunk/src_plugins/order/order.h (revision 27480) @@ -37,6 +37,7 @@ PCB_DAD_DECL_NOINIT(dlg) int active; /* already open - allow only one instance */ vtp0_t names; + void *odata; /* implementation-specific data of the current order */ } order_ctx_t; /* order implementation - registered by an order plugin */ @@ -47,7 +48,6 @@ int (*load_fields)(pcb_order_imp_t *imp, order_ctx_t *octx); void (*free_fields)(pcb_order_imp_t *imp, order_ctx_t *octx); void (*populate_dad)(pcb_order_imp_t *imp, order_ctx_t *octx); - void *odata; /* implementation-specific data of the current order */ }; extern vtp0_t pcb_order_imps; /* of (pcb_order_imp_t *) items */ @@ -59,6 +59,7 @@ pcb_hid_attr_type_t type; pcb_hid_attr_val_t val; char **enum_vals; + char *help; int wid; /* widget id, if any */ char name[1]; /* dynamic length */ } pcb_order_field_t; Index: trunk/src_plugins/order_pcbway/pcbway.c =================================================================== --- trunk/src_plugins/order_pcbway/pcbway.c (revision 27479) +++ trunk/src_plugins/order_pcbway/pcbway.c (revision 27480) @@ -138,111 +138,99 @@ return doc; } -static int pcbway_populate_dad_(pcb_hidlib_t *hidlib, pcb_order_imp_t *imp, order_ctx_t *octx, xmlNode *root) +static int pcbway_load_fields_(pcb_hidlib_t *hidlib, pcb_order_imp_t *imp, order_ctx_t *octx, xmlNode *root) { xmlNode *n, *v; + pcbway_form_t *form = (pcbway_form_t *)octx->odata; for(root = root->children; (root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"PcbQuotationRequest") != 0); root = root->next) ; if (root == NULL) return -1; - PCB_DAD_BEGIN_VBOX(octx->dlg); - PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_SCROLL | PCB_HATF_EXPFILL); - for(n = root->children; n != NULL; n = n->next) { - const char *type, *note, *dflt; - if (n->type == XML_TEXT_NODE) - continue; - type = (const char *)xmlGetProp(n, (const xmlChar *)"type"); - note = (const char *)xmlGetProp(n, (const xmlChar *)"note"); - dflt = (const char *)xmlGetProp(n, (const xmlChar *)"default"); - if (type == NULL) - type = "label"; - PCB_DAD_BEGIN_HBOX(octx->dlg); - PCB_DAD_LABEL(octx->dlg, (char *)n->name); - PCB_DAD_BEGIN_VBOX(octx->dlg); - PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); - PCB_DAD_END(octx->dlg); - if (strcmp(type, "enum") == 0) { - int di = 0, i; - vtp0_t tmp; - vtp0_init(&tmp); - for(v = n->children, i = 0; v != NULL; v = v->next) { - char *s; - if ((n->type == XML_TEXT_NODE) || (xmlStrcmp(v->name, (xmlChar *)"Value") != 0) || (n->children->type != XML_TEXT_NODE)) - continue; - s = pcb_strdup(v->children->content); - vtp0_append(&tmp, s); - if ((dflt != NULL) && (strcmp(s, dflt) == 0)) - di = i; - i++; - } - vtp0_append(&tmp, NULL); - PCB_DAD_ENUM(octx->dlg, tmp.array); - if (dflt != NULL) - PCB_DAD_DEFAULT_NUM(octx->dlg, di); - } - else if (strcmp(type, "integer") == 0) { - PCB_DAD_INTEGER(octx->dlg, ""); - if (dflt != NULL) - PCB_DAD_DEFAULT_NUM(octx->dlg, atoi(dflt)); - } - else if (strcmp(type, "mm") == 0) { - PCB_DAD_COORD(octx->dlg, ""); - if (dflt != NULL) - PCB_DAD_DEFAULT_NUM(octx->dlg, PCB_MM_TO_COORD(atoi(dflt))); - } - else if (strcmp(type, "string") == 0) { - PCB_DAD_STRING(octx->dlg); - if (dflt != NULL) - PCB_DAD_DEFAULT_PTR(octx->dlg, dflt); - } - PCB_DAD_END(octx->dlg); + for(n = root->children; n != NULL; n = n->next) { + const char *type, *note, *dflt; + pcb_order_field_t *f; + if ((n->type == XML_TEXT_NODE) || (n->name == NULL)) + continue; + type = (const char *)xmlGetProp(n, (const xmlChar *)"type"); + note = (const char *)xmlGetProp(n, (const xmlChar *)"note"); + dflt = (const char *)xmlGetProp(n, (const xmlChar *)"default"); + + if ((type != NULL && strlen(type) > 128) || (strlen((char *)n->name) > 128) || (note != NULL && strlen(note) > 256) || (dflt != NULL && strlen(dflt) > 128)) { + pcb_message(PCB_MSG_ERROR, "order_pcbway: invalid field description: too long\n"); + return -1; } - PCB_DAD_BEGIN_VBOX(octx->dlg); - PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); - PCB_DAD_LABEL(octx->dlg, ""); - PCB_DAD_LABEL(octx->dlg, ""); - PCB_DAD_END(octx->dlg); + f = calloc(sizeof(pcb_order_field_t) + strlen((char *)n->name), 1); + strcpy(f->name, (char *)n->name); + if (note != NULL) + f->help = pcb_strdup(note); + if (type == NULL) { + f->type = PCB_HATT_LABEL; + } + else if (strcmp(type, "enum") == 0) { + int di = 0, i; + vtp0_t tmp; - - PCB_DAD_BEGIN_HBOX(octx->dlg); - PCB_DAD_BUTTON(octx->dlg, "Update data"); - PCB_DAD_HELP(octx->dlg, "Copy data from board to form"); - PCB_DAD_BEGIN_VBOX(octx->dlg); - PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); - PCB_DAD_END(octx->dlg); - PCB_DAD_BUTTON(octx->dlg, "Quote"); - PCB_DAD_HELP(octx->dlg, "Generate a price quote"); - PCB_DAD_BUTTON(octx->dlg, "Order"); - PCB_DAD_HELP(octx->dlg, "Order PCB"); - PCB_DAD_END(octx->dlg); - - PCB_DAD_END(octx->dlg); + f->type = PCB_HATT_ENUM; + vtp0_init(&tmp); + for(v = n->children, i = 0; v != NULL; v = v->next) { + char *s; + if ((n->type == XML_TEXT_NODE) || (xmlStrcmp(v->name, (xmlChar *)"Value") != 0) || (n->children->type != XML_TEXT_NODE)) + continue; + s = pcb_strdup((char *)v->children->content); + vtp0_append(&tmp, s); + if ((dflt != NULL) && (strcmp(s, dflt) == 0)) + di = i; + i++; + } + vtp0_append(&tmp, NULL); + f->enum_vals = (char **)tmp.array; + if (dflt != NULL) + f->val.lng = di; + } + else if (strcmp(type, "integer") == 0) { + f->type = PCB_HATT_INTEGER; + if (dflt != NULL) + f->val.lng = PCB_MM_TO_COORD(atoi(dflt)); + } + else if (strcmp(type, "mm") == 0) { + f->type = PCB_HATT_COORD; + if (dflt != NULL) + f->val.crd = PCB_MM_TO_COORD(strtod(dflt, NULL)); + } + else if (strcmp(type, "string") == 0) { + f->type = PCB_HATT_STRING; + if (dflt != NULL) + f->val.str = pcb_strdup(dflt); + } + else { + f->type = PCB_HATT_LABEL; + } + vtp0_append(&form->fields, f); + if (form->fields.used > 128) { + pcb_message(PCB_MSG_ERROR, "order_pcbway: too many fields for a form\n"); + return -1; + } + } return 0; } static int pcbway_load_fields(pcb_order_imp_t *imp, order_ctx_t *octx) { - return 0; -} - -static void pcbway_free_fields(pcb_order_imp_t *imp, order_ctx_t *octx) -{ -} - -static void pcbway_populate_dad(pcb_order_imp_t *imp, order_ctx_t *octx) -{ char *cachedir, *path; xmlDoc *doc; xmlNode *root; + int res = 0; + octx->odata = NULL; + if ((CFG.api_key == NULL) || (*CFG.api_key == '\0')) { - PCB_DAD_LABEL(octx->dlg, "Error: no api_key available."); + pcb_message(PCB_MSG_ERROR, "order_pcbway: no api_key available."); return -1; } if (pcbway_cache_update(&PCB->hidlib) != 0) { - PCB_DAD_LABEL(octx->dlg, "Error: failed to update the cache."); + pcb_message(PCB_MSG_ERROR, "order_pcbway: failed to update the cache."); return -1; } @@ -252,27 +240,99 @@ if (doc != NULL) { root = xmlDocGetRootElement(doc); if ((root != NULL) && (xmlStrcmp(root->name, (xmlChar *)"PCBWayAPI") == 0)) { - if (pcbway_populate_dad_(&PCB->hidlib, imp, octx, root) != 0) - PCB_DAD_LABEL(octx->dlg, "xml error: invalid API xml\n"); + octx->odata = calloc(sizeof(pcbway_form_t), 1); + if (pcbway_load_fields_(&PCB->hidlib, imp, octx, root) != 0) { + pcb_message(PCB_MSG_ERROR, "order_pcbway: xml error: invalid API xml\n"); + res = -1; + } } else - PCB_DAD_LABEL(octx->dlg, "xml error: root is not \n"); + pcb_message(PCB_MSG_ERROR, "order_pcbway: xml error: root is not \n"); } else - PCB_DAD_LABEL(octx->dlg, "xml error: failed to parse the xml\n"); + pcb_message(PCB_MSG_ERROR, "order_pcbway: xml error: failed to parse the xml\n"); xmlFreeDoc(doc); free(cachedir); free(path); + + return res; } +static void pcbway_free_fields(pcb_order_imp_t *imp, order_ctx_t *octx) +{ +} + +static void pcbway_populate_dad(pcb_order_imp_t *imp, order_ctx_t *octx) +{ + int n; + pcbway_form_t *form = octx->odata; + + PCB_DAD_BEGIN_VBOX(octx->dlg); + PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_SCROLL | PCB_HATF_EXPFILL); + + for(n = 0; n < form->fields.used; n++) { + pcb_order_field_t *f = form->fields.array[n]; + + PCB_DAD_BEGIN_HBOX(octx->dlg); + PCB_DAD_LABEL(octx->dlg, f->name); + PCB_DAD_BEGIN_VBOX(octx->dlg); + PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); + PCB_DAD_END(octx->dlg); + switch(f->type) { + case PCB_HATT_ENUM: + PCB_DAD_ENUM(octx->dlg, f->enum_vals); + PCB_DAD_DEFAULT_NUM(octx->dlg, f->val.lng); + break; + case PCB_HATT_INTEGER: + PCB_DAD_INTEGER(octx->dlg, ""); + PCB_DAD_DEFAULT_NUM(octx->dlg, f->val.lng); + break; + case PCB_HATT_COORD: + PCB_DAD_COORD(octx->dlg, ""); + PCB_DAD_DEFAULT_NUM(octx->dlg, f->val.crd); + break; + case PCB_HATT_STRING: + PCB_DAD_STRING(octx->dlg); + PCB_DAD_DEFAULT_PTR(octx->dlg, f->val.str); + break; + case PCB_HATT_LABEL: break; + default: + PCB_DAD_LABEL(octx->dlg, ""); + } + PCB_DAD_END(octx->dlg); + } + + + PCB_DAD_BEGIN_VBOX(octx->dlg); + PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); + PCB_DAD_LABEL(octx->dlg, ""); + PCB_DAD_LABEL(octx->dlg, ""); + PCB_DAD_END(octx->dlg); + + PCB_DAD_BEGIN_HBOX(octx->dlg); + PCB_DAD_BUTTON(octx->dlg, "Update data"); + PCB_DAD_HELP(octx->dlg, "Copy data from board to form"); + PCB_DAD_BEGIN_VBOX(octx->dlg); + PCB_DAD_COMPFLAG(octx->dlg, PCB_HATF_EXPFILL); + PCB_DAD_END(octx->dlg); + PCB_DAD_BUTTON(octx->dlg, "Quote"); + PCB_DAD_HELP(octx->dlg, "Generate a price quote"); + PCB_DAD_BUTTON(octx->dlg, "Order"); + PCB_DAD_HELP(octx->dlg, "Order PCB"); + PCB_DAD_END(octx->dlg); + + PCB_DAD_END(octx->dlg); + return 0; + +} + static pcb_order_imp_t pcbway = { "PCBWay", NULL, pcbway_load_fields, pcbway_free_fields, - pcbway_populate_dad, - NULL + pcbway_populate_dad };