32 #if !defined(WIN32) && !defined(QUARTZ)
68 #include <cairo-win32.h>
70 #include <cairo-quartz.h>
72 #include <cairo-xlib.h>
83 #define GERBV_PROJECT_FILE_EXT ".gvp"
84 const char* gerbv_project_file_name = N_(
"Gerbv Project");
85 const char* gerbv_project_file_pat =
"*" GERBV_PROJECT_FILE_EXT;
88 static void callbacks_units_changed(gerbv_gui_unit_t unit);
89 static void callbacks_update_statusbar_coordinates(gint x, gint y);
90 static void callbacks_update_ruler_scales(
void);
91 static void callbacks_render_type_changed(
void);
92 static void show_no_layers_warning(
void);
94 static double screen_units(
double);
95 static const char* screen_units_str(
void);
97 static double line_length(
double,
double,
double,
double);
98 static double arc_length(
double,
double);
102 static void drill_report(gerbv_aperture_t*[],
int);
105 static void analyze_window_size_restore(GtkWidget*);
106 static void analyze_window_size_store(GtkWidget*, gpointer);
108 static void update_selected_object_message(gboolean userTriedToSelect);
111 utf8_strncpy(gchar* dst,
const gchar* src, gsize byte_len) {
113 glong char_len = g_utf8_strlen(src, byte_len - 1);
114 return g_utf8_strncpy(dst, src, char_len);
118 utf8_snprintf(gchar* dst, gsize byte_len,
const gchar* fmt, ...) {
122 gchar* str = g_strdup_vprintf(fmt, ap);
124 utf8_strncpy(dst, str, byte_len);
131 show_no_layers_warning(
void) {
132 gchar* str = g_new(gchar, MAX_DISTLEN);
133 utf8_strncpy(str, _(
"No layers are currently loaded. A layer must be loaded first."), MAX_DISTLEN - 7);
134 utf8_snprintf(screen.statusbar.diststr, MAX_DISTLEN,
"<b>%s</b>", str);
150 _(
"Do you want to close any open layers "
151 "and start a new project?"),
152 _(
"Starting a new project will cause all currently "
153 "open layers to be closed. Any unsaved changes "
155 FALSE, NULL, GTK_STOCK_CLOSE, GTK_STOCK_CANCEL
161 callbacks_update_layer_tree();
162 selection_clear(&screen.selectionInfo);
163 update_selected_object_message(FALSE);
170 render_refresh_rendered_image_on_screen();
186 _(
"Do you want to close any open layers and load "
187 "an existing project?"),
188 _(
"Loading a project will cause all currently open "
189 "layers to be closed. Any unsaved changes "
191 FALSE, NULL, GTK_STOCK_CLOSE, GTK_STOCK_CANCEL
202 main_open_project_from_filename(
mainProject, project_filename);
216 GSList* fns_is_mod = NULL;
217 GSList* fns_cnt = NULL;
218 GSList* fns_lay_num = NULL;
223 if (filenames == NULL)
228 for (GSList* fn = filenames; fn; fn = fn->next) {
229 gboolean is_project = FALSE;
234 render_refresh_rendered_image_on_screen();
235 callbacks_update_layer_tree();
242 for (GSList* fn = filenames; fn; fn = fn->next) {
248 if (strlen(fpn) == strlen(fn->data) && 0 == g_ascii_strncasecmp(fpn, fn->data, strlen(fn->data))) {
253 cnt = g_slist_append(cnt, GINT_TO_POINTER(c));
260 for (GSList* fn = filenames; fn; fn = fn->next) {
261 if (strlen(fpn) == strlen(fn->data) && 0 == g_ascii_strncasecmp(fpn, fn->data, strlen(fn->data))) {
262 fns = g_slist_append(fns, fn->data);
264 fns_cnt = g_slist_append(fns_cnt, g_slist_nth_data(cnt, g_slist_position(filenames, fn)));
265 fns_lay_num = g_slist_append(fns_lay_num, GINT_TO_POINTER(fidx));
272 answer = GTK_RESPONSE_NONE;
273 if (g_slist_length(fns) > 0)
278 case GTK_RESPONSE_CANCEL:
279 case GTK_RESPONSE_NONE:
280 case GTK_RESPONSE_DELETE_EVENT:
284 case GTK_RESPONSE_YES:
285 for (GSList* fn = fns; fn; fn = fn->next) {
286 if (fn->data != NULL)
288 mainProject, GPOINTER_TO_INT(g_slist_nth_data(fns_lay_num, g_slist_position(fns, fn)))
293 case GTK_RESPONSE_OK:
296 for (GSList* fn = filenames; fn; fn = fn->next) {
297 if (NULL != g_slist_find(fns, fn->data))
304 for (GSList* fn = filenames; fn; fn = fn->next) {
305 if (0 == GPOINTER_TO_INT(g_slist_nth_data(cnt, g_slist_position(filenames, fn))))
310 g_slist_free(fns_is_mod);
311 g_slist_free(fns_cnt);
312 g_slist_free(fns_lay_num);
316 render_refresh_rendered_image_on_screen();
317 callbacks_update_layer_tree();
329 screen.win.gerber = gtk_file_chooser_dialog_new(
330 _(
"Open Gerbv project, Gerber, drill, "
331 "or pick&place files"),
332 NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
336 gtk_file_chooser_set_select_multiple((GtkFileChooser*)screen.win.gerber, TRUE);
337 gtk_file_chooser_set_current_folder((GtkFileChooser*)screen.win.gerber,
mainProject->
path);
338 gtk_widget_show(screen.win.gerber);
339 if (gtk_dialog_run((GtkDialog*)screen.win.gerber) == GTK_RESPONSE_ACCEPT) {
340 fns = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(screen.win.gerber));
343 mainProject->
path = gtk_file_chooser_get_current_folder((GtkFileChooser*)screen.win.gerber);
345 gtk_widget_destroy(screen.win.gerber);
348 g_slist_free_full(fns, g_free);
353 callbacks_revert_activate(GtkMenuItem* menuitem, gpointer user_data) {
355 selection_clear(&screen.selectionInfo);
356 update_selected_object_message(FALSE);
357 render_refresh_rendered_image_on_screen();
358 callbacks_update_layer_tree();
363 callbacks_save_project_activate(GtkMenuItem* menuitem, gpointer user_data) {
367 callbacks_generic_save_activate(menuitem, (gpointer)CALLBACKS_SAVE_PROJECT_AS);
368 callbacks_update_layer_tree();
374 callbacks_save_layer_activate(GtkMenuItem* menuitem, gpointer user_data) {
383 callbacks_update_layer_tree();
387 callbacks_update_layer_tree();
391 struct l_image_info {
402 gint i, filecount, img;
406 struct l_image_info {
411 images = (
struct l_image_info*)g_new0(
struct l_image_info, 1);
416 default: GERB_COMPILE_ERROR(_(
"Unknown Layer type for merge"));
goto err;
418 dprintf(
"Looking for matching files\n");
426 images = (
struct l_image_info*)g_renew(
struct l_image_info, images, img + 1);
430 GERB_COMPILE_ERROR(_(
"Not Enough Files of same type to merge"));
433 dprintf(
"Now merging files\n");
434 for (i = 0; i < img; ++i) {
437 thisTransform = images[i].transform;
438 if (NULL == thisTransform)
439 thisTransform = &identityTransform;
454 const gchar* file_extension,
const gchar* untitled_file_extension
456 unsigned int count = 0;
462 if (first_vis_file == NULL) {
466 *dir_name = g_path_get_dirname(first_vis_file->
fullPathname);
469 if (++count == 2 && file_name) {
470 *file_name = g_strdup_printf(
"%s%s", pgettext(
"file name",
"untitled"), untitled_file_extension);
475 if (count == 1 && file_name)
476 *file_name = g_strdup_printf(
"%s%s", first_vis_file->
name, file_extension);
483 callbacks_generic_save_activate(GtkMenuItem* menuitem, gpointer user_data) {
484 gchar* new_file_name = NULL;
485 gchar* file_name = NULL;
486 gchar* dir_name = NULL;
487 gboolean error_visible_layers = FALSE;
488 gchar* windowTitle = NULL;
491 gint processType = GPOINTER_TO_INT(user_data);
492 GtkFileFilter* filter;
493 GtkSpinButton* spin_but;
494 GtkTooltips* tooltips;
500 if (file_index < 0) {
502 _(
"No layer is currently active"), _(
"Please select a layer and try again."), FALSE, NULL
509 screen.win.gerber = gtk_file_chooser_dialog_new(
"", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, NULL, NULL, NULL);
510 GtkFileChooser* file_chooser_p = GTK_FILE_CHOOSER(screen.win.gerber);
511 gtk_file_chooser_set_do_overwrite_confirmation(file_chooser_p, TRUE);
513 hbox = gtk_hbox_new(0, 0);
514 spin_but = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(0, 0, 1));
515 label = gtk_label_new(
"");
516 tooltips = gtk_tooltips_new();
517 gtk_box_pack_end(GTK_BOX(hbox), GTK_WIDGET(spin_but), 0, 0, 1);
518 gtk_box_pack_end(GTK_BOX(hbox), label, 0, 0, 5);
519 gtk_box_pack_end(GTK_BOX(GTK_DIALOG(screen.win.gerber)->vbox), hbox, 0, 0, 2);
521 switch (processType) {
522 case CALLBACKS_SAVE_PROJECT_AS:
523 windowTitle = g_strdup(_(
"Save project as..."));
529 file_name = g_strdup_printf(
"%s%s", pgettext(
"file name",
"untitled"), GERBV_PROJECT_FILE_EXT);
533 filter = gtk_file_filter_new();
534 gtk_file_filter_set_name(filter, _(gerbv_project_file_name));
535 gtk_file_filter_add_pattern(filter, gerbv_project_file_pat);
536 gtk_file_chooser_add_filter(file_chooser_p, filter);
538 filter = gtk_file_filter_new();
539 gtk_file_filter_set_name(filter, _(
"All"));
540 gtk_file_filter_add_pattern(filter,
"*");
541 gtk_file_chooser_add_filter(file_chooser_p, filter);
544 case CALLBACKS_SAVE_FILE_PS:
545 windowTitle = g_strdup_printf(_(
"Export visible layers to %s file as..."), _(
"PS"));
546 if (0 == visible_file_name(&file_name, &dir_name, -1,
".ps",
".ps")) {
547 error_visible_layers = TRUE;
552 case CALLBACKS_SAVE_FILE_PDF:
553 windowTitle = g_strdup_printf(_(
"Export visible layers to %s file as..."), _(
"PDF"));
554 if (0 == visible_file_name(&file_name, &dir_name, -1,
".pdf",
".pdf")) {
555 error_visible_layers = TRUE;
560 case CALLBACKS_SAVE_FILE_SVG:
561 windowTitle = g_strdup_printf(_(
"Export visible layers to %s file as..."), _(
"SVG"));
562 if (0 == visible_file_name(&file_name, &dir_name, -1,
".svg",
".svg")) {
563 error_visible_layers = TRUE;
568 case CALLBACKS_SAVE_FILE_DXF:
571 g_strdup_printf(_(
"Export \"%s\" layer #%d to DXF file as..."), act_file->
name, file_index + 1);
572 file_name = g_strconcat(act_file->
name,
".dxf", NULL);
576 case CALLBACKS_SAVE_FILE_PNG:
577 windowTitle = g_strdup_printf(_(
"Export visible layers to %s file as..."), _(
"PNG"));
578 if (0 == visible_file_name(&file_name, &dir_name, -1,
".png",
".png")) {
579 error_visible_layers = TRUE;
583 gtk_label_set_text(GTK_LABEL(label), _(
"DPI:"));
584 gtk_spin_button_set_range(spin_but, 0, 6000);
585 gtk_spin_button_set_increments(spin_but, 10, 100);
586 gtk_tooltips_set_tip(tooltips, GTK_WIDGET(label), _(
"DPI value, autoscaling if 0"), NULL);
587 gtk_tooltips_set_tip(tooltips, GTK_WIDGET(spin_but), _(
"DPI value, autoscaling if 0"), NULL);
588 gtk_spin_button_set_value(spin_but, dpi);
589 gtk_widget_show_all(hbox);
592 case CALLBACKS_SAVE_FILE_RS274X:
593 windowTitle = g_strdup_printf(
594 _(
"Export \"%s\" layer #%d to "
595 "RS-274X file as..."),
596 act_file->
name, file_index + 1
600 file_name = g_strconcat(act_file->
name,
".gbr", NULL);
602 file_name = g_strdup(act_file->
name);
606 case CALLBACKS_SAVE_FILE_RS274XM:
608 g_strdup(_(
"Export merged visible layers to "
609 "RS-274X file as..."));
611 error_visible_layers = TRUE;
614 case CALLBACKS_SAVE_FILE_DRILL:
615 windowTitle = g_strdup_printf(
616 _(
"Export \"%s\" layer #%d to "
617 "Excellon drill file as..."),
618 act_file->
name, file_index + 1
622 file_name = g_strconcat(act_file->
name,
".drl", NULL);
624 file_name = g_strdup(act_file->
name);
628 case CALLBACKS_SAVE_FILE_DRILLM:
630 g_strdup(_(
"Export merged visible layers to "
631 "Excellon drill file as..."));
633 error_visible_layers = TRUE;
636 case CALLBACKS_SAVE_FILE_IDRILL:
637 windowTitle = g_strdup_printf(
638 _(
"Export \"%s\" layer #%d to ISEL NCP drill file as..."), act_file->
name, file_index + 1
640 file_name = g_strconcat(act_file->
name,
".ncp", NULL);
644 case CALLBACKS_SAVE_FILE_GEDA_PCB:
646 g_strdup_printf(_(
"Export \"%s\" layer #%d to gEDA PCB file as..."), act_file->
name, file_index + 1);
647 file_name = g_strconcat(act_file->
name,
".pcb", NULL);
650 case CALLBACKS_SAVE_LAYER_AS:
651 windowTitle = g_strdup_printf(_(
"Save \"%s\" layer #%d as..."), act_file->
name, file_index + 1);
652 file_name = g_strdup(act_file->
name);
657 if (file_name != NULL) {
658 gtk_file_chooser_set_current_name(file_chooser_p, file_name);
661 if (dir_name != NULL) {
662 gtk_file_chooser_set_current_folder(file_chooser_p, dir_name);
666 gtk_dialog_add_buttons(
667 GTK_DIALOG(screen.win.gerber), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL
670 gtk_window_set_title(GTK_WINDOW(screen.win.gerber), windowTitle);
673 if (error_visible_layers) {
674 switch (processType) {
675 case CALLBACKS_SAVE_FILE_RS274XM:
677 _(
"Not enough Gerber layers are visible"),
678 _(
"Two or more Gerber layers must be visible "
679 "for export with merge."),
680 FALSE, NULL, NULL, GTK_STOCK_CANCEL
683 case CALLBACKS_SAVE_FILE_DRILLM:
685 _(
"Not enough Excellon layers are visible"),
686 _(
"Two or more Excellon layers must be visible "
687 "for export with merge."),
688 FALSE, NULL, NULL, GTK_STOCK_CANCEL
693 _(
"No layers are visible"),
695 "layers must be visible for export."),
696 FALSE, NULL, NULL, GTK_STOCK_CANCEL
700 gtk_widget_destroy(screen.win.gerber);
701 callbacks_update_layer_tree();
706 gtk_widget_show(screen.win.gerber);
707 if (gtk_dialog_run(GTK_DIALOG(screen.win.gerber)) == GTK_RESPONSE_ACCEPT) {
708 new_file_name = gtk_file_chooser_get_filename(file_chooser_p);
709 dpi = gtk_spin_button_get_value_as_int(spin_but);
711 gtk_widget_destroy(screen.win.gerber);
713 if (!new_file_name) {
714 callbacks_update_layer_tree();
719 switch (processType) {
720 case CALLBACKS_SAVE_PROJECT_AS:
721 main_save_as_project_from_filename(
mainProject, new_file_name);
722 rename_main_window(new_file_name, NULL);
724 case CALLBACKS_SAVE_FILE_PS:
729 case CALLBACKS_SAVE_FILE_DXF:
733 _(
"\"%s\" layer #%d saved as DXF in \"%s\""), act_file->
name, file_index + 1, new_file_name
738 case CALLBACKS_SAVE_FILE_PNG:
751 bb.
left - (w * GERBV_DEFAULT_BORDER_COEFF) / 2.0,
752 bb.
top - (h * GERBV_DEFAULT_BORDER_COEFF) / 2.0,
754 w * dpi * (1 + GERBV_DEFAULT_BORDER_COEFF),
755 h * dpi * (1 + GERBV_DEFAULT_BORDER_COEFF),
761 case CALLBACKS_SAVE_LAYER_AS:
762 gerbv_save_layer_from_index(
mainProject, file_index, new_file_name);
768 g_free(act_file->
name);
769 act_file->
name = g_path_get_basename(new_file_name);
772 case CALLBACKS_SAVE_FILE_RS274X:
775 _(
"\"%s\" layer #%d saved as Gerber in \"%s\""), act_file->
name, file_index + 1, new_file_name
779 case CALLBACKS_SAVE_FILE_DRILL:
782 _(
"\"%s\" layer #%d saved as drill in \"%s\""), act_file->
name, file_index + 1, new_file_name
786 case CALLBACKS_SAVE_FILE_IDRILL:
789 _(
"\"%s\" layer #%d saved as ISEL NCP drill "
791 act_file->
name, file_index + 1, new_file_name
795 case CALLBACKS_SAVE_FILE_GEDA_PCB:
798 _(
"\"%s\" layer #%d saved as gEDA PCB "
800 act_file->
name, file_index + 1, new_file_name
804 case CALLBACKS_SAVE_FILE_RS274XM:
811 _(
"Merged visible Gerber layers "
812 "and saved in \"%s\""),
820 case CALLBACKS_SAVE_FILE_DRILLM:
828 _(
"Merged visible drill layers "
829 "and saved in \"%s\""),
837 g_free(new_file_name);
838 callbacks_update_layer_tree();
844 #if GTK_CHECK_VERSION(2, 10, 0)
847 callbacks_begin_print(GtkPrintOperation* operation, GtkPrintContext* context, gpointer user_data) {
848 gtk_print_operation_set_n_pages(operation, 1);
853 callbacks_print_render_page(GtkPrintOperation* operation, GtkPrintContext* context, gint page_nr, gpointer user_data) {
854 GtkPrintSettings* pSettings = gtk_print_operation_get_print_settings(operation);
860 (gint)gtk_print_context_get_width(context),
861 (gint)gtk_print_context_get_height(context) };
866 gdouble xres = gtk_print_context_get_dpi_x(context);
867 gdouble yres = gtk_print_context_get_dpi_y(context);
868 gdouble scalePercentage = gtk_print_settings_get_scale(pSettings);
872 gerbv_render_translate_to_fit_display(
mainProject, &renderInfo);
873 cr = gtk_print_context_get_cairo_context(context);
874 gerbv_render_all_layers_to_cairo_target_for_vector_output(
mainProject, cr, &renderInfo);
879 callbacks_print_activate(GtkMenuItem* menuitem, gpointer user_data) {
880 GtkPrintOperation* print;
883 print = gtk_print_operation_new();
885 g_signal_connect(print,
"begin_print", G_CALLBACK(callbacks_begin_print), NULL);
886 g_signal_connect(print,
"draw_page", G_CALLBACK(callbacks_print_render_page), NULL);
890 (void)gtk_print_operation_run(
891 print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, (GtkWindow*)screen.win.topLevelWindow, NULL
894 g_object_unref(print);
900 callbacks_fullscreen_toggled(GtkMenuItem* menuitem, gpointer user_data) {
902 GdkWindowState state = gdk_window_get_state(gtk_widget_get_window(screen.win.topLevelWindow));
903 if (state & GDK_WINDOW_STATE_FULLSCREEN)
904 gtk_window_unfullscreen(GTK_WINDOW(screen.win.topLevelWindow));
906 gtk_window_fullscreen(GTK_WINDOW(screen.win.topLevelWindow));
911 callbacks_show_toolbar_toggled(GtkMenuItem* menuitem, gpointer user_data) {
912 gtk_widget_set_visible(user_data, GTK_CHECK_MENU_ITEM(menuitem)->active);
917 callbacks_show_sidepane_toggled(GtkMenuItem* menuitem, gpointer user_data) {
918 gtk_widget_set_visible(user_data, GTK_CHECK_MENU_ITEM(menuitem)->active);
923 callbacks_show_selection_on_invisible(GtkMenuItem* menuitem, gpointer user_data) {
925 render_refresh_rendered_image_on_screen();
930 callbacks_show_cross_on_drill_holes(GtkMenuItem* menuitem, gpointer user_data) {
932 render_refresh_rendered_image_on_screen();
941 int i = GPOINTER_TO_INT(user_data);
948 if (0 <= i && i <= mainProject->last_loaded) {
967 callbacks_update_layer_tree();
970 render_refresh_rendered_image_on_screen();
972 render_recreate_composite_surface(screen.drawing_area);
973 callbacks_force_expose_event_for_screen();
979 callbacks_zoom_in_activate(GtkMenuItem* menuitem, gpointer user_data) {
980 render_zoom_display(ZOOM_IN, 0, 0, 0);
985 callbacks_zoom_out_activate(GtkMenuItem* menuitem, gpointer user_data) {
986 render_zoom_display(ZOOM_OUT, 0, 0, 0);
991 callbacks_fit_to_window_activate(GtkMenuItem* menuitem, gpointer user_data) {
993 render_refresh_rendered_image_on_screen();
1005 default:
return "Unknown";
1018 gerbv_aperture_list_t* aperture_list;
1026 GString* general_report_str = g_string_new(NULL);
1027 if (stat->layer_count == 0) {
1028 g_string_printf(general_report_str, _(
"No Gerber layers visible!"));
1030 if (stat->error_list->error_text == NULL) {
1034 "No errors found in %d visible "
1036 "No errors found in %d visible "
1046 "Found errors in %d visible "
1048 "Found errors in %d visible "
1057 GtkWidget* general_label = gtk_label_new(general_report_str->str);
1058 g_string_free(general_report_str, TRUE);
1059 gtk_misc_set_alignment(GTK_MISC(general_label), 0, 0);
1060 gtk_misc_set_padding(GTK_MISC(general_label), 7, 7);
1061 gtk_label_set_selectable(GTK_LABEL(general_label), TRUE);
1063 struct table* general_table;
1066 table_new_with_columns(3, _(
"Layer"), G_TYPE_UINT, _(
"Type"), G_TYPE_STRING, _(
"Description"), G_TYPE_STRING);
1067 table_set_column_align(general_table, 0, 1.0);
1075 table_add_row(general_table, i + 1, _(
"RS-274X file"), files[i]->fullPathname);
1077 str = g_strdup_printf(
1078 _(
"%g x %g %s"), screen_units(fabs(files[i]->image->
info->max_x - files[i]->
image->
info->min_x)),
1079 screen_units(fabs(files[i]->image->
info->max_y - files[i]->
image->
info->min_y)), screen_units_str()
1081 table_add_row(general_table, i + 1, _(
"Bounding size"), str);
1085 if (stat->layer_count > 0 && stat->error_list->error_text != NULL) {
1086 for (
gerbv_error_list_t* err_list = stat->error_list; err_list != NULL; err_list = err_list->next) {
1088 if (i != err_list->layer - 1)
1091 table_add_row(general_table, err_list->layer, error_type_string(err_list->type), err_list->error_text);
1097 GtkWidget* G_report_window = gtk_scrolled_window_new(NULL, NULL);
1098 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(G_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1100 struct table* G_table = table_new_with_columns(
1101 3, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT, _(
"Note"), G_TYPE_STRING
1103 table_set_column_align(G_table, 0, 1.0);
1104 table_set_column_align(G_table, 1, 1.0);
1105 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(G_table->widget), TRUE);
1125 table_add_row(G_table,
"", stat->G_unknown, _(
"unknown G-codes"));
1127 table_set_sortable(G_table);
1128 gtk_container_add(GTK_CONTAINER(G_report_window), G_table->widget);
1131 GtkWidget* D_report_window = gtk_scrolled_window_new(NULL, NULL);
1132 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(D_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1134 struct table* D_table = table_new_with_columns(
1135 3, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT, _(
"Note"), G_TYPE_STRING
1137 table_set_column_align(D_table, 0, 1.0);
1138 table_set_column_align(D_table, 1, 1.0);
1139 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(D_table->widget), TRUE);
1143 table_add_row(D_table,
"", stat->D_unknown, _(
"unknown D-codes"));
1144 table_add_row(D_table,
"", stat->D_error, _(
"D-code errors"));
1146 table_set_sortable(D_table);
1147 gtk_container_add(GTK_CONTAINER(D_report_window), D_table->widget);
1150 GtkWidget* M_report_window = gtk_scrolled_window_new(NULL, NULL);
1151 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(M_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1153 struct table* M_table = table_new_with_columns(
1154 3, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT, _(
"Note"), G_TYPE_STRING
1156 table_set_column_align(M_table, 0, 1.0);
1157 table_set_column_align(M_table, 1, 1.0);
1158 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(M_table->widget), TRUE);
1162 table_add_row(M_table,
"", stat->M_unknown, _(
"unknown M-codes"));
1164 table_set_sortable(M_table);
1165 gtk_container_add(GTK_CONTAINER(M_report_window), M_table->widget);
1168 GtkWidget* misc_report_window = gtk_scrolled_window_new(NULL, NULL);
1169 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(misc_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1171 struct table* misc_table =
1172 table_new_with_columns(2, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT);
1173 table_set_column_align(misc_table, 1, 1.0);
1174 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(misc_table->widget), TRUE);
1175 table_add_row(misc_table,
"X", stat->X);
1176 table_add_row(misc_table,
"Y", stat->Y);
1177 table_add_row(misc_table,
"I", stat->I);
1178 table_add_row(misc_table,
"J", stat->J);
1179 table_add_row(misc_table,
"*", stat->star);
1180 table_add_row(misc_table, _(
"Unknown"), stat->unknown);
1182 table_set_sortable(misc_table);
1183 gtk_container_add(GTK_CONTAINER(misc_report_window), misc_table->widget);
1186 GtkWidget* aperture_def_report_window = gtk_scrolled_window_new(NULL, NULL);
1187 gtk_scrolled_window_set_policy(
1188 GTK_SCROLLED_WINDOW(aperture_def_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
1191 if (stat->aperture_list->number == -1) {
1192 GtkWidget* aperture_def_label = gtk_label_new(_(
"No aperture definitions found in active Gerber file(s)!"));
1193 gtk_misc_set_alignment(GTK_MISC(aperture_def_label), 0, 0);
1194 gtk_misc_set_padding(GTK_MISC(aperture_def_label), 7, 7);
1195 gtk_label_set_selectable(GTK_LABEL(aperture_def_label), TRUE);
1196 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_def_report_window), aperture_def_label);
1198 struct table* aperture_def_table = table_new_with_columns(
1199 6, _(
"Layer"), G_TYPE_UINT, _(
"D code"), G_TYPE_STRING, _(
"Aperture"), G_TYPE_STRING, _(
"Param[0]"),
1200 G_TYPE_DOUBLE, _(
"Param[1]"), G_TYPE_DOUBLE, _(
"Param[2]"), G_TYPE_DOUBLE
1202 table_set_column_align(aperture_def_table, 0, 1.0);
1203 table_set_column_align(aperture_def_table, 1, 1.0);
1204 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(aperture_def_table->widget), TRUE);
1205 gtk_tree_view_set_search_column(GTK_TREE_VIEW(aperture_def_table->widget), 1);
1207 GString* gstr = g_string_new(NULL);
1208 for (aperture_list = stat->aperture_list; aperture_list != NULL; aperture_list = aperture_list->next) {
1209 g_string_printf(gstr,
"D%d", aperture_list->number);
1212 aperture_list->parameter[0], aperture_list->parameter[1], aperture_list->parameter[2]
1215 g_string_free(gstr, TRUE);
1216 table_set_sortable(aperture_def_table);
1217 gtk_container_add(GTK_CONTAINER(aperture_def_report_window), aperture_def_table->widget);
1221 GtkWidget* aperture_usage_report_window = gtk_scrolled_window_new(NULL, NULL);
1222 gtk_scrolled_window_set_policy(
1223 GTK_SCROLLED_WINDOW(aperture_usage_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
1226 unsigned int aperture_count = 0;
1228 if (stat->D_code_list->number == -1) {
1229 GtkWidget* aperture_usage_label = gtk_label_new(_(
"No apertures used in Gerber file(s)!"));
1230 gtk_misc_set_alignment(GTK_MISC(aperture_usage_label), 0, 0);
1231 gtk_misc_set_padding(GTK_MISC(aperture_usage_label), 7, 7);
1232 gtk_label_set_selectable(GTK_LABEL(aperture_usage_label), TRUE);
1233 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_usage_report_window), aperture_usage_label);
1235 struct table* aperture_usage_table =
1236 table_new_with_columns(2, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT);
1237 table_set_column_align(aperture_usage_table, 0, 1.0);
1238 table_set_column_align(aperture_usage_table, 1, 1.0);
1239 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(aperture_usage_table->widget), TRUE);
1241 GString* gstr = g_string_new(NULL);
1242 for (aperture_list = stat->D_code_list; aperture_list != NULL; aperture_list = aperture_list->next) {
1243 g_string_printf(gstr,
"D%d", aperture_list->number);
1244 table_add_row(aperture_usage_table, gstr->str, aperture_list->count);
1245 aperture_count += aperture_list->count;
1247 g_string_free(gstr, TRUE);
1248 table_add_row(aperture_usage_table, _(
"Total"), aperture_count);
1249 table_set_sortable(aperture_usage_table);
1250 gtk_container_add(GTK_CONTAINER(aperture_usage_report_window), aperture_usage_table->widget);
1254 GtkWidget* analyze_active_gerbers;
1255 analyze_active_gerbers = gtk_dialog_new_with_buttons(
1256 _(
"Gerber codes report on visible layers"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
1257 GTK_RESPONSE_ACCEPT, NULL
1259 gtk_container_set_border_width(GTK_CONTAINER(analyze_active_gerbers), 5);
1261 gtk_dialog_set_default_response(GTK_DIALOG(analyze_active_gerbers), GTK_RESPONSE_ACCEPT);
1262 g_signal_connect_after(
1263 G_OBJECT(analyze_active_gerbers),
"response", G_CALLBACK(gtk_widget_destroy), GTK_WIDGET(analyze_active_gerbers)
1267 GtkWidget* general_report_window = gtk_scrolled_window_new(NULL, NULL);
1268 gtk_scrolled_window_set_policy(
1269 GTK_SCROLLED_WINDOW(general_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
1272 GtkWidget* vbox = gtk_vbox_new(0, 0);
1273 gtk_box_pack_start(GTK_BOX(vbox), general_label, 0, 0, 0);
1274 gtk_box_pack_start(GTK_BOX(vbox), general_table->widget, 0, 0, 0);
1275 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(general_report_window), vbox);
1278 GtkWidget* notebook = gtk_notebook_new();
1280 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(general_report_window), gtk_label_new(_(
"General")));
1282 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(G_report_window), gtk_label_new(_(
"G codes")));
1284 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(D_report_window), gtk_label_new(_(
"D codes")));
1286 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(M_report_window), gtk_label_new(_(
"M codes")));
1288 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(misc_report_window), gtk_label_new(_(
"Misc. codes")));
1290 gtk_notebook_append_page(
1291 GTK_NOTEBOOK(notebook), GTK_WIDGET(aperture_def_report_window), gtk_label_new(_(
"Aperture definitions"))
1294 gtk_notebook_append_page(
1295 GTK_NOTEBOOK(notebook), GTK_WIDGET(aperture_usage_report_window), gtk_label_new(_(
"Aperture usage"))
1299 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_gerbers)->vbox), GTK_WIDGET(notebook));
1301 if (screen.settings) {
1302 analyze_window_size_restore(analyze_active_gerbers);
1304 G_OBJECT(analyze_active_gerbers),
"response", G_CALLBACK(analyze_window_size_store),
1305 GTK_WIDGET(analyze_active_gerbers)
1308 gtk_window_set_default_size(GTK_WINDOW(analyze_active_gerbers), 640, 320);
1311 gtk_widget_show_all(analyze_active_gerbers);
1331 GString* general_report_str = g_string_new(NULL);
1332 if (stat->layer_count == 0) {
1333 g_string_printf(general_report_str, _(
"No drill layers visible!"));
1335 if (stat->error_list->error_text == NULL) {
1339 "No errors found in %d visible "
1341 "No errors found in %d visible "
1351 "Found errors found in %d visible "
1353 "Found errors found in %d visible "
1362 GtkWidget* general_label = gtk_label_new(general_report_str->str);
1363 g_string_free(general_report_str, TRUE);
1364 gtk_misc_set_alignment(GTK_MISC(general_label), 0, 0);
1365 gtk_misc_set_padding(GTK_MISC(general_label), 7, 7);
1366 gtk_label_set_selectable(GTK_LABEL(general_label), TRUE);
1368 struct table* general_table;
1371 table_new_with_columns(3, _(
"Layer"), G_TYPE_UINT, _(
"Type"), G_TYPE_STRING, _(
"Description"), G_TYPE_STRING);
1372 table_set_column_align(general_table, 0, 1.0);
1380 table_add_row(general_table, i + 1, _(
"Excellon file"), files[i]->fullPathname);
1382 str = g_strdup_printf(
1383 _(
"%g x %g %s"), screen_units(fabs(files[i]->image->
info->max_x - files[i]->
image->
info->min_x)),
1384 screen_units(fabs(files[i]->image->
info->max_y - files[i]->
image->
info->min_y)), screen_units_str()
1386 table_add_row(general_table, i + 1, _(
"Bounding size"), str);
1390 if (stat->layer_count > 0 && stat->error_list->error_text != NULL) {
1391 for (
gerbv_error_list_t* err_list = stat->error_list; err_list != NULL; err_list = err_list->next) {
1393 if (i != err_list->layer - 1)
1396 table_add_row(general_table, err_list->layer, error_type_string(err_list->type), err_list->error_text);
1402 GtkWidget* G_report_window = gtk_scrolled_window_new(NULL, NULL);
1403 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(G_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1405 struct table* G_table = table_new_with_columns(
1406 3, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT, _(
"Note"), G_TYPE_STRING
1408 table_set_column_align(G_table, 0, 1.0);
1409 table_set_column_align(G_table, 1, 1.0);
1410 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(G_table->widget), TRUE);
1422 table_add_row(G_table,
"", stat->G_unknown, _(
"unknown G-codes"));
1424 table_set_sortable(G_table);
1425 gtk_container_add(GTK_CONTAINER(G_report_window), G_table->widget);
1428 GtkWidget* M_report_window = gtk_scrolled_window_new(NULL, NULL);
1429 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(M_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1431 struct table* M_table = table_new_with_columns(
1432 3, _(
"Code"), G_TYPE_STRING, pgettext(
"table",
"Count"), G_TYPE_UINT, _(
"Note"), G_TYPE_STRING
1434 table_set_column_align(M_table, 0, 1.0);
1435 table_set_column_align(M_table, 1, 1.0);
1436 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(M_table->widget), TRUE);
1450 table_add_row(M_table,
"", stat->M_unknown, _(
"unknown M-codes"));
1452 table_set_sortable(M_table);
1453 gtk_container_add(GTK_CONTAINER(M_report_window), M_table->widget);
1456 GtkWidget* misc_report_window = gtk_scrolled_window_new(NULL, NULL);
1457 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(misc_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1459 struct table* misc_table = table_new_with_columns(
1462 pgettext(
"table",
"Count"), G_TYPE_STRING, _(
"Code"), G_TYPE_STRING
1464 table_set_column_align(misc_table, 0, 1.0);
1465 str = g_strdup_printf(
"%d", stat->comment);
1466 table_add_row(misc_table, str, _(
"Comments"));
1468 str = g_strdup_printf(
"%d", stat->unknown);
1469 table_add_row(misc_table, str, _(
"Unknown codes"));
1471 str = g_strdup_printf(
"%d", stat->R);
1472 table_add_row(misc_table, str, _(
"Repeat hole (R)"));
1474 if (stat->detect != NULL) {
1475 table_add_row(misc_table,
"", stat->detect);
1478 table_set_sortable(misc_table);
1479 gtk_container_add(GTK_CONTAINER(misc_report_window), misc_table->widget);
1482 GtkWidget* drill_usage_report_window = gtk_scrolled_window_new(NULL, NULL);
1483 gtk_scrolled_window_set_policy(
1484 GTK_SCROLLED_WINDOW(drill_usage_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
1487 struct table* drill_usage_table = table_new_with_columns(
1488 4, _(
"Drill no."), G_TYPE_UINT, _(
"Dia."), G_TYPE_DOUBLE, _(
"Units"), G_TYPE_STRING, pgettext(
"table",
"Count"),
1492 table_set_column_align(drill_usage_table, 0, 1.0);
1493 table_set_column_align(drill_usage_table, 3, 1.0);
1494 gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(drill_usage_table->widget), TRUE);
1507 table_set_sortable(drill_usage_table);
1508 gtk_container_add(GTK_CONTAINER(drill_usage_report_window), drill_usage_table->widget);
1511 GtkWidget* analyze_active_drill;
1512 analyze_active_drill = gtk_dialog_new_with_buttons(
1513 _(
"Drill codes report on visible layers"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
1514 GTK_RESPONSE_ACCEPT, NULL
1516 gtk_container_set_border_width(GTK_CONTAINER(analyze_active_drill), 5);
1518 gtk_dialog_set_default_response(GTK_DIALOG(analyze_active_drill), GTK_RESPONSE_ACCEPT);
1519 g_signal_connect_after(
1520 G_OBJECT(analyze_active_drill),
"response", G_CALLBACK(gtk_widget_destroy), GTK_WIDGET(analyze_active_drill)
1524 GtkWidget* general_report_window = gtk_scrolled_window_new(NULL, NULL);
1525 gtk_scrolled_window_set_policy(
1526 GTK_SCROLLED_WINDOW(general_report_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC
1529 GtkWidget* vbox = gtk_vbox_new(0, 0);
1530 gtk_box_pack_start(GTK_BOX(vbox), general_label, 0, 0, 0);
1531 gtk_box_pack_start(GTK_BOX(vbox), general_table->widget, 0, 0, 0);
1532 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(general_report_window), vbox);
1535 GtkWidget* notebook = gtk_notebook_new();
1537 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(general_report_window), gtk_label_new(_(
"General")));
1539 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(G_report_window), gtk_label_new(_(
"G codes")));
1541 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(M_report_window), gtk_label_new(_(
"M codes")));
1543 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), GTK_WIDGET(misc_report_window), gtk_label_new(_(
"Misc. codes")));
1545 gtk_notebook_append_page(
1546 GTK_NOTEBOOK(notebook), GTK_WIDGET(drill_usage_report_window), gtk_label_new(_(
"Drill usage"))
1550 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_drill)->vbox), GTK_WIDGET(notebook));
1552 if (screen.settings) {
1553 analyze_window_size_restore(analyze_active_drill);
1555 G_OBJECT(analyze_active_drill),
"response", G_CALLBACK(analyze_window_size_store),
1556 GTK_WIDGET(analyze_active_drill)
1559 gtk_window_set_default_size(GTK_WINDOW(analyze_active_drill), 640, 320);
1562 gtk_widget_show_all(analyze_active_drill);
1569 callbacks_control_gerber_options_activate(GtkMenuItem* menuitem, gpointer user_data) {}
1573 callbacks_online_manual_activate(GtkMenuItem* menuitem, gpointer user_data) {}
1584 gboolean layers_dirty = FALSE;
1595 _(
"Do you want to close all open layers and quit the program?"),
1596 _(
"Quitting the program will cause any unsaved changes "
1598 FALSE, NULL, GTK_STOCK_QUIT, GTK_STOCK_CANCEL
1605 if (screen.settings && !screen.background_is_from_project) {
1609 clr = bg->red / 257 << 16 | bg->green / 257 << 8 | bg->blue / 257;
1610 g_settings_set_uint(screen.settings,
"background-color", clr);
1614 if (screen.settings) {
1615 GtkWindow* win = GTK_WINDOW(screen.win.topLevelWindow);
1620 is_max = FALSE != (GDK_WINDOW_STATE_MAXIMIZED & gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(win))));
1621 g_settings_set_boolean(screen.settings,
"window-maximized", is_max);
1624 gtk_window_get_size(win, (gint*)xy, (gint*)(xy + 1));
1625 var = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, xy, 2,
sizeof(xy[0]));
1626 g_settings_set_value(screen.settings,
"window-size", var);
1628 gtk_window_get_position(win, (gint*)xy, (gint*)(xy + 1));
1629 var = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, xy, 2,
sizeof(xy[0]));
1630 g_settings_set_value(screen.settings,
"window-position", var);
1648 GtkWidget* aboutdialog1;
1650 gchar* translators = _(
"translator-credits");
1652 gchar*
string = g_strdup_printf(
1653 _(
"Gerbv — a Gerber (RS-274/X) viewer\n"
1656 "Compiled on %s at %s\n"
1658 "Gerbv was originally developed as part of the gEDA Project "
1659 "but is now separately maintained.\n"
1661 "For more information see:\n"
1662 " gerbv homepage: https://gerbv.github.io/\n"
1663 " gerbv repository: https://github.com/gerbv/gerbv"),
1664 VERSION, __DATE__, __TIME__
1667 #if GTK_CHECK_VERSION(2, 6, 0)
1669 g_strdup_printf(_(
"Gerbv — a Gerber (RS-274/X) viewer\n"
1671 "Copyright (C) 2000—2007 Stefan Petersen\n"
1673 "This program is free software: you can redistribute it and/or modify\n"
1674 "it under the terms of the GNU General Public License as published by\n"
1675 "the Free Software Foundation, either version 2 of the License, or\n"
1676 "(at your option) any later version.\n"
1678 "This program is distributed in the hope that it will be useful,\n"
1679 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1680 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1681 "GNU General Public License for more details.\n\n"
1682 "You should have received a copy of the GNU General Public License\n"
1683 "along with this program. If not, see <http://www.gnu.org/licenses/>."));
1690 aboutdialog1 = gtk_about_dialog_new();
1691 gtk_container_set_border_width(GTK_CONTAINER(aboutdialog1), 5);
1692 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(aboutdialog1), VERSION);
1693 gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(aboutdialog1), _(
"Gerbv"));
1695 gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(aboutdialog1), translators);
1696 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(aboutdialog1),
string);
1697 gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(aboutdialog1), license);
1700 a_size =
sizeof(authors_string_array) /
sizeof(authors_string_array[0]);
1701 a = g_new(gchar*, a_size);
1702 for (i = 0; i < a_size; i++)
1703 a[i] = _(authors_string_array[i]);
1705 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(aboutdialog1), (
const gchar**)a);
1706 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(aboutdialog1),
"https://gerbv.github.io/");
1709 g_signal_connect(G_OBJECT(aboutdialog1),
"response", G_CALLBACK(gtk_widget_destroy), GTK_WIDGET(aboutdialog1));
1714 aboutdialog1 = gtk_message_dialog_new(
1715 GTK_WINDOW(screen.win.topLevelWindow), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
1719 gtk_window_set_title(GTK_WINDOW(aboutdialog1), _(
"About Gerbv"));
1722 g_signal_connect_swapped(aboutdialog1,
"response", G_CALLBACK(gtk_widget_destroy), aboutdialog1);
1726 gtk_widget_show_all(GTK_WIDGET(aboutdialog1));
1741 GtkWidget* bugs_dialog = gtk_dialog_new_with_buttons(
1742 _(
"Known bugs in Gerbv"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL
1744 gtk_container_set_border_width(GTK_CONTAINER(bugs_dialog), 5);
1745 gtk_dialog_set_default_response(GTK_DIALOG(bugs_dialog), GTK_RESPONSE_ACCEPT);
1746 g_signal_connect(G_OBJECT(bugs_dialog),
"response", G_CALLBACK(gtk_widget_destroy), GTK_WIDGET(bugs_dialog));
1749 GString* bugs_string = g_string_new(NULL);
1750 for (i = 0; bugs_string_array[i] != NULL; i++) {
1752 g_string_append_printf(bugs_string,
"%s\n", (bugs_string_array[i][0] ==
'\0') ?
"" : _(bugs_string_array[i]));
1756 GtkWidget* bugs_label = gtk_label_new(bugs_string->str);
1757 g_string_free(bugs_string, FALSE);
1758 gtk_misc_set_alignment(GTK_MISC(bugs_label), 0, 0);
1759 gtk_misc_set_padding(GTK_MISC(bugs_label), 7, 7);
1762 GtkWidget* bugs_window = gtk_scrolled_window_new(NULL, NULL);
1763 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(bugs_window), GTK_WIDGET(bugs_label));
1764 gtk_widget_set_size_request(bugs_window, 600, 300);
1765 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(bugs_dialog)->vbox), GTK_WIDGET(bugs_window));
1767 gtk_widget_show_all(GTK_WIDGET(bugs_dialog));
1768 gtk_dialog_run(GTK_DIALOG(bugs_dialog));
1773 callbacks_calculate_actual_distance(gdouble inputDimension) {
1774 return screen_units(inputDimension);
1779 callbacks_update_ruler_pointers(
void) {
1780 double xPosition, yPosition;
1785 if (!((screen.unit == GERBV_MILS) && ((screenRenderInfo.
scaleFactorX < 80) || (screenRenderInfo.
scaleFactorY < 80))
1787 xPosition = callbacks_calculate_actual_distance(xPosition);
1788 yPosition = callbacks_calculate_actual_distance(yPosition);
1790 g_object_set(G_OBJECT(screen.win.hRuler),
"position", xPosition, NULL);
1791 g_object_set(G_OBJECT(screen.win.vRuler),
"position", yPosition, NULL);
1796 callbacks_render_type_changed() {
1797 static gboolean isChanging = FALSE;
1803 GtkCheckMenuItem* check_item = screen.win.menu_view_render_group[type];
1804 dprintf(
"%s(): type = %d, check_item = %p\n", __FUNCTION__, type, check_item);
1805 gtk_check_menu_item_set_active(check_item, TRUE);
1806 gtk_combo_box_set_active(screen.win.sidepaneRenderComboBox, type);
1808 render_refresh_rendered_image_on_screen();
1814 callbacks_units_changed(gerbv_gui_unit_t unit) {
1815 static gboolean isChanging = FALSE;
1823 if (unit == GERBV_MILS || unit == GERBV_MMS || unit == GERBV_INS) {
1824 gtk_combo_box_set_active(GTK_COMBO_BOX(screen.win.statusUnitComboBox), unit);
1825 gtk_check_menu_item_set_active(screen.win.menu_view_unit_group[unit], TRUE);
1828 callbacks_update_ruler_scales();
1829 callbacks_update_statusbar_coordinates(screen.last_x, screen.last_y);
1831 if (screen.tool == MEASURE)
1832 callbacks_update_statusbar_measured_distance(screen.measure_last_x, screen.measure_last_y);
1839 callbacks_update_ruler_scales(
void) {
1840 double xStart, xEnd, yStart, yEnd;
1849 if (!((screen.unit == GERBV_MILS) && ((screenRenderInfo.
scaleFactorX < 80) || (screenRenderInfo.
scaleFactorY < 80))
1851 xStart = callbacks_calculate_actual_distance(xStart);
1852 xEnd = callbacks_calculate_actual_distance(xEnd);
1853 yStart = callbacks_calculate_actual_distance(yStart);
1854 yEnd = callbacks_calculate_actual_distance(yEnd);
1858 if (screen.win.hRuler)
1859 gtk_ruler_set_range(GTK_RULER(screen.win.hRuler), xStart, xEnd, 0, xEnd - xStart);
1861 if (screen.win.vRuler)
1862 gtk_ruler_set_range(GTK_RULER(screen.win.vRuler), yEnd, yStart, 0, yEnd - yStart);
1867 callbacks_update_scrollbar_limits(
void) {
1872 GtkAdjustment* hAdjust = (GtkAdjustment*)screen.win.hAdjustment;
1873 GtkAdjustment* vAdjust = (GtkAdjustment*)screen.win.vAdjustment;
1876 hAdjust->page_increment = hAdjust->page_size;
1877 hAdjust->step_increment = hAdjust->page_size / 10.0;
1879 vAdjust->page_increment = vAdjust->page_size;
1880 vAdjust->step_increment = vAdjust->page_size / 10.0;
1885 callbacks_update_scrollbar_positions();
1890 callbacks_update_scrollbar_positions(
void) {
1891 gdouble positionX, positionY;
1894 if (positionX < ((GtkAdjustment*)screen.win.hAdjustment)->lower)
1895 positionX = ((GtkAdjustment*)screen.win.hAdjustment)->lower;
1897 > (((GtkAdjustment*)screen.win.hAdjustment)->upper - ((GtkAdjustment*)screen.win.hAdjustment)->page_size))
1899 (((GtkAdjustment*)screen.win.hAdjustment)->upper - ((GtkAdjustment*)screen.win.hAdjustment)->page_size);
1900 gtk_adjustment_set_value((GtkAdjustment*)screen.win.hAdjustment, positionX);
1902 positionY = ((GtkAdjustment*)screen.win.vAdjustment)->upper - screenRenderInfo.
lowerLeftY
1903 - ((GtkAdjustment*)screen.win.vAdjustment)->page_size + ((GtkAdjustment*)screen.win.vAdjustment)->lower;
1904 if (positionY < ((GtkAdjustment*)screen.win.vAdjustment)->lower)
1905 positionY = ((GtkAdjustment*)screen.win.vAdjustment)->lower;
1907 > (((GtkAdjustment*)screen.win.vAdjustment)->upper - ((GtkAdjustment*)screen.win.vAdjustment)->page_size))
1909 (((GtkAdjustment*)screen.win.vAdjustment)->upper - ((GtkAdjustment*)screen.win.vAdjustment)->page_size);
1910 gtk_adjustment_set_value((GtkAdjustment*)screen.win.vAdjustment, positionY);
1915 callbacks_scrollbar_button_released(GtkWidget* widget, GdkEventButton* event) {
1918 screen.state = NORMAL;
1919 render_refresh_rendered_image_on_screen();
1925 callbacks_scrollbar_button_pressed(GtkWidget* widget, GdkEventButton* event) {
1927 screen.state = SCROLLBAR;
1933 callbacks_hadjustment_value_changed(GtkAdjustment* adjustment, gpointer user_data) {
1936 if (screen.state == SCROLLBAR) {
1937 screenRenderInfo.
lowerLeftX = gtk_adjustment_get_value(adjustment);
1943 callbacks_vadjustment_value_changed(GtkAdjustment* adjustment, gpointer user_data) {
1946 if (screen.state == SCROLLBAR) {
1948 adjustment->upper - (gtk_adjustment_get_value(adjustment) + adjustment->page_size) + adjustment->lower;
1954 callbacks_layer_tree_visibility_toggled(gint index) {
1957 callbacks_update_layer_tree();
1959 render_refresh_rendered_image_on_screen();
1961 render_recreate_composite_surface(screen.drawing_area);
1962 callbacks_force_expose_event_for_screen();
1968 callbacks_get_col_num_from_tree_view_col(GtkTreeViewColumn* col) {
1972 g_return_val_if_fail(col != NULL, -1);
1973 g_return_val_if_fail(col->tree_view != NULL, -1);
1974 cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view));
1975 num = g_list_index(cols, (gpointer)col);
1982 callbacks_add_layer_button_clicked(GtkButton* button, gpointer user_data) {
1988 callbacks_unselect_all_tool_buttons(
void) {}
1991 callbacks_switch_to_normal_tool_cursor(gint toolNumber) {
1992 GdkWindow* drawing_area_window = screen.drawing_area->window;
1995 switch (toolNumber) {
1996 case POINTER: gdk_window_set_cursor(drawing_area_window, GERBV_DEF_CURSOR);
break;
1998 cursor = gdk_cursor_new(GDK_FLEUR);
1999 gdk_window_set_cursor(drawing_area_window, cursor);
2000 gdk_cursor_destroy(cursor);
2003 cursor = gdk_cursor_new(GDK_SIZING);
2004 gdk_window_set_cursor(drawing_area_window, cursor);
2005 gdk_cursor_destroy(cursor);
2008 cursor = gdk_cursor_new(GDK_CROSSHAIR);
2009 gdk_window_set_cursor(drawing_area_window, cursor);
2010 gdk_cursor_destroy(cursor);
2018 callbacks_switch_to_correct_cursor(
void) {
2019 GdkWindow* drawing_area_window = screen.drawing_area->window;
2022 if (screen.state == IN_MOVE) {
2023 cursor = gdk_cursor_new(GDK_FLEUR);
2024 gdk_window_set_cursor(drawing_area_window, cursor);
2025 gdk_cursor_destroy(cursor);
2027 }
else if (screen.state == IN_ZOOM_OUTLINE) {
2028 cursor = gdk_cursor_new(GDK_SIZING);
2029 gdk_window_set_cursor(drawing_area_window, cursor);
2030 gdk_cursor_destroy(cursor);
2033 callbacks_switch_to_normal_tool_cursor(screen.tool);
2038 callbacks_change_tool(GtkButton* button, gpointer user_data) {
2039 gint toolNumber = GPOINTER_TO_INT(user_data);
2042 if (screen.win.updatingTools)
2044 screen.win.updatingTools = TRUE;
2045 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonPointer), FALSE);
2046 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonPan), FALSE);
2047 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonZoom), FALSE);
2048 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonMeasure), FALSE);
2049 switch (toolNumber) {
2051 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonPointer), TRUE);
2052 screen.tool = POINTER;
2053 screen.state = NORMAL;
2055 screen.statusbar.diststr,
2056 _(
"Click to select objects in the active layer. "
2057 "Middle click and drag to pan."),
2062 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonPan), TRUE);
2064 screen.state = NORMAL;
2066 screen.statusbar.diststr, _(
"Click and drag to pan. Right click and drag to zoom."), MAX_DISTLEN
2070 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonZoom), TRUE);
2072 screen.state = NORMAL;
2074 screen.statusbar.diststr, _(
"Click and drag to zoom in. Shift+click to zoom out."), MAX_DISTLEN
2079 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(screen.win.toolButtonMeasure), TRUE);
2080 screen.tool = MEASURE;
2081 screen.state = NORMAL;
2083 screen.statusbar.diststr, _(
"Click and drag to measure a distance or select two apertures."),
2088 screen.measure_start_x = 0;
2089 screen.measure_start_y = 0;
2090 screen.measure_stop_x = 0;
2091 screen.measure_stop_y = 0;
2094 if (selection_length(&screen.selectionInfo) == 2) {
2095 gerbv_selection_item_t item[2];
2098 item[0] = selection_get_item_by_index(&screen.selectionInfo, 0);
2099 item[1] = selection_get_item_by_index(&screen.selectionInfo, 1);
2100 net[0] = item[0].net;
2101 net[1] = item[1].net;
2103 if ((net[0]->aperture_state == net[1]->aperture_state)
2105 screen.measure_start_x = net[0]->
stop_x;
2106 screen.measure_start_y = net[0]->
stop_y;
2108 &screen.measure_start_x, &screen.measure_start_y, item[0].image,
mainProject
2111 screen.measure_stop_x = net[1]->
stop_x;
2112 screen.measure_stop_y = net[1]->
stop_y;
2114 &screen.measure_stop_x, &screen.measure_stop_y, item[1].image,
mainProject
2124 callbacks_switch_to_normal_tool_cursor(toolNumber);
2126 screen.win.updatingTools = FALSE;
2127 callbacks_force_expose_event_for_screen();
2132 callbacks_select_layer_row(gint rowIndex) {
2133 GtkTreeSelection* selection;
2135 GtkListStore* list_store = (GtkListStore*)gtk_tree_view_get_model((GtkTreeView*)screen.win.layerTree);
2137 selection = gtk_tree_view_get_selection((GtkTreeView*)screen.win.layerTree);
2139 if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, rowIndex)) {
2140 gtk_tree_selection_select_iter(selection, &iter);
2152 GtkTreeSelection* selection;
2154 GtkListStore* list_store = (GtkListStore*)gtk_tree_view_get_model((GtkTreeView*)screen.win.layerTree);
2155 gint index = -1, i = 0;
2158 selection = gtk_tree_view_get_selection((GtkTreeView*)screen.win.layerTree);
2159 if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
2160 while (gtk_tree_model_iter_nth_child((GtkTreeModel*)list_store, &iter, NULL, i)) {
2161 if (gtk_tree_selection_iter_is_selected(selection, &iter)) {
2172 callbacks_remove_layer_button_clicked(GtkButton* button, gpointer user_data) {
2175 if ((index >= 0) && (index <= mainProject->last_loaded)) {
2176 render_remove_selected_objects_belonging_to_layer(&screen.selectionInfo,
mainProject->
file[index]->
image);
2177 update_selected_object_message(FALSE);
2180 callbacks_update_layer_tree();
2182 index = MAX(0, index - 1);
2183 callbacks_select_layer_row(index);
2186 render_refresh_rendered_image_on_screen();
2188 render_recreate_composite_surface(screen.drawing_area);
2189 callbacks_force_expose_event_for_screen();
2196 callbacks_move_layer_down_menu_activate(GtkMenuItem* menuitem, gpointer user_data) {
2197 callbacks_move_layer_down_button_clicked(NULL, NULL);
2198 gtk_widget_grab_focus(screen.win.layerTree);
2203 callbacks_move_layer_down_button_clicked(GtkButton* button, gpointer user_data) {
2206 show_no_layers_warning();
2210 if (index < mainProject->last_loaded) {
2211 gerbv_change_layer_order(
mainProject, index, index + 1);
2212 callbacks_update_layer_tree();
2213 callbacks_select_layer_row(index + 1);
2216 render_refresh_rendered_image_on_screen();
2218 render_recreate_composite_surface(screen.drawing_area);
2219 callbacks_force_expose_event_for_screen();
2226 callbacks_move_layer_up_menu_activate(GtkMenuItem* menuitem, gpointer user_data) {
2227 callbacks_move_layer_up_button_clicked(NULL, NULL);
2228 gtk_widget_grab_focus(screen.win.layerTree);
2233 callbacks_move_layer_up_button_clicked(GtkButton* button, gpointer user_data) {
2236 show_no_layers_warning();
2240 gerbv_change_layer_order(
mainProject, index, index - 1);
2241 callbacks_update_layer_tree();
2242 callbacks_select_layer_row(index - 1);
2244 render_refresh_rendered_image_on_screen();
2246 render_recreate_composite_surface(screen.drawing_area);
2247 callbacks_force_expose_event_for_screen();
2254 callbacks_layer_tree_row_inserted(GtkTreeModel* tree_model, GtkTreePath* path, GtkTreeIter* oIter, gpointer user_data) {
2255 gint *indices = NULL, oldPosition, newPosition;
2257 if ((!screen.win.treeIsUpdating) && (path != NULL)) {
2258 indices = gtk_tree_path_get_indices(path);
2260 newPosition = indices[0];
2264 if (oldPosition < newPosition)
2268 gerbv_change_layer_order(
mainProject, oldPosition, newPosition);
2271 render_refresh_rendered_image_on_screen();
2273 render_recreate_composite_surface(screen.drawing_area);
2274 callbacks_force_expose_event_for_screen();
2277 GtkTreeSelection* selection;
2279 GtkListStore* list_store = (GtkListStore*)gtk_tree_view_get_model((GtkTreeView*)screen.win.layerTree);
2281 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(screen.win.layerTree));
2282 if (gtk_tree_model_get_iter((GtkTreeModel*)list_store, &iter, path))
2283 gtk_tree_selection_select_iter(selection, &iter);
2290 callbacks_show_color_picker_dialog(gint index) {
2291 screen.win.colorSelectionDialog = NULL;
2292 GtkColorSelectionDialog* cs = (GtkColorSelectionDialog*)gtk_color_selection_dialog_new(_(
"Select a color"));
2293 GtkColorSelection* colorsel = (GtkColorSelection*)cs->colorsel;
2295 screen.win.colorSelectionDialog = (GtkWidget*)cs;
2296 screen.win.colorSelectionIndex = index;
2302 gtk_color_selection_set_has_opacity_control(colorsel, TRUE);
2305 gtk_widget_show_all((GtkWidget*)cs);
2306 if (gtk_dialog_run((GtkDialog*)cs) == GTK_RESPONSE_OK) {
2307 GtkColorSelection* colorsel = (GtkColorSelection*)cs->colorsel;
2308 gint rowIndex = screen.win.colorSelectionIndex;
2312 gdk_colormap_alloc_color(gdk_colormap_get_system(), &
mainProject->
file[rowIndex]->
color, FALSE, TRUE);
2321 callbacks_update_layer_tree();
2322 render_refresh_rendered_image_on_screen();
2324 gtk_widget_destroy((GtkWidget*)cs);
2325 screen.win.colorSelectionDialog = NULL;
2330 callbacks_invert_layer_clicked(GtkButton* button, gpointer user_data) {
2333 show_no_layers_warning();
2337 render_refresh_rendered_image_on_screen();
2338 callbacks_update_layer_tree();
2343 callbacks_change_layer_color_clicked(GtkButton* button, gpointer user_data) {
2346 show_no_layers_warning();
2349 callbacks_show_color_picker_dialog(index);
2353 callbacks_change_background_color_clicked(GtkButton* button, gpointer user_data) {
2354 callbacks_show_color_picker_dialog(-1);
2359 callbacks_reload_layer_clicked(GtkButton* button, gpointer user_data) {
2363 show_no_layers_warning();
2367 render_remove_selected_objects_belonging_to_layer(&screen.selectionInfo,
mainProject->
file[index]->
image);
2368 update_selected_object_message(FALSE);
2371 render_refresh_rendered_image_on_screen();
2372 callbacks_update_layer_tree();
2376 callbacks_change_layer_edit_clicked(GtkButton* button, gpointer userData) {
2383 show_no_layers_warning();
2399 if (files[i] && files[i]->isVisible)
2404 transforms[j] = NULL;
2406 interface_show_layer_edit_dialog(transforms, screen.unit);
2408 render_refresh_rendered_image_on_screen();
2409 callbacks_update_layer_tree();
2414 callbacks_change_layer_format_clicked(GtkButton* button, gpointer user_data) {
2415 gerbv_HID_Attribute* attr = NULL;
2418 gerbv_HID_Attr_Val* results = NULL;
2423 show_no_layers_warning();
2426 dprintf(
"%s(): index = %d\n", __FUNCTION__, index);
2431 type = N_(
"Unknown type");
2433 if (attr == NULL || n == 0) {
2435 _(
"This file type does not currently have any editable features"),
2436 _(
"Format editing is currently only supported for Excellon drill file formats."), FALSE, NULL
2441 dprintf(
"%s(): n = %d, attr = %p\n", __FUNCTION__, n, attr);
2445 _(
"This layer has changed!"),
2446 _(
"Editing the file type will reload the layer, "
2447 "destroying your changes. Click OK to edit "
2448 "the file type and destroy your changes, "
2449 "or Cancel to leave."),
2450 TRUE, NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL
2456 results = (gerbv_HID_Attr_Val*)malloc(n *
sizeof(gerbv_HID_Attr_Val));
2457 if (results == NULL)
2458 GERB_FATAL_ERROR(
"%s(): malloc failed", __FUNCTION__);
2461 if (attribute_interface_dialog(attr, n, results, _(
"Edit file format"), _(type))) {
2466 dprintf(
"%s(): reloading layer\n", __func__);
2469 for (i = 0; i < n; i++) {
2470 if (results[i].str_value)
2471 free(results[i].str_value);
2476 render_refresh_rendered_image_on_screen();
2477 callbacks_update_layer_tree();
2482 callbacks_file_drop_event(
2483 GtkWidget* widget, GdkDragContext* dc, gint x, gint y, GtkSelectionData* data, guint info, guint time, gpointer p
2485 gchar **uris, **uri;
2488 uris = gtk_selection_data_get_uris(data);
2492 for (uri = uris; *uri; uri++) {
2493 const char* prefix_str =
2499 if (g_strrstr(*uri, prefix_str) == *uri)
2500 fns = g_slist_append(fns, g_uri_unescape_string(*uri + strlen(prefix_str), NULL));
2504 g_slist_free_full(fns, g_free);
2512 callbacks_layer_tree_key_press(GtkWidget* widget, GdkEventKey* event, gpointer user_data) {
2516 if (event->keyval == GDK_space) {
2519 GtkTreeViewColumn* col;
2523 tree = (GtkTreeView*)screen.win.layerTree;
2524 gtk_tree_view_get_cursor(tree, &path, &col);
2526 indices = gtk_tree_path_get_indices(path);
2528 idx = callbacks_get_col_num_from_tree_view_col(col);
2530 callbacks_show_color_picker_dialog(indices[0]);
2533 gtk_tree_path_free(path);
2542 callbacks_layer_tree_button_press(GtkWidget* widget, GdkEventButton* event, gpointer user_data) {
2545 GtkTreeViewColumn* col;
2549 GtkListStore* list_store = (GtkListStore*)gtk_tree_view_get_model((GtkTreeView*)screen.win.layerTree);
2551 if (event->button == 1) {
2552 if (gtk_tree_view_get_path_at_pos((GtkTreeView*)widget, event->x, event->y, &path, &col, &x, &y)
2553 && gtk_tree_model_get_iter((GtkTreeModel*)list_store, &iter, path)) {
2554 indices = gtk_tree_path_get_indices(path);
2556 switch (callbacks_get_col_num_from_tree_view_col(col)) {
2558 callbacks_select_layer_row(indices[0]);
2559 callbacks_layer_tree_visibility_toggled(indices[0]);
2562 callbacks_show_color_picker_dialog(indices[0]);
2572 gtk_menu_popup(GTK_MENU(screen.win.layerTreePopupMenu), NULL, NULL, NULL, NULL, event->button, event->time);
2581 callbacks_update_layer_tree(
void) {
2582 GtkListStore* list_store = (GtkListStore*)gtk_tree_view_get_model((GtkTreeView*)screen.win.layerTree);
2585 GtkTreeSelection* selection;
2586 gint oldSelectedRow;
2588 if (screen.win.treeIsUpdating)
2591 screen.win.treeIsUpdating = TRUE;
2594 if (oldSelectedRow < 0)
2597 gtk_list_store_clear(list_store);
2600 GdkPixbuf * pixbuf, *blackPixbuf;
2601 unsigned char red, green, blue, alpha;
2610 red = (
unsigned char)(file->
color.red * 255 / G_MAXUINT16);
2611 green = (
unsigned char)(file->
color.green * 255 / G_MAXUINT16);
2612 blue = (
unsigned char)(file->
color.blue * 255 / G_MAXUINT16);
2613 alpha = (
unsigned char)(file->
alpha * 255 / G_MAXUINT16);
2615 color = red * (256 * 256 * 256) + green * (256 * 256) + blue * 256 + alpha;
2616 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 20, 15);
2617 gdk_pixbuf_fill(pixbuf, color);
2619 blackPixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 20, 15);
2620 color = 100 * (256 * 256 * 256) + 100 * (256 * 256) + 100 * 256 + 150;
2621 gdk_pixbuf_fill(blackPixbuf, color);
2624 gdk_pixbuf_copy_area(pixbuf, 1, 1, 18, 13, blackPixbuf, 1, 1);
2625 g_object_unref(pixbuf);
2627 gtk_list_store_append(list_store, &iter);
2629 gchar startChar[2], *modifiedCode;
2633 gint numberOfModifications = 0;
2636 numberOfModifications++;
2640 numberOfModifications++;
2645 numberOfModifications++;
2650 numberOfModifications++;
2654 numberOfModifications++;
2656 if (numberOfModifications > 1)
2658 if (numberOfModifications == 0)
2659 modifiedCode = g_strdup(
"");
2661 modifiedCode = g_strdup(startChar);
2668 layerName = g_strconcat(
"*",
"<i>", file->
name,
"</i>", NULL);
2671 layerName = g_strdup(file->
name);
2674 gtk_list_store_set(list_store, &iter, 0, file->
isVisible, 1, blackPixbuf, 2, layerName, 3, modifiedCode, -1);
2676 g_free(modifiedCode);
2678 g_object_unref(blackPixbuf);
2681 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(screen.win.layerTree));
2686 if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) {
2687 if (gtk_tree_model_iter_nth_child((GtkTreeModel*)list_store, &iter, NULL, oldSelectedRow)) {
2688 gtk_tree_selection_select_iter(selection, &iter);
2692 gtk_widget_set_sensitive(screen.win.curLayerMenuItem, showItems);
2693 gtk_widget_set_sensitive(screen.win.curAnalyzeMenuItem, showItems);
2694 gtk_widget_set_sensitive(screen.win.curEditMenuItem, showItems);
2695 for (
unsigned int i = 0; i < G_N_ELEMENTS(screen.win.curFileMenuItem); i++) {
2696 gtk_widget_set_sensitive(screen.win.curFileMenuItem[i], showItems);
2698 screen.win.treeIsUpdating = FALSE;
2703 callbacks_display_object_properties_clicked(GtkButton* button, gpointer user_data) {
2707 if (index < 0 || selection_length(&screen.selectionInfo) == 0) {
2709 _(
"No object is currently selected"),
2710 _(
"Objects must be selected using the pointer tool "
2711 "before you can view the object properties."),
2717 for (i = 0; i < selection_length(&screen.selectionInfo); i++) {
2718 gerbv_selection_item_t sItem = selection_get_item_by_index(&screen.selectionInfo, i);
2728 g_message(_(
"Object type: Polygon"));
2748 g_message(
"---------------------------------------");
2761 while (now - 30 < start) {
2763 dprintf(
"Benchmark(): Starting redraw #%d\n", i);
2764 gerbv_render_to_pixmap_using_gdk(
mainProject, renderedPixmap, renderInfo, NULL, NULL);
2766 dprintf(
"Elapsed time = %ld seconds\n", (
long int)(now - start));
2769 _(
"FAST (=GDK) mode benchmark: %d redraws "
2770 "in %ld seconds (%g redraws/second)"),
2771 i, (
long int)(now - start), (
double)i / (
double)(now - start)
2773 gdk_pixmap_unref(renderedPixmap);
2780 while (now - 30 < start) {
2782 dprintf(
"Benchmark(): Starting redraw #%d\n", i);
2783 cairo_surface_t* cSurface =
2785 cairo_t* cairoTarget = cairo_create(cSurface);
2786 gerbv_render_all_layers_to_cairo_target(
mainProject, cairoTarget, renderInfo);
2787 cairo_destroy(cairoTarget);
2788 cairo_surface_destroy(cSurface);
2790 dprintf(
"Elapsed time = %ld seconds\n", (
long int)(now - start));
2793 _(
"NORMAL (=Cairo) mode benchmark: %d redraws "
2794 "in %ld seconds (%g redraws/second)"),
2795 i, (
long int)(now - start), (
double)i / (
double)(now - start)
2801 callbacks_benchmark_clicked(GtkButton* button, gpointer user_data) {
2806 _(
"Performance benchmark"),
2807 _(
"Application will be unresponsive for 1 minute! "
2808 "Run performance benchmark?"),
2809 FALSE, NULL, GTK_STOCK_OK, GTK_STOCK_CANCEL
2813 GERB_COMPILE_WARNING(_(
"Running full zoom benchmark..."));
2814 while (g_main_context_iteration(NULL, FALSE)) {}
2819 callbacks_support_benchmark(&renderInfo);
2821 GERB_COMPILE_WARNING(_(
"Running x5 zoom benchmark..."));
2822 while (g_main_context_iteration(NULL, FALSE)) {}
2828 callbacks_support_benchmark(&renderInfo);
2833 callbacks_edit_object_properties_clicked(GtkButton* button, gpointer user_data) {}
2837 callbacks_live_edit(GtkWidget* button, gpointer user_data) {
2838 GtkDialog* toplevel = GTK_DIALOG(gtk_widget_get_toplevel(button));
2839 gtk_dialog_response(toplevel, GTK_RESPONSE_APPLY);
2844 callbacks_move_objects_clicked(GtkButton* button, gpointer user_data) {
2846 gerbv_image_move_selected_objects(screen.selectionInfo.selectedNodeArray, -0.050, 0.050);
2847 callbacks_update_layer_tree();
2848 selection_clear(&screen.selectionInfo);
2849 update_selected_object_message(FALSE);
2850 render_refresh_rendered_image_on_screen();
2855 callbacks_reduce_object_area_clicked(GtkButton* button, gpointer user_data) {
2857 gerbv_image_reduce_area_of_selected_objects(screen.selectionInfo.selectedNodeArray, 0.20, 3, 3, 0.01);
2858 selection_clear(&screen.selectionInfo);
2859 update_selected_object_message(FALSE);
2860 render_refresh_rendered_image_on_screen();
2865 callbacks_delete_objects_clicked(GtkButton* button, gpointer user_data) {
2866 if (selection_length(&screen.selectionInfo) == 0) {
2868 _(
"No object is currently selected"),
2869 _(
"Objects must be selected using the pointer tool "
2870 "before they can be deleted."),
2882 _(
"Do you want to permanently delete "
2883 "the selected objects from <i>visible</i> layers?"),
2884 _(
"Gerbv currently has no undo function, so "
2885 "this action cannot be undone. This action "
2886 "will not change the saved file unless you "
2887 "save the file afterwards."),
2895 for (i = 0; i < selection_length(&screen.selectionInfo);) {
2896 gerbv_selection_item_t sel_item = selection_get_item_by_index(&screen.selectionInfo, i);
2906 selection_clear_item_by_index(&screen.selectionInfo, i);
2909 update_selected_object_message(FALSE);
2911 render_refresh_rendered_image_on_screen();
2912 callbacks_update_layer_tree();
2917 callbacks_drawingarea_configure_event(GtkWidget* widget, GdkEventConfigure* event) {
2918 GdkDrawable* drawable = widget->window;
2924 int x_off = 0, y_off = 0;
2926 if (GDK_IS_WINDOW(widget->window)) {
2928 GdkWindow* window = GDK_WINDOW(widget->window);
2929 gdk_window_get_internal_paint_info(window, &drawable, &x_off, &y_off);
2931 if (screen.windowSurface)
2932 cairo_surface_destroy((cairo_surface_t*)screen.windowSurface);
2934 #if defined(WIN32) || defined(QUARTZ)
2935 cairo_t* cairoTarget = gdk_cairo_create(GDK_WINDOW(widget->window));
2937 screen.windowSurface = cairo_get_target(cairoTarget);
2940 screen.windowSurface = cairo_surface_reference(screen.windowSurface);
2941 cairo_destroy(cairoTarget);
2943 GdkVisual* visual = gdk_drawable_get_visual(drawable);
2944 screen.windowSurface = (gpointer)cairo_xlib_surface_create(
2945 GDK_DRAWABLE_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable), GDK_VISUAL_XVISUAL(visual),
2954 render_refresh_rendered_image_on_screen();
2960 callbacks_drawingarea_expose_event(GtkWidget* widget, GdkEventExpose* event) {
2962 GdkPixmap* new_pixmap;
2963 GdkGC* gc = gdk_gc_new(widget->window);
2968 new_pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1);
2972 gdk_draw_rectangle(new_pixmap, gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height);
2978 if (screen.pixmap != NULL) {
2980 new_pixmap, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], screen.pixmap, event->area.x - screen.off_x,
2981 event->area.y - screen.off_y, event->area.x, event->area.y, event->area.width, event->area.height
2989 widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], new_pixmap, event->area.x, event->area.y,
2990 event->area.x, event->area.y, event->area.width, event->area.height
2993 gdk_pixmap_unref(new_pixmap);
2999 if (screen.state == IN_ZOOM_OUTLINE) {
3000 render_draw_zoom_outline(screen.centered_outline_zoom);
3001 }
else if (screen.state == IN_MEASURE) {
3004 if (screen.tool == MEASURE && screen.state != IN_MEASURE) {
3013 int x_off = 0, y_off = 0;
3014 GdkDrawable* drawable = widget->window;
3016 if (GDK_IS_WINDOW(widget->window)) {
3018 GdkWindow* window = GDK_WINDOW(widget->window);
3019 gdk_window_get_internal_paint_info(window, &drawable, &x_off, &y_off);
3021 gdk_drawable_get_size(drawable, &width, &height);
3023 #if defined(WIN32) || defined(QUARTZ)
3025 cr = gdk_cairo_create(GDK_WINDOW(widget->window));
3027 cairo_surface_t* buffert;
3029 GdkVisual* visual = gdk_drawable_get_visual(drawable);
3030 buffert = (gpointer)cairo_xlib_surface_create(
3031 GDK_DRAWABLE_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable), GDK_VISUAL_XVISUAL(visual),
event->area.width,
3034 cr = cairo_create(buffert);
3036 cairo_translate(cr, -event->area.x + screen.off_x, -event->area.y + screen.off_y);
3037 render_project_to_cairo_target(cr);
3039 #if !defined(WIN32) && !defined(QUARTZ)
3040 cairo_surface_destroy(buffert);
3043 if (screen.tool == MEASURE)
3050 callbacks_screen2board(gdouble* X, gdouble* Y, gint x, gint y) {
3062 const char* gerbv_coords_pattern_mils_str = N_(
"%8.2f %8.2f");
3066 callbacks_update_statusbar_coordinates(gint x, gint y) {
3069 callbacks_screen2board(&X, &Y, x, y);
3071 switch (screen.unit) {
3074 screen.statusbar.coordstr, MAX_COORDLEN, _(gerbv_coords_pattern_mils_str), COORD2MILS(X), COORD2MILS(Y)
3078 utf8_snprintf(screen.statusbar.coordstr, MAX_COORDLEN, _(
"%8.3f %8.3f"), COORD2MMS(X), COORD2MMS(Y));
3080 default: utf8_snprintf(screen.statusbar.coordstr, MAX_COORDLEN, _(
"%4.5f %4.5f"), COORD2INS(X), COORD2INS(Y));
3087 update_selected_object_message(gboolean userTriedToSelect) {
3088 if (screen.tool != POINTER)
3091 gint selectionLength = selection_length(&screen.selectionInfo);
3093 if (selectionLength == 0) {
3094 if (userTriedToSelect) {
3097 gchar* str = g_new(gchar, MAX_DISTLEN);
3100 _(
"No object selected. Objects can "
3101 "only be selected in the active "
3105 utf8_snprintf(screen.statusbar.diststr, MAX_DISTLEN,
"<b>%s</b>", str);
3109 screen.statusbar.diststr,
3110 _(
"Click to select objects in the "
3111 "active layer. Middle click and drag "
3118 screen.statusbar.diststr, MAX_DISTLEN,
3119 ngettext(
"%d object are currently selected",
"%d objects are currently selected", selectionLength),
3129 callbacks_drawingarea_motion_notify_event(GtkWidget* widget, GdkEventMotion* event) {
3131 GdkModifierType state;
3134 gdk_window_get_pointer(event->window, &x, &y, &state);
3138 state =
event->state;
3141 switch (screen.state) {
3144 if (screen.last_x != 0 || screen.last_y != 0) {
3146 screen.off_x += x - screen.last_x;
3147 screen.off_y += y - screen.last_y;
3151 callbacks_force_expose_event_for_screen();
3152 callbacks_update_scrollbar_positions();
3157 case IN_ZOOM_OUTLINE:
3159 if (screen.last_x || screen.last_y)
3160 render_draw_zoom_outline(screen.centered_outline_zoom);
3163 render_draw_zoom_outline(screen.centered_outline_zoom);
3170 callbacks_screen2board(&(screen.measure_stop_x), &(screen.measure_stop_y), x, y);
3178 case IN_SELECTION_DRAG:
3180 if (screen.last_x || screen.last_y)
3181 render_draw_selection_box_outline();
3184 render_draw_selection_box_outline();
3192 callbacks_update_statusbar_coordinates(x, y);
3193 callbacks_update_ruler_pointers();
3199 callbacks_drawingarea_button_press_event(GtkWidget* widget, GdkEventButton* event) {
3200 GdkWindow* drawing_area_window = screen.drawing_area->window;
3203 switch (event->button) {
3205 if (screen.tool == POINTER) {
3209 screen.state = IN_SELECTION_DRAG;
3210 screen.start_x =
event->x;
3211 screen.start_y =
event->y;
3212 }
else if (screen.tool == PAN) {
3214 screen.state = IN_MOVE;
3215 screen.last_x =
event->x;
3216 screen.last_y =
event->y;
3217 }
else if (screen.tool == ZOOM) {
3218 screen.state = IN_ZOOM_OUTLINE;
3220 screen.start_x =
event->x;
3221 screen.start_y =
event->y;
3222 screen.centered_outline_zoom =
event->state;
3223 }
else if (screen.tool == MEASURE) {
3224 screen.state = IN_MEASURE;
3225 callbacks_screen2board(&(screen.measure_start_x), &(screen.measure_start_y), event->x, event->y);
3226 screen.measure_stop_x = screen.measure_start_x;
3227 screen.measure_stop_y = screen.measure_start_y;
3229 callbacks_force_expose_event_for_screen();
3233 screen.state = IN_MOVE;
3234 screen.last_x =
event->x;
3235 screen.last_y =
event->y;
3236 cursor = gdk_cursor_new(GDK_FLEUR);
3237 gdk_window_set_cursor(drawing_area_window, cursor);
3238 gdk_cursor_destroy(cursor);
3241 if (screen.tool == POINTER) {
3244 if (selection_length(&screen.selectionInfo) == 0) {
3247 render_fill_selection_buffer_from_mouse_click(event->x, event->y, index, SELECTION_REPLACE);
3249 selection_clear(&screen.selectionInfo);
3250 update_selected_object_message(FALSE);
3251 render_refresh_rendered_image_on_screen();
3256 if (selection_length(&screen.selectionInfo) != 0) {
3257 update_selected_object_message(TRUE);
3259 GTK_MENU(screen.win.drawWindowPopupMenu), NULL, NULL, NULL, NULL, event->button, event->time
3265 screen.state = IN_ZOOM_OUTLINE;
3266 screen.start_x =
event->x;
3267 screen.start_y =
event->y;
3268 screen.centered_outline_zoom =
event->state & GDK_SHIFT_MASK;
3269 cursor = gdk_cursor_new(GDK_SIZING);
3270 gdk_window_set_cursor(drawing_area_window, cursor);
3271 gdk_cursor_destroy(cursor);
3274 case 4: render_zoom_display(ZOOM_IN_CMOUSE, 0, event->x, event->y);
break;
3275 case 5: render_zoom_display(ZOOM_OUT_CMOUSE, 0, event->x, event->y);
break;
3278 callbacks_switch_to_correct_cursor();
3285 GtkMenuItem** menu_items = (GtkMenuItem**)screen.win.curEditAlingItem;
3286 gerbv_selection_item_t si[2];
3287 int id[2] = { -1, -1 };
3291 if (selection_length(sel_info) == 2) {
3292 si[0] = selection_get_item_by_index(sel_info, 0);
3293 si[1] = selection_get_item_by_index(sel_info, 1);
3296 if (f[i]->image == si[0].image)
3299 if (f[i]->image == si[1].image)
3304 if (
id[0] *
id[1] >= 0 &&
id[0] !=
id[1]) {
3310 str = g_strdup_printf(_(
"#_%i %s > #%i %s"),
id[0] + 1, f[
id[0]]->name,
id[1] + 1, f[
id[1]]->name);
3311 gtk_menu_item_set_label(menu_items[0], str);
3314 str = g_strdup_printf(_(
"#_%i %s > #%i %s"),
id[1] + 1, f[
id[1]]->name,
id[0] + 1, f[
id[0]]->name);
3315 gtk_menu_item_set_label(menu_items[1], str);
3318 gtk_widget_set_sensitive(screen.win.curEditAlingMenuItem, TRUE);
3325 gtk_widget_set_sensitive(screen.win.curEditAlingMenuItem, FALSE);
3326 gtk_menu_item_set_label(menu_items[0],
"");
3327 gtk_menu_item_set_label(menu_items[1],
"");
3337 gerbv_selection_item_t item[2];
3340 int align_second_to_first = GPOINTER_TO_INT(user_data);
3344 if (selection_length(sel_info) != 2)
3347 item[0] = selection_get_item_by_index(sel_info, 0);
3348 item[1] = selection_get_item_by_index(sel_info, 1);
3353 if (fi[0] == NULL || fi[1] == NULL || fi[0] == fi[1])
3357 for (i = 0; i < 2; i++) {
3376 x[i] = net->
cirseg->cp_x;
3377 y[i] = net->
cirseg->cp_y;
3381 _(
"Can't align by this "
3389 _(
"Can't align by this "
3398 if (align_second_to_first) {
3406 render_refresh_rendered_image_on_screen();
3407 callbacks_update_layer_tree();
3412 callbacks_drawingarea_button_release_event(GtkWidget* widget, GdkEventButton* event) {
3415 if (event->type != GDK_BUTTON_RELEASE)
3418 switch (screen.state) {
3422 render_refresh_rendered_image_on_screen();
3423 callbacks_switch_to_normal_tool_cursor(screen.tool);
3426 case IN_ZOOM_OUTLINE:
3427 if ((event->state & GDK_SHIFT_MASK) != 0) {
3428 render_zoom_display(ZOOM_OUT_CMOUSE, 0, event->x, event->y);
3432 else if ((abs(screen.start_x - event->x) < 4) && (abs(screen.start_y - event->y) < 4)) {
3433 render_zoom_display(ZOOM_IN_CMOUSE, 0, event->x, event->y);
3437 callbacks_switch_to_normal_tool_cursor(screen.tool);
3440 case IN_SELECTION_DRAG:
3446 enum selection_action sel_action = SELECTION_REPLACE;
3448 if (event->state & GDK_SHIFT_MASK)
3449 sel_action = SELECTION_ADD;
3450 else if (event->state & GDK_CONTROL_MASK)
3451 sel_action = SELECTION_TOGGLE;
3454 if ((fabs((
double)(screen.last_x - screen.start_x)) < 5)
3455 && (fabs((
double)(screen.last_y - screen.start_y)) < 5)) {
3456 render_fill_selection_buffer_from_mouse_click(event->x, event->y, index, sel_action);
3458 render_fill_selection_buffer_from_mouse_drag(
3459 event->x, event->y, screen.start_x, screen.start_y, index, sel_action
3464 update_selected_object_message(TRUE);
3466 check_align_files_possibility(&screen.selectionInfo);
3468 render_refresh_rendered_image_on_screen();
3474 screen.state = NORMAL;
3481 callbacks_window_key_press_event(GtkWidget* widget, GdkEventKey* event) {
3482 switch (event->keyval) {
3484 if (screen.tool == POINTER) {
3485 selection_clear(&screen.selectionInfo);
3486 update_selected_object_message(FALSE);
3491 screen.state = NORMAL;
3492 render_refresh_rendered_image_on_screen();
3503 callbacks_window_key_release_event(GtkWidget* widget, GdkEventKey* event) {
3510 callbacks_window_scroll_event(GtkWidget* widget, GdkEventScroll* event) {
3511 switch (event->direction) {
3512 case GDK_SCROLL_UP: render_zoom_display(ZOOM_IN_CMOUSE, 0, event->x, event->y);
break;
3513 case GDK_SCROLL_DOWN: render_zoom_display(ZOOM_OUT_CMOUSE, 0, event->x, event->y);
break;
3514 case GDK_SCROLL_LEFT:
3516 case GDK_SCROLL_RIGHT:
3518 default:
return TRUE;
3532 if ((screen.statusbar.coordstr != NULL) && (GTK_IS_LABEL(screen.win.statusMessageLeft))) {
3533 gtk_label_set_text(GTK_LABEL(screen.win.statusMessageLeft), screen.statusbar.coordstr);
3535 if ((screen.statusbar.diststr != NULL) && (GTK_IS_LABEL(screen.win.statusMessageRight))) {
3536 gtk_label_set_markup(GTK_LABEL(screen.win.statusMessageRight), screen.statusbar.diststr);
3542 callbacks_update_statusbar_measured_distance(gdouble dx, gdouble dy) {
3543 gdouble delta = hypot(dx, dy);
3545 if (screen.unit == GERBV_MILS) {
3547 screen.statusbar.diststr, MAX_DISTLEN, _(
"Measured distance: %8.2f mils (%8.2f x, %8.2f y)"),
3548 COORD2MILS(delta), COORD2MILS(dx), COORD2MILS(dy)
3550 }
else if (screen.unit == GERBV_MMS) {
3552 screen.statusbar.diststr, MAX_DISTLEN, _(
"Measured distance: %8.3f mm (%8.3f x, %8.3f y)"),
3553 COORD2MMS(delta), COORD2MMS(dx), COORD2MMS(dy)
3557 screen.statusbar.diststr, MAX_DISTLEN, _(
"Measured distance: %4.5f inches (%4.5f x, %4.5f y)"),
3558 COORD2INS(delta), COORD2INS(dx), COORD2INS(dy)
3566 callbacks_sidepane_render_type_combo_box_changed(GtkComboBox* widget, gpointer user_data) {
3569 dprintf(
"%s(): type = %d\n", __FUNCTION__, type);
3571 if (type < 0 || type == screenRenderInfo.
renderType)
3575 callbacks_render_type_changed();
3580 callbacks_viewmenu_rendertype_changed(GtkCheckMenuItem* widget, gpointer user_data) {
3586 dprintf(
"%s(): type = %d\n", __FUNCTION__, type);
3589 callbacks_render_type_changed();
3594 callbacks_viewmenu_units_changed(GtkCheckMenuItem* widget, gpointer user_data) {
3595 gerbv_gui_unit_t unit = GPOINTER_TO_INT(user_data);
3597 if (unit < 0 || unit == screen.unit)
3600 dprintf(
"%s(): unit = %d, screen.unit = %d\n", __FUNCTION__, unit, screen.unit);
3602 callbacks_units_changed(unit);
3607 callbacks_statusbar_unit_combo_box_changed(GtkComboBox* widget, gpointer user_data) {
3608 gerbv_gui_unit_t unit = gtk_combo_box_get_active(widget);
3609 int force_change = GPOINTER_TO_INT(user_data);
3611 if (!force_change && (unit < 0 || unit == screen.unit))
3614 callbacks_units_changed(unit);
3619 callbacks_clear_messages_button_clicked(GtkButton* button, gpointer user_data) {
3620 GtkTextBuffer* textbuffer;
3621 GtkTextIter start, end;
3623 screen.length_sum = 0;
3625 textbuffer = gtk_text_view_get_buffer((GtkTextView*)screen.win.messageTextView);
3626 gtk_text_buffer_get_start_iter(textbuffer, &start);
3627 gtk_text_buffer_get_end_iter(textbuffer, &end);
3628 gtk_text_buffer_delete(textbuffer, &start, &end);
3633 callbacks_handle_log_messages(
3634 const gchar* log_domain, GLogLevelFlags log_level,
const gchar* message, gpointer user_data
3636 GtkTextBuffer* textbuffer = NULL;
3639 GtkTextMark * StartMark = NULL, *StopMark = NULL;
3640 GtkTextIter StartIter, StopIter;
3641 GtkWidget * dialog, *label;
3643 if (!screen.win.messageTextView)
3646 textbuffer = gtk_text_view_get_buffer((GtkTextView*)screen.win.messageTextView);
3649 gtk_text_buffer_get_end_iter(textbuffer, &iter);
3653 StartMark = gtk_text_buffer_create_mark(textbuffer,
"NewTextStart", &iter, TRUE);
3655 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"blue_foreground");
3658 tag = gtk_text_buffer_create_tag(textbuffer,
"black_foreground",
"foreground",
"black", NULL);
3659 tag = gtk_text_buffer_create_tag(textbuffer,
"blue_foreground",
"foreground",
"blue", NULL);
3660 tag = gtk_text_buffer_create_tag(textbuffer,
"red_foreground",
"foreground",
"red", NULL);
3661 tag = gtk_text_buffer_create_tag(textbuffer,
"darkred_foreground",
"foreground",
"darkred", NULL);
3662 tag = gtk_text_buffer_create_tag(textbuffer,
"darkblue_foreground",
"foreground",
"darkblue", NULL);
3663 tag = gtk_text_buffer_create_tag(textbuffer,
"darkgreen_foreground",
"foreground",
"darkgreen", NULL);
3664 tag = gtk_text_buffer_create_tag(textbuffer,
"saddlebrown_foreground",
"foreground",
"saddlebrown", NULL);
3671 switch (log_level & G_LOG_LEVEL_MASK) {
3672 case G_LOG_LEVEL_ERROR:
3674 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"red_foreground");
3675 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
3676 gtk_widget_show(screen.win.sidepane_notebook);
3678 case G_LOG_LEVEL_CRITICAL:
3679 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"red_foreground");
3680 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
3681 gtk_widget_show(screen.win.sidepane_notebook);
3683 case G_LOG_LEVEL_WARNING:
3684 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"darkred_foreground");
3685 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
3686 gtk_widget_show(screen.win.sidepane_notebook);
3688 case G_LOG_LEVEL_MESSAGE:
3689 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"darkblue_foreground");
3690 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen.win.sidepane_notebook), 1);
3691 gtk_widget_show(screen.win.sidepane_notebook);
3693 case G_LOG_LEVEL_INFO:
3694 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"darkgreen_foreground");
3696 case G_LOG_LEVEL_DEBUG:
3697 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"saddlebrown_foreground");
3699 default: tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer),
"black_foreground");
break;
3705 if (log_level & G_LOG_FLAG_FATAL) {
3706 fprintf(stderr, _(
"Fatal error: %s\n"), message);
3709 dialog = gtk_dialog_new_with_buttons(
3710 _(
"Fatal Error"), NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
3711 GTK_RESPONSE_ACCEPT, NULL
3714 label = gtk_label_new(g_strdup_printf(_(
"Fatal error: %s"), message));
3715 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
3716 gtk_label_set_selectable(GTK_LABEL(label), TRUE);
3717 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), gtk_label_new(_(
"\nGerbv will be closed now!")));
3719 gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
3721 gtk_widget_show_all(dialog);
3722 gtk_dialog_run(GTK_DIALOG(dialog));
3725 gtk_text_buffer_insert(textbuffer, &iter, message, -1);
3726 gtk_text_buffer_insert(textbuffer, &iter,
"\n", -1);
3729 g_signal_emit_by_name(textbuffer,
"paste-done", NULL);
3731 gtk_text_buffer_get_end_iter(textbuffer, &iter);
3733 StopMark = gtk_text_buffer_create_mark(textbuffer,
"NewTextStop", &iter, TRUE);
3735 gtk_text_buffer_get_iter_at_mark(textbuffer, &StartIter, StartMark);
3736 gtk_text_buffer_get_iter_at_mark(textbuffer, &StopIter, StopMark);
3738 gtk_text_buffer_apply_tag(textbuffer, tag, &StartIter, &StopIter);
3743 callbacks_force_expose_event_for_screen(
void) {
3744 GdkRectangle update_rect;
3752 gdk_window_invalidate_rect(screen.drawing_area->window, &update_rect, FALSE);
3755 callbacks_update_ruler_scales();
3756 callbacks_update_scrollbar_limits();
3757 callbacks_update_scrollbar_positions();
3761 screen_units(
double d) {
3762 switch (screen.unit) {
3763 case GERBV_INS:
return COORD2INS(d);
break;
3764 case GERBV_MILS:
return COORD2MILS(d);
break;
3765 case GERBV_MMS:
return COORD2MMS(d);
break;
3772 screen_units_str(
void) {
3774 const char* units_str[] = { N_(
"mil"), N_(
"mm"), N_(
"in") };
3776 return _(units_str[screen.unit]);
3780 line_length(
double x0,
double y0,
double x1,
double y1) {
3781 double dx = x0 - x1;
3782 double dy = y0 - y1;
3784 return hypot(dx, dy);
3788 arc_length(
double dia,
double angle) {
3789 return M_PI * dia * (angle / 360.0);
3796 gboolean show_length = FALSE;
3797 gboolean aperture_is_valid = FALSE;
3798 double x, y, len = 0;
3801 aperture_is_valid = TRUE;
3815 g_message(_(
"Object type: Line"));
3817 g_message(_(
"Object type: Slot (drilled)"));
3826 g_message(_(
"Object type: Arc"));
3827 len = arc_length(net->
cirseg->width, fabs(net->
cirseg->angle1 - net->
cirseg->angle2));
3831 default: g_message(_(
"Object type: Unknown"));
break;
3835 g_message(_(
" Exposure: On"));
3837 if (aperture_is_valid) {
3847 g_message(_(
" Start: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3852 g_message(_(
" Stop: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3861 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3863 x = net->
cirseg->width / 2;
3866 g_message(_(
" Radius: %g %s"), screen_units(x), screen_units_str());
3868 g_message(_(
" Angle: %g deg"), fabs(net->
cirseg->angle1 - net->
cirseg->angle2));
3869 g_message(_(
" Angles: (%g, %g) deg"), net->
cirseg->angle1, net->
cirseg->angle2);
3871 _(
" Direction: %s"),
3883 double dia = aper->parameter[0];
3884 g_message(_(
" Slot length: %g %s"), screen_units(len + dia), screen_units_str());
3887 screen.length_sum += len;
3889 _(
" Length: %g (sum: %g) %s"), screen_units(len), screen_units(screen.length_sum),
3894 net_layer_file_report(net, img, prj);
3900 g_message(_(
"Object type: Flashed aperture"));
3902 g_message(_(
"Object type: Drill"));
3904 if (aperture_is_valid) {
3914 g_message(_(
" Location: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3916 net_layer_file_report(net, img, prj);
3927 double* params = apertures[aperture_num]->parameter;
3928 gerbv_simplified_amacro_t* sam = apertures[aperture_num]->simplified;
3930 g_message(_(
" Aperture used: D%d"), aperture_num);
3932 _(
" Aperture type: %s"),
3938 g_message(_(
" Diameter: %g %s"), screen_units(params[0]), screen_units_str());
3943 _(
" Dimensions: %gx%g %s"), screen_units(params[0]), screen_units(params[1]), screen_units_str()
3948 switch (sam->type) {
3951 _(
" Diameter: %g %s"), screen_units(sam->parameter[CIRCLE_DIAMETER]), screen_units_str()
3953 x += sam->parameter[CIRCLE_CENTER_X];
3954 y += sam->parameter[CIRCLE_CENTER_Y];
3956 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3960 g_message(_(
" Number of points: %g"), sam->parameter[OUTLINE_NUMBER_OF_POINTS]);
3961 x += sam->parameter[OUTLINE_FIRST_X];
3962 y += sam->parameter[OUTLINE_FIRST_Y];
3964 g_message(_(
" Start: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3965 g_message(_(
" Rotation: %g deg"), sam->parameter[OUTLINE_ROTATION_IDX(sam->parameter)]);
3969 g_message(_(
" Number of points: %g"), sam->parameter[POLYGON_NUMBER_OF_POINTS]);
3971 _(
" Diameter: %g %s"), screen_units(sam->parameter[POLYGON_DIAMETER]), screen_units_str()
3973 x += sam->parameter[POLYGON_CENTER_X];
3974 y += sam->parameter[POLYGON_CENTER_Y];
3976 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
3977 g_message(_(
" Rotation: %g deg"), sam->parameter[POLYGON_ROTATION]);
3982 _(
" Outside diameter: %g %s"), screen_units(sam->parameter[MOIRE_OUTSIDE_DIAMETER]),
3986 _(
" Ring thickness: %g %s"), screen_units(sam->parameter[MOIRE_CIRCLE_THICKNESS]),
3990 _(
" Gap width: %g %s"), screen_units(sam->parameter[MOIRE_GAP_WIDTH]), screen_units_str()
3992 g_message(_(
" Number of rings: %g"), sam->parameter[MOIRE_NUMBER_OF_CIRCLES]);
3994 _(
" Crosshair thickness: %g %s"),
3995 screen_units(sam->parameter[MOIRE_CROSSHAIR_THICKNESS]), screen_units_str()
3998 _(
" Crosshair length: %g %s"), screen_units(sam->parameter[MOIRE_CROSSHAIR_LENGTH]),
4001 x += sam->parameter[MOIRE_CENTER_X];
4002 y += sam->parameter[MOIRE_CENTER_Y];
4004 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4005 g_message(_(
" Rotation: %g deg"), sam->parameter[MOIRE_ROTATION]);
4010 _(
" Outside diameter: %g %s"), screen_units(sam->parameter[THERMAL_OUTSIDE_DIAMETER]),
4014 _(
" Inside diameter: %g %s"), screen_units(sam->parameter[THERMAL_INSIDE_DIAMETER]),
4018 _(
" Crosshair thickness: %g %s"),
4019 screen_units(sam->parameter[THERMAL_CROSSHAIR_THICKNESS]), screen_units_str()
4021 x += sam->parameter[THERMAL_CENTER_X];
4022 y += sam->parameter[THERMAL_CENTER_Y];
4024 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4025 g_message(_(
" Rotation: %g deg"), sam->parameter[THERMAL_ROTATION]);
4030 _(
" Width: %g %s"), screen_units(sam->parameter[LINE20_WIDTH]), screen_units_str()
4032 x += sam->parameter[LINE20_START_X];
4033 y += sam->parameter[LINE20_START_Y];
4035 g_message(_(
" Start: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4036 x += sam->parameter[LINE20_END_X];
4037 y += sam->parameter[LINE20_END_Y];
4039 g_message(_(
" Stop: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4040 g_message(_(
" Rotation: %g deg"), sam->parameter[LINE20_ROTATION]);
4045 _(
" Width: %g %s"), screen_units(sam->parameter[LINE21_WIDTH]), screen_units_str()
4048 _(
" Height: %g %s"), screen_units(sam->parameter[LINE21_HEIGHT]), screen_units_str()
4050 x += sam->parameter[LINE21_CENTER_X];
4051 y += sam->parameter[LINE21_CENTER_Y];
4053 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4054 g_message(_(
" Rotation: %g deg"), sam->parameter[LINE21_ROTATION]);
4059 _(
" Width: %g %s"), screen_units(sam->parameter[LINE22_WIDTH]), screen_units_str()
4062 _(
" Height: %g %s"), screen_units(sam->parameter[LINE22_HEIGHT]), screen_units_str()
4064 x += sam->parameter[LINE22_LOWER_LEFT_X];
4065 y += sam->parameter[LINE22_LOWER_LEFT_Y];
4068 _(
" Lower left: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str()
4070 g_message(_(
" Rotation: %g deg"), sam->parameter[LINE22_ROTATION]);
4082 drill_report(gerbv_aperture_t* apertures[],
int aperture_num) {
4084 double* params = apertures[aperture_num]->parameter;
4086 g_message(_(
" Tool used: T%d"), aperture_num);
4088 g_message(_(
" Diameter: %g %s"), screen_units(params[0]), screen_units_str());
4108 g_message(_(
" Number of vertices: %u"), c - 1);
4121 g_message(_(
" Line from: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4127 g_message(_(
" Line to: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4136 g_message(_(
" Arc from: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4141 g_message(_(
" Arc to: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4146 g_message(_(
" Center: (%g, %g) %s"), screen_units(x), screen_units(y), screen_units_str());
4151 g_message(_(
" Radius: %g %s"), screen_units(x) / 2, screen_units_str());
4153 g_message(_(
" Angle: %g deg"), fabs(n->
cirseg->angle1 - n->
cirseg->angle2));
4154 g_message(_(
" Angles: (%g, %g) deg"), n->
cirseg->angle1, n->
cirseg->angle2);
4156 _(
" Direction: %s"),
4171 if (net->
label != NULL)
4172 g_message(_(
" Net label: %s"), net->
label->str);
4176 g_message(_(
" Layer name: %s"), net->
layer->
name);
4181 g_message(_(
" In file: %s"), prj->
file[i]->
name);
4187 analyze_window_size_restore(GtkWidget* win) {
4192 if (!screen.settings)
4195 var = g_settings_get_value(screen.settings,
"analyze-window-size");
4196 xy = g_variant_get_fixed_array(var, &num,
sizeof(*xy));
4198 gtk_window_set_default_size(GTK_WINDOW(win), xy[0], xy[1]);
4199 g_variant_unref(var);
4201 var = g_settings_get_value(screen.settings,
"analyze-window-position");
4202 xy = g_variant_get_fixed_array(var, &num,
sizeof(*xy));
4204 gtk_window_move(GTK_WINDOW(win), xy[0], xy[1]);
4205 g_variant_unref(var);
4210 analyze_window_size_store(GtkWidget* win, gpointer user_data) {
4215 if (!screen.settings)
4218 is_max = FALSE != (GDK_WINDOW_STATE_MAXIMIZED & gdk_window_get_state(gtk_widget_get_window(win)));
4222 gtk_window_get_size(GTK_WINDOW(win), (gint*)xy, (gint*)(xy + 1));
4223 var = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, xy, 2,
sizeof(xy[0]));
4224 g_settings_set_value(screen.settings,
"analyze-window-size", var);
4226 gtk_window_get_position(GTK_WINDOW(win), (gint*)xy, (gint*)(xy + 1));
4227 var = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32, xy, 2,
sizeof(xy[0]));
4228 g_settings_set_value(screen.settings,
"analyze-window-position", var);
Dynamic GUI window creation header info.
Generated at build time authors list.
Generated at build time bugs list.
void open_files(GSList *filenames)
File -> open action requested or file drop event happened.
void callbacks_bugs_activate(GtkMenuItem *menuitem, gpointer user_data)
The help -> bugs menu item was selected.
gboolean callbacks_quit_activate(GtkMenuItem *menuitem, gpointer user_data)
The file -> quit menu item was selected or the user requested the main window to be closed by other m...
void callbacks_update_statusbar(void)
Displays additional information in the statusbar.
void callbacks_open_activate(GtkMenuItem *menuitem, gpointer user_data)
The file -> open action was selected.
void callbacks_align_files_from_sel_clicked(GtkMenuItem *menu_item, gpointer user_data)
The edit -> align layers menu item was selected.
void callbacks_analyze_active_drill_activate(GtkMenuItem *menuitem, gpointer user_data)
The analyze -> analyze drill file menu item was selected.
static gint callbacks_get_selected_row_index(void)
This fcn returns the index of selected layer (selected in the layer window on left).
gerbv_image_t * merge_images(int type)
Go through each file and look at visibility, then type.
void open_project(char *project_filename)
The file -> open menu item was selected.
void callbacks_analyze_active_gerbers_activate(GtkMenuItem *menuitem, gpointer user_data)
The analyze -> analyze Gerbers menu item was selected.
void callbacks_about_activate(GtkMenuItem *menuitem, gpointer user_data)
The help -> about menu item was selected.
void callbacks_new_project_activate(GtkMenuItem *menuitem, gpointer user_data)
The file -> new menu item was selected.
void callbacks_toggle_layer_visibility_activate(GtkMenuItem *menuitem, gpointer user_data)
View/"Toggle visibility layer X" or Current layer/"Toggle visibility" menu item was activated.
Header info for the GUI callback functions.
Header info for the GDK rendering functions.
Header info for the cairo rendering functions and the related selection calculating functions.
const char * drill_g_code_name(drill_g_code_t g_code)
Return drill G-code name by code number.
const char * drill_m_code_name(drill_m_code_t m_code)
Return drill M-code name by code number.
Header info for the Excellon drill parsing functions.
void gerbv_drill_stats_destroy(gerbv_drill_stats_t *stats)
gboolean gerbv_export_drill_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in Excellon drill format.
gboolean gerbv_export_dxf_file_from_image(const gchar *file_name, gerbv_image_t *input_img, gerbv_user_transformation_t *trans)
Export an image to a new file in DXF format.
gboolean gerbv_export_geda_pcb_file_from_image(const gchar *file_name, gerbv_image_t *input_img, gerbv_user_transformation_t *trans)
Export an image to a new file in gEDA PCB format.
void gerbv_export_png_file_from_project(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo, const gchar *filename)
Render a project to a PNG file using user-specified render info.
void gerbv_export_svg_file_from_project_autoscaled(gerbv_project_t *gerbvProject, const gchar *filename)
Render a project to a SVG file, autoscaling the layers to fit inside the specified image dimensions.
void gerbv_export_postscript_file_from_project_autoscaled(gerbv_project_t *gerbvProject, const gchar *filename)
Render a project to a Postscript file, autoscaling the layers to fit inside the specified image dimen...
void gerbv_export_pdf_file_from_project_autoscaled(gerbv_project_t *gerbvProject, const gchar *filename)
Render a project to a PDF file, autoscaling the layers to fit inside the specified image dimensions.
void gerbv_export_png_file_from_project_autoscaled(gerbv_project_t *gerbvProject, int widthInPixels, int heightInPixels, const gchar *filename)
Render a project to a PNG file, autoscaling the layers to fit inside the specified image dimensions.
gboolean gerbv_export_isel_drill_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in ISEL NCP drill format.
gboolean gerbv_export_rs274x_file_from_image(const gchar *filename, gerbv_image_t *inputImage, gerbv_user_transformation_t *transform)
Export an image to a new file in RS274X format.
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
void gerbv_image_copy_image(gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform, gerbv_image_t *destinationImage)
Copy an image into an existing image, effectively merging the two together.
void gerbv_image_delete_net(gerbv_net_t *currentNet)
Delete a net in an existing image.
gerbv_image_t * gerbv_image_duplicate_image(gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform)
Duplicate an existing image and return the new copy.
void gerbv_stats_destroy(gerbv_stats_t *stats)
const char * gerber_d_code_name(int d_code)
Return Gerber D-code name by code number.
const char * gerber_g_code_name(int g_code)
Return Gerber G-code name by code number.
const char * gerber_m_code_name(int m_code)
Return Gerber M-code name by code number.
void gerbv_open_layer_from_filename(gerbv_project_t *gerbvProject, const gchar *filename)
Open a file, parse the contents, and add a new layer to an existing project.
const char * gerbv_interpolation_name(gerbv_interpolation_t interp)
Return string name of gerbv_interpolation_t interpolation.
gerbv_fileinfo_t * gerbv_get_fileinfo_for_image(const gerbv_image_t *image, const gerbv_project_t *project)
const char * gerbv_aperture_type_name(gerbv_aperture_type_t type)
Return string name of gerbv_aperture_type_t aperture type.
void gerbv_render_zoom_to_fit_display(gerbv_project_t *gerbvProject, gerbv_render_info_t *renderInfo)
Calculate the zoom and translations to fit the rendered scene inside the given scene size.
int gerbv_transform_coord_for_image(double *x, double *y, const gerbv_image_t *image, const gerbv_project_t *project)
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_OFF
@ GERBV_APERTURE_STATE_ON
@ GERBV_APERTURE_STATE_FLASH
@ GERBV_RENDER_TYPE_CAIRO_HIGH_QUALITY
@ GERBV_RENDER_TYPE_GDK_XOR
@ GERBV_RENDER_TYPE_CAIRO_NORMAL
@ GERBV_APTYPE_MACRO_LINE20
@ GERBV_APTYPE_MACRO_LINE21
@ GERBV_APTYPE_MACRO_OUTLINE
@ GERBV_APTYPE_MACRO_CIRCLE
@ GERBV_APTYPE_MACRO_POLYGON
@ GERBV_APTYPE_MACRO_THERMAL
@ GERBV_APTYPE_MACRO_LINE22
@ GERBV_APTYPE_MACRO_MOIRE
@ GERBV_INTERPOLATION_LINEARx01
@ GERBV_INTERPOLATION_PAREA_START
@ GERBV_INTERPOLATION_LINEARx001
@ GERBV_INTERPOLATION_CW_CIRCULAR
@ GERBV_INTERPOLATION_PAREA_END
@ GERBV_INTERPOLATION_LINEARx10
@ GERBV_INTERPOLATION_CCW_CIRCULAR
@ GERBV_INTERPOLATION_LINEARx1
int interface_reopen_question(GSList *fns, GSList *fns_is_mod, GSList *fns_cnt, GSList *fns_lay_num)
This dialog box shows a text message with three buttons in the case if the file to be open was alread...
void interface_show_alert_dialog(gchar *primaryText, gchar *secondaryText, gboolean show_checkbox, gboolean *ask_to_show_again)
This dialog box shows a textmessage and one button: "OK".
gboolean interface_get_alert_dialog_response(const gchar *primaryText, const gchar *secondaryText, gboolean show_checkbox, gboolean *ask_to_show_again, const gchar *true_button_label, const gchar *false_button_label)
This dialog box shows a message and two buttons: "True" and "False".
Header info for the GUI building functions for Gerber Viewer.
gerbv_project_t * mainProject
Global state variable to keep track of what's happening on the screen.
Header info for common structs and functions used for the GUI application.
int project_is_gerbv_project(const char *filename, gboolean *ret)
Checks whether the supplied file look like a gerbv project by reading the first line and checking if ...
Header info for loading and saving project files.
void render_calculate_zoom_from_outline(GtkWidget *widget, GdkEventButton *event)
Will determine the outline of the zoomed regions.
gerbv_stats_t * generate_gerber_analysis(void)
void render_draw_measure_distance(void)
Displays a measured distance graphically on screen and in statusbar.
void render_toggle_measure_line(void)
Draws/erases measure line.
gerbv_drill_stats_t * generate_drill_analysis(void)
Header info for the rendering support functions for gerbv.
Header info for the selection support functions for libgerbv.
gerbv_user_transformation_t transform
gerbv_layertype_t layertype
gerbv_aperture_t * aperture[APERTURE_MAX]
gerbv_image_info_t * info
gerbv_aperture_state_t aperture_state
gerbv_interpolation_t interpolation
gboolean show_invisible_selection
gboolean check_before_delete
gboolean show_cross_on_drill_holes
gerbv_render_types_t renderType
Header info for GTK widgets table functions.