From 67f9d9b4ee228bc14bbb55c3ae463c6f3d5f4cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 18 Mar 2019 21:12:47 +0100 Subject: [PATCH 01/12] Add source for ListBox Drag and Drop --- layer/layer-selector.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/layer/layer-selector.c b/layer/layer-selector.c index 6e9ef41..772aa39 100644 --- a/layer/layer-selector.c +++ b/layer/layer-selector.c @@ -56,7 +56,9 @@ struct _LayerSelector { G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT) -/* Drag and drop code */ +/* Drag and drop code + * Original code from https://blog.gtk.org/2017/06/01/drag-and-drop-in-lists-revisited/ + */ static void sel_layer_element_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) { From 008fe52cb25d72711b703891287ffb8741175778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 21 Mar 2019 21:24:59 +0100 Subject: [PATCH 02/12] Rename gds-parser folder to gds-utils because it no longer contains only the parser --- CMakeLists.txt | 4 ++-- cairo-output/cairo-output.h | 2 +- command-line.c | 4 ++-- external-renderer.h | 2 +- gds-render-gui.c | 4 ++-- {gds-parser => gds-utils}/gds-parser.c | 0 {gds-parser => gds-utils}/gds-parser.h | 0 {gds-parser => gds-utils}/gds-tree-checker.c | 0 {gds-parser => gds-utils}/gds-tree-checker.h | 0 {gds-parser => gds-utils}/gds-types.h | 0 latex-output/latex-output.h | 2 +- layer/layer-selector.c | 2 +- tree-renderer/lib-cell-renderer.c | 2 +- tree-renderer/tree-store.c | 2 +- trigonometric/cell-trigonometrics.h | 2 +- 15 files changed, 13 insertions(+), 13 deletions(-) rename {gds-parser => gds-utils}/gds-parser.c (100%) rename {gds-parser => gds-utils}/gds-parser.h (100%) rename {gds-parser => gds-utils}/gds-tree-checker.c (100%) rename {gds-parser => gds-utils}/gds-tree-checker.h (100%) rename {gds-parser => gds-utils}/gds-types.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b48142f..e866adc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ add_definitions(${GLIB2_CFLAGS_OTHER}) aux_source_directory("widgets" LAYER_SOURCES) aux_source_directory("tree-renderer" RENDERER_SOURCES) -aux_source_directory("gds-parser" PARSER_SOURCES) +aux_source_directory("gds-utils" GDS_SOURCES) aux_source_directory("latex-output" LATEX_SOURCES) aux_source_directory("cairo-output" CAIRO_SOURCES) aux_source_directory("trigonometric" TRIG_SOURCES) @@ -27,7 +27,7 @@ set(SOURCE ${SOURCE} ${LAYER_SOURCES} ${RENDERER_SOURCES} - ${PARSER_SOURCES} + ${GDS_SOURCES} ${LATEX_SOURCES} ${CAIRO_SOURCES} ${TRIG_SOURCES} diff --git a/cairo-output/cairo-output.h b/cairo-output/cairo-output.h index 3afccbe..32038ee 100644 --- a/cairo-output/cairo-output.h +++ b/cairo-output/cairo-output.h @@ -25,7 +25,7 @@ #define __CAIRO_OUTPUT_H__ #include "../layer/layer-info.h" -#include "../gds-parser/gds-types.h" +#include "../gds-utils/gds-types.h" /** @addtogroup Cairo-Renderer * @{ diff --git a/command-line.c b/command-line.c index ee7e8ec..af95917 100644 --- a/command-line.c +++ b/command-line.c @@ -30,13 +30,13 @@ #include #include "command-line.h" -#include "gds-parser/gds-parser.h" +#include "gds-utils/gds-parser.h" #include "mapping-parser.h" #include "layer/layer-info.h" #include "cairo-output/cairo-output.h" #include "latex-output/latex-output.h" #include "external-renderer.h" -#include "gds-parser/gds-tree-checker.h" +#include "gds-utils/gds-tree-checker.h" /** * @brief Delete layer_info and free nem element. diff --git a/external-renderer.h b/external-renderer.h index 841b219..63f5077 100644 --- a/external-renderer.h +++ b/external-renderer.h @@ -31,7 +31,7 @@ #ifndef _EXTERNAL_RENDERER_H_ #define _EXTERNAL_RENDERER_H_ -#include "gds-parser/gds-types.h" +#include "gds-utils/gds-types.h" #include /** diff --git a/gds-render-gui.c b/gds-render-gui.c index 55a0a32..f4ab8a1 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -29,7 +29,7 @@ #include "gds-render-gui.h" #include -#include "gds-parser/gds-parser.h" +#include "gds-utils/gds-parser.h" #include #include "layer/layer-selector.h" #include "tree-renderer/tree-store.h" @@ -39,7 +39,7 @@ #include "trigonometric/cell-trigonometrics.h" #include "version/version.h" #include "tree-renderer/lib-cell-renderer.h" -#include "gds-parser/gds-tree-checker.h" +#include "gds-utils/gds-tree-checker.h" enum gds_render_gui_signal_sig_ids {SIGNAL_WINDOW_CLOSED = 0, SIGNAL_COUNT}; diff --git a/gds-parser/gds-parser.c b/gds-utils/gds-parser.c similarity index 100% rename from gds-parser/gds-parser.c rename to gds-utils/gds-parser.c diff --git a/gds-parser/gds-parser.h b/gds-utils/gds-parser.h similarity index 100% rename from gds-parser/gds-parser.h rename to gds-utils/gds-parser.h diff --git a/gds-parser/gds-tree-checker.c b/gds-utils/gds-tree-checker.c similarity index 100% rename from gds-parser/gds-tree-checker.c rename to gds-utils/gds-tree-checker.c diff --git a/gds-parser/gds-tree-checker.h b/gds-utils/gds-tree-checker.h similarity index 100% rename from gds-parser/gds-tree-checker.h rename to gds-utils/gds-tree-checker.h diff --git a/gds-parser/gds-types.h b/gds-utils/gds-types.h similarity index 100% rename from gds-parser/gds-types.h rename to gds-utils/gds-types.h diff --git a/latex-output/latex-output.h b/latex-output/latex-output.h index 2329171..f20c543 100644 --- a/latex-output/latex-output.h +++ b/latex-output/latex-output.h @@ -31,7 +31,7 @@ * @{ */ -#include "../gds-parser/gds-types.h" +#include "../gds-utils/gds-types.h" #include #include #include "../layer/layer-info.h" diff --git a/layer/layer-selector.c b/layer/layer-selector.c index 772aa39..48f4f0c 100644 --- a/layer/layer-selector.c +++ b/layer/layer-selector.c @@ -30,7 +30,7 @@ #include "layer-selector.h" #include "layer-info.h" -#include "../gds-parser/gds-parser.h" +#include "../gds-utils/gds-parser.h" #include "../widgets/layer-element.h" #include "../mapping-parser.h" #include diff --git a/tree-renderer/lib-cell-renderer.c b/tree-renderer/lib-cell-renderer.c index 99e96e5..6af5512 100644 --- a/tree-renderer/lib-cell-renderer.c +++ b/tree-renderer/lib-cell-renderer.c @@ -18,7 +18,7 @@ */ #include "lib-cell-renderer.h" -#include "../gds-parser/gds-types.h" +#include "../gds-utils/gds-types.h" G_DEFINE_TYPE(LibCellRenderer, lib_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT) diff --git a/tree-renderer/tree-store.c b/tree-renderer/tree-store.c index 3da3d63..9ab9411 100644 --- a/tree-renderer/tree-store.c +++ b/tree-renderer/tree-store.c @@ -30,7 +30,7 @@ #include "tree-store.h" #include "lib-cell-renderer.h" -#include "../gds-parser/gds-types.h" +#include "../gds-utils/gds-types.h" /** * @brief this function olny allows cells to be selected diff --git a/trigonometric/cell-trigonometrics.h b/trigonometric/cell-trigonometrics.h index 2a4ba5d..6136bb2 100644 --- a/trigonometric/cell-trigonometrics.h +++ b/trigonometric/cell-trigonometrics.h @@ -32,7 +32,7 @@ #define _CELL_TRIGONOMETRICS_H_ #include "bounding-box.h" -#include "../gds-parser/gds-types.h" +#include "../gds-utils/gds-types.h" /** * @brief calculate_cell_bounding_box Calculate bounding box of gds cell From 4c0df5638638f5f18bc3b9aa7c60a74b307a05cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 21 Mar 2019 21:26:31 +0100 Subject: [PATCH 03/12] cast unused variables --- tree-renderer/tree-store.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tree-renderer/tree-store.c b/tree-renderer/tree-store.c index 9ab9411..de4194c 100644 --- a/tree-renderer/tree-store.c +++ b/tree-renderer/tree-store.c @@ -51,6 +51,9 @@ static gboolean tree_sel_func(GtkTreeSelection *selection, struct gds_cell *cell; unsigned int error_level; gboolean ret = FALSE; + (void)selection; + (void)path_currently_selected; + (void)data; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1); @@ -112,6 +115,8 @@ exit_filter: static void change_filter(GtkWidget *entry, gpointer data) { struct tree_stores *stores = (struct tree_stores *)data; + (void)entry; + gtk_tree_model_filter_refilter(stores->filter); } From b43b142a75bfa67a28b7a5ca8ff0f7990dfbfbb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 21 Mar 2019 21:48:11 +0100 Subject: [PATCH 04/12] Coding improvements in conversion settings dialog --- widgets/conv-settings-dialog.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/widgets/conv-settings-dialog.c b/widgets/conv-settings-dialog.c index d4444d7..79533d4 100644 --- a/widgets/conv-settings-dialog.c +++ b/widgets/conv-settings-dialog.c @@ -140,6 +140,7 @@ static double convert_number_to_engineering(double input, const char **out_prefi 1E2, 1E3, 1E6, 1E9, 1E12, 1E15, 1E18, 1E21, 1E24}; const int prefix_count = (int)(sizeof(prefixes)/sizeof(char *)); + /* Start with the 2nd smallest prefix */ for (idx = 1; idx < prefix_count; idx++) { if (input < scale[idx]) { /* This prefix is bigger than the number. Take the previous one */ @@ -212,7 +213,7 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self) GtkWidget *box; GtkDialog *dialog; - dialog = &(self->parent); + dialog = &self->parent; builder = gtk_builder_new_from_resource("/dialog.glade"); box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box")); @@ -260,10 +261,7 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent) void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings) { - /*GList *radio_buttons; - *GList *temp_button_list; - *GtkToggleButton *temp_button = NULL; - */ + if (!settings || !dialog) return; settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale)); From 5537c076a83efe13b2e05fb7ecdba98f866a7704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Thu, 21 Mar 2019 22:22:35 +0100 Subject: [PATCH 05/12] Add logo as resource and configure about dialog to use logo from resource --- glade/CMakeLists.txt | 1 + glade/about.glade | 2 +- glade/resources.xml | 1 + main.c | 16 ++++++++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/glade/CMakeLists.txt b/glade/CMakeLists.txt index 19dcf2f..7e98584 100644 --- a/glade/CMakeLists.txt +++ b/glade/CMakeLists.txt @@ -1,6 +1,7 @@ add_custom_target(glib-resources DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resources.c) add_custom_command(DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.glade + ${CMAKE_CURRENT_SOURCE_DIR}/resources.xml OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resources.c COMMAND diff --git a/glade/about.glade b/glade/about.glade index a0a6784..b21402d 100644 --- a/glade/about.glade +++ b/glade/about.glade @@ -10,7 +10,7 @@ https://git.shimatta.de/mhu/gds-render Git Repository Mario Hüttel <mario.huettel@gmx.net> - gds-render + gpl-2-0-only diff --git a/glade/resources.xml b/glade/resources.xml index e33bed3..97ba844 100644 --- a/glade/resources.xml +++ b/glade/resources.xml @@ -5,6 +5,7 @@ about.glade layer-widget.glade dialog.glade + ../icon/gds-render.svg diff --git a/main.c b/main.c index 3a419d5..5d6de63 100644 --- a/main.c +++ b/main.c @@ -52,6 +52,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_ { GtkBuilder *builder; GtkDialog *dialog; + GdkPixbuf *logo_buf; + GError *error = NULL; (void)user_data; (void)action; (void)parameter; @@ -60,6 +62,20 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_ dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog")); gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string); + + /* Load icon from resource */ + logo_buf = gdk_pixbuf_new_from_resource_at_scale("/logo.svg", 100, 100, TRUE, &error); + if (logo_buf) { + /* Set logo */ + gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo_buf); + + /* Pixbuf is now owned by about dialog. Unref */ + g_object_unref(logo_buf); + } else if (error) { + fprintf(stderr, "Logo could not be displayed: %s\n", error->message); + g_error_free(error); + } + gtk_dialog_run(dialog); gtk_widget_destroy(GTK_WIDGET(dialog)); From ff3f692f2c8112c44ba6e7476a227729cb286c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 22 Mar 2019 21:59:27 +0100 Subject: [PATCH 06/12] Make renderer settings dialog settings unique for each window --- gds-render-gui.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/gds-render-gui.c b/gds-render-gui.c index f4ab8a1..8763640 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -57,6 +57,7 @@ struct _GdsRenderGui { LayerSelector *layer_selector; GtkTreeView *cell_tree_view; GList *gds_libraries; + struct render_settings render_dialog_settings; }; G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT) @@ -245,10 +246,6 @@ end_destroy: static void on_convert_clicked(gpointer button, gpointer user) { (void)button; - static struct render_settings sett = { - .scale = 1000.0, - .renderer = RENDERER_LATEX_TIKZ, - }; GdsRenderGui *self; GtkTreeSelection *selection; GtkTreeIter iter; @@ -263,12 +260,15 @@ static void on_convert_clicked(gpointer button, gpointer user) char *file_name; union bounding_box cell_box; unsigned int height, width; + struct render_settings *sett; self = RENDERER_GUI(user); if (!self) return; + sett = &self->render_dialog_settings; + /* Get selected cell */ selection = gtk_tree_view_get_selection(self->cell_tree_view); if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) @@ -295,14 +295,14 @@ static void on_convert_clicked(gpointer button, gpointer user) /* Show settings dialog */ settings = renderer_settings_dialog_new(GTK_WINDOW(self->main_window)); - renderer_settings_dialog_set_settings(settings, &sett); + renderer_settings_dialog_set_settings(settings, sett); renderer_settings_dialog_set_database_unit_scale(settings, cell_to_render->parent_library->unit_in_meters); renderer_settings_dialog_set_cell_height(settings, height); renderer_settings_dialog_set_cell_width(settings, width); res = gtk_dialog_run(GTK_DIALOG(settings)); if (res == GTK_RESPONSE_OK) { - renderer_settings_dialog_get_settings(settings, &sett); + renderer_settings_dialog_get_settings(settings, sett); gtk_widget_destroy(GTK_WIDGET(settings)); } else { gtk_widget_destroy(GTK_WIDGET(settings)); @@ -310,13 +310,13 @@ static void on_convert_clicked(gpointer button, gpointer user) } /* save file dialog */ - dialog = gtk_file_chooser_dialog_new((sett.renderer == RENDERER_LATEX_TIKZ + dialog = gtk_file_chooser_dialog_new((sett->renderer == RENDERER_LATEX_TIKZ ? "Save LaTeX File" : "Save PDF"), GTK_WINDOW(self->main_window), GTK_FILE_CHOOSER_ACTION_SAVE, "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL); /* Set file filter according to settings */ filter = gtk_file_filter_new(); - switch (sett.renderer) { + switch (sett->renderer) { case RENDERER_LATEX_TIKZ: gtk_file_filter_add_pattern(filter, "*.tex"); gtk_file_filter_set_name(filter, "LaTeX-Files"); @@ -340,23 +340,23 @@ static void on_convert_clicked(gpointer button, gpointer user) file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); - switch (sett.renderer) { + switch (sett->renderer) { case RENDERER_LATEX_TIKZ: output_file = fopen(file_name, "w"); - latex_render_cell_to_code(cell_to_render, layer_list, output_file, sett.scale, - sett.tex_pdf_layers, sett.tex_standalone); + latex_render_cell_to_code(cell_to_render, layer_list, output_file, sett->scale, + sett->tex_pdf_layers, sett->tex_standalone); fclose(output_file); break; case RENDERER_CAIROGRAPHICS_SVG: case RENDERER_CAIROGRAPHICS_PDF: cairo_render_cell_to_vector_file(cell_to_render, layer_list, - (sett.renderer == RENDERER_CAIROGRAPHICS_PDF + (sett->renderer == RENDERER_CAIROGRAPHICS_PDF ? file_name : NULL), - (sett.renderer == RENDERER_CAIROGRAPHICS_SVG + (sett->renderer == RENDERER_CAIROGRAPHICS_SVG ? file_name : NULL), - sett.scale); + sett->scale); break; } g_free(file_name); @@ -534,6 +534,13 @@ static void gds_render_gui_init(GdsRenderGui *self) g_object_unref(main_builder); + /* Set default conversion/rendering settings */ + self->render_dialog_settings.scale = 1000; + self->render_dialog_settings.renderer = RENDERER_LATEX_TIKZ; + self->render_dialog_settings.tex_pdf_layers = FALSE; + self->render_dialog_settings.tex_standalone = FALSE; + + /* Reference all objects referenced by this object */ g_object_ref(self->main_window); g_object_ref(self->cell_tree_view); From 38f18009fcd5e6e83e8b5a55ba80bc78b3fe2d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 22 Mar 2019 22:15:56 +0100 Subject: [PATCH 07/12] Rework Cairo-Render output messages --- cairo-output/cairo-output.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cairo-output/cairo-output.c b/cairo-output/cairo-output.c index 9db1b8e..5d66557 100644 --- a/cairo-output/cairo-output.c +++ b/cairo-output/cairo-output.c @@ -235,8 +235,12 @@ void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, /* Print size */ cairo_recording_surface_ink_extents(layers[linfo->layer].rec, &rec_x0, &rec_y0, &rec_width, &rec_height); - printf("Size of layer %d: %lf -- %lf\n", linfo->layer, - rec_width, rec_height); + printf("Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n", + linfo->layer, + (linfo->name && linfo->name[0] ? " (" : ""), + (linfo->name && linfo->name[0] ? linfo->name : ""), + (linfo->name && linfo->name[0] ? ")" : ""), + rec_width, rec_height, rec_x0, rec_y0); /* update bounding box */ xmin = MIN(xmin, rec_x0); @@ -250,7 +254,7 @@ void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, } - printf("Bounding box: (%lf,%lf) -- (%lf,%lf)\n", xmin, ymin, xmax, ymax); + printf("Cell bounding box: (%lf | %lf) -- (%lf | %lf)\n", xmin, ymin, xmax, ymax); if (pdf_file) { pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin); From 188086de5216a64da7f51d8d2a24d0fd183ebeba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 22 Mar 2019 22:24:48 +0100 Subject: [PATCH 08/12] Rework code: simplify if --- gds-render-gui.c | 134 +++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/gds-render-gui.c b/gds-render-gui.c index 8763640..b295a57 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -153,85 +153,83 @@ static void on_load_gds(gpointer button, gpointer user) dialog_result = gtk_dialog_run(GTK_DIALOG(open_dialog)); - if (dialog_result == GTK_RESPONSE_ACCEPT) { + if (dialog_result != GTK_RESPONSE_ACCEPT) + goto end_destroy; - /* Get File name */ - filename = gtk_file_chooser_get_filename(file_chooser); + /* Get File name */ + filename = gtk_file_chooser_get_filename(file_chooser); - gtk_tree_store_clear(self->cell_tree_store); - clear_lib_list(&self->gds_libraries); + gtk_tree_store_clear(self->cell_tree_store); + clear_lib_list(&self->gds_libraries); - /* Parse new GDSII file */ - gds_result = parse_gds_from_file(filename, &self->gds_libraries); + /* Parse new GDSII file */ + gds_result = parse_gds_from_file(filename, &self->gds_libraries); - /* Delete file name afterwards */ - g_free(filename); - if (gds_result) - goto end_destroy; + /* Delete file name afterwards */ + g_free(filename); + if (gds_result) + goto end_destroy; - /* remove suggested action from Open button */ - button_style = gtk_widget_get_style_context(GTK_WIDGET(button)); - gtk_style_context_remove_class(button_style, "suggested-action"); + /* remove suggested action from Open button */ + button_style = gtk_widget_get_style_context(GTK_WIDGET(button)); + gtk_style_context_remove_class(button_style, "suggested-action"); - for (lib = self->gds_libraries; lib != NULL; lib = lib->next) { - gds_lib = (struct gds_library *)lib->data; - /* Create top level iter */ - gtk_tree_store_append(self->cell_tree_store, &libiter, NULL); + for (lib = self->gds_libraries; lib != NULL; lib = lib->next) { + gds_lib = (struct gds_library *)lib->data; + /* Create top level iter */ + gtk_tree_store_append(self->cell_tree_store, &libiter, NULL); + /* 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(self->cell_tree_store, &libiter, + CELL_SEL_LIBRARY, gds_lib, + CELL_SEL_MODDATE, mod_date->str, + CELL_SEL_ACCESSDATE, acc_date->str, + -1); + + /* Check this library. This might take a while */ + (void)gds_tree_check_cell_references(gds_lib); + (void)gds_tree_check_reference_loops(gds_lib); + /* 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(self->cell_tree_store, &celliter, &libiter); /* Convert dates to String */ - mod_date = generate_string_from_date(&gds_lib->mod_time); - acc_date = generate_string_from_date(&gds_lib->access_time); + mod_date = generate_string_from_date(&gds_c->mod_time); + acc_date = generate_string_from_date(&gds_c->access_time); - gtk_tree_store_set(self->cell_tree_store, &libiter, - CELL_SEL_LIBRARY, gds_lib, + /* Get the checking results for this cell */ + cell_error_level = 0; + if (gds_c->checks.unresolved_child_count) + cell_error_level |= LIB_CELL_RENDERER_ERROR_WARN; + + /* Check if it is completely b0rken */ + if (gds_c->checks.affected_by_reference_loop) + cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR; + + /* Add cell to tree store model */ + gtk_tree_store_set(self->cell_tree_store, &celliter, + CELL_SEL_CELL, gds_c, CELL_SEL_MODDATE, mod_date->str, CELL_SEL_ACCESSDATE, acc_date->str, + CELL_SEL_CELL_ERROR_STATE, cell_error_level, -1); - /* Check this library. This might take a while */ - (void)gds_tree_check_cell_references(gds_lib); - (void)gds_tree_check_reference_loops(gds_lib); - /* 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 cells */ + } /* for libraries */ - for (cell = gds_lib->cells; cell != NULL; cell = cell->next) { - gds_c = (struct gds_cell *)cell->data; - gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter); - - /* Convert dates to String */ - mod_date = generate_string_from_date(&gds_c->mod_time); - acc_date = generate_string_from_date(&gds_c->access_time); - - /* Get the checking results for this cell */ - cell_error_level = 0; - if (gds_c->checks.unresolved_child_count) - cell_error_level |= LIB_CELL_RENDERER_ERROR_WARN; - - /* Check if it is completely b0rken */ - if (gds_c->checks.affected_by_reference_loop) - cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR; - - /* Add cell to tree store model */ - gtk_tree_store_set(self->cell_tree_store, &celliter, - CELL_SEL_CELL, gds_c, - CELL_SEL_MODDATE, mod_date->str, - CELL_SEL_ACCESSDATE, acc_date->str, - CELL_SEL_CELL_ERROR_STATE, cell_error_level, - -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); - } - } - - /* Create Layers in Layer Box */ - layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries); - } + /* Create Layers in Layer Box */ + layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries); end_destroy: /* Destroy dialog and filter */ @@ -351,11 +349,11 @@ static void on_convert_clicked(gpointer button, gpointer user) case RENDERER_CAIROGRAPHICS_PDF: cairo_render_cell_to_vector_file(cell_to_render, layer_list, (sett->renderer == RENDERER_CAIROGRAPHICS_PDF - ? file_name - : NULL), + ? file_name + : NULL), (sett->renderer == RENDERER_CAIROGRAPHICS_SVG - ? file_name - : NULL), + ? file_name + : NULL), sett->scale); break; } @@ -523,10 +521,10 @@ static void gds_render_gui_init(GdsRenderGui *self) /* Set buttons for loading and saving */ layer_selector_set_load_mapping_button(self->layer_selector, - GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping")), - self->main_window); + GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping")), + self->main_window); layer_selector_set_save_mapping_button(self->layer_selector, GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping")), - self->main_window); + self->main_window); /* Connect delete-event */ g_signal_connect(GTK_WIDGET(self->main_window), "delete-event", From f237004e6ce4f5d884f05fc27a2f58eb4342d77b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 22 Mar 2019 22:43:24 +0100 Subject: [PATCH 09/12] Remove useless function call --- gds-render-gui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gds-render-gui.c b/gds-render-gui.c index b295a57..5a7785a 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -482,7 +482,6 @@ static void gds_render_gui_init(GdsRenderGui *self) GtkWidget *sort_down_button; main_builder = gtk_builder_new_from_resource("/main.glade"); - gtk_builder_connect_signals(main_builder, NULL); self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree")); self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search")); From a99a469cf0e09c3c5996d849655c97b48b4af71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 25 Mar 2019 17:56:57 +0100 Subject: [PATCH 10/12] Rename functions of mapping parser --- command-line.c | 2 +- layer/layer-selector.c | 4 ++-- mapping-parser.c | 4 ++-- mapping-parser.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/command-line.c b/command-line.c index af95917..03caa08 100644 --- a/command-line.c +++ b/command-line.c @@ -98,7 +98,7 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb dstream = g_data_input_stream_new(G_INPUT_STREAM(stream)); i = 0; do { - res = load_csv_line(dstream, &layer_export, &layer_name, &layer, &layer_color); + res = mapping_parser_load_line(dstream, &layer_export, &layer_name, &layer, &layer_color); if (res == 0) { if (!layer_export) continue; diff --git a/layer/layer-selector.c b/layer/layer-selector.c index 48f4f0c..7b99156 100644 --- a/layer/layer-selector.c +++ b/layer/layer-selector.c @@ -592,7 +592,7 @@ static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gch gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(le)); } - while((result = load_csv_line(dstream, &export, &name, &layer, &color)) >= 0) { + while((result = mapping_parser_load_line(dstream, &export, &name, &layer, &color)) >= 0) { /* skip broken line */ if (result == 1) continue; @@ -678,7 +678,7 @@ static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gc for (temp = le_list; temp != NULL; temp = temp->next) { /* To be sure it is a valid string */ workbuff[0] = 0; - create_csv_line(LAYER_ELEMENT(temp->data), workbuff, sizeof(workbuff)); + mapping_parser_gen_csv_line(LAYER_ELEMENT(temp->data), workbuff, sizeof(workbuff)); fwrite(workbuff, sizeof(char), strlen(workbuff), file); } diff --git a/mapping-parser.c b/mapping-parser.c index 861b776..e5fad1b 100644 --- a/mapping-parser.c +++ b/mapping-parser.c @@ -31,7 +31,7 @@ #include "mapping-parser.h" -int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color) +int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color) { int ret; gsize len; @@ -94,7 +94,7 @@ ret_direct: } -void create_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len) +void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len) { int i; GString *string; diff --git a/mapping-parser.h b/mapping-parser.h index 4fe92dc..dec10a4 100644 --- a/mapping-parser.h +++ b/mapping-parser.h @@ -43,7 +43,7 @@ * @param color RGBA color. * @return 1 if malformatted line, 0 if parsing was successful and parameters are valid, -1 if file end */ -int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color); +int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color); /** * @brief Create Line for LayerMapping file with supplied information @@ -51,7 +51,7 @@ int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int * * @param line_buffer buffer to write to * @param max_len Maximum length that cna be used in \p line_buffer */ -void create_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len); +void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len); /** @} */ From 829c9a2386a19eaddbde814009f2e603e44cc635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 25 Mar 2019 18:47:12 +0100 Subject: [PATCH 11/12] Restructure code, improve doxygen documentation --- gds-render-gui.c | 21 +++++++++--------- gds-render-gui.h | 4 ++-- layer/layer-selector.c | 49 +++++++++++++++++++++++++++++------------ layer/layer-selector.h | 27 ++++++++++++----------- widgets/layer-element.c | 21 ++++++++++-------- widgets/layer-element.h | 29 ++++++++++++++++-------- 6 files changed, 94 insertions(+), 57 deletions(-) diff --git a/gds-render-gui.c b/gds-render-gui.c index 5a7785a..6f68fc0 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -63,12 +63,11 @@ struct _GdsRenderGui { G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT) /** - * @brief Window close event of main window - * - * Closes the main window. This leads to the termination of the whole application - * @param window main window - * @param user not used - * @return TRUE. This indicates that the event has been fully handled + * @brief Main window close event + * @param window GtkWindow which is closed + * @param event unused event + * @param user GdsRenderGui instance + * @return Status of the event handling. Always true. */ static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user) { @@ -113,7 +112,7 @@ static GString *generate_string_from_date(struct gds_time_field *date) /** * @brief Callback function of Load GDS button * @param button - * @param user Necessary Data + * @param user GdsRenderGui instance */ static void on_load_gds(gpointer button, gpointer user) { @@ -367,9 +366,11 @@ ret_layer_destroy: } /** - * @brief cell_tree_view_activated - * @param tree_view Not used - * @param user convert button data + * @brief cell_tree_view_activated Callback for 'double click' on cell selector element + * @param tree_view The tree view the event occured in + * @param path path to the selected row + * @param column The clicked column + * @param user pointer to GdsRenderGui object */ static void cell_tree_view_activated(gpointer tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user) diff --git a/gds-render-gui.h b/gds-render-gui.h index 9e2941b..46dd3a2 100644 --- a/gds-render-gui.h +++ b/gds-render-gui.h @@ -41,7 +41,7 @@ G_DECLARE_FINAL_TYPE(GdsRenderGui, gds_render_gui, RENDERER, GUI, GObject); /** * @brief Create new GdsRenderGui Object - * @return + * @return New object */ GdsRenderGui *gds_render_gui_new(); @@ -50,7 +50,7 @@ GdsRenderGui *gds_render_gui_new(); * * This function returns the main window of the GUI, which can later be displayed. * All handling of hte GUI is taken care of inside the GdsRenderGui Object - * @return + * @return The generated main window */ GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui); diff --git a/layer/layer-selector.c b/layer/layer-selector.c index 7b99156..b23dc2f 100644 --- a/layer/layer-selector.c +++ b/layer/layer-selector.c @@ -424,9 +424,10 @@ static void layer_selector_clear_widgets(LayerSelector *self) } /** - * @brief Check if specific layer number is present in list box - * @param layer Layer nu,ber - * @return TRUE if present + * @brief Check if a specific layer element with the given layer number is present in the layer selector + * @param self LayerSelector instance + * @param layer Layer number to check for + * @return TRUE if layer is present, else FALSE */ static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer) { GList *list; @@ -449,17 +450,30 @@ static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, return ret; } +/** + * @brief Setup the necessary drag and drop callbacks of layer elements. + * @param self LayerSelector instance. Used to get the DnD target entry. + * @param element LayerElement instance to set the callbacks + */ static void sel_layer_element_setup_dnd_callbacks(LayerSelector *self, LayerElement *element) { - layer_element_set_dnd_callbacks(element, &self->dnd_target, 1, - sel_layer_element_drag_begin, - sel_layer_element_drag_data_get, - sel_layer_element_drag_end); + struct layer_element_dnd_data dnd_data; + + if (!self || !element) + return; + + dnd_data.entries = &self->dnd_target; + dnd_data.entry_count = 1; + dnd_data.drag_end = sel_layer_element_drag_end; + dnd_data.drag_begin = sel_layer_element_drag_begin; + dnd_data.drag_data_get = sel_layer_element_drag_data_get; + + layer_element_set_dnd_callbacks(element, &dnd_data); } /** - * @brief Analyze \p cell and append used layers to list box - * @param listbox listbox to add layer + * @brief Analyze \p cell layers and append detected layers to layer selector \p self + * @param self LayerSelector instance * @param cell Cell to analyze */ static void layer_selector_analyze_cell_layers(LayerSelector *self, struct gds_cell *cell) @@ -557,8 +571,15 @@ static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, i } /** - * @brief Load file and apply layer definitions to listbox - * @param file_name CSV Layer Mapping File + * @brief Load the layer mapping from a CSV formatted file + * + * This function imports the layer specification from a file (see @ref lmf-spec). + * The layer ordering defined in the file is kept. All layers present in the + * current loaded library, which are not present in the layer mapping file + * are appended at the end of the layer selector list. + * + * @param self LayerSelector instance + * @param file_name File name to load from */ static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gchar *file_name) { @@ -658,9 +679,9 @@ static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user /** - * @brief Save layer mapping of whole list box into file - * @param file_name layer mapping file - * @param list_box listbox + * @brief Save layer mapping of selector \p self to a file + * @param self LayerSelector instance + * @param file_name File name to save to */ static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gchar *file_name) { diff --git a/layer/layer-selector.h b/layer/layer-selector.h index 10e87e0..2719434 100644 --- a/layer/layer-selector.h +++ b/layer/layer-selector.h @@ -48,39 +48,40 @@ enum layer_selector_sort_algo {LAYER_SELECTOR_SORT_DOWN = 0, LAYER_SELECTOR_SORT LayerSelector *layer_selector_new(GtkListBox *list_box); /** - * @brief Generate layer widgets in \p listbox + * @brief Generate layer widgets in in the LayerSelector instance * @note This clears all previously inserted elements - * @param listbox + * @param selector LayerSelector instance * @param libs The libraries to add */ void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs); /** * @brief Supply button for loading the layer mapping - * @param button - * @param main_window Parent window for dialogs + * @param selector LayerSelector instance + * @param button Load button. Will be referenced + * @param main_window Parent window for dialogs. Will be referenced */ void layer_selector_set_load_mapping_button(LayerSelector *selector, GtkWidget *button, GtkWindow *main_window); /** * @brief Supply button for saving the layer mapping - * @param button - * @param main_window Parent window for dialogs + * @param selector LayerSelector instance + * @param button Save button. Will be refeneced + * @param main_window Parent window for dialogs. Will be referenced */ void layer_selector_set_save_mapping_button(LayerSelector *selector, GtkWidget *button, GtkWindow *main_window); /** - * @brief get the layer information present in the listbox of the selector - * @return List with layer_info elements + * @brief Get a list of all layers that shall be exported when rendering the cells + * @param selector Layer selector instance + * @return List of layer_info structures containing the layer information */ GList *layer_selector_export_rendered_layer_info(LayerSelector *selector); /** - * @brief Force sorting of the layer selector in a specified way - * - * If the layer selector is not yet set up, this function has no effect. - * - * @param sort_function Sorting direction + * @brief Force the layer selector list to be sorted according to \p sort_function + * @param selector LayerSelector instance + * @param sort_function The sorting method (up or down sorting) */ void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort_algo sort_function); diff --git a/widgets/layer-element.c b/widgets/layer-element.c index f1d3efd..d9257b2 100644 --- a/widgets/layer-element.c +++ b/widgets/layer-element.c @@ -120,26 +120,29 @@ void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba) { if (!rgba) return; + gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba); } void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba) { + if (!elem || !rgba) + return; + gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba); } -void layer_element_set_dnd_callbacks(LayerElement *elem, GtkTargetEntry *entries, int entry_count, - void (*drag_begin)(GtkWidget *, GdkDragContext *, gpointer), - void (*drag_data_get)(GtkWidget *, GdkDragContext *, - GtkSelectionData *, guint , guint, gpointer), - void (*drag_end)(GtkWidget *, GdkDragContext *, gpointer)) +void layer_element_set_dnd_callbacks(LayerElement *elem, struct layer_element_dnd_data *data) { + if (!elem || !data) + return; + /* Setup drag and drop */ gtk_style_context_add_class (gtk_widget_get_style_context(GTK_WIDGET(elem)), "row"); - gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK, entries, entry_count, GDK_ACTION_MOVE); - g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(drag_begin), NULL); - g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(drag_data_get), NULL); - g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(drag_end), NULL); + gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK, data->entries, data->entry_count, GDK_ACTION_MOVE); + g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(data->drag_begin), NULL); + g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(data->drag_data_get), NULL); + g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(data->drag_end), NULL); } diff --git a/widgets/layer-element.h b/widgets/layer-element.h index 8d30c09..a514363 100644 --- a/widgets/layer-element.h +++ b/widgets/layer-element.h @@ -56,6 +56,22 @@ struct _LayerElement { LayerElementPriv priv; }; +/** + * @brief This structure holds the necessary data to set up a LayerElement for Drag'n'Drop + */ +struct layer_element_dnd_data { + /** @brief Array of target entries for the DnD operation */ + GtkTargetEntry *entries; + /** @brief Count of elements in layer_element_dnd_data::entries array */ + int entry_count; + /** @brief Callback function for drag_begin event */ + void (*drag_begin)(GtkWidget *, GdkDragContext *, gpointer); + /** @brief Callback fucktion for data_get event */ + void (*drag_data_get)(GtkWidget *, GdkDragContext *, GtkSelectionData *, guint, guint, gpointer); + /** @brief Callback function for drag_end event */ + void (*drag_end)(GtkWidget *, GdkDragContext *, gpointer); +}; + /** * @brief Create new layer element object * @return new object @@ -119,16 +135,11 @@ void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba); void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba); /** - * @brief layer_element_set_dnd_callbacks - * @param elem - * @param entries - * @param entry_count + * @brief Setup drag and drop of \p elem for use in the LayerSelector + * @param elem Layer element to set up + * @param data Data array containing the necessary callbacks etc. for drag and drop. */ -void layer_element_set_dnd_callbacks(LayerElement *elem, GtkTargetEntry *entries, int entry_count, - void (*drag_begin)(GtkWidget *, GdkDragContext *, gpointer), - void (*drag_data_get)(GtkWidget *, GdkDragContext *, - GtkSelectionData *, guint , guint, gpointer), - void (*drag_end)(GtkWidget *, GdkDragContext *, gpointer)); +void layer_element_set_dnd_callbacks(LayerElement *elem, struct layer_element_dnd_data *data); G_END_DECLS From d6fb6ba6b08f0c0af0d2a4bff62d9c2431a51038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 25 Mar 2019 18:57:48 +0100 Subject: [PATCH 12/12] Remove SVG output from GUI, fixes issue #9 --- glade/dialog.glade | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/glade/dialog.glade b/glade/dialog.glade index 792d1ca..f24f7f1 100644 --- a/glade/dialog.glade +++ b/glade/dialog.glade @@ -16,7 +16,6 @@ Generate LaTeX/TikZ output - True True True False @@ -32,11 +31,9 @@ Render PDF using Cairographics - True True True False - True True latex-radio @@ -49,11 +46,10 @@ Render SVG using Cairographics (too buggy at the moment) - True True + False True False - True True latex-radio