From 17b5848335f73256f48bf4511bce23d574388316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sat, 19 May 2018 20:26:33 +0200 Subject: [PATCH] Implement Date/Time Field Support. Change Text Color for cell names --- gdsparse.c | 72 ++++++++++++++++++++++++++++++++++++++++----- gdsparse.h | 4 ++- main.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 149 insertions(+), 13 deletions(-) diff --git a/gdsparse.c b/gdsparse.c index 9fcc924..488f398 100644 --- a/gdsparse.c +++ b/gdsparse.c @@ -83,7 +83,7 @@ static int name_cell_ref(struct gds_cell_instance *cell_inst, return 0; } -static double gds_convert_double(char *data) +static double gds_convert_double(const char *data) { bool sign_bit; int i; @@ -123,7 +123,7 @@ static double gds_convert_double(char *data) return ret_val; } -static signed int gds_convert_signed_int(char *data) +static signed int gds_convert_signed_int(const char *data) { int ret; @@ -139,7 +139,7 @@ static signed int gds_convert_signed_int(char *data) return ret; } -static int16_t gds_convert_signed_int16(char *data) +static int16_t gds_convert_signed_int16(const char *data) { if (!data) { GDS_ERROR("This should not happen"); @@ -149,7 +149,17 @@ static int16_t gds_convert_signed_int16(char *data) (((int16_t)(data[1]) & 0xFF) << 0)); } -static GList *append_library(GList *curr_list) +static uint16_t gds_convert_unsigend_int16(const char *data) +{ + if (!data) { + GDS_ERROR("This should not happen"); + return 0; + } + return (uint16_t)((((uint16_t)(data[0]) & 0xFF) << 8) | + (((uint16_t)(data[1]) & 0xFF) << 0)); +} + +static GList *append_library(GList *curr_list, struct gds_library **library_ptr) { struct gds_library *lib; @@ -161,6 +171,9 @@ static GList *append_library(GList *curr_list) lib->cell_names = NULL; } else return NULL; + if (library_ptr) + *library_ptr = lib; + return g_list_append(curr_list, lib); } @@ -331,6 +344,46 @@ void scan_library_references(gpointer library_list_item, gpointer user) g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib); } +void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date) +{ + if (!access_date || !mod_date) { + GDS_WARN("Date structures invalid"); + return; + } + + if (length != (2*6*2)) { + GDS_WARN("Could not parse date field! Not the specified length"); + return; + } + + mod_date->year = gds_convert_unsigend_int16(buffer); + buffer += 2; + mod_date->month = gds_convert_unsigend_int16(buffer); + buffer += 2; + mod_date->day = gds_convert_unsigend_int16(buffer); + buffer += 2; + mod_date->hour = gds_convert_unsigend_int16(buffer); + buffer += 2; + mod_date->minute = gds_convert_unsigend_int16(buffer); + buffer += 2; + mod_date->second = gds_convert_unsigend_int16(buffer); + buffer += 2; + + access_date->year = gds_convert_unsigend_int16(buffer); + buffer += 2; + access_date->month = gds_convert_unsigend_int16(buffer); + buffer += 2; + access_date->day = gds_convert_unsigend_int16(buffer); + buffer += 2; + access_date->hour = gds_convert_unsigend_int16(buffer); + buffer += 2; + access_date->minute = gds_convert_unsigend_int16(buffer); + buffer += 2; + access_date->second = gds_convert_unsigend_int16(buffer); + + +} + int parse_gds_from_file(const char *filename, GList **library_list) { char workbuff[1024]; @@ -404,7 +457,7 @@ int parse_gds_from_file(const char *filename, GList **library_list) /* if begin: Allocate structures */ switch (rec_type) { case BGNLIB: - lib_list = append_library(lib_list); + lib_list = append_library(lib_list, ¤t_lib); if (lib_list == NULL) { GDS_ERROR("Allocating memory failed"); run = -3; @@ -412,8 +465,6 @@ int parse_gds_from_file(const char *filename, GList **library_list) } printf("Entering Lib\n"); - current_lib = (struct gds_library *) - g_list_last(lib_list)->data; break; case ENDLIB: if (current_lib == NULL) { @@ -547,6 +598,13 @@ int parse_gds_from_file(const char *filename, GList **library_list) } switch (rec_type) { + case BGNLIB: + /* Parse date record */ + gds_parse_date(workbuff, read, ¤t_lib->mod_time, ¤t_lib->access_time); + break; + case BGNSTR: + gds_parse_date(workbuff, read, ¤t_cell->mod_time, ¤t_cell->access_time); + break; case LIBNAME: name_library(current_lib, read, workbuff); break; diff --git a/gdsparse.h b/gdsparse.h index ca16c07..97f3f32 100644 --- a/gdsparse.h +++ b/gdsparse.h @@ -35,6 +35,7 @@ struct gds_time_field { uint16_t minute; uint16_t second; }; + struct gds_point { int x; int y; @@ -68,7 +69,8 @@ struct gds_cell { struct gds_library { char name[CELL_NAME_MAX]; - struct gds_time_field time; + struct gds_time_field mod_time; + struct gds_time_field access_time; double unit_to_meters; GList *cells; GList *cell_names; diff --git a/main.c b/main.c index 7a27ed2..b723bd8 100644 --- a/main.c +++ b/main.c @@ -27,7 +27,9 @@ enum cell_store_columns { LIBRARY, CELL, - STORE_COLUMN + MODDATE, + ACCESSDATE, + STORE_COLUMN_COUNT }; @@ -45,7 +47,19 @@ gboolean on_window_close(gpointer window, gpointer user) return TRUE; } +static GString *generate_string_from_date(struct gds_time_field *date) +{ + GString *str; + str = g_string_new_len(NULL, 50); + g_string_printf(str, "%02u.%02u.%u - %02u:%02u", + (unsigned int)date->day, + (unsigned int)date->month, + (unsigned int)date->year, + (unsigned int)date->hour, + (unsigned int)date->minute); + return str; +} void on_load_gds(gpointer button, gpointer user) { @@ -64,6 +78,8 @@ void on_load_gds(gpointer button, gpointer user) gint dialog_result; int gds_result; char *filename; + GString *mod_date; + GString *acc_date; open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", ptr->main_window, GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel", GTK_RESPONSE_CANCEL, "Open GDSII", GTK_RESPONSE_ACCEPT, NULL); @@ -100,11 +116,40 @@ void on_load_gds(gpointer button, gpointer user) gds_lib = (struct gds_library *)lib->data; /* Create top level iter */ gtk_tree_store_append (store, &libiter, NULL); - gtk_tree_store_set (store, &libiter, LIBRARY, gds_lib->name, -1); + + /* Convert dates to String */ + mod_date = generate_string_from_date(&gds_lib->mod_time); + acc_date = generate_string_from_date(&gds_lib->access_time); + + gtk_tree_store_set (store, &libiter, + LIBRARY, gds_lib->name, + MODDATE, mod_date->str, + ACCESSDATE, acc_date->str, + -1); + + /* Delete GStrings including string data. */ + /* Cell store copies String type data items */ + g_string_free(mod_date, TRUE); + g_string_free(acc_date, TRUE); + for (cell = gds_lib->cells; cell != NULL; cell = cell->next) { gds_c = (struct gds_cell *)cell->data; gtk_tree_store_append (store, &celliter, &libiter); - gtk_tree_store_set (store, &celliter, CELL, gds_c->name, -1); + + /* Convert dates to String */ + mod_date = generate_string_from_date(&gds_c->mod_time); + acc_date = generate_string_from_date(&gds_c->access_time); + + gtk_tree_store_set (store, &celliter, + CELL, gds_c->name, + MODDATE, mod_date->str, + ACCESSDATE, acc_date->str, + -1); + + /* Delete GStrings including string data. */ + /* Cell store copies String type data items */ + g_string_free(mod_date, TRUE); + g_string_free(acc_date, TRUE); } } @@ -127,16 +172,47 @@ static GtkTreeStore * setup_cell_selector(GtkTreeView* view) GtkTreeStore *cell_store; GtkCellRenderer *render; + GtkCellRenderer *render_cell; GtkTreeViewColumn *column; + GdkRGBA cell_text_color; + GValue val = G_VALUE_INIT; - cell_store = gtk_tree_store_new(STORE_COLUMN, G_TYPE_STRING, G_TYPE_STRING); + cell_store = gtk_tree_store_new(STORE_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model(view, GTK_TREE_MODEL(cell_store)); render = gtk_cell_renderer_text_new(); + render_cell = gtk_cell_renderer_text_new(); + + /* Set foreground color */ + cell_text_color.alpha = 1; + cell_text_color.red = (double)61.0/(double)255.0; + cell_text_color.green = (double)152.0/(double)255.0; + cell_text_color.blue = 0.0; + + g_value_init(&val, G_TYPE_BOOLEAN); + g_value_set_boolean(&val, TRUE); + g_object_set_property(G_OBJECT(render_cell), "foreground-set", &val); + g_value_unset(&val); + + g_value_init(&val, GDK_TYPE_RGBA); + g_value_set_boxed(&val, &cell_text_color); + g_object_set_property(G_OBJECT(render_cell), "foreground-rgba", &val); + g_value_unset(&val); + + + + column = gtk_tree_view_column_new_with_attributes("Library", render, "text", LIBRARY, NULL); gtk_tree_view_append_column(view, column); - column = gtk_tree_view_column_new_with_attributes("Cell", render, "text", CELL, NULL); + /* Cell color: #3D9801 */ + column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "text", CELL, NULL); + gtk_tree_view_append_column(view, column); + + column = gtk_tree_view_column_new_with_attributes("Mod. Date", render, "text", MODDATE, NULL); + gtk_tree_view_append_column(view, column); + + column = gtk_tree_view_column_new_with_attributes("Acc. Date", render, "text", ACCESSDATE, NULL); gtk_tree_view_append_column(view, column); return cell_store;