2 * gEDA - GNU Electronic Design Automation
3 * This file is a part of gerbv.
5 * Copyright (C) 2000-2003 Stefan Petersen (spe@stacken.kth.se)
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 \brief Callback functions for the GUI widgets
39 #include <gdk/gdkkeysyms.h>
61 #include "callbacks.h"
62 #include "interface.h"
63 #include "attribute.h"
70 #include <cairo-win32.h>
72 #include <cairo-xlib.h>
76 #define dprintf if(DEBUG) printf
78 /* This default extension should really not be changed, but if it absolutely
79 * must change, the ../win32/gerbv.nsi.in *must* be changed to reflect that.
80 * Just grep for the extension (gvp) and change it in two places in that file.
82 #define GERBV_PROJECT_FILE_NAME "Gerbv Project"
83 #define GERBV_PROJECT_FILE_EXT ".gvp"
84 #define GERBV_PROJECT_FILE_PAT "*.gvp"
86 #define SAVE_PROJECT 0
87 #define SAVE_AS_PROJECT 1
88 #define OPEN_PROJECT 2
89 # define _(String) (String)
91 /**Global variable to keep track of what's happening on the screen.
92 Declared extern in gerbv_screen.h
94 extern gerbv_screen_t screen
;
95 extern gerbv_render_info_t screenRenderInfo
;
98 /* These are the names of the valid apertures. These
99 * values are used in several places in this file.
100 * Please keep this in sync with the gerbv_aperture_type_t
101 * enum defined in gerbv.h */
102 char *ap_names
[] = {"NONE",
105 "OVAL", /* an ovular (obround) aperture */
106 "POLYGON", /* a polygon aperture */
107 "MACRO", /* a RS274X macro */
108 "MACRO_CIRCLE", /* a RS274X circle macro */
109 "MACRO_OUTLINE", /* a RS274X outline macro */
110 "MACRO_POLYGON", /* a RS274X polygon macro */
111 "MACRO_MOIRE", /* a RS274X moire macro */
112 "MACRO_THERMAL", /* a RS274X thermal macro */
113 "MACRO_LINE20", /* a RS274X line (code 20) macro */
114 "MACRO_LINE21", /* a RS274X line (code 21) macro */
115 "MACRO_LINE22" /* a RS274X line (code 22) macro */
118 gint
callbacks_get_selected_row_index (void);
120 /* --------------------------------------------------------- */
122 callbacks_generate_alert_dialog (gchar
*primaryText
, gchar
*secondaryText
){
123 GtkWidget
*dialog
, *label
;
125 dialog
= gtk_dialog_new_with_buttons (primaryText
,
126 (GtkWindow
*)screen
.win
.topLevelWindow
,
127 GTK_DIALOG_DESTROY_WITH_PARENT
,
128 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
129 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
,
131 label
= gtk_label_new (secondaryText
);
132 /* Add the label, and show everything we've added to the dialog. */
133 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog
)->vbox
),
135 gtk_widget_show_all (dialog
);
139 /* --------------------------------------------------------- */
141 * The file -> new menu item was selected. Create new
146 callbacks_new_activate (GtkMenuItem
*menuitem
,
149 if (mainProject
->last_loaded
>= 0) {
150 if (!interface_get_alert_dialog_response (
151 "Do you want to close any open layers and start a new project?",
152 "Starting a new project will cause all currently open layers to be closed. Any unsaved changes will be lost.",
157 /* Unload all layers and then clear layer window */
158 gerbv_unload_all_layers (mainProject
);
159 callbacks_update_layer_tree ();
160 render_clear_selection_buffer ();
162 /* Destroy project info */
163 if (mainProject
->project
) {
164 g_free(mainProject
->project
);
165 mainProject
->project
= NULL
;
167 render_refresh_rendered_image_on_screen();
171 /* --------------------------------------------------------- */
173 * The file -> open menu item was selected. Open a
178 callbacks_open_project_activate (GtkMenuItem
*menuitem
,
181 gchar
*filename
=NULL
;
182 GtkFileFilter
* filter
;
184 if (mainProject
->last_loaded
>= 0) {
185 if (!interface_get_alert_dialog_response (
186 "Do you want to close any open layers and load an existing project?",
187 "Loading a project will cause all currently open layers to be closed. Any unsaved changes will be lost.",
194 gtk_file_chooser_dialog_new ("Open project file...",
196 GTK_FILE_CHOOSER_ACTION_OPEN
,
197 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
198 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
200 gtk_file_chooser_set_current_folder ((GtkFileChooser
*) screen
.win
.gerber
,
203 filter
= gtk_file_filter_new();
204 gtk_file_filter_set_name(filter
, GERBV_PROJECT_FILE_NAME
);
205 gtk_file_filter_add_pattern(filter
, GERBV_PROJECT_FILE_PAT
);
206 gtk_file_chooser_add_filter ((GtkFileChooser
*) screen
.win
.gerber
,
209 filter
= gtk_file_filter_new();
210 gtk_file_filter_set_name(filter
, "All");
211 gtk_file_filter_add_pattern(filter
, "*");
212 gtk_file_chooser_add_filter ((GtkFileChooser
*) screen
.win
.gerber
,
215 gtk_widget_show (screen
.win
.gerber
);
216 if (gtk_dialog_run ((GtkDialog
*)screen
.win
.gerber
) == GTK_RESPONSE_ACCEPT
) {
218 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (screen
.win
.gerber
));
219 /* update the last folder */
220 g_free (mainProject
->path
);
221 mainProject
->path
= gtk_file_chooser_get_current_folder ((GtkFileChooser
*) screen
.win
.gerber
);
223 gtk_widget_destroy (screen
.win
.gerber
);
226 gerbv_unload_all_layers (mainProject
);
227 main_open_project_from_filename (mainProject
, filename
);
229 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
230 render_refresh_rendered_image_on_screen();
231 callbacks_update_layer_tree();
237 /* --------------------------------------------------------- */
239 * The file -> open layer menu item was selected. Open a
240 * layer (or layers) from a file.
244 callbacks_open_layer_activate (GtkMenuItem
*menuitem
,
247 GSList
*filenames
=NULL
;
248 GSList
*filename
=NULL
;
251 gtk_file_chooser_dialog_new ("Open Gerber, drill, or pick & place file(s)...",
253 GTK_FILE_CHOOSER_ACTION_OPEN
,
254 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
255 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
258 gtk_file_chooser_set_select_multiple((GtkFileChooser
*) screen
.win
.gerber
, TRUE
);
259 gtk_file_chooser_set_current_folder ((GtkFileChooser
*) screen
.win
.gerber
,
261 gtk_widget_show (screen
.win
.gerber
);
262 if (gtk_dialog_run ((GtkDialog
*)screen
.win
.gerber
) == GTK_RESPONSE_ACCEPT
) {
264 gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (screen
.win
.gerber
));
265 /* update the last folder */
266 g_free (mainProject
->path
);
267 mainProject
->path
= gtk_file_chooser_get_current_folder ((GtkFileChooser
*) screen
.win
.gerber
);
269 gtk_widget_destroy (screen
.win
.gerber
);
271 /* Now try to open all gerbers specified */
272 for (filename
=filenames
; filename
; filename
=filename
->next
) {
273 gerbv_open_layer_from_filename(mainProject
, filename
->data
, NULL
);
275 g_slist_free(filenames
);
277 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
278 render_refresh_rendered_image_on_screen();
279 callbacks_update_layer_tree();
285 /* --------------------------------------------------------- */
287 * The file -> open zip file menu item was selected. Open a
288 * zip file and read in all file name.
292 callbacks_open_zip_activate(GtkMenuItem
*menuitem
,
295 gchar
*zipname
= NULL
;
296 GSList
*filename
= NULL
;
297 GSList
*filenames
= NULL
;
298 GtkFileFilter
*filter
;
301 gtk_file_chooser_dialog_new ("Open a zip file with Gerber, drill, or pick & place file(s)...",
303 GTK_FILE_CHOOSER_ACTION_OPEN
,
304 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
305 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
308 filter
= gtk_file_filter_new();
309 gtk_file_filter_set_name(filter
,"Zip Files (*.zip)");
310 gtk_file_filter_add_pattern(filter
, "*.zip");
311 gtk_file_chooser_add_filter((GtkFileChooser
*) screen
.win
.gerber
, filter
);
313 filter
= gtk_file_filter_new();
314 gtk_file_filter_set_name(filter
,"All Files (*.*)");
315 gtk_file_filter_add_pattern(filter
, "*.*");
316 gtk_file_chooser_add_filter((GtkFileChooser
*) screen
.win
.gerber
, filter
);
318 gtk_file_chooser_set_current_folder ((GtkFileChooser
*) screen
.win
.gerber
,
320 gtk_widget_show (screen
.win
.gerber
);
322 if (gtk_dialog_run ((GtkDialog
*)screen
.win
.gerber
) == GTK_RESPONSE_ACCEPT
) {
324 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (screen
.win
.gerber
));
325 /* update the last folder */
326 g_free (mainProject
->path
);
327 mainProject
->path
= gtk_file_chooser_get_current_folder ((GtkFileChooser
*) screen
.win
.gerber
);
329 gtk_widget_destroy (screen
.win
.gerber
);
331 gerb_filenames_in_zip(zipname
, &filenames
);
333 for (filename
= filenames
; filename
; filename
= filename
->next
) {
334 gerbv_open_layer_from_filename (mainProject
, filename
->data
, zipname
);
336 g_slist_free(filenames
);
338 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
339 render_refresh_rendered_image_on_screen();
340 callbacks_update_layer_tree();
345 /* --------------------------------------------------------- */
347 callbacks_revert_activate (GtkMenuItem
*menuitem
,
350 gerbv_revert_all_files (mainProject
);
351 render_clear_selection_buffer();
352 callbacks_update_selected_object_message(FALSE
);
353 render_refresh_rendered_image_on_screen();
354 callbacks_update_layer_tree();
357 /* --------------------------------------------------------- */
359 callbacks_save_project_activate (GtkMenuItem
*menuitem
,
362 if (mainProject
->project
)
363 main_save_project_from_filename (mainProject
, mainProject
->project
);
365 callbacks_generic_save_activate (menuitem
, (gpointer
) CALLBACKS_SAVE_PROJECT_AS
);
366 callbacks_update_layer_tree();
370 /* --------------------------------------------------------- */
372 callbacks_save_layer_activate (GtkMenuItem
*menuitem
,
375 /* first figure out which layer in the layer side menu is selected */
376 gint index
=callbacks_get_selected_row_index();
378 /* Now save that layer */
380 if (!gerbv_save_layer_from_index (mainProject
, index
, mainProject
->file
[index
]->fullPathname
)) {
381 interface_show_alert_dialog("Gerbv cannot export this file type",
385 mainProject
->file
[index
]->layer_dirty
= FALSE
;
386 callbacks_update_layer_tree();
390 callbacks_update_layer_tree();
394 /* --------------------------------------------------------- */
396 callbacks_generic_save_activate (GtkMenuItem
*menuitem
,
399 gchar
*filename
=NULL
;
400 gint processType
= GPOINTER_TO_INT (user_data
);
401 gchar
*windowTitle
=NULL
;
402 GtkFileFilter
* filter
;
404 if (processType
== CALLBACKS_SAVE_PROJECT_AS
)
405 windowTitle
= g_strdup ("Save project as...");
406 else if (processType
== CALLBACKS_SAVE_FILE_PS
)
407 windowTitle
= g_strdup ("Export PS file as...");
408 else if (processType
== CALLBACKS_SAVE_FILE_PDF
)
409 windowTitle
= g_strdup ("Export PDF file as...");
410 else if (processType
== CALLBACKS_SAVE_FILE_SVG
)
411 windowTitle
= g_strdup ("Export SVG file as...");
412 else if (processType
== CALLBACKS_SAVE_FILE_PNG
)
413 windowTitle
= g_strdup ("Export PNG file as...");
414 else if (processType
== CALLBACKS_SAVE_FILE_RS274X
)
415 windowTitle
= g_strdup ("Export RS-274X file as...");
416 else if (processType
== CALLBACKS_SAVE_FILE_DRILL
)
417 windowTitle
= g_strdup ("Export Excellon drill file as...");
418 else if (processType
== CALLBACKS_SAVE_LAYER_AS
)
419 windowTitle
= g_strdup ("Save layer as...");
422 gtk_file_chooser_dialog_new (windowTitle
, NULL
,
423 GTK_FILE_CHOOSER_ACTION_SAVE
,
424 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
425 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
427 g_free (windowTitle
);
429 /* if we're saving or exporting a layer, start off in the location of the
431 if (processType
!= CALLBACKS_SAVE_PROJECT_AS
) {
432 gint index
=callbacks_get_selected_row_index();
434 gchar
*dirName
= g_path_get_dirname (mainProject
->file
[index
]->fullPathname
);
435 gtk_file_chooser_set_current_folder ((GtkFileChooser
*) screen
.win
.gerber
,
441 if (processType
== CALLBACKS_SAVE_PROJECT_AS
) {
442 filter
= gtk_file_filter_new();
443 gtk_file_filter_set_name(filter
, GERBV_PROJECT_FILE_NAME
);
444 gtk_file_filter_add_pattern(filter
, GERBV_PROJECT_FILE_PAT
);
445 gtk_file_chooser_add_filter ((GtkFileChooser
*) screen
.win
.gerber
,
448 filter
= gtk_file_filter_new();
449 gtk_file_filter_set_name(filter
, "All");
450 gtk_file_filter_add_pattern(filter
, "*");
451 gtk_file_chooser_add_filter ((GtkFileChooser
*) screen
.win
.gerber
,
454 gtk_file_chooser_set_current_name ((GtkFileChooser
*) screen
.win
.gerber
,
455 "untitled" GERBV_PROJECT_FILE_EXT
);
458 gtk_widget_show (screen
.win
.gerber
);
459 if (gtk_dialog_run ((GtkDialog
*)screen
.win
.gerber
) == GTK_RESPONSE_ACCEPT
) {
460 filename
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (screen
.win
.gerber
));
462 gtk_widget_destroy (screen
.win
.gerber
);
465 if (processType
== CALLBACKS_SAVE_PROJECT_AS
) {
466 main_save_as_project_from_filename (mainProject
, filename
);
467 rename_main_window(filename
, NULL
);
469 else if (processType
== CALLBACKS_SAVE_FILE_PS
)
470 gerbv_export_postscript_file_from_project_autoscaled (mainProject
, filename
);
471 else if (processType
== CALLBACKS_SAVE_FILE_PDF
)
472 gerbv_export_pdf_file_from_project_autoscaled (mainProject
, filename
);
473 else if (processType
== CALLBACKS_SAVE_FILE_SVG
)
474 gerbv_export_svg_file_from_project_autoscaled (mainProject
, filename
);
475 else if (processType
== CALLBACKS_SAVE_FILE_PNG
)
476 gerbv_export_png_file_from_project_autoscaled (mainProject
,
477 screenRenderInfo
.displayWidth
, screenRenderInfo
.displayHeight
,
479 else if (processType
== CALLBACKS_SAVE_LAYER_AS
) {
480 gint index
=callbacks_get_selected_row_index();
482 gerbv_save_layer_from_index (mainProject
, index
, filename
);
483 /* rename the file path in the index, so future saves will reference the new file path */
484 g_free (mainProject
->file
[index
]->fullPathname
);
485 mainProject
->file
[index
]->fullPathname
= g_strdup (filename
);
486 g_free (mainProject
->file
[index
]->name
);
487 mainProject
->file
[index
]->name
= g_path_get_basename (filename
);
489 else if (processType
== CALLBACKS_SAVE_FILE_RS274X
) {
490 gint index
=callbacks_get_selected_row_index();
492 gerbv_export_rs274x_file_from_image (filename
, mainProject
->file
[index
]->image
,
493 &mainProject
->file
[index
]->transform
);
495 else if (processType
== CALLBACKS_SAVE_FILE_DRILL
) {
496 gint index
=callbacks_get_selected_row_index();
498 gerbv_export_drill_file_from_image (filename
, mainProject
->file
[index
]->image
,
499 &mainProject
->file
[index
]->transform
);
503 callbacks_update_layer_tree();
507 /* --------------------------------------------------------- */
508 #if GTK_CHECK_VERSION(2,10,0)
511 callbacks_begin_print (GtkPrintOperation
*operation
, GtkPrintContext
*context
,
512 gpointer user_data
) {
513 gtk_print_operation_set_n_pages (operation
, 1);
517 /* --------------------------------------------------------- */
519 callbacks_print_render_page (GtkPrintOperation
*operation
,
520 GtkPrintContext
*context
,
524 GtkPrintSettings
*pSettings
= gtk_print_operation_get_print_settings (operation
);
525 gerbv_render_info_t renderInfo
= {1.0, 1.0, 0, 0, 3,
526 (gint
) gtk_print_context_get_width (context
),
527 (gint
) gtk_print_context_get_height (context
)};
531 /* have to assume x and y resolutions are the same for now, since we
532 don't support differing scales in the gerb_render_info_t struct yet */
533 gdouble xres
= gtk_print_context_get_dpi_x (context
);
534 gdouble yres
= gtk_print_context_get_dpi_y (context
);
535 gdouble scalePercentage
= gtk_print_settings_get_scale (pSettings
);
536 renderInfo
.scaleFactorX
= scalePercentage
/ 100 * xres
;
537 renderInfo
.scaleFactorY
= scalePercentage
/ 100 * yres
;
539 gerbv_render_translate_to_fit_display (mainProject
, &renderInfo
);
540 cr
= gtk_print_context_get_cairo_context (context
);
541 for(i
= 0; i
<= mainProject
->last_loaded
; i
++) {
542 if (mainProject
->file
[i
] && mainProject
->file
[i
]->isVisible
) {
543 //cairo_push_group (cr);
544 gerbv_render_layer_to_cairo_target (cr
, mainProject
->file
[i
], &renderInfo
);
545 //cairo_pop_group_to_source (cr);
546 //cairo_paint_with_alpha (cr, screen.file[i]->alpha);
551 /* --------------------------------------------------------- */
553 callbacks_print_activate (GtkMenuItem
*menuitem
, gpointer user_data
)
555 GtkPrintOperation
*print
;
556 GtkPrintOperationResult res
;
558 print
= gtk_print_operation_new ();
560 g_signal_connect (print
, "begin_print", G_CALLBACK (callbacks_begin_print
), NULL
);
561 g_signal_connect (print
, "draw_page", G_CALLBACK (callbacks_print_render_page
), NULL
);
563 //GtkPrintSettings *pSettings = gtk_print_operation_get_print_settings (print);
565 res
= gtk_print_operation_run (print
, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
,
566 (GtkWindow
*) screen
.win
.topLevelWindow
, NULL
);
568 g_object_unref (print
);
570 #endif /* GTK_CHECK_VERSION(2,10,0) */
572 /* --------------------------------------------------------- */
574 callbacks_zoom_in_activate (GtkMenuItem
*menuitem
,
577 render_zoom_display (ZOOM_IN
, 0, 0, 0);
580 /* --------------------------------------------------------- */
582 callbacks_zoom_out_activate (GtkMenuItem
*menuitem
,
585 render_zoom_display (ZOOM_OUT
, 0, 0, 0);
588 /* --------------------------------------------------------- */
590 callbacks_fit_to_window_activate (GtkMenuItem
*menuitem
,
593 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
594 render_refresh_rendered_image_on_screen();
598 /* --------------------------------------------------------- */
600 * The analyze -> analyze Gerbers menu item was selected.
601 * Compile statistics on all open Gerber layers and then display
606 callbacks_analyze_active_gerbers_activate(GtkMenuItem
*menuitem
,
609 gerbv_stats_t
*stats_report
;
610 GString
*G_report_string
= g_string_new(NULL
);
611 GString
*D_report_string
= g_string_new(NULL
);
612 GString
*M_report_string
= g_string_new(NULL
);
613 GString
*misc_report_string
= g_string_new(NULL
);
614 GString
*general_report_string
= g_string_new(NULL
);
615 GString
*error_report_string
= g_string_new(NULL
);
616 gerbv_error_list_t
*my_error_list
;
617 gchar
*error_level
= NULL
;
618 GString
*aperture_def_report_string
= g_string_new(NULL
);
619 GString
*aperture_use_report_string
= g_string_new(NULL
);
620 gerbv_aperture_list_t
*my_aperture_list
;
623 /* First get a report of stats & errors accumulated from all layers */
624 stats_report
= generate_gerber_analysis();
626 /* General info report */
627 g_string_printf(general_report_string
,
628 "General information\n");
629 g_string_append_printf(general_report_string
,
630 " Active layer count = %d\n",
631 stats_report
->layer_count
);
632 g_string_append_printf(general_report_string
,
636 for (idx
= 0; idx
<= mainProject
->last_loaded
; idx
++) {
637 if (mainProject
->file
[idx
] &&
638 mainProject
->file
[idx
]->isVisible
&&
639 (mainProject
->file
[idx
]->image
->layertype
== GERBV_LAYERTYPE_RS274X
) ) {
640 g_string_append_printf(general_report_string
,
641 " %-45s %-10d\n", mainProject
->file
[idx
]->name
, idx
+1);
645 /* Error report (goes into general report tab) */
646 if (stats_report
->layer_count
== 0) {
647 g_string_printf(error_report_string
,
648 "\n\nNo Gerber files active (visible)!\n");
649 } else if (stats_report
->error_list
->error_text
== NULL
) {
650 g_string_printf(error_report_string
,
651 "\n\nNo errors found in active Gerber file(s)!\n");
653 g_string_printf(error_report_string
,
654 "\n\nErrors found in active Gerber file(s):\n");
655 for(my_error_list
= stats_report
->error_list
;
656 my_error_list
!= NULL
;
657 my_error_list
= my_error_list
->next
) {
658 switch(my_error_list
->type
) {
659 case GERBV_MESSAGE_FATAL
: /* We should never get this one since the
660 * program should terminate first.... */
661 error_level
= g_strdup_printf("FATAL: ");
663 case GERBV_MESSAGE_ERROR
:
664 error_level
= g_strdup_printf("ERROR: ");
666 case GERBV_MESSAGE_WARNING
:
667 error_level
= g_strdup_printf("WARNING: ");
669 case GERBV_MESSAGE_NOTE
:
670 error_level
= g_strdup_printf("NOTE: ");
673 g_string_append_printf(error_report_string
,
675 my_error_list
->layer
,
677 my_error_list
->error_text
);
683 g_string_append_printf(general_report_string
,
685 error_report_string
->str
);
686 g_string_free(error_report_string
, TRUE
);
688 /* Now compile stats related to reading G codes */
689 g_string_printf(G_report_string
,
690 "G code statistics (all active layers)\n");
691 g_string_append_printf(G_report_string
,
692 "<code> = <number of incidences>\n");
693 g_string_append_printf(G_report_string
,
697 g_string_append_printf(G_report_string
,
700 "1X linear interpolation");
701 g_string_append_printf(G_report_string
,
705 g_string_append_printf(G_report_string
,
708 "CCW interpolation");
709 g_string_append_printf(G_report_string
,
712 "Comment/ignore block");
713 g_string_append_printf(G_report_string
,
716 "10X linear interpolation");
717 g_string_append_printf(G_report_string
,
720 "0.1X linear interpolation");
721 g_string_append_printf(G_report_string
,
724 "0.01X linear interpolation");
725 g_string_append_printf(G_report_string
,
729 g_string_append_printf(G_report_string
,
733 g_string_append_printf(G_report_string
,
737 g_string_append_printf(G_report_string
,
741 g_string_append_printf(G_report_string
,
745 g_string_append_printf(G_report_string
,
749 g_string_append_printf(G_report_string
,
752 "Disable 360 circ. interpolation");
753 g_string_append_printf(G_report_string
,
756 "Enable 360 circ. interpolation");
757 g_string_append_printf(G_report_string
,
761 g_string_append_printf(G_report_string
,
764 "Incremental units");
765 g_string_append_printf(G_report_string
,
766 "Unknown G codes = %d\n",
767 stats_report
->G_unknown
);
770 g_string_printf(D_report_string
, "D code statistics (all active layers)\n");
771 g_string_append_printf(D_report_string
,
772 "<code> = <number of incidences>\n");
773 g_string_append_printf(D_report_string
,
777 g_string_append_printf(D_report_string
,
781 g_string_append_printf(D_report_string
,
785 g_string_append_printf(D_report_string
,
786 "Undefined D codes = %d\n",
787 stats_report
->D_unknown
);
788 g_string_append_printf(D_report_string
,
789 "D code Errors = %d\n",
790 stats_report
->D_error
);
793 g_string_printf(M_report_string
, "M code statistics (all active layers)\n");
794 g_string_append_printf(M_report_string
,
795 "<code> = <number of incidences>\n");
796 g_string_append_printf(M_report_string
,
800 g_string_append_printf(M_report_string
,
804 g_string_append_printf(M_report_string
,
808 g_string_append_printf(M_report_string
,
809 "Unknown M codes = %d\n",
810 stats_report
->M_unknown
);
813 g_string_printf(misc_report_string
, "Misc code statistics (all active layers)\n");
814 g_string_append_printf(misc_report_string
,
815 "<code> = <number of incidences>\n");
816 g_string_append_printf(misc_report_string
,
817 "X = %d\n", stats_report
->X
);
818 g_string_append_printf(misc_report_string
,
819 "Y = %d\n", stats_report
->Y
);
820 g_string_append_printf(misc_report_string
,
821 "I = %d\n", stats_report
->I
);
822 g_string_append_printf(misc_report_string
,
823 "J = %d\n", stats_report
->J
);
824 g_string_append_printf(misc_report_string
,
825 "* = %d\n", stats_report
->star
);
826 g_string_append_printf(misc_report_string
,
827 "Unknown codes = %d\n",
828 stats_report
->unknown
);
830 /* Report apertures defined in input files. */
832 if (stats_report
->aperture_list
->number
== -1) {
833 g_string_printf(aperture_def_report_string
,
834 "No aperture definitions found in Gerber file(s)!\n");
836 g_string_printf(aperture_def_report_string
,
837 "Apertures defined in Gerber file(s) (by layer)\n");
838 g_string_append_printf(aperture_def_report_string
,
839 " %-6s %-8s %12s %8s %8s %8s\n",
847 for(my_aperture_list
= stats_report
->aperture_list
;
848 my_aperture_list
!= NULL
;
849 my_aperture_list
= my_aperture_list
->next
) {
851 g_string_append_printf(aperture_def_report_string
,
852 " %-6d D%-4d%13s %8.3f %8.3f %8.3f\n",
853 my_aperture_list
->layer
,
854 my_aperture_list
->number
,
855 ap_names
[my_aperture_list
->type
],
856 my_aperture_list
->parameter
[0],
857 my_aperture_list
->parameter
[1],
858 my_aperture_list
->parameter
[2]
863 /* Report apertures usage count in input files. */
864 if (stats_report
->D_code_list
->number
== -1) {
865 g_string_printf(aperture_use_report_string
,
866 "No apertures used in Gerber file(s)!\n");
869 /* Now add list of user-defined D codes (apertures) */
871 g_string_printf(aperture_use_report_string
,
872 "Apertures used in Gerber file(s) (all active layers)\n");
873 g_string_append_printf(aperture_use_report_string
,
874 "<aperture code> = <number of uses>\n");
875 for (my_aperture_list
= stats_report
->D_code_list
;
876 my_aperture_list
!= NULL
;
877 my_aperture_list
= my_aperture_list
->next
) {
879 g_string_append_printf(aperture_use_report_string
,
881 my_aperture_list
->number
,
882 my_aperture_list
->count
888 /* Create top level dialog window for report */
889 GtkWidget
*analyze_active_gerbers
;
890 analyze_active_gerbers
= gtk_dialog_new_with_buttons("Gerber codes report",
892 GTK_DIALOG_DESTROY_WITH_PARENT
,
896 gtk_container_set_border_width (GTK_CONTAINER (analyze_active_gerbers
), 5);
898 gtk_dialog_set_default_response (GTK_DIALOG(analyze_active_gerbers
),
899 GTK_RESPONSE_ACCEPT
);
900 g_signal_connect (G_OBJECT(analyze_active_gerbers
),
902 G_CALLBACK (gtk_widget_destroy
),
903 GTK_WIDGET(analyze_active_gerbers
));
905 /* Use fixed width font for all reports */
906 PangoFontDescription
*font
=
907 pango_font_description_from_string ("monospace");
909 /* Create GtkLabel to hold general report text */
910 GtkWidget
*general_report_label
= gtk_label_new (general_report_string
->str
);
911 g_string_free (general_report_string
, TRUE
);
912 gtk_misc_set_alignment(GTK_MISC(general_report_label
), 0, 0);
913 gtk_misc_set_padding(GTK_MISC(general_report_label
), 13, 13);
914 gtk_label_set_selectable(GTK_LABEL(general_report_label
), TRUE
);
915 gtk_widget_modify_font (GTK_WIDGET(general_report_label
),
917 /* Put general report text into scrolled window */
918 GtkWidget
*general_code_report_window
= gtk_scrolled_window_new (NULL
, NULL
);
919 /* This throws a warning. Must find different approach.... */
920 gtk_widget_set_size_request(GTK_WIDGET(general_code_report_window
),
923 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(general_code_report_window
),
924 GTK_WIDGET(general_report_label
));
926 /* Create GtkLabel to hold G code text */
927 GtkWidget
*G_report_label
= gtk_label_new (G_report_string
->str
);
928 g_string_free (G_report_string
, TRUE
);
929 gtk_misc_set_alignment(GTK_MISC(G_report_label
), 0, 0);
930 gtk_misc_set_padding(GTK_MISC(G_report_label
), 13, 13);
931 gtk_label_set_selectable(GTK_LABEL(G_report_label
), TRUE
);
932 gtk_widget_modify_font (GTK_WIDGET(G_report_label
),
935 /* Create GtkLabel to hold D code text */
936 GtkWidget
*D_report_label
= gtk_label_new (D_report_string
->str
);
937 g_string_free (D_report_string
, TRUE
);
938 gtk_misc_set_alignment(GTK_MISC(D_report_label
), 0, 0);
939 gtk_misc_set_padding(GTK_MISC(D_report_label
), 13, 13);
940 gtk_label_set_selectable(GTK_LABEL(D_report_label
), TRUE
);
941 gtk_widget_modify_font (GTK_WIDGET(D_report_label
),
944 /* Create GtkLabel to hold M code text */
945 GtkWidget
*M_report_label
= gtk_label_new (M_report_string
->str
);
946 g_string_free (M_report_string
, TRUE
);
947 gtk_misc_set_alignment(GTK_MISC(M_report_label
), 0, 0);
948 gtk_misc_set_padding(GTK_MISC(M_report_label
), 13, 13);
949 gtk_label_set_selectable(GTK_LABEL(M_report_label
), TRUE
);
950 gtk_widget_modify_font (GTK_WIDGET(M_report_label
),
953 /* Create GtkLabel to hold misc code text */
954 GtkWidget
*misc_report_label
= gtk_label_new (misc_report_string
->str
);
955 g_string_free (misc_report_string
, TRUE
);
956 gtk_misc_set_alignment(GTK_MISC(misc_report_label
), 0, 0);
957 gtk_misc_set_padding(GTK_MISC(misc_report_label
), 13, 13);
958 gtk_label_set_selectable(GTK_LABEL(misc_report_label
), TRUE
);
959 gtk_widget_modify_font (GTK_WIDGET(misc_report_label
),
962 /* Create GtkLabel to hold aperture defintion text */
963 GtkWidget
*aperture_def_report_label
= gtk_label_new (aperture_def_report_string
->str
);
964 g_string_free (aperture_def_report_string
, TRUE
);
965 gtk_misc_set_alignment(GTK_MISC(aperture_def_report_label
), 0, 0);
966 gtk_misc_set_padding(GTK_MISC(aperture_def_report_label
), 13, 13);
967 gtk_label_set_selectable(GTK_LABEL(aperture_def_report_label
), TRUE
);
968 gtk_widget_modify_font (GTK_WIDGET(aperture_def_report_label
),
970 /* Put aperture definintion text into scrolled window */
971 GtkWidget
*aperture_def_report_window
= gtk_scrolled_window_new (NULL
, NULL
);
972 /* This throws a warning. Must find different approach.... */
973 gtk_widget_set_size_request(GTK_WIDGET(aperture_def_report_window
),
976 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_def_report_window
),
977 GTK_WIDGET(aperture_def_report_label
));
979 /* Create GtkLabel to hold aperture use text */
980 GtkWidget
*aperture_use_report_label
= gtk_label_new (aperture_use_report_string
->str
);
981 g_string_free (aperture_use_report_string
, TRUE
);
982 gtk_misc_set_alignment(GTK_MISC(aperture_use_report_label
), 0, 0);
983 gtk_misc_set_padding(GTK_MISC(aperture_use_report_label
), 13, 13);
984 gtk_label_set_selectable(GTK_LABEL(aperture_use_report_label
), TRUE
);
985 gtk_widget_modify_font (GTK_WIDGET(aperture_use_report_label
),
987 /* Put aperture definintion text into scrolled window */
988 GtkWidget
*aperture_use_report_window
= gtk_scrolled_window_new (NULL
, NULL
);
989 /* This throws a warning. Must find different approach.... */
990 gtk_widget_set_size_request(GTK_WIDGET(aperture_use_report_window
),
993 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(aperture_use_report_window
),
994 GTK_WIDGET(aperture_use_report_label
));
996 /* Create tabbed notebook widget and add report label widgets. */
997 GtkWidget
*notebook
= gtk_notebook_new();
999 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1000 GTK_WIDGET(general_code_report_window
),
1001 gtk_label_new("General"));
1003 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1004 GTK_WIDGET(G_report_label
),
1005 gtk_label_new("G codes"));
1007 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1008 GTK_WIDGET(D_report_label
),
1009 gtk_label_new("D codes"));
1011 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1012 GTK_WIDGET(M_report_label
),
1013 gtk_label_new("M codes"));
1015 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1016 GTK_WIDGET(misc_report_label
),
1017 gtk_label_new("Misc. codes"));
1019 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1020 GTK_WIDGET(aperture_def_report_window
),
1021 gtk_label_new("Aperture definitions"));
1023 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1024 GTK_WIDGET(aperture_use_report_window
),
1025 gtk_label_new("Aperture usage"));
1028 /* Now put notebook into dialog window and show the whole thing */
1029 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_gerbers
)->vbox
),
1030 GTK_WIDGET(notebook
));
1032 gtk_widget_show_all(analyze_active_gerbers
);
1034 /* free the stats report */
1035 gerbv_stats_destroy (stats_report
);
1040 /* --------------------------------------------------------- */
1042 * The analyze -> analyze drill file menu item was selected.
1043 * Complie statistics on all open drill layers and then display
1048 callbacks_analyze_active_drill_activate(GtkMenuItem
*menuitem
,
1051 gerbv_drill_stats_t
*stats_report
;
1052 GString
*G_report_string
= g_string_new(NULL
);
1053 GString
*M_report_string
= g_string_new(NULL
);
1054 GString
*misc_report_string
= g_string_new(NULL
);
1055 gerbv_drill_list_t
*my_drill_list
;
1056 GString
*drill_report_string
= g_string_new(NULL
);
1057 GString
*general_report_string
= g_string_new(NULL
);
1058 GString
*error_report_string
= g_string_new(NULL
);
1059 gerbv_error_list_t
*my_error_list
;
1060 gchar
*error_level
= NULL
;
1063 stats_report
= (gerbv_drill_stats_t
*) generate_drill_analysis();
1065 /* General and error window strings */
1066 g_string_printf(general_report_string
, "General information\n");
1067 g_string_append_printf(general_report_string
,
1068 " Active layer count = %d\n",
1069 stats_report
->layer_count
);
1071 g_string_append_printf(general_report_string
,
1072 "\n\nFiles processed:\n");
1073 for (idx
= mainProject
->last_loaded
; idx
>= 0; idx
--) {
1074 if (mainProject
->file
[idx
] &&
1075 mainProject
->file
[idx
]->isVisible
&&
1076 (mainProject
->file
[idx
]->image
->layertype
== GERBV_LAYERTYPE_DRILL
) ) {
1077 g_string_append_printf(general_report_string
,
1079 mainProject
->file
[idx
]->name
);
1084 if (stats_report
->layer_count
== 0) {
1085 g_string_printf(error_report_string
, "\n\nNo drill files active (visible)!\n");
1086 } else if (stats_report
->error_list
->error_text
== NULL
) {
1087 g_string_printf(error_report_string
,
1088 "\n\nNo errors found in active drill file(s)!\n");
1090 g_string_printf(error_report_string
,
1091 "\n\nErrors found in active drill file(s):\n");
1092 for(my_error_list
= stats_report
->error_list
;
1093 my_error_list
!= NULL
;
1094 my_error_list
= my_error_list
->next
) {
1095 switch(my_error_list
->type
) {
1096 case GERBV_MESSAGE_FATAL
: /* We should never get this one since the
1097 * program should terminate first.... */
1098 error_level
= g_strdup_printf("FATAL: ");
1100 case GERBV_MESSAGE_ERROR
:
1101 error_level
= g_strdup_printf("ERROR: ");
1103 case GERBV_MESSAGE_WARNING
:
1104 error_level
= g_strdup_printf("WARNING: ");
1106 case GERBV_MESSAGE_NOTE
:
1107 error_level
= g_strdup_printf("NOTE: ");
1110 g_string_append_printf(error_report_string
,
1112 my_error_list
->layer
,
1114 my_error_list
->error_text
);
1118 g_string_append_printf(general_report_string
,
1119 "%s", error_report_string
->str
);
1120 g_string_free(error_report_string
, TRUE
);
1123 /* G code window strings */
1124 g_string_printf(G_report_string
, "G code statistics (all active layers)\n");
1125 g_string_append_printf(G_report_string
,
1126 "<code> = <number of incidences>\n");
1127 g_string_append_printf(G_report_string
,
1128 "G00 = %-6d (%s)\n",
1131 g_string_append_printf(G_report_string
,
1132 "G01 = %-6d (%s)\n",
1134 "1X linear interpolation");
1135 g_string_append_printf(G_report_string
,
1136 "G02 = %-6d (%s)\n",
1138 "CW interpolation");
1139 g_string_append_printf(G_report_string
,
1140 "G03 = %-6d (%s)\n",
1142 "CCW interpolation");
1143 g_string_append_printf(G_report_string
,
1144 "G04 = %-6d (%s)\n",
1147 g_string_append_printf(G_report_string
,
1148 "G05 = %-6d (%s)\n",
1151 g_string_append_printf(G_report_string
,
1152 "G90 = %-6d (%s)\n",
1155 g_string_append_printf(G_report_string
,
1156 "G91 = %-6d (%s)\n",
1158 "Incremental units");
1159 g_string_append_printf(G_report_string
,
1160 "G93 = %-6d (%s)\n",
1163 g_string_append_printf(G_report_string
,
1164 "Unknown G codes = %d\n",
1165 stats_report
->G_unknown
);
1167 /* M code window strings */
1168 g_string_printf(M_report_string
, "M code statistics (all active layers)\n");
1169 g_string_append_printf(M_report_string
,
1170 "<code> = <number of incidences>\n");
1171 g_string_append_printf(M_report_string
,
1172 "M00 = %-6d (%s)\n",
1175 g_string_append_printf(M_report_string
,
1176 "M01 = %-6d (%s)\n",
1179 g_string_append_printf(M_report_string
,
1180 "M18 = %-6d (%s)\n",
1183 g_string_append_printf(M_report_string
,
1184 "M25 = %-6d (%s)\n",
1187 g_string_append_printf(M_report_string
,
1188 "M30 = %-6d (%s)\n",
1190 "End program rewind");
1191 g_string_append_printf(M_report_string
,
1192 "M31 = %-6d (%s)\n",
1195 g_string_append_printf(M_report_string
,
1196 "M45 = %-6d (%s)\n",
1199 g_string_append_printf(M_report_string
,
1200 "M47 = %-6d (%s)\n",
1202 "Operator message");
1203 g_string_append_printf(M_report_string
,
1204 "M48 = %-6d (%s)\n",
1206 "Begin program header");
1207 g_string_append_printf(M_report_string
,
1208 "M71 = %-6d (%s)\n",
1211 g_string_append_printf(M_report_string
,
1212 "M72 = %-6d (%s)\n",
1215 g_string_append_printf(M_report_string
,
1216 "M95 = %-6d (%s)\n",
1218 "End program header");
1219 g_string_append_printf(M_report_string
,
1220 "M97 = %-6d (%s)\n",
1223 g_string_append_printf(M_report_string
,
1224 "M98 = %-6d (%s)\n",
1227 g_string_append_printf(M_report_string
,
1228 "Unknown M codes = %d\n",
1229 stats_report
->M_unknown
);
1232 /* misc report strings */
1233 g_string_printf(misc_report_string
, "Misc code statistics (all active layers)\n");
1234 g_string_append_printf(misc_report_string
,
1235 "<code> = <number of incidences>\n");
1236 g_string_append_printf(misc_report_string
,
1238 stats_report
->comment
);
1239 g_string_append_printf(misc_report_string
,
1240 "Unknown codes = %d\n",
1241 stats_report
->unknown
);
1243 g_string_append_printf(misc_report_string
,
1248 if (stats_report
->detect
!= NULL
) {
1249 g_string_append_printf(misc_report_string
,
1251 stats_report
->detect
);
1253 /* drill report window strings */
1254 g_string_printf(drill_report_string
, "Drills used (all active layers)\n");
1255 g_string_append_printf(drill_report_string
, "%10s %8s %8s %8s\n",
1256 "Drill no.", "Dia.", "Units", "Count");
1257 for(my_drill_list
= stats_report
->drill_list
;
1258 my_drill_list
!= NULL
;
1259 my_drill_list
= my_drill_list
->next
) {
1260 if (my_drill_list
->drill_num
== -1) break; /* No drill list */
1261 g_string_append_printf(drill_report_string
,
1262 "%10d %8.3f %8s %8d\n",
1263 my_drill_list
->drill_num
,
1264 my_drill_list
->drill_size
,
1265 my_drill_list
->drill_unit
,
1266 my_drill_list
->drill_count
);
1269 g_string_append_printf(drill_report_string
, "Total drill count %d\n",
1270 stats_report
->total_count
);
1272 /* Use fixed width font for all reports */
1273 PangoFontDescription
*font
=
1274 pango_font_description_from_string ("monospace");
1276 /* Create top level dialog window for report */
1277 GtkWidget
*analyze_active_drill
;
1278 analyze_active_drill
= gtk_dialog_new_with_buttons("Drill file codes report",
1280 GTK_DIALOG_DESTROY_WITH_PARENT
,
1282 GTK_RESPONSE_ACCEPT
,
1284 gtk_container_set_border_width (GTK_CONTAINER (analyze_active_drill
), 5);
1285 gtk_dialog_set_default_response (GTK_DIALOG(analyze_active_drill
),
1286 GTK_RESPONSE_ACCEPT
);
1287 g_signal_connect (G_OBJECT(analyze_active_drill
),
1289 G_CALLBACK (gtk_widget_destroy
),
1290 GTK_WIDGET(analyze_active_drill
));
1292 /* Create GtkLabel to hold general report text */
1293 GtkWidget
*general_report_label
= gtk_label_new (general_report_string
->str
);
1294 g_string_free(general_report_string
, TRUE
);
1295 gtk_misc_set_alignment(GTK_MISC(general_report_label
), 0, 0);
1296 gtk_misc_set_padding(GTK_MISC(general_report_label
), 13, 13);
1297 gtk_label_set_selectable(GTK_LABEL(general_report_label
), TRUE
);
1298 gtk_widget_modify_font (GTK_WIDGET(general_report_label
),
1301 /* Create GtkLabel to hold G code text */
1302 GtkWidget
*G_report_label
= gtk_label_new (G_report_string
->str
);
1303 g_string_free(G_report_string
, TRUE
);
1304 gtk_misc_set_alignment(GTK_MISC(G_report_label
), 0, 0);
1305 gtk_misc_set_padding(GTK_MISC(G_report_label
), 13, 13);
1306 gtk_label_set_selectable(GTK_LABEL(G_report_label
), TRUE
);
1307 gtk_widget_modify_font (GTK_WIDGET(G_report_label
),
1310 /* Create GtkLabel to hold M code text */
1311 GtkWidget
*M_report_label
= gtk_label_new (M_report_string
->str
);
1312 g_string_free(M_report_string
, TRUE
);
1313 gtk_misc_set_alignment(GTK_MISC(M_report_label
), 0, 0);
1314 gtk_misc_set_padding(GTK_MISC(M_report_label
), 13, 13);
1315 gtk_label_set_selectable(GTK_LABEL(M_report_label
), TRUE
);
1316 gtk_widget_modify_font (GTK_WIDGET(M_report_label
),
1319 /* Create GtkLabel to hold misc code text */
1320 GtkWidget
*misc_report_label
= gtk_label_new (misc_report_string
->str
);
1321 g_string_free(misc_report_string
, TRUE
);
1322 gtk_misc_set_alignment(GTK_MISC(misc_report_label
), 0, 0);
1323 gtk_misc_set_padding(GTK_MISC(misc_report_label
), 13, 13);
1324 gtk_label_set_selectable(GTK_LABEL(misc_report_label
), TRUE
);
1325 gtk_widget_modify_font (GTK_WIDGET(misc_report_label
),
1328 /* Create GtkLabel to hold drills used text */
1329 GtkWidget
*drill_report_label
= gtk_label_new (drill_report_string
->str
);
1330 g_string_free(drill_report_string
, TRUE
);
1331 gtk_misc_set_alignment(GTK_MISC(drill_report_label
), 0, 0);
1332 gtk_misc_set_padding(GTK_MISC(drill_report_label
), 13, 13);
1333 gtk_label_set_selectable(GTK_LABEL(drill_report_label
), TRUE
);
1334 gtk_widget_modify_font (GTK_WIDGET(drill_report_label
),
1337 /* Create tabbed notebook widget and add report label widgets. */
1338 GtkWidget
*notebook
= gtk_notebook_new();
1340 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1341 GTK_WIDGET(general_report_label
),
1342 gtk_label_new("General"));
1344 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1345 GTK_WIDGET(G_report_label
),
1346 gtk_label_new("G codes"));
1348 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1349 GTK_WIDGET(M_report_label
),
1350 gtk_label_new("M codes"));
1352 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1353 GTK_WIDGET(misc_report_label
),
1354 gtk_label_new("Misc. codes"));
1356 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
),
1357 GTK_WIDGET(drill_report_label
),
1358 gtk_label_new("Drills used"));
1360 /* Now put notebook into dialog window and show the whole thing */
1361 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(analyze_active_drill
)->vbox
),
1362 GTK_WIDGET(notebook
));
1363 gtk_widget_show_all(analyze_active_drill
);
1364 gerbv_drill_stats_destroy (stats_report
);
1368 /* --------------------------------------------------------- */
1370 callbacks_control_gerber_options_activate (GtkMenuItem
*menuitem
,
1376 /* --------------------------------------------------------- */
1378 callbacks_online_manual_activate (GtkMenuItem
*menuitem
,
1384 /* --------------------------------------------------------- */
1386 * The file -> quit menu item was selected.
1387 * Check that all changes have been saved, and then quit.
1391 callbacks_quit_activate (GtkMenuItem
*menuitem
,
1394 gboolean layers_dirty
= FALSE
;
1397 for (idx
= 0; idx
<=mainProject
->last_loaded
; idx
++) {
1398 if (mainProject
->file
[idx
] == NULL
) break;
1399 layers_dirty
= layers_dirty
|| mainProject
->file
[idx
]->layer_dirty
;
1403 !interface_get_alert_dialog_response(
1404 "Do you want to close all open layers and quit the program?",
1405 "Quitting the program will cause any unsaved changes to be lost.",
1410 gerbv_unload_all_layers (mainProject
);
1414 /* --------------------------------------------------------- */
1416 * The help -> about menu item was selected.
1417 * Show the about dialog.
1421 callbacks_about_activate (GtkMenuItem
*menuitem
,
1424 GtkWidget
*aboutdialog1
;
1425 /* TRANSLATORS: Replace this string with your names, one name per line. */
1426 /* gchar *translators = _("translator-credits"); */
1428 gchar
*string
= g_strdup_printf ( "gerbv -- a Gerber (RS-274/X) viewer.\n\n"
1429 "This is gerbv version %s\n"
1430 "Compiled on %s at %s\n"
1432 "gerbv is part of the gEDA Project.\n"
1434 "For more information see:\n"
1435 " gerbv homepage: http://gerbv.gpleda.org/\n"
1436 " gEDA homepage: http://gpleda.org/\n"
1437 " gEDA Wiki: http://geda.seul.org/wiki/",
1438 VERSION
, __DATE__
, __TIME__
);
1439 #if GTK_CHECK_VERSION(2,6,0)
1440 gchar
*license
= g_strdup_printf("gerbv -- a Gerber (RS-274/X) viewer.\n\n"
1441 "Copyright (C) 2000-2007 Stefan Petersen\n\n"
1442 "This program is free software: you can redistribute it and/or modify\n"
1443 "it under the terms of the GNU General Public License as published by\n"
1444 "the Free Software Foundation, either version 2 of the License, or\n"
1445 "(at your option) any later version.\n\n"
1446 "This program is distributed in the hope that it will be useful,\n"
1447 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1448 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1449 "GNU General Public License for more details.\n\n"
1450 "You should have received a copy of the GNU General Public License\n"
1451 "along with this program. If not, see <http://www.gnu.org/licenses/>.");
1452 #include "authors.c"
1454 aboutdialog1
= gtk_about_dialog_new ();
1455 gtk_container_set_border_width (GTK_CONTAINER (aboutdialog1
), 5);
1456 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (aboutdialog1
), VERSION
);
1457 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (aboutdialog1
), _("Gerbv"));
1459 /* gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (aboutdialog1), translators); */
1460 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (aboutdialog1
), string
);
1461 gtk_about_dialog_set_license(GTK_ABOUT_DIALOG (aboutdialog1
), license
);
1463 /* The authors.c file is autogenerated at build time */
1464 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG (aboutdialog1
), authors_string_array
);
1465 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG (aboutdialog1
), "http://gerbv.gpleda.org/");
1467 g_signal_connect (G_OBJECT(aboutdialog1
),"response",
1468 G_CALLBACK (gtk_widget_destroy
), GTK_WIDGET(aboutdialog1
));
1473 aboutdialog1
= gtk_message_dialog_new ( GTK_WINDOW (screen
.win
.topLevelWindow
),
1474 GTK_DIALOG_DESTROY_WITH_PARENT
,
1480 gtk_window_set_title ( GTK_WINDOW (aboutdialog1
), _("About Gerbv"));
1482 /* Destroy the dialog when the user responds to it (e.g. clicks a button) */
1483 g_signal_connect_swapped (aboutdialog1
, "response",
1484 G_CALLBACK (gtk_widget_destroy
),
1489 gtk_widget_show_all(GTK_WIDGET(aboutdialog1
));
1493 /* --------------------------------------------------------- */
1495 * The help -> bugs menu item was selected.
1496 * Show the known bugs window
1500 callbacks_bugs_activate (GtkMenuItem
*menuitem
,
1506 /* Create the top level dialog widget with an OK button */
1507 GtkWidget
*bugs_dialog
= gtk_dialog_new_with_buttons("Known bugs in gerbv",
1509 GTK_DIALOG_DESTROY_WITH_PARENT
,
1510 GTK_STOCK_OK
, GTK_RESPONSE_ACCEPT
,
1512 gtk_container_set_border_width (GTK_CONTAINER (bugs_dialog
), 5);
1513 gtk_dialog_set_default_response (GTK_DIALOG(bugs_dialog
),
1514 GTK_RESPONSE_ACCEPT
);
1515 g_signal_connect (G_OBJECT(bugs_dialog
), "response",
1516 G_CALLBACK (gtk_widget_destroy
), GTK_WIDGET(bugs_dialog
));
1518 /* First create single bugs_string from bugs_string_array */
1519 GString
*bugs_string
= g_string_new(NULL
);
1520 for (i
=0; bugs_string_array
[i
] != NULL
; i
++) {
1521 g_string_append_printf(bugs_string
,
1523 bugs_string_array
[i
]);
1526 /* Create GtkLabel to hold text */
1527 GtkWidget
*bugs_label
= gtk_label_new (bugs_string
->str
);
1528 g_string_free(bugs_string
, TRUE
);
1529 gtk_misc_set_alignment(GTK_MISC(bugs_label
), 0, 0);
1530 gtk_misc_set_padding(GTK_MISC(bugs_label
), 13, 13);
1532 /* Put text into scrolled window */
1533 GtkWidget
*bugs_window
= gtk_scrolled_window_new (NULL
, NULL
);
1534 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(bugs_window
),
1535 GTK_WIDGET(bugs_label
));
1536 gtk_widget_set_size_request(GTK_WIDGET(bugs_window
), 600, 300);
1537 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(bugs_dialog
)->vbox
),
1538 GTK_WIDGET(bugs_window
));
1540 gtk_widget_show_all(GTK_WIDGET(bugs_dialog
));
1541 gtk_dialog_run(GTK_DIALOG(bugs_dialog
));
1545 /* --------------------------------------------------------- */
1546 gdouble
callbacks_calculate_actual_distance (gdouble inputDimension
) {
1547 gdouble returnValue
= 0.0;
1549 if (screen
.unit
== GERBV_MILS
) {
1550 returnValue
= COORD2MILS(inputDimension
);
1551 } else if (screen
.unit
== GERBV_MMS
) {
1552 returnValue
= COORD2MMS(inputDimension
);
1554 returnValue
= COORD2MILS(inputDimension
)/1000;
1559 /* --------------------------------------------------------- */
1560 void callbacks_update_ruler_pointers (void) {
1561 double xPosition
, yPosition
;
1562 xPosition
= screenRenderInfo
.lowerLeftX
+ (screen
.last_x
/ screenRenderInfo
.scaleFactorX
);
1563 yPosition
= screenRenderInfo
.lowerLeftY
+ ((screenRenderInfo
.displayHeight
- screen
.last_y
) / screenRenderInfo
.scaleFactorY
);
1565 if (!((screen
.unit
== GERBV_MILS
) && ((screenRenderInfo
.scaleFactorX
< 80)||(screenRenderInfo
.scaleFactorY
< 80)))) {
1566 xPosition
= callbacks_calculate_actual_distance (xPosition
);
1567 yPosition
= callbacks_calculate_actual_distance (yPosition
);
1569 g_object_set (G_OBJECT (screen
.win
.hRuler
), "position", xPosition
, NULL
);
1570 g_object_set (G_OBJECT (screen
.win
.vRuler
), "position", yPosition
, NULL
);
1573 /* --------------------------------------------------------- */
1574 void callbacks_update_ruler_scales (void) {
1575 double xStart
, xEnd
, yStart
, yEnd
;
1577 xStart
= screenRenderInfo
.lowerLeftX
;
1578 yStart
= screenRenderInfo
.lowerLeftY
;
1579 xEnd
= screenRenderInfo
.lowerLeftX
+ (screenRenderInfo
.displayWidth
/ screenRenderInfo
.scaleFactorX
);
1580 yEnd
= screenRenderInfo
.lowerLeftY
+ (screenRenderInfo
.displayHeight
/ screenRenderInfo
.scaleFactorY
);
1581 /* mils can get super crowded with large boards, but inches are too
1582 large for most boards. So, we leave mils in for now and just switch
1583 to inches if the scale factor gets too small */
1584 if (!((screen
.unit
== GERBV_MILS
) && ((screenRenderInfo
.scaleFactorX
< 80)||(screenRenderInfo
.scaleFactorY
< 80)))) {
1585 xStart
= callbacks_calculate_actual_distance (xStart
);
1586 xEnd
= callbacks_calculate_actual_distance (xEnd
);
1587 yStart
= callbacks_calculate_actual_distance (yStart
);
1588 yEnd
= callbacks_calculate_actual_distance (yEnd
);
1590 /* make sure the widgets actually exist before setting (in case this gets
1591 called before everything is realized */
1592 if (screen
.win
.hRuler
)
1593 gtk_ruler_set_range (GTK_RULER (screen
.win
.hRuler
), xStart
, xEnd
, 0, xEnd
- xStart
);
1594 /* reverse y min and max, since the ruler starts at the top */
1595 if (screen
.win
.vRuler
)
1596 gtk_ruler_set_range (GTK_RULER (screen
.win
.vRuler
), yEnd
, yStart
, 0, yEnd
- yStart
);
1599 /* --------------------------------------------------------- */
1600 void callbacks_update_scrollbar_limits (void){
1601 gerbv_render_info_t tempRenderInfo
= {0, 0, 0, 0, 3, screenRenderInfo
.displayWidth
,
1602 screenRenderInfo
.displayHeight
};
1604 GtkAdjustment
*hAdjust
= (GtkAdjustment
*)screen
.win
.hAdjustment
;
1605 GtkAdjustment
*vAdjust
= (GtkAdjustment
*)screen
.win
.vAdjustment
;
1606 gerbv_render_zoom_to_fit_display (mainProject
, &tempRenderInfo
);
1607 hAdjust
->lower
= tempRenderInfo
.lowerLeftX
;
1608 hAdjust
->page_increment
= hAdjust
->page_size
;
1609 hAdjust
->step_increment
= hAdjust
->page_size
/ 10.0;
1610 vAdjust
->lower
= tempRenderInfo
.lowerLeftY
;
1611 vAdjust
->page_increment
= vAdjust
->page_size
;
1612 vAdjust
->step_increment
= vAdjust
->page_size
/ 10.0;
1613 hAdjust
->upper
= tempRenderInfo
.lowerLeftX
+ (tempRenderInfo
.displayWidth
/ tempRenderInfo
.scaleFactorX
);
1614 hAdjust
->page_size
= screenRenderInfo
.displayWidth
/ screenRenderInfo
.scaleFactorX
;
1615 vAdjust
->upper
= tempRenderInfo
.lowerLeftY
+ (tempRenderInfo
.displayHeight
/ tempRenderInfo
.scaleFactorY
);
1616 vAdjust
->page_size
= screenRenderInfo
.displayHeight
/ screenRenderInfo
.scaleFactorY
;
1617 callbacks_update_scrollbar_positions ();
1620 /* --------------------------------------------------------- */
1621 void callbacks_update_scrollbar_positions (void){
1622 gdouble positionX
,positionY
;
1624 positionX
= screenRenderInfo
.lowerLeftX
;
1625 if (positionX
< ((GtkAdjustment
*)screen
.win
.hAdjustment
)->lower
)
1626 positionX
= ((GtkAdjustment
*)screen
.win
.hAdjustment
)->lower
;
1627 if (positionX
> (((GtkAdjustment
*)screen
.win
.hAdjustment
)->upper
- ((GtkAdjustment
*)screen
.win
.hAdjustment
)->page_size
))
1628 positionX
= (((GtkAdjustment
*)screen
.win
.hAdjustment
)->upper
- ((GtkAdjustment
*)screen
.win
.hAdjustment
)->page_size
);
1629 gtk_adjustment_set_value ((GtkAdjustment
*)screen
.win
.hAdjustment
, positionX
);
1631 positionY
= ((GtkAdjustment
*)screen
.win
.vAdjustment
)->upper
- screenRenderInfo
.lowerLeftY
-
1632 ((GtkAdjustment
*)screen
.win
.vAdjustment
)->page_size
+
1633 ((GtkAdjustment
*)screen
.win
.vAdjustment
)->lower
;
1634 if (positionY
< ((GtkAdjustment
*)screen
.win
.vAdjustment
)->lower
)
1635 positionY
= ((GtkAdjustment
*)screen
.win
.vAdjustment
)->lower
;
1636 if (positionY
> (((GtkAdjustment
*)screen
.win
.vAdjustment
)->upper
- ((GtkAdjustment
*)screen
.win
.vAdjustment
)->page_size
))
1637 positionY
= (((GtkAdjustment
*)screen
.win
.vAdjustment
)->upper
- ((GtkAdjustment
*)screen
.win
.vAdjustment
)->page_size
);
1638 gtk_adjustment_set_value ((GtkAdjustment
*)screen
.win
.vAdjustment
, positionY
);
1641 /* --------------------------------------------------------- */
1643 callbacks_scrollbar_button_released (GtkWidget
*widget
, GdkEventButton
*event
){
1646 screen
.state
= NORMAL
;
1647 render_refresh_rendered_image_on_screen();
1651 /* --------------------------------------------------------- */
1653 callbacks_scrollbar_button_pressed (GtkWidget
*widget
, GdkEventButton
*event
){
1654 //screen.last_x = ((GtkAdjustment *)screen.win.hAdjustment)->value;
1655 screen
.state
= SCROLLBAR
;
1659 /* --------------------------------------------------------- */
1660 void callbacks_hadjustment_value_changed (GtkAdjustment
*adjustment
, gpointer user_data
){
1661 /* make sure we're actually using the scrollbar to make sure we don't reset
1662 lowerLeftX during a scrollbar redraw during something else */
1663 if (screen
.state
== SCROLLBAR
) {
1664 screenRenderInfo
.lowerLeftX
= gtk_adjustment_get_value (adjustment
);
1668 /* --------------------------------------------------------- */
1669 void callbacks_vadjustment_value_changed (GtkAdjustment
*adjustment
, gpointer user_data
){
1670 /* make sure we're actually using the scrollbar to make sure we don't reset
1671 lowerLeftY during a scrollbar redraw during something else */
1672 if (screen
.state
== SCROLLBAR
) {
1673 screenRenderInfo
.lowerLeftY
= adjustment
->upper
-
1674 (gtk_adjustment_get_value (adjustment
) + adjustment
->page_size
) + adjustment
->lower
;
1678 /* --------------------------------------------------------- */
1680 callbacks_layer_tree_visibility_button_toggled (GtkCellRendererToggle
*cell_renderer
,
1682 gpointer user_data
){
1683 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
1684 ((GtkTreeView
*) screen
.win
.layerTree
);
1686 gboolean newVisibility
=TRUE
;
1689 gtk_tree_model_get_iter_from_string ((GtkTreeModel
*)list_store
, &iter
, path
);
1691 GtkTreePath
*treePath
= gtk_tree_path_new_from_string (path
);
1692 if (gtk_tree_model_get_iter((GtkTreeModel
*)list_store
, &iter
, treePath
)) {
1695 indeces
= gtk_tree_path_get_indices (treePath
);
1697 if (mainProject
->file
[index
]->isVisible
)
1698 newVisibility
= FALSE
;
1699 mainProject
->file
[index
]->isVisible
= newVisibility
;
1701 callbacks_update_layer_tree ();
1702 if (screenRenderInfo
.renderType
< 2) {
1703 render_refresh_rendered_image_on_screen();
1706 render_recreate_composite_surface (screen
.drawing_area
);
1707 callbacks_force_expose_event_for_screen ();
1712 /* --------------------------------------------------------- */
1714 callbacks_get_col_number_from_tree_view_column (GtkTreeViewColumn
*col
)
1719 g_return_val_if_fail ( col
!= NULL
, -1 );
1720 g_return_val_if_fail ( col
->tree_view
!= NULL
, -1 );
1721 cols
= gtk_tree_view_get_columns(GTK_TREE_VIEW(col
->tree_view
));
1722 num
= g_list_index(cols
, (gpointer
) col
);
1727 /* --------------------------------------------------------- */
1729 callbacks_add_layer_button_clicked (GtkButton
*button
, gpointer user_data
) {
1730 callbacks_open_layer_activate (NULL
, NULL
);
1733 /* --------------------------------------------------------- */
1735 callbacks_unselect_all_tool_buttons (void) {
1740 callbacks_switch_to_normal_tool_cursor (gint toolNumber
) {
1743 switch (toolNumber
) {
1745 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1749 cursor
= gdk_cursor_new(GDK_FLEUR
);
1750 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1752 gdk_cursor_destroy(cursor
);
1755 cursor
= gdk_cursor_new(GDK_SIZING
);
1756 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1758 gdk_cursor_destroy(cursor
);
1761 cursor
= gdk_cursor_new(GDK_CROSSHAIR
);
1762 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1764 gdk_cursor_destroy(cursor
);
1771 /* --------------------------------------------------------- */
1773 callbacks_switch_to_correct_cursor (void) {
1776 if (screen
.state
== IN_MOVE
) {
1777 cursor
= gdk_cursor_new(GDK_FLEUR
);
1778 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1780 gdk_cursor_destroy(cursor
);
1783 else if (screen
.state
== IN_ZOOM_OUTLINE
) {
1784 cursor
= gdk_cursor_new(GDK_SIZING
);
1785 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
1787 gdk_cursor_destroy(cursor
);
1790 callbacks_switch_to_normal_tool_cursor (screen
.tool
);
1793 /* --------------------------------------------------------- */
1795 callbacks_change_tool (GtkButton
*button
, gpointer user_data
) {
1796 gint toolNumber
= GPOINTER_TO_INT (user_data
);
1798 /* make sure se don't get caught in endless recursion here */
1799 if (screen
.win
.updatingTools
)
1801 screen
.win
.updatingTools
= TRUE
;
1802 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonPointer
), FALSE
);
1803 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonPan
), FALSE
);
1804 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonZoom
), FALSE
);
1805 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonMeasure
), FALSE
);
1806 switch (toolNumber
) {
1808 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonPointer
), TRUE
);
1809 screen
.tool
= POINTER
;
1810 screen
.state
= NORMAL
;
1811 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
1812 "Click to select objects in the current layer. Middle click and drag to pan.");
1815 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonPan
), TRUE
);
1817 screen
.state
= NORMAL
;
1818 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
1819 "Click and drag to pan. Right click and drag to zoom.");
1822 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonZoom
), TRUE
);
1824 screen
.state
= NORMAL
;
1825 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
1826 "Click and drag to zoom in. Shift+click to zoom out.");
1829 gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (screen
.win
.toolButtonMeasure
), TRUE
);
1830 screen
.tool
= MEASURE
;
1831 screen
.state
= NORMAL
;
1832 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
, "Click and drag to measure a distance.");
1837 callbacks_switch_to_normal_tool_cursor (toolNumber
);
1838 callbacks_update_statusbar();
1839 screen
.win
.updatingTools
= FALSE
;
1840 callbacks_force_expose_event_for_screen();
1843 /* --------------------------------------------------------- */
1845 callbacks_select_row (gint rowIndex
) {
1846 GtkTreeSelection
*selection
;
1848 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
1849 ((GtkTreeView
*) screen
.win
.layerTree
);
1851 selection
= gtk_tree_view_get_selection((GtkTreeView
*) screen
.win
.layerTree
);
1852 if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store
), &iter
, NULL
, rowIndex
)) {
1853 gtk_tree_selection_select_iter (selection
, &iter
);
1857 /* --------------------------------------------------------- */
1859 * This fcn returns the index of selected layer (selected in
1860 * the layer window on left).
1864 callbacks_get_selected_row_index (void) {
1865 GtkTreeSelection
*selection
;
1867 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
1868 ((GtkTreeView
*) screen
.win
.layerTree
);
1871 /* This will only work in single or browse selection mode! */
1872 selection
= gtk_tree_view_get_selection((GtkTreeView
*) screen
.win
.layerTree
);
1873 if (gtk_tree_selection_get_selected(selection
, NULL
, &iter
)) {
1874 while (gtk_tree_model_iter_nth_child ((GtkTreeModel
*)list_store
,
1876 if (gtk_tree_selection_iter_is_selected (selection
, &iter
)) {
1885 /* --------------------------------------------------------- */
1887 callbacks_remove_layer_button_clicked (GtkButton
*button
, gpointer user_data
) {
1888 gint index
=callbacks_get_selected_row_index();
1890 if ((index
>= 0) && (index
<= mainProject
->last_loaded
)) {
1891 render_remove_selected_objects_belonging_to_layer (index
);
1892 gerbv_unload_layer (mainProject
, index
);
1893 callbacks_update_layer_tree ();
1894 callbacks_select_row (0);
1896 if (screenRenderInfo
.renderType
< 2) {
1897 render_refresh_rendered_image_on_screen();
1900 render_recreate_composite_surface (screen
.drawing_area
);
1901 callbacks_force_expose_event_for_screen ();
1906 /* --------------------------------------------------------- */
1908 callbacks_move_layer_down_button_clicked (GtkButton
*button
, gpointer user_data
) {
1909 gint index
=callbacks_get_selected_row_index();
1911 if ((index
>= 0) && (index
< mainProject
->last_loaded
)) {
1912 gerbv_change_layer_order (mainProject
, index
, index
+ 1);
1913 callbacks_update_layer_tree ();
1914 callbacks_select_row (index
+ 1);
1915 if (screenRenderInfo
.renderType
< 2) {
1916 render_refresh_rendered_image_on_screen();
1919 render_recreate_composite_surface (screen
.drawing_area
);
1920 callbacks_force_expose_event_for_screen ();
1925 /* --------------------------------------------------------- */
1927 callbacks_move_layer_up_clicked (GtkButton
*button
, gpointer user_data
) {
1928 gint index
=callbacks_get_selected_row_index();
1931 gerbv_change_layer_order (mainProject
, index
, index
- 1);
1932 callbacks_update_layer_tree ();
1933 callbacks_select_row (index
- 1);
1934 if (screenRenderInfo
.renderType
< 2) {
1935 render_refresh_rendered_image_on_screen();
1938 render_recreate_composite_surface (screen
.drawing_area
);
1939 callbacks_force_expose_event_for_screen ();
1944 /* --------------------------------------------------------- */
1945 void callbacks_layer_tree_row_inserted (GtkTreeModel
*tree_model
, GtkTreePath
*path
,
1946 GtkTreeIter
*oIter
, gpointer user_data
) {
1947 gint
*indeces
=NULL
,oldPosition
,newPosition
;
1949 if ((!screen
.win
.treeIsUpdating
)&&(path
!= NULL
)) {
1950 indeces
= gtk_tree_path_get_indices (path
);
1952 newPosition
= indeces
[0];
1953 oldPosition
= callbacks_get_selected_row_index ();
1954 /* compensate for the fact that the old row has already
1956 if (oldPosition
< newPosition
)
1960 gerbv_change_layer_order (mainProject
, oldPosition
, newPosition
);
1962 if (screenRenderInfo
.renderType
< 2) {
1963 render_refresh_rendered_image_on_screen();
1966 render_recreate_composite_surface (screen
.drawing_area
);
1967 callbacks_force_expose_event_for_screen ();
1969 /* select the new line */
1970 GtkTreeSelection
*selection
;
1972 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
1973 ((GtkTreeView
*) screen
.win
.layerTree
);
1975 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(screen
.win
.layerTree
));
1976 if (gtk_tree_model_get_iter ((GtkTreeModel
*)list_store
, &iter
, path
))
1977 gtk_tree_selection_select_iter (selection
, &iter
);
1982 /* --------------------------------------------------------- */
1984 callbacks_show_color_picker_dialog (gint index
){
1985 screen
.win
.colorSelectionDialog
= NULL
;
1986 GtkColorSelectionDialog
*cs
= (GtkColorSelectionDialog
*) gtk_color_selection_dialog_new ("Select a color");
1987 GtkColorSelection
*colorsel
= (GtkColorSelection
*) cs
->colorsel
;
1989 screen
.win
.colorSelectionDialog
= (GtkWidget
*) cs
;
1990 screen
.win
.colorSelectionIndex
= index
;
1992 gtk_color_selection_set_current_color (colorsel
, &mainProject
->file
[index
]->color
);
1994 gtk_color_selection_set_current_color (colorsel
, &mainProject
->background
);
1995 if ((screenRenderInfo
.renderType
>= 2)&&(index
>= 0)) {
1996 gtk_color_selection_set_has_opacity_control (colorsel
, TRUE
);
1997 gtk_color_selection_set_current_alpha (colorsel
, mainProject
->file
[index
]->alpha
);
1999 gtk_widget_show_all((GtkWidget
*)cs
);
2000 if (gtk_dialog_run ((GtkDialog
*)cs
) == GTK_RESPONSE_OK
) {
2001 GtkColorSelection
*colorsel
= (GtkColorSelection
*) cs
->colorsel
;
2002 gint rowIndex
= screen
.win
.colorSelectionIndex
;
2005 gtk_color_selection_get_current_color (colorsel
, &mainProject
->file
[rowIndex
]->color
);
2006 gdk_colormap_alloc_color(gdk_colormap_get_system(), &mainProject
->file
[rowIndex
]->color
, FALSE
, TRUE
);
2009 gtk_color_selection_get_current_color (colorsel
, &mainProject
->background
);
2010 gdk_colormap_alloc_color(gdk_colormap_get_system(), &mainProject
->background
, FALSE
, TRUE
);
2012 if ((screenRenderInfo
.renderType
>= 2)&&(index
>= 0)) {
2013 mainProject
->file
[rowIndex
]->alpha
= gtk_color_selection_get_current_alpha (colorsel
);
2016 callbacks_update_layer_tree ();
2017 render_refresh_rendered_image_on_screen();
2019 gtk_widget_destroy ((GtkWidget
*)cs
);
2020 screen
.win
.colorSelectionDialog
= NULL
;
2023 /* --------------------------------------------------------- */
2025 callbacks_invert_layer_clicked (GtkButton
*button
, gpointer user_data
) {
2026 gint index
=callbacks_get_selected_row_index();
2028 mainProject
->file
[index
]->transform
.inverted
= !mainProject
->file
[index
]->transform
.inverted
;
2029 render_refresh_rendered_image_on_screen ();
2030 callbacks_update_layer_tree ();
2033 /* --------------------------------------------------------- */
2035 callbacks_change_layer_color_clicked (GtkButton
*button
, gpointer user_data
) {
2036 gint index
=callbacks_get_selected_row_index();
2038 callbacks_show_color_picker_dialog (index
);
2042 callbacks_change_background_color_clicked (GtkButton
*button
, gpointer user_data
) {
2043 callbacks_show_color_picker_dialog (-1);
2046 /* --------------------------------------------------------------------------- */
2048 callbacks_reload_layer_clicked (GtkButton
*button
, gpointer user_data
) {
2049 gint index
= callbacks_get_selected_row_index();
2051 render_remove_selected_objects_belonging_to_layer (index
);
2052 gerbv_revert_file (mainProject
, index
);
2053 render_refresh_rendered_image_on_screen ();
2054 callbacks_update_layer_tree();
2058 callbacks_change_layer_orientation_clicked (GtkButton
*button
, gpointer userData
){
2059 gint index
= callbacks_get_selected_row_index();
2061 interface_show_modify_orientation_dialog(&mainProject
->file
[index
]->transform
,screen
.unit
);
2062 render_refresh_rendered_image_on_screen ();
2063 callbacks_update_layer_tree ();
2066 /* --------------------------------------------------------------------------- */
2068 callbacks_change_layer_format_clicked (GtkButton
*button
, gpointer user_data
)
2070 gerbv_HID_Attribute
*attr
= NULL
;
2073 gerbv_HID_Attr_Val
* results
= NULL
;
2074 gint index
= callbacks_get_selected_row_index();
2078 dprintf ("%s(): index = %d\n", __FUNCTION__
, index
);
2079 attr
= mainProject
->file
[index
]->image
->info
->attr_list
;
2080 n
= mainProject
->file
[index
]->image
->info
->n_attr
;
2081 type
= mainProject
->file
[index
]->image
->info
->type
;
2085 if (attr
== NULL
|| n
== 0)
2087 interface_show_alert_dialog("This file type does not currently have any editable features",
2088 "Format editing is currently only supported for Excellon drill file formats.",
2094 dprintf ("%s(): n = %d, attr = %p\n", __FUNCTION__
, n
, attr
);
2097 if (mainProject
->file
[index
]->layer_dirty
) {
2098 rc
= interface_get_alert_dialog_response ("This layer has changed!",
2099 "Editing the file type will reload the layer, destroying your changes. Click OK to edit the file type and destroy your changes, or Cancel to leave.",
2102 if (rc
== 0) return; /* Return if user hit Cancel */
2105 results
= (gerbv_HID_Attr_Val
*) malloc (n
* sizeof (gerbv_HID_Attr_Val
));
2106 if (results
== NULL
)
2108 fprintf (stderr
, "%s() -- malloc failed\n", __FUNCTION__
);
2112 /* non-zero means cancel was picked */
2113 if (attribute_interface_dialog (attr
, n
, results
,
2122 dprintf ("%s(): Reloading layer\n", __FUNCTION__
);
2123 gerbv_revert_file (mainProject
, index
);
2125 for (i
= 0; i
< n
; i
++)
2127 if (results
[i
].str_value
)
2128 free (results
[i
].str_value
);
2133 render_refresh_rendered_image_on_screen();
2134 callbacks_update_layer_tree();
2137 /* --------------------------------------------------------------------------- */
2139 callbacks_layer_tree_button_press (GtkWidget
*widget
, GdkEventButton
*event
,
2140 gpointer user_data
) {
2143 GtkTreeViewColumn
*column
;
2147 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
2148 ((GtkTreeView
*) screen
.win
.layerTree
);
2149 if (event
->button
== 1) {
2150 if (gtk_tree_view_get_path_at_pos ((GtkTreeView
*) widget
, event
->x
, event
->y
,
2151 &path
, &column
, &x
, &y
)) {
2152 if (gtk_tree_model_get_iter((GtkTreeModel
*)list_store
, &iter
, path
)) {
2154 indeces
= gtk_tree_path_get_indices (path
);
2156 columnIndex
= callbacks_get_col_number_from_tree_view_column (column
);
2157 if ((columnIndex
== 1) && (indeces
[0] <= mainProject
->last_loaded
)){
2158 callbacks_show_color_picker_dialog (indeces
[0]);
2159 /* don't propagate the signal, since drag and drop can
2160 sometimes activated during color selection */
2167 /* don't pop up the menu if we don't have any loaded files */
2168 else if ((event
->button
== 3)&&(mainProject
->last_loaded
>= 0)) {
2169 gtk_menu_popup(GTK_MENU(screen
.win
.layerTreePopupMenu
), NULL
, NULL
, NULL
, NULL
,
2170 event
->button
, event
->time
);
2172 /* always allow the click to propagate and make sure the line is activated */
2176 /* --------------------------------------------------------------------------- */
2178 callbacks_update_layer_tree (void) {
2179 GtkListStore
*list_store
= (GtkListStore
*) gtk_tree_view_get_model
2180 ((GtkTreeView
*) screen
.win
.layerTree
);
2183 GtkTreeSelection
*selection
;
2184 gint oldSelectedRow
;
2186 if (!screen
.win
.treeIsUpdating
) {
2187 screen
.win
.treeIsUpdating
= TRUE
;
2189 oldSelectedRow
= callbacks_get_selected_row_index();
2190 if (oldSelectedRow
< 0)
2192 gtk_list_store_clear (list_store
);
2194 for (idx
= 0; idx
<= mainProject
->last_loaded
; idx
++) {
2195 if (mainProject
->file
[idx
]) {
2196 GdkPixbuf
*pixbuf
,*blackPixbuf
;
2199 unsigned char red
, green
, blue
, alpha
;
2201 red
= (unsigned char) (mainProject
->file
[idx
]->color
.red
* 255 / G_MAXUINT16
) ;
2202 green
= (unsigned char) (mainProject
->file
[idx
]->color
.green
* 255 / G_MAXUINT16
) ;
2203 blue
= (unsigned char) (mainProject
->file
[idx
]->color
.blue
*255 / G_MAXUINT16
) ;
2204 alpha
= (unsigned char) (mainProject
->file
[idx
]->alpha
* 255 / G_MAXUINT16
) ;
2206 color
= (red
)* (256*256*256) + (green
) * (256*256) + (blue
)* (256) + (alpha
);
2207 pixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, 20, 15);
2208 gdk_pixbuf_fill (pixbuf
, color
);
2210 blackPixbuf
= gdk_pixbuf_new (GDK_COLORSPACE_RGB
, TRUE
, 8, 20, 15);
2211 color
= (100 )* (256*256*256) + (100 ) * (256*256) + (100 )* (256) + (150 );
2212 gdk_pixbuf_fill (blackPixbuf
, color
);
2214 /* copy the color area into the black pixbuf */
2215 gdk_pixbuf_copy_area (pixbuf
, 1, 1, 18, 13, blackPixbuf
, 1, 1);
2216 /* free the color buffer, since we don't need it anymore */
2217 g_object_unref(pixbuf
);
2219 gtk_list_store_append (list_store
, &iter
);
2221 gchar startChar
[2],*modifiedCode
;
2222 /* terminate the letter string */
2225 gint numberOfModifications
= 0;
2226 if (mainProject
->file
[idx
]->transform
.inverted
) {
2228 numberOfModifications
++;
2230 if (mainProject
->file
[idx
]->transform
.mirrorAroundX
||
2231 mainProject
->file
[idx
]->transform
.mirrorAroundY
) {
2233 numberOfModifications
++;
2235 if ((abs(mainProject
->file
[idx
]->transform
.translateX
) > 0.000001) ||
2236 (fabs(mainProject
->file
[idx
]->transform
.translateY
) > 0.000001)) {
2238 numberOfModifications
++;
2240 if ((abs(mainProject
->file
[idx
]->transform
.scaleX
- 1) > 0.000001) ||
2241 (fabs(mainProject
->file
[idx
]->transform
.scaleY
- 1) > 0.000001)) {
2243 numberOfModifications
++;
2245 if ((fabs(mainProject
->file
[idx
]->transform
.rotation
) > 0.000001)) {
2247 numberOfModifications
++;
2249 if (numberOfModifications
> 1)
2251 if (numberOfModifications
== 0)
2252 modifiedCode
= g_strdup ("");
2254 modifiedCode
= g_strdup (startChar
);
2256 /* display any unsaved layers differently to show the user they are
2259 if (mainProject
->file
[idx
]->layer_dirty
== TRUE
) {
2260 /* The layer has unsaved changes in it. Show layer name in italics. */
2261 layerName
= g_strconcat ("*","<i>",mainProject
->file
[idx
]->name
,"</i>",NULL
);
2264 /* layer is clean. Show layer name using normal font. */
2265 layerName
= g_strdup (mainProject
->file
[idx
]->name
);
2267 gtk_list_store_set (list_store
, &iter
,
2268 0, mainProject
->file
[idx
]->isVisible
,
2274 g_free (modifiedCode
);
2275 /* pixbuf has a refcount of 2 now, as the list store has added its own reference */
2276 g_object_unref(blackPixbuf
);
2280 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(screen
.win
.layerTree
));
2282 /* if no line is selected yet, select the first row (if it has data) */
2283 /* or, select the line that was previously selected */
2285 if (!gtk_tree_selection_get_selected (selection
, NULL
, &iter
)) {
2286 if (gtk_tree_model_iter_nth_child ((GtkTreeModel
*) list_store
,
2287 &iter
, NULL
, oldSelectedRow
)) {
2288 gtk_tree_selection_select_iter (selection
, &iter
);
2291 screen
.win
.treeIsUpdating
= FALSE
;
2295 /* --------------------------------------------------------------------------- */
2297 callbacks_display_object_properties_clicked (GtkButton
*button
, gpointer user_data
){
2301 gboolean validAperture
;
2303 gint index
=callbacks_get_selected_row_index();
2307 if (screen
.selectionInfo
.type
== GERBV_SELECTION_EMPTY
) {
2308 interface_show_alert_dialog("No object is currently selected",
2309 "Objects must be selected using the pointer tool before you can view the object properties.",
2315 for (i
=0; i
<screen
.selectionInfo
.selectedNodeArray
->len
; i
++){
2316 gerbv_selection_item_t sItem
= g_array_index (screen
.selectionInfo
.selectedNodeArray
,
2317 gerbv_selection_item_t
, i
);
2319 gerbv_net_t
*net
= sItem
.net
;
2320 gerbv_image_t
*image
= sItem
.image
;
2323 /* get the aperture definition for the selected item */
2324 if (net
->aperture
> 0) {
2325 ap_type
= image
->aperture
[net
->aperture
]->type
;
2326 validAperture
= TRUE
;
2329 validAperture
= FALSE
;
2332 /* Also get layer name specified in file by %LN directive
2333 * (if it exists). */
2334 if (net
->layer
->name
== NULL
) {
2335 layer_name
= g_strdup("<unnamed layer>");
2337 layer_name
= g_strdup(net
->layer
->name
);
2340 if (net
->label
== NULL
) {
2341 net_label
= g_strdup("<unlabeled net>");
2343 net_label
= g_strdup((gchar
*)net
->label
);
2345 if (net
->interpolation
== GERBV_INTERPOLATION_PAREA_START
) {
2346 g_message ("Object type: Polygon\n");
2349 switch (net
->aperture_state
){
2350 case GERBV_APERTURE_STATE_OFF
:
2352 case GERBV_APERTURE_STATE_ON
:
2353 if (i
!=0) g_message ("\n"); /* Spacing for a pretty display */
2354 switch (net
->interpolation
) {
2355 case GERBV_INTERPOLATION_x10
:
2356 case GERBV_INTERPOLATION_LINEARx01
:
2357 case GERBV_INTERPOLATION_LINEARx001
:
2358 case GERBV_INTERPOLATION_LINEARx1
:
2359 g_message ("Object type: Line\n");
2361 case GERBV_INTERPOLATION_CW_CIRCULAR
:
2362 case GERBV_INTERPOLATION_CCW_CIRCULAR
:
2363 g_message ("Object type: Arc\n");
2366 g_message ("Object type: Unknown\n");
2369 g_message (" Exposure: On\n");
2370 if (validAperture
) {
2371 g_message (" Aperture used: D%d\n", net
->aperture
);
2372 g_message (" Aperture type: %s\n", ap_names
[ap_type
]);
2374 g_message (" Start location: (%g, %g)\n", net
->start_x
, net
->start_y
);
2375 g_message (" Stop location: (%g, %g)\n", net
->stop_x
, net
->stop_y
);
2376 g_message (" Layer name: %s\n", layer_name
);
2377 g_message (" Net label: %s\n", net_label
);
2378 g_message (" In file: %s\n", mainProject
->file
[index
]->name
);
2380 case GERBV_APERTURE_STATE_FLASH
:
2381 if (i
!=0) g_message ("\n"); /* Spacing for a pretty display */
2382 g_message ("Object type: Flashed aperture\n");
2383 if (validAperture
) {
2384 g_message (" Aperture used: D%d\n", net
->aperture
);
2385 g_message (" Aperture type: %s\n", ap_names
[ap_type
]);
2387 g_message (" Location: (%g, %g)\n", net
->stop_x
, net
->stop_y
);
2388 g_message (" Layer name: %s\n", layer_name
);
2389 g_message (" Net label: %s\n", net_label
);
2390 g_message (" In file: %s\n", mainProject
->file
[index
]->name
);
2395 g_free (layer_name
);
2397 /* Use separator for different report requests */
2398 g_message ("---------------------------------------\n");
2402 callbacks_support_benchmark (gerbv_render_info_t
*renderInfo
) {
2405 GdkPixmap
*renderedPixmap
= gdk_pixmap_new (NULL
, renderInfo
->displayWidth
,
2406 renderInfo
->displayHeight
, 24);
2408 // start by running the GDK (fast) rendering test
2412 while( now
- 30 < start
) {
2414 dprintf("Benchmark(): Starting redraw #%d\n", i
);
2415 gerbv_render_to_pixmap_using_gdk (mainProject
, renderedPixmap
, renderInfo
, NULL
, NULL
);
2417 dprintf("Elapsed time = %ld seconds\n", (long int) (now
- start
));
2419 g_message("FAST mode benchmark: %d redraws in %ld seconds (%g redraws/second)\n",
2420 i
, (long int) (now
- start
), (double) i
/ (double)(now
- start
));
2421 gdk_pixmap_unref(renderedPixmap
);
2423 // run the cairo (normal) render mode
2427 renderInfo
->renderType
= 2;
2428 while( now
- 30 < start
) {
2430 dprintf("Benchmark(): Starting redraw #%d\n", i
);
2431 cairo_surface_t
*cSurface
= cairo_image_surface_create (CAIRO_FORMAT_ARGB32
,
2432 renderInfo
->displayWidth
, renderInfo
->displayHeight
);
2433 cairo_t
*cairoTarget
= cairo_create (cSurface
);
2434 gerbv_render_all_layers_to_cairo_target (mainProject
, cairoTarget
, renderInfo
);
2435 cairo_destroy (cairoTarget
);
2436 cairo_surface_destroy (cSurface
);
2438 dprintf("Elapsed time = %ld seconds\n", (long int) (now
- start
));
2440 g_message("NORMAL mode benchmark: %d redraws in %ld seconds (%g redraws/second)\n",
2441 i
, (long int) (now
- start
), (double) i
/ (double)(now
- start
));
2444 /* --------------------------------------------------------------------------- */
2446 callbacks_benchmark_clicked (GtkButton
*button
, gpointer user_data
)
2448 // prepare render size and options (canvas size width and height are last 2 variables)
2449 gerbv_render_info_t renderInfo
= {1.0, 1.0, 0, 0, 0, 640, 480};
2450 // autoscale the image for now...maybe we don't want to do this in order to
2451 // allow benchmarking of different zoom levels?
2452 gerbv_render_zoom_to_fit_display (mainProject
, &renderInfo
);
2454 g_message("Full zoom benchmarks\n");
2455 callbacks_support_benchmark (&renderInfo
);
2458 g_message("x5 zoom benchmarks\n");
2459 renderInfo
.lowerLeftX
+= (screenRenderInfo
.displayWidth
/
2460 screenRenderInfo
.scaleFactorX
) / 3.0;
2461 renderInfo
.lowerLeftY
+= (screenRenderInfo
.displayHeight
/
2462 screenRenderInfo
.scaleFactorY
) / 3.0;
2463 renderInfo
.scaleFactorX
*= 5;
2464 renderInfo
.scaleFactorY
*= 5;
2465 callbacks_support_benchmark (&renderInfo
);
2468 /* --------------------------------------------------------------------------- */
2470 callbacks_edit_object_properties_clicked (GtkButton
*button
, gpointer user_data
){
2473 /* --------------------------------------------------------------------------- */
2475 callbacks_move_objects_clicked (GtkButton
*button
, gpointer user_data
){
2476 /* for testing, just hard code in some translations here */
2477 gerbv_image_move_selected_objects (screen
.selectionInfo
.selectedNodeArray
, -0.050, 0.050);
2478 callbacks_update_layer_tree();
2479 render_clear_selection_buffer ();
2480 render_refresh_rendered_image_on_screen ();
2483 /* --------------------------------------------------------------------------- */
2485 callbacks_reduce_object_area_clicked (GtkButton
*button
, gpointer user_data
){
2486 /* for testing, just hard code in some parameters */
2487 gerbv_image_reduce_area_of_selected_objects (screen
.selectionInfo
.selectedNodeArray
, 0.20, 3, 3, 0.01);
2488 render_clear_selection_buffer ();
2489 render_refresh_rendered_image_on_screen ();
2492 /* --------------------------------------------------------------------------- */
2494 callbacks_delete_objects_clicked (GtkButton
*button
, gpointer user_data
){
2495 if (screen
.selectionInfo
.type
== GERBV_SELECTION_EMPTY
) {
2496 interface_show_alert_dialog("No object is currently selected",
2503 gint index
=callbacks_get_selected_row_index();
2507 if (mainProject
->check_before_delete
== TRUE
) {
2508 if (!interface_get_alert_dialog_response(
2509 "Do you want to permanently delete the selected objects?",
2510 "Gerbv currently has no undo function, so this action cannot be undone. This action will not change the saved file unless you save the file afterwards.",
2512 &(mainProject
->check_before_delete
)))
2516 gerbv_image_delete_selected_nets (mainProject
->file
[index
]->image
,
2517 screen
.selectionInfo
.selectedNodeArray
);
2518 render_refresh_rendered_image_on_screen ();
2519 /* Set layer_dirty flag to TRUE */
2520 mainProject
->file
[index
]->layer_dirty
= TRUE
;
2521 callbacks_update_layer_tree();
2523 render_clear_selection_buffer ();
2524 callbacks_update_selected_object_message(FALSE
);
2527 /* --------------------------------------------------------------------------- */
2529 callbacks_drawingarea_configure_event (GtkWidget
*widget
, GdkEventConfigure
*event
)
2531 GdkDrawable
*drawable
= widget
->window
;
2533 gdk_drawable_get_size (drawable
, &screenRenderInfo
.displayWidth
, &screenRenderInfo
.displayHeight
);
2535 /* set this up if cairo is compiled, since we may need to switch over to
2536 using the surface at any time */
2537 int x_off
=0, y_off
=0;
2540 if (GDK_IS_WINDOW(widget
->window
)) {
2541 /* query the window's backbuffer if it has one */
2542 GdkWindow
*window
= GDK_WINDOW(widget
->window
);
2543 gdk_window_get_internal_paint_info (window
, &drawable
, &x_off
, &y_off
);
2545 visual
= gdk_drawable_get_visual (drawable
);
2546 if (screen
.windowSurface
)
2547 cairo_surface_destroy ((cairo_surface_t
*)
2548 screen
.windowSurface
);
2550 cairo_t
*cairoTarget
= gdk_cairo_create (GDK_WINDOW(widget
->window
));
2552 screen
.windowSurface
= cairo_get_target (cairoTarget
);
2553 /* increase surface reference by one so it isn't freed when the cairo_t
2554 is destroyed next */
2555 screen
.windowSurface
= cairo_surface_reference (screen
.windowSurface
);
2556 cairo_destroy (cairoTarget
);
2558 screen
.windowSurface
= (gpointer
) cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable
),
2559 GDK_DRAWABLE_XID (drawable
),
2560 GDK_VISUAL_XVISUAL (visual
),
2561 screenRenderInfo
.displayWidth
,
2562 screenRenderInfo
.displayHeight
);
2564 /* if this is the first time, go ahead and call autoscale even if we don't
2565 have a model loaded */
2566 if ((screenRenderInfo
.scaleFactorX
< 0.001)||(screenRenderInfo
.scaleFactorY
< 0.001)) {
2567 gerbv_render_zoom_to_fit_display (mainProject
, &screenRenderInfo
);
2569 render_refresh_rendered_image_on_screen();
2573 /* --------------------------------------------------------- */
2575 callbacks_drawingarea_expose_event (GtkWidget
*widget
, GdkEventExpose
*event
)
2577 if (screenRenderInfo
.renderType
< 2) {
2578 GdkPixmap
*new_pixmap
;
2579 GdkGC
*gc
= gdk_gc_new(widget
->window
);
2582 * Create a pixmap with default background
2584 new_pixmap
= gdk_pixmap_new(widget
->window
,
2585 widget
->allocation
.width
,
2586 widget
->allocation
.height
,
2589 gdk_gc_set_foreground(gc
, &mainProject
->background
);
2591 gdk_draw_rectangle(new_pixmap
, gc
, TRUE
,
2592 event
->area
.x
, event
->area
.y
,
2593 event
->area
.width
, event
->area
.height
);
2596 * Copy gerber pixmap onto background if we have one to copy.
2597 * Do translation at the same time.
2599 if (screen
.pixmap
!= NULL
) {
2600 gdk_draw_pixmap(new_pixmap
,
2601 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
2603 event
->area
.x
- screen
.off_x
,
2604 event
->area
.y
- screen
.off_y
,
2605 event
->area
.x
, event
->area
.y
,
2606 event
->area
.width
, event
->area
.height
);
2610 * Draw the whole thing onto screen
2612 gdk_draw_pixmap(widget
->window
,
2613 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
2615 event
->area
.x
, event
->area
.y
,
2616 event
->area
.x
, event
->area
.y
,
2617 event
->area
.width
, event
->area
.height
);
2619 gdk_pixmap_unref(new_pixmap
);
2623 * Draw Zooming outline if we are in that mode
2625 if (screen
.state
== IN_ZOOM_OUTLINE
) {
2626 render_draw_zoom_outline(screen
.centered_outline_zoom
);
2628 else if (screen
.state
== IN_MEASURE
) {
2629 render_draw_measure_distance();
2631 if (screen
.tool
== MEASURE
&& screen
.state
!= IN_MEASURE
) {
2632 render_toggle_measure_line();
2640 int x_off
=0, y_off
=0;
2641 GdkDrawable
*drawable
= widget
->window
;
2644 if (GDK_IS_WINDOW(widget
->window
)) {
2645 /* query the window's backbuffer if it has one */
2646 GdkWindow
*window
= GDK_WINDOW(widget
->window
);
2647 gdk_window_get_internal_paint_info (window
,
2648 &drawable
, &x_off
, &y_off
);
2650 visual
= gdk_drawable_get_visual (drawable
);
2651 gdk_drawable_get_size (drawable
, &width
, &height
);
2655 cr
= gdk_cairo_create (GDK_WINDOW(widget
->window
));
2657 cairo_surface_t
*buffert
;
2659 buffert
= (gpointer
) cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable
),
2660 GDK_DRAWABLE_XID (drawable
),
2661 GDK_VISUAL_XVISUAL (visual
),
2662 event
->area
.width
, event
->area
.height
);
2663 cr
= cairo_create (buffert
);
2665 cairo_translate (cr
, -event
->area
.x
+ screen
.off_x
, -event
->area
.y
+ screen
.off_y
);
2666 render_project_to_cairo_target (cr
);
2669 cairo_surface_destroy (buffert
);
2672 if (screen
.tool
== MEASURE
)
2673 render_toggle_measure_line();
2677 /* Transforms screen coordinates to board ones */
2679 callbacks_screen2board(gdouble
*X
, gdouble
*Y
, gint x
, gint y
) {
2681 /* make sure we don't divide by zero (which is possible if the gui
2682 isn't displayed yet */
2683 if ((screenRenderInfo
.scaleFactorX
> 0.001)||(screenRenderInfo
.scaleFactorY
> 0.001)) {
2684 *X
= screenRenderInfo
.lowerLeftX
+ (x
/ screenRenderInfo
.scaleFactorX
);
2685 *Y
= screenRenderInfo
.lowerLeftY
+ ((screenRenderInfo
.displayHeight
- y
)
2686 / screenRenderInfo
.scaleFactorY
);
2693 /* --------------------------------------------------------- */
2695 callbacks_update_statusbar_coordinates (gint x
, gint y
) {
2698 callbacks_screen2board(&X
, &Y
, x
, y
);
2699 if (screen
.unit
== GERBV_MILS
) {
2700 snprintf(screen
.statusbar
.coordstr
, MAX_COORDLEN
,
2702 COORD2MILS(X
), COORD2MILS(Y
));
2703 } else if (screen
.unit
== GERBV_MMS
) {
2704 snprintf(screen
.statusbar
.coordstr
, MAX_COORDLEN
,
2706 COORD2MMS(X
), COORD2MMS(Y
));
2708 snprintf(screen
.statusbar
.coordstr
, MAX_COORDLEN
,
2710 COORD2MILS(X
) / 1000.0, COORD2MILS(Y
) / 1000.0);
2712 callbacks_update_statusbar();
2716 callbacks_update_selected_object_message (gboolean userTriedToSelect
) {
2717 if (screen
.tool
!= POINTER
)
2720 gint selectionLength
= screen
.selectionInfo
.selectedNodeArray
->len
;
2721 if ((selectionLength
== 0)&&(userTriedToSelect
)) {
2722 /* update status bar message to make sure the user knows
2723 about needing to select the layer */
2724 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
2725 "<b>No object selected. Objects can only be selected in the active layer.</b>");
2727 else if (selectionLength
== 0) {
2728 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
2729 "Click to select objects in the current layer. Middle click and drag to pan.");
2731 else if (selectionLength
== 1) {
2732 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
2733 "1 object is currently selected");
2736 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
2737 "%d objects are currently selected",selectionLength
);
2739 callbacks_update_statusbar();
2742 /* --------------------------------------------------------- */
2744 callbacks_drawingarea_motion_notify_event (GtkWidget
*widget
, GdkEventMotion
*event
)
2747 GdkModifierType state
;
2750 gdk_window_get_pointer (event
->window
, &x
, &y
, &state
);
2754 state
= event
->state
;
2757 switch (screen
.state
) {
2759 if (screen
.last_x
!= 0 || screen
.last_y
!= 0) {
2760 /* Move pixmap to get a snappier feel of movement */
2761 screen
.off_x
+= x
- screen
.last_x
;
2762 screen
.off_y
+= y
- screen
.last_y
;
2764 screenRenderInfo
.lowerLeftX
-= ((x
- screen
.last_x
) / screenRenderInfo
.scaleFactorX
);
2765 screenRenderInfo
.lowerLeftY
+= ((y
- screen
.last_y
) / screenRenderInfo
.scaleFactorY
);
2766 callbacks_force_expose_event_for_screen ();
2767 callbacks_update_scrollbar_positions ();
2772 case IN_ZOOM_OUTLINE
: {
2773 if (screen
.last_x
|| screen
.last_y
)
2774 render_draw_zoom_outline(screen
.centered_outline_zoom
);
2777 render_draw_zoom_outline(screen
.centered_outline_zoom
);
2781 /* clear the previous drawn line by drawing over it */
2782 render_toggle_measure_line();
2783 callbacks_screen2board(&(screen
.measure_last_x
), &(screen
.measure_last_y
),
2785 /* screen.last_[xy] are updated to move the ruler pointers */
2788 /* draw the new line and write the new distance */
2789 render_draw_measure_distance();
2792 case IN_SELECTION_DRAG
: {
2793 if (screen
.last_x
|| screen
.last_y
)
2794 render_draw_selection_box_outline();
2797 render_draw_selection_box_outline();
2805 callbacks_update_statusbar_coordinates (x
, y
);
2806 callbacks_update_ruler_pointers ();
2808 } /* motion_notify_event */
2810 /* --------------------------------------------------------- */
2812 callbacks_drawingarea_button_press_event (GtkWidget
*widget
, GdkEventButton
*event
)
2816 switch (event
->button
) {
2818 if (screen
.tool
== POINTER
) {
2820 /* selection will only work with cairo, so do nothing if it's
2822 screen
.state
= IN_SELECTION_DRAG
;
2823 screen
.start_x
= event
->x
;
2824 screen
.start_y
= event
->y
;
2826 else if (screen
.tool
== PAN
) {
2828 screen
.state
= IN_MOVE
;
2829 screen
.last_x
= event
->x
;
2830 screen
.last_y
= event
->y
;
2832 else if (screen
.tool
== ZOOM
) {
2833 screen
.state
= IN_ZOOM_OUTLINE
;
2834 /* Zoom outline mode initiated */
2835 screen
.start_x
= event
->x
;
2836 screen
.start_y
= event
->y
;
2837 screen
.centered_outline_zoom
= event
->state
;
2839 else if (screen
.tool
== MEASURE
) {
2840 screen
.state
= IN_MEASURE
;
2841 callbacks_screen2board(&(screen
.measure_start_x
), &(screen
.measure_start_y
),
2842 event
->x
, event
->y
);
2843 screen
.measure_last_x
= screen
.measure_start_x
;
2844 screen
.measure_last_y
= screen
.measure_start_y
;
2845 /* force an expose event to clear any previous measure lines */
2846 callbacks_force_expose_event_for_screen ();
2850 screen
.state
= IN_MOVE
;
2851 screen
.last_x
= event
->x
;
2852 screen
.last_y
= event
->y
;
2853 cursor
= gdk_cursor_new(GDK_FLEUR
);
2854 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
2856 gdk_cursor_destroy(cursor
);
2859 if (screen
.tool
== POINTER
) {
2860 /* if no items are selected, try and find the item the user
2862 if (screen
.selectionInfo
.type
== GERBV_SELECTION_EMPTY
) {
2863 gint index
=callbacks_get_selected_row_index();
2865 (index
<= mainProject
->last_loaded
) &&
2866 (mainProject
->file
[index
]->isVisible
)) {
2867 render_fill_selection_buffer_from_mouse_click(event
->x
,event
->y
,index
,TRUE
);
2869 render_clear_selection_buffer ();
2870 render_refresh_rendered_image_on_screen ();
2873 /* only show the popup if we actually have something selected now */
2874 if (screen
.selectionInfo
.type
!= GERBV_SELECTION_EMPTY
)
2875 gtk_menu_popup(GTK_MENU(screen
.win
.drawWindowPopupMenu
), NULL
, NULL
, NULL
, NULL
,
2876 event
->button
, event
->time
);
2878 /* Zoom outline mode initiated */
2879 screen
.state
= IN_ZOOM_OUTLINE
;
2880 screen
.start_x
= event
->x
;
2881 screen
.start_y
= event
->y
;
2882 screen
.centered_outline_zoom
= event
->state
& GDK_SHIFT_MASK
;
2883 cursor
= gdk_cursor_new(GDK_SIZING
);
2884 gdk_window_set_cursor(GDK_WINDOW(screen
.drawing_area
->window
),
2886 gdk_cursor_destroy(cursor
);
2889 case 4 : /* Scroll wheel */
2890 render_zoom_display (ZOOM_IN_CMOUSE
, 0, event
->x
, event
->y
);
2892 case 5 : /* Scroll wheel */
2893 render_zoom_display (ZOOM_OUT_CMOUSE
, 0, event
->x
, event
->y
);
2898 callbacks_switch_to_correct_cursor ();
2902 /* --------------------------------------------------------- */
2904 callbacks_drawingarea_button_release_event (GtkWidget
*widget
, GdkEventButton
*event
)
2906 if (event
->type
== GDK_BUTTON_RELEASE
) {
2907 if (screen
.state
== IN_MOVE
) {
2910 render_refresh_rendered_image_on_screen();
2911 callbacks_switch_to_normal_tool_cursor (screen
.tool
);
2913 else if (screen
.state
== IN_ZOOM_OUTLINE
) {
2914 if ((event
->state
& GDK_SHIFT_MASK
) != 0) {
2915 render_zoom_display (ZOOM_OUT_CMOUSE
, 0, event
->x
, event
->y
);
2917 /* if the user just clicks without dragging, then simply
2918 zoom in a preset amount */
2919 else if ((abs(screen
.start_x
- event
->x
) < 4) &&
2920 (abs(screen
.start_y
- event
->y
) < 4)) {
2921 render_zoom_display (ZOOM_IN_CMOUSE
, 0, event
->x
, event
->y
);
2924 render_calculate_zoom_from_outline (widget
, event
);
2925 callbacks_switch_to_normal_tool_cursor (screen
.tool
);
2927 else if (screen
.state
== IN_SELECTION_DRAG
) {
2928 /* selection will only work with cairo, so do nothing if it's
2930 gint index
=callbacks_get_selected_row_index();
2931 /* determine if this was just a click or a box drag */
2933 (mainProject
->file
[index
]->isVisible
)) {
2934 gboolean eraseOldSelection
= TRUE
;
2936 if ((event
->state
& GDK_SHIFT_MASK
) ||
2937 (event
->state
& GDK_CONTROL_MASK
)) {
2938 eraseOldSelection
= FALSE
;
2940 if ((fabs((double)(screen
.last_x
- screen
.start_x
)) < 5) &&
2941 (fabs((double)(screen
.last_y
- screen
.start_y
)) < 5))
2942 render_fill_selection_buffer_from_mouse_click(event
->x
,event
->y
,index
,eraseOldSelection
);
2944 render_fill_selection_buffer_from_mouse_drag(event
->x
,event
->y
,
2945 screen
.start_x
,screen
.start_y
,index
,eraseOldSelection
);
2946 /* check if anything was selected */
2947 callbacks_update_selected_object_message (TRUE
);
2949 render_clear_selection_buffer ();
2950 render_refresh_rendered_image_on_screen ();
2953 screen
.last_x
= screen
.last_y
= 0;
2954 screen
.state
= NORMAL
;
2957 } /* button_release_event */
2959 /* --------------------------------------------------------- */
2961 callbacks_window_key_press_event (GtkWidget
*widget
, GdkEventKey
*event
)
2963 switch(event
->keyval
) {
2965 if (screen
.tool
== POINTER
) {
2966 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
2967 "No objects are currently selected");
2968 callbacks_update_statusbar();
2969 render_clear_selection_buffer ();
2976 /* Escape may be used to abort outline zoom and just plain repaint */
2977 if (event
->keyval
== GDK_Escape
) {
2978 screen
.state
= NORMAL
;
2979 render_refresh_rendered_image_on_screen();
2983 } /* key_press_event */
2985 /* --------------------------------------------------------- */
2987 callbacks_window_key_release_event (GtkWidget
*widget
, GdkEventKey
*event
)
2990 } /* key_release_event */
2992 /* --------------------------------------------------------- */
2995 callbacks_window_scroll_event(GtkWidget
*widget
, GdkEventScroll
*event
)
2997 switch (event
->direction
) {
2999 render_zoom_display (ZOOM_IN_CMOUSE
, 0, event
->x
, event
->y
);
3001 case GDK_SCROLL_DOWN
:
3002 render_zoom_display (ZOOM_OUT_CMOUSE
, 0, event
->x
, event
->y
);
3004 case GDK_SCROLL_LEFT
:
3006 case GDK_SCROLL_RIGHT
:
3012 } /* scroll_event */
3015 /* ------------------------------------------------------------------ */
3016 /** Displays additional information in the statusbar.
3017 The Statusbar is divided into three sections:\n
3018 statusbar.coordstr for coords\n
3019 statusbar.diststr for displaying measured distances or the designator
3020 (right click on a graphically marked and also actively selected part)\n
3021 statusbar.msg for e.g. showing progress of actions*/
3023 callbacks_update_statusbar(void)
3025 if ((screen
.statusbar
.coordstr
!= NULL
)&&(GTK_IS_LABEL(screen
.win
.statusMessageLeft
))) {
3026 gtk_label_set_text(GTK_LABEL(screen
.win
.statusMessageLeft
), screen
.statusbar
.coordstr
);
3028 if ((screen
.statusbar
.diststr
!= NULL
)&&(GTK_IS_LABEL(screen
.win
.statusMessageRight
))) {
3029 gtk_label_set_markup(GTK_LABEL(screen
.win
.statusMessageRight
), screen
.statusbar
.diststr
);
3033 /* --------------------------------------------------------- */
3035 callbacks_update_statusbar_measured_distance (gdouble dx
, gdouble dy
){
3036 gdouble delta
= sqrt(dx
*dx
+ dy
*dy
);
3038 if (screen
.unit
== GERBV_MILS
) {
3039 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
3040 "Measured distance: %8.2f mils (%8.2f x, %8.2f y)",
3041 COORD2MILS(delta
), COORD2MILS(dx
), COORD2MILS(dy
));
3043 else if (screen
.unit
== GERBV_MMS
) {
3044 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
3045 "Measured distance: %8.3f mms (%8.3f x, %8.3f y)",
3046 COORD2MMS(delta
), COORD2MMS(dx
), COORD2MMS(dy
));
3049 snprintf(screen
.statusbar
.diststr
, MAX_DISTLEN
,
3050 "Measured distance: %4.5f inches (%4.5f x, %4.5f y)",
3051 COORD2MILS(delta
) / 1000.0, COORD2MILS(dx
) / 1000.0,
3052 COORD2MILS(dy
) / 1000.0);
3054 callbacks_update_statusbar();
3057 /* --------------------------------------------------------- */
3059 callbacks_sidepane_render_type_combo_box_changed (GtkComboBox
*widget
, gpointer user_data
) {
3060 int activeRow
= gtk_combo_box_get_active (widget
);
3062 dprintf ("%s(): activeRow = %d\n", __FUNCTION__
, activeRow
);
3063 screenRenderInfo
.renderType
= activeRow
;
3065 render_refresh_rendered_image_on_screen();
3068 /* --------------------------------------------------------- */
3070 callbacks_statusbar_unit_combo_box_changed (GtkComboBox
*widget
, gpointer user_data
) {
3071 int activeRow
= gtk_combo_box_get_active (widget
);
3073 if (activeRow
>= 0) {
3074 screen
.unit
= activeRow
;
3076 callbacks_update_ruler_scales();
3077 callbacks_update_statusbar_coordinates (screen
.last_x
, screen
.last_y
);
3079 if (screen
.tool
== MEASURE
)
3080 callbacks_update_statusbar_measured_distance (screen
.win
.lastMeasuredX
,
3081 screen
.win
.lastMeasuredY
);
3084 /* --------------------------------------------------------- */
3086 callbacks_clear_messages_button_clicked (GtkButton
*button
, gpointer user_data
) {
3087 GtkTextBuffer
*textbuffer
;
3088 GtkTextIter start
, end
;
3090 textbuffer
= gtk_text_view_get_buffer((GtkTextView
*)screen
.win
.messageTextView
);
3091 gtk_text_buffer_get_start_iter(textbuffer
, &start
);
3092 gtk_text_buffer_get_end_iter(textbuffer
, &end
);
3093 gtk_text_buffer_delete (textbuffer
, &start
, &end
);
3096 /* --------------------------------------------------------- */
3098 callbacks_handle_log_messages(const gchar
*log_domain
, GLogLevelFlags log_level
,
3099 const gchar
*message
, gpointer user_data
) {
3100 GtkTextBuffer
*textbuffer
= NULL
;
3103 GtkTextMark
*StartMark
= NULL
, *StopMark
= NULL
;
3104 GtkTextIter StartIter
, StopIter
;
3106 if (!screen
.win
.messageTextView
)
3109 textbuffer
= gtk_text_view_get_buffer((GtkTextView
*)screen
.win
.messageTextView
);
3111 /* create a mark for the end of the text. */
3112 gtk_text_buffer_get_end_iter(textbuffer
, &iter
);
3114 /* get the current end position of the text (it will be the
3115 start of the new text. */
3116 StartMark
= gtk_text_buffer_create_mark(textbuffer
,
3117 "NewTextStart", &iter
, TRUE
);
3119 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3121 /* the tag does not exist: create it and let them exist in the tag table.*/
3123 tag
= gtk_text_buffer_create_tag(textbuffer
, "black_foreground",
3124 "foreground", "black", NULL
);
3125 tag
= gtk_text_buffer_create_tag(textbuffer
, "blue_foreground",
3126 "foreground", "blue", NULL
);
3127 tag
= gtk_text_buffer_create_tag(textbuffer
, "red_foreground",
3128 "foreground", "red", NULL
);
3129 tag
= gtk_text_buffer_create_tag(textbuffer
, "darkred_foreground",
3130 "foreground", "darkred", NULL
);
3131 tag
= gtk_text_buffer_create_tag(textbuffer
, "darkblue_foreground",
3132 "foreground", "darkblue", NULL
);
3133 tag
= gtk_text_buffer_create_tag (textbuffer
, "darkgreen_foreground",
3134 "foreground", "darkgreen", NULL
);
3135 tag
= gtk_text_buffer_create_tag (textbuffer
,
3136 "saddlebrown_foreground",
3137 "foreground", "saddlebrown", NULL
);
3141 * See rgb.txt for the color names definition
3142 * (on my PC it is on /usr/X11R6/lib/X11/rgb.txt)
3144 switch (log_level
& G_LOG_LEVEL_MASK
) {
3145 case G_LOG_LEVEL_ERROR
:
3146 /* a message of this kind aborts the application calling abort() */
3147 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3149 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen
.win
.sidepane_notebook
), 1);
3150 gtk_widget_show(screen
.win
.sidepane_notebook
);
3152 case G_LOG_LEVEL_CRITICAL
:
3153 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3155 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen
.win
.sidepane_notebook
), 1);
3156 gtk_widget_show(screen
.win
.sidepane_notebook
);
3158 case G_LOG_LEVEL_WARNING
:
3159 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3160 "darkred_foreground");
3161 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen
.win
.sidepane_notebook
), 1);
3162 gtk_widget_show(screen
.win
.sidepane_notebook
);
3164 case G_LOG_LEVEL_MESSAGE
:
3165 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3166 "darkblue_foreground");
3167 gtk_notebook_set_current_page(GTK_NOTEBOOK(screen
.win
.sidepane_notebook
), 1);
3168 gtk_widget_show(screen
.win
.sidepane_notebook
);
3170 case G_LOG_LEVEL_INFO
:
3171 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3172 "darkgreen_foreground");
3174 case G_LOG_LEVEL_DEBUG
:
3175 tag
= gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(textbuffer
),
3176 "saddlebrown_foreground");
3179 tag
= gtk_text_tag_table_lookup (gtk_text_buffer_get_tag_table(textbuffer
),
3180 "black_foreground");
3185 * Fatal aborts application. We will try to get the message out anyhow.
3187 if (log_level
& G_LOG_FLAG_FATAL
)
3188 fprintf(stderr
, "Fatal error : %s\n", message
);
3190 gtk_text_buffer_insert(textbuffer
, &iter
, message
, -1);
3192 gtk_text_buffer_get_end_iter(textbuffer
, &iter
);
3194 StopMark
= gtk_text_buffer_create_mark(textbuffer
,
3195 "NewTextStop", &iter
, TRUE
);
3197 gtk_text_buffer_get_iter_at_mark(textbuffer
, &StartIter
, StartMark
);
3198 gtk_text_buffer_get_iter_at_mark(textbuffer
, &StopIter
, StopMark
);
3200 gtk_text_buffer_apply_tag(textbuffer
, tag
, &StartIter
, &StopIter
);
3203 /* --------------------------------------------------------- */
3204 void callbacks_force_expose_event_for_screen (void){
3206 GdkRectangle update_rect
;
3210 update_rect
.width
= screenRenderInfo
.displayWidth
;
3211 update_rect
.height
= screenRenderInfo
.displayHeight
;
3213 /* Calls expose_event */
3214 gdk_window_invalidate_rect (screen
.drawing_area
->window
, &update_rect
, FALSE
);
3216 /* update other gui things that could have changed */
3217 callbacks_update_ruler_scales();
3218 callbacks_update_scrollbar_limits();
3219 callbacks_update_scrollbar_positions();