/**************************************************************************************************** * construct the widget ****************************************************************************************************/ config_widget_construct(ConfigWidget * config_widget, Config * config) { GtkWidget *box_v = GTK_WIDGET(config_widget); int count = config -> num_entries; GtkWidget * labels[count]; config_widget -> entries = malloc(sizeof(GtkWidget*) * count); GtkWidget ** entries = config_widget -> entries; int i; char buf[100]; for (i = 0; i < count; i++){ ConfEntry ce = config -> entries[i]; labels[i] = gtk_label_new(ce.name); switch (ce.type){ case TYPE_STRING: case TYPE_DIR: case TYPE_IP:{ sprintf(buf, "%s", (char*)ce.data); entries[i] = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entries[i]), buf) ; break; } case TYPE_PASSWORD:{ sprintf(buf, "%s", (char*)ce.data); entries[i] = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(entries[i]), FALSE); gtk_entry_set_text(GTK_ENTRY(entries[i]), buf) ; break; } case TYPE_COLOR:{ sprintdouble(buf, ((ColorQuadriple*)ce.data) -> r, 2); sprintf(buf+strlen(buf), "%s", ","); sprintdouble(buf+strlen(buf), ((ColorQuadriple*)ce.data) -> g, 2); sprintf(buf+strlen(buf), "%s", ","); sprintdouble(buf+strlen(buf), ((ColorQuadriple*)ce.data) -> b, 2); sprintf(buf+strlen(buf), "%s", ","); sprintdouble(buf+strlen(buf), ((ColorQuadriple*)ce.data) -> a, 2); entries[i] = color_box_new(); color_box_set_current_value(GOSM_COLOR_BOX(entries[i]), buf); break; } case TYPE_INT:{ sprintf(buf, "%d", *(int*)ce.data); entries[i] = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entries[i]), buf); break; } case TYPE_DOUBLE:{ sprintdouble(buf, *(double*)ce.data, 4); entries[i] = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entries[i]), buf); break; } case TYPE_BOOLEAN:{ entries[i] = gtk_check_button_new(); gboolean active = *(gboolean*)ce.data; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entries[i]), active); break; } default:{ entries[i] = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(entries[i]), ce.data_str); } } } GtkWidget * table = gtk_table_new(2, 9, FALSE); for (i = 0; i < count; i++){ GtkWidget * box = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(box), labels[i], FALSE, FALSE, 0); gtk_table_attach(GTK_TABLE(table), box, 0, 1, i, i+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), entries[i], 1, 2, i, i+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); } GtkWidget * scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), table); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); GtkWidget * box_buttons = gtk_hbox_new(FALSE, 0); config_widget -> button_confirm = gtk_button_new_from_stock("gtk-apply"); config_widget -> button_cancel = gtk_button_new_from_stock("gtk-cancel"); gtk_box_pack_start(GTK_BOX(box_buttons), config_widget -> button_confirm, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(box_buttons), config_widget -> button_cancel , FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(box_v), scrolled, TRUE, TRUE, 0); gtk_box_pack_end (GTK_BOX(box_v), box_buttons, FALSE, FALSE, 0); }
/* Construct a string identifying some SEXP, either as a scalar value or as a pointer. If we use its pointer, set NAMED = 2 on the pointer used. Return that pointer, or R_NilValue. */ SEXP stringify_item(SEXP item, char *bufptr) { int done = 0; SEXP item_ptr = R_NilValue; while(!done) { switch (TYPEOF(item)) { case PROMSXP: /* if we have a promise, drill down. */ item = PRCODE(item); break; case CHARSXP: /* interned string, represent its pointer */ item_ptr = item; bufptr += sprintf(bufptr, "c%p", CHAR(item_ptr)); done = 1; break; case REALSXP: case INTSXP: case STRSXP: case LGLSXP: /* we have a code literal. represent it canonically, and don't hold a ref to a scalar. */ if (LENGTH(item) == 0) { switch(TYPEOF(item)) { case REALSXP: bufptr += sprintf(bufptr, "r0"); break; case INTSXP: bufptr += sprintf(bufptr, "i0"); break; case LGLSXP: bufptr += sprintf(bufptr, "l0"); break; case STRSXP: bufptr += sprintf(bufptr, "s0"); break; default: error("Unexpected type %s (this shouldn't happen)", TYPEOF(item)); } } else if (LENGTH(item) == 1) { switch(TYPEOF(item)) { case REALSXP: bufptr += sprintf(bufptr, "r"); bufptr += sprintdouble(bufptr, REAL(item)[0]); break; case INTSXP: bufptr += sprintf(bufptr, "i%x", INTEGER(item)[0]); break; case LGLSXP: bufptr += sprintf(bufptr, "l%x", LOGICAL(item)[0]); break; case STRSXP: item_ptr = STRING_ELT(item, 0); bufptr += sprintf(bufptr, "s%p", CHAR(item_ptr)); break; default: error("Unexpected type %s (this shouldn't happen)", TYPEOF(item)); } } else { /* for non-scalar vectors, represent the pointer */ item_ptr = item; bufptr += sprintf(bufptr, "v%p", (void *)item_ptr); } done = 1; break; case VECSXP: item_ptr = item; bufptr += sprintf(bufptr, "l%p", (void *)item_ptr); done = 1; break; case CLOSXP: item_ptr = item; bufptr += sprintf(bufptr, "c_%p/%p/%p", (void *) FORMALS(item), (void *) BODY(item), (void *) CLOENV(item)); done = 1; break; case SYMSXP: case LANGSXP: case EXPRSXP: case BCODESXP: case BUILTINSXP: case SPECIALSXP: case NILSXP: /* We have an expression-ish, represent its pointer. */ item_ptr = item; bufptr += sprintf(bufptr, "e%p", (void *)item_ptr); done = 1; break; default: error("Unexpected type %s", type2char(TYPEOF(item))); } } if (item_ptr != R_NilValue) { SET_NAMED(item_ptr, 2); } return item_ptr; }