1 /* Lepton EDA Schematic Capture
2  * Copyright (C) 1998-2010 Ales Hvezda
3  * Copyright (C) 1998-2016 gEDA Contributors
4  * Copyright (C) 2017-2021 Lepton EDA Contributors
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 #include <config.h>
21 
22 #include "gschem.h"
23 
24 static void
25 handle_undo (GschemToplevel *w_current);
26 
27 static void
28 notify_options (GschemToplevel *w_current);
29 
30 static void
31 renderer_load_font (EdaRenderer* renderer);
32 
33 
34 /* A list of common values for the dash length drop down menu
35  */
36 static const char *routine_dash_length[] =
37 {
38    "50",
39    "75",
40    "100",
41    "125",
42    "150"
43 };
44 
45 #define ROUTINE_DASH_LENGTH_COUNT (sizeof(routine_dash_length)/sizeof(char*))
46 
47 
48 
49 /* A list of common values for the dash space drop down menu
50  */
51 static const char *routine_dash_space[] =
52 {
53    "50",
54    "75",
55    "100",
56    "125",
57    "150"
58 };
59 
60 #define ROUTINE_DASH_SPACE_COUNT (sizeof(routine_dash_space)/sizeof(char*))
61 
62 
63 
64 /* A list of common values for the fill angle drop down menu
65  */
66 static const char *routine_fill_angle[] =
67 {
68    "0",
69    "30",
70    "45",
71    "60",
72    "90",
73    "120",
74    "135",
75    "150"
76 };
77 
78 #define ROUTINE_FILL_ANGLE_COUNT (sizeof(routine_fill_angle)/sizeof(char*))
79 
80 
81 
82 /* A list of common values for the fill pitch drop down menu
83  */
84 static const char *routine_fill_pitch[] =
85 {
86    "50",
87    "100",
88    "150",
89    "200"
90 };
91 
92 #define ROUTINE_FILL_PITCH_COUNT (sizeof(routine_fill_pitch)/sizeof(char*))
93 
94 
95 
96 /* A list of common values for the fill line width drop down menu
97  */
98 static const char *routine_fill_width[] =
99 {
100    "0",
101    "5",
102    "10",
103    "15",
104    "20"
105 };
106 
107 #define ROUTINE_FILL_WIDTH_COUNT (sizeof(routine_fill_width)/sizeof(char*))
108 
109 
110 
111 /* A list of common values for the line width drop down menu
112  */
113 static const char *routine_line_width[] =
114 {
115    "0",
116    "5",
117    "10",
118    "15",
119    "20"
120 };
121 
122 #define ROUTINE_LINE_WIDTH_COUNT (sizeof(routine_line_width)/sizeof(char*))
123 
124 
125 
126 /* A list of common sizes for the drop down menu
127  */
128 static const char *routine_text_size[] =
129 {
130    "8",
131    "9",
132    "10",
133    "11",
134    "12",
135    "14",
136    "16",
137    "18",
138    "20",
139    "22",
140    "24",
141    "26"
142 };
143 
144 #define ROUTINE_TEXT_SIZE_COUNT (sizeof(routine_text_size)/sizeof(char*))
145 
146 
147 
gschem_toplevel_new()148 GschemToplevel *gschem_toplevel_new ()
149 {
150   GschemToplevel *w_current;
151 
152   w_current = g_new0 (GschemToplevel, 1);
153 
154   w_current->toplevel = NULL;
155 
156   w_current->dont_invalidate = FALSE;
157 
158   /* ------------------- */
159   /* main window widgets */
160   /* ------------------- */
161   w_current->main_window  = NULL;
162   w_current->drawing_area = NULL;
163   w_current->menubar      = NULL;
164   w_current->popup_menu   = NULL;
165   w_current->find_text_widget = NULL;
166   w_current->macro_widget  = NULL;
167   w_current->bottom_widget = NULL;
168   w_current->translate_widget = NULL;
169 
170   w_current->toolbar_select = NULL;
171   w_current->toolbar_net    = NULL;
172   w_current->toolbar_bus    = NULL;
173 
174 
175   /* tabbed GUI: notebook: */
176   w_current->xtabs_nbook = NULL;
177 
178   /* tabbed GUI: data structures: */
179   w_current->xtabs_info_list = NULL;
180 
181 
182   /* docks: */
183   w_current->bottom_notebook = NULL;
184   w_current->right_notebook  = NULL;
185 
186   /* bottom dock: widgets: */
187   w_current->find_text_state = NULL;
188   w_current->log_widget      = NULL;
189 
190   /* right dock: widgets: */
191   w_current->object_properties = NULL;
192   w_current->text_properties   = NULL;
193   w_current->options_widget    = NULL;
194 
195   /* color scheme editor widget: */
196   w_current->color_edit_widget = NULL;
197 
198   /* font selection widget: */
199   w_current->font_select_widget = NULL;
200 
201   /* page selection widget: */
202   w_current->page_select_widget = NULL;
203 
204   /* dialogs for widgets */
205   w_current->options_widget_dialog    = NULL;
206   w_current->text_properties_dialog   = NULL;
207   w_current->object_properties_dialog = NULL;
208   w_current->log_widget_dialog        = NULL;
209   w_current->find_text_state_dialog   = NULL;
210   w_current->color_edit_dialog        = NULL;
211   w_current->font_select_dialog       = NULL;
212   w_current->page_select_dialog       = NULL;
213 
214 
215   w_current->keyaccel_string = NULL;
216   w_current->keyaccel_string_source_id = FALSE;
217 
218   /* ------------ */
219   /* Dialog boxes */
220   /* ------------ */
221   w_current->cswindow     = NULL;
222   w_current->tiwindow     = NULL;
223   w_current->sewindow     = NULL;
224   w_current->aawindow     = NULL;
225   w_current->mawindow     = NULL;
226   w_current->aewindow     = NULL;
227   w_current->hkwindow     = NULL;
228   w_current->cowindow     = NULL;
229   w_current->coord_world  = NULL;
230   w_current->coord_screen = NULL;
231 
232   /* ------------------------------- */
233   /* Manager for recently used files */
234   /* ------------------------------- */
235   w_current->recent_manager = NULL;
236 
237   /* -------------------------------------- */
238   /* Models for widgets inside dialog boxes */
239   /* -------------------------------------- */
240   w_current->dash_length_list_store = NULL;
241   w_current->dash_space_list_store = NULL;
242   w_current->fill_angle_list_store = NULL;
243   w_current->fill_pitch_list_store = NULL;
244   w_current->fill_width_list_store = NULL;
245   w_current->line_width_list_store = NULL;
246   w_current->text_size_list_store = NULL;
247 
248   /* ----------------------------------------- */
249   /* An adapter for manipulating the selection */
250   /* ----------------------------------------- */
251   w_current->selection_adapter = NULL;
252 
253   /* ----------------- */
254   /* Picture placement */
255   /* ----------------- */
256   w_current->current_pixbuf = NULL;
257   w_current->pixbuf_filename = NULL;
258   w_current->pixbuf_wh_ratio = 0;
259 
260   /* ------------- */
261   /* Drawing state */
262   /* ------------- */
263   w_current->renderer = EDA_RENDERER (g_object_new (EDA_TYPE_RENDERER, NULL));
264   renderer_load_font (w_current->renderer);
265 
266   w_current->first_wx = -1;
267   w_current->first_wy = -1;
268   w_current->second_wx = -1;
269   w_current->second_wy = -1;
270   w_current->third_wx = -1;
271   w_current->third_wy = -1;
272   w_current->distance = 0;
273   w_current->magnetic_wx = -1;
274   w_current->magnetic_wy = -1;
275   w_current->inside_action = 0;
276   w_current->rubber_visible = 0;
277   w_current->net_direction = 0;
278   w_current->which_grip = -1;
279   w_current->which_object = NULL;
280   w_current->temp_path = NULL;
281   w_current->pathcontrol = TRUE;
282 
283   /* ------------------ */
284   /* Rubberbanding nets */
285   /* ------------------ */
286   w_current->stretch_list = NULL;
287 
288   /* --------------------- */
289   /* Gschem internal state */
290   /* --------------------- */
291   w_current->num_untitled = 0;
292   w_current->event_state = SELECT;
293   w_current->min_zoom = 0;
294   w_current->max_zoom = 8;
295   w_current->drawbounding_action_mode = FREE;
296   w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
297   w_current->CONTROLKEY = 0;
298   w_current->SHIFTKEY   = 0;
299   w_current->ALTKEY     = 0;
300   w_current->buffer_number = 0;
301   w_current->clipboard_buffer = NULL;
302 
303   /* ------------------ */
304   /* rc/user parameters */
305   /* ------------------ */
306   w_current->options = gschem_options_new();
307 
308   g_signal_connect_swapped (G_OBJECT (w_current->options),
309                             "notify",
310                             G_CALLBACK (notify_options),
311                             w_current);
312 
313   w_current->text_caps = 0;
314   w_current->text_size = 0;
315 
316   w_current->zoom_with_pan = 0;
317   w_current->actionfeedback_mode = OUTLINE;
318   w_current->net_direction_mode = TRUE;
319   w_current->net_selection_mode = 0;
320   w_current->net_selection_state = 0;
321   w_current->embed_component = 0;
322   w_current->include_component = 0;
323   w_current->scrollbars_flag = 0;
324   w_current->third_button = 0;
325   w_current->third_button_cancel = TRUE;
326   w_current->middle_button = 0;
327   w_current->file_preview = 0;
328   w_current->enforce_hierarchy = 0;
329   w_current->fast_mousepan = 0;
330   w_current->continue_component_place = 0;
331   w_current->undo_levels = 0;
332   w_current->undo_control = 0;
333   w_current->undo_type = 0;
334   w_current->undo_panzoom = 0;
335   w_current->draw_grips = 0;
336   w_current->warp_cursor = 0;
337   w_current->toolbars = 0;
338   w_current->handleboxes = 0;
339   w_current->bus_ripper_size = 0;
340   w_current->bus_ripper_type = 0;
341   w_current->bus_ripper_rotation = 0;
342   w_current->grid_mode = GRID_MODE_NONE;
343   w_current->dots_grid_fixed_threshold = 10;
344   w_current->dots_grid_dot_size = 1;
345   w_current->dots_grid_mode = DOTS_GRID_VARIABLE_MODE;
346   w_current->mesh_grid_display_threshold = 3;
347   w_current->mousepan_gain = 5;
348   w_current->keyboardpan_gain = 10;
349   w_current->select_slack_pixels = 4;
350   w_current->zoom_gain = 20;
351   w_current->scrollpan_steps = 8;
352 
353   w_current->bus_ripper_symname = NULL;
354 
355   w_current->smob = SCM_UNDEFINED;
356 
357   return w_current;
358 }
359 
360 
361 
362 /*! \brief Free the gschem toplevel
363  *
364  *  \param [in] w_current The gschem toplevel
365  */
366 void
gschem_toplevel_free(GschemToplevel * w_current)367 gschem_toplevel_free (GschemToplevel *w_current)
368 {
369   if (w_current->toplevel != NULL) {
370     s_toplevel_delete (w_current->toplevel);
371     w_current->toplevel = NULL;
372   }
373 
374   if (w_current->dash_length_list_store != NULL) {
375     g_object_unref (w_current->dash_length_list_store);
376     w_current->dash_length_list_store = NULL;
377   }
378 
379   if (w_current->dash_space_list_store != NULL) {
380     g_object_unref (w_current->dash_space_list_store);
381     w_current->dash_space_list_store = NULL;
382   }
383 
384   if (w_current->fill_angle_list_store != NULL) {
385     g_object_unref (w_current->fill_angle_list_store);
386     w_current->fill_angle_list_store = NULL;
387   }
388 
389   if (w_current->fill_pitch_list_store != NULL) {
390     g_object_unref (w_current->fill_pitch_list_store);
391     w_current->fill_pitch_list_store = NULL;
392   }
393 
394   if (w_current->fill_width_list_store != NULL) {
395     g_object_unref (w_current->fill_width_list_store);
396     w_current->fill_width_list_store = NULL;
397   }
398 
399   if (w_current->line_width_list_store != NULL) {
400     g_object_unref (w_current->line_width_list_store);
401     w_current->line_width_list_store = NULL;
402   }
403 
404   if (w_current->text_size_list_store != NULL) {
405     g_object_unref (w_current->text_size_list_store);
406     w_current->text_size_list_store = NULL;
407   }
408 
409   if (w_current->options != NULL) {
410     g_object_unref (w_current->options);
411     w_current->options = NULL;
412   }
413 
414   if (w_current->renderer != NULL) {
415     g_object_unref (w_current->renderer);
416     w_current->renderer = NULL;
417   }
418 
419   g_free (w_current);
420 }
421 
422 
423 
424 /*! \brief Get the selection adapter
425  *
426  *  \param [in] w_current The current gschem toplevel
427  *  \return The selection adapter
428  */
429 GschemPageView*
gschem_toplevel_get_current_page_view(GschemToplevel * w_current)430 gschem_toplevel_get_current_page_view (GschemToplevel *w_current)
431 {
432   g_return_val_if_fail (w_current != NULL, NULL);
433 
434   return GSCHEM_PAGE_VIEW (w_current->drawing_area);
435 }
436 
437 
438 
439 /*! \brief Get the selection adapter
440  *
441  *  \param [in] w_current The current gschem toplevel
442  *  \return The selection adapter
443  */
444 GschemSelectionAdapter*
gschem_toplevel_get_selection_adapter(GschemToplevel * w_current)445 gschem_toplevel_get_selection_adapter (GschemToplevel *w_current)
446 {
447   g_return_val_if_fail (w_current != NULL, NULL);
448 
449   if (w_current->selection_adapter == NULL) {
450     w_current->selection_adapter = gschem_selection_adapter_new ();
451 
452     g_signal_connect_swapped (w_current->selection_adapter,
453                               "handle-undo",
454                               G_CALLBACK (handle_undo),
455                               w_current);
456 
457 
458     gschem_selection_adapter_set_toplevel (w_current->selection_adapter, w_current->toplevel);
459 
460     LeptonPage *active_page = schematic_window_get_active_page (w_current);
461     if (active_page != NULL) {
462       gschem_selection_adapter_set_selection (w_current->selection_adapter,
463                                               active_page->selection_list);
464     } else {
465       gschem_selection_adapter_set_selection (w_current->selection_adapter,
466                                               NULL);
467     }
468   }
469 
470   return w_current->selection_adapter;
471 }
472 
473 
474 
475 /*! \brief Get a list of the commonly used dash lengths
476  *
477  *  \param [in] w_current The current gschem toplevel
478  *  \return A list of the commonly used dash_lengths
479  */
480 GtkListStore*
gschem_toplevel_get_dash_length_list_store(GschemToplevel * w_current)481 gschem_toplevel_get_dash_length_list_store (GschemToplevel *w_current)
482 {
483   g_return_val_if_fail (w_current != NULL, NULL);
484 
485   if (w_current->dash_length_list_store == NULL) {
486     w_current->dash_length_list_store = x_integerls_new_with_values (routine_dash_length, ROUTINE_DASH_LENGTH_COUNT);
487   }
488 
489   return w_current->dash_length_list_store;
490 }
491 
492 
493 
494 /*! \brief Get a list of the commonly used dash spacing
495  *
496  *  \param [in] w_current The current gschem toplevel
497  *  \return A list of the commonly used dash spacing
498  */
499 GtkListStore*
gschem_toplevel_get_dash_space_list_store(GschemToplevel * w_current)500 gschem_toplevel_get_dash_space_list_store (GschemToplevel *w_current)
501 {
502   g_return_val_if_fail (w_current != NULL, NULL);
503 
504   if (w_current->dash_space_list_store == NULL) {
505     w_current->dash_space_list_store = x_integerls_new_with_values (routine_dash_space, ROUTINE_DASH_SPACE_COUNT);
506   }
507 
508   return w_current->dash_space_list_store;
509 }
510 
511 
512 
513 /*! \brief Get a list of the commonly used fill angles
514  *
515  *  \param [in] w_current The current gschem toplevel
516  *  \return A list of the commonly used fill angles
517  */
518 GtkListStore*
gschem_toplevel_get_fill_angle_list_store(GschemToplevel * w_current)519 gschem_toplevel_get_fill_angle_list_store (GschemToplevel *w_current)
520 {
521   g_return_val_if_fail (w_current != NULL, NULL);
522 
523   if (w_current->fill_angle_list_store == NULL) {
524     w_current->fill_angle_list_store = x_integerls_new_with_values (routine_fill_angle, ROUTINE_FILL_ANGLE_COUNT);
525   }
526 
527   return w_current->fill_angle_list_store;
528 }
529 
530 
531 
532 /*! \brief Get a list of the commonly used fill pitches
533  *
534  *  \param [in] w_current The current gschem toplevel
535  *  \return A list of the commonly used fill pitches
536  */
537 GtkListStore*
gschem_toplevel_get_fill_pitch_list_store(GschemToplevel * w_current)538 gschem_toplevel_get_fill_pitch_list_store (GschemToplevel *w_current)
539 {
540   g_return_val_if_fail (w_current != NULL, NULL);
541 
542   if (w_current->fill_pitch_list_store == NULL) {
543     w_current->fill_pitch_list_store = x_integerls_new_with_values (routine_fill_pitch, ROUTINE_FILL_PITCH_COUNT);
544   }
545 
546   return w_current->fill_pitch_list_store;
547 }
548 
549 
550 
551 /*! \brief Get a list of the commonly used fill line widths
552  *
553  *  \param [in] w_current The current gschem toplevel
554  *  \return A list of the commonly used fill line widths
555  */
556 GtkListStore*
gschem_toplevel_get_fill_width_list_store(GschemToplevel * w_current)557 gschem_toplevel_get_fill_width_list_store (GschemToplevel *w_current)
558 {
559   g_return_val_if_fail (w_current != NULL, NULL);
560 
561   if (w_current->fill_width_list_store == NULL) {
562     w_current->fill_width_list_store = x_integerls_new_with_values (routine_fill_width, ROUTINE_FILL_WIDTH_COUNT);
563   }
564 
565   return w_current->fill_width_list_store;
566 }
567 
568 
569 
570 /*! \brief Get a list of the commonly used line widths
571  *
572  *  \param [in] w_current The current gschem toplevel
573  *  \return A list of the commonly used line widths
574  */
575 GtkListStore*
gschem_toplevel_get_line_width_list_store(GschemToplevel * w_current)576 gschem_toplevel_get_line_width_list_store (GschemToplevel *w_current)
577 {
578   g_return_val_if_fail (w_current != NULL, NULL);
579 
580   if (w_current->line_width_list_store == NULL) {
581     w_current->line_width_list_store = x_integerls_new_with_values (routine_line_width, ROUTINE_LINE_WIDTH_COUNT);
582   }
583 
584   return w_current->line_width_list_store;
585 }
586 
587 
588 
589 /*! \brief Get a list of the commonly used text sizes
590  *
591  *  \param [in] w_current The current gschem toplevel
592  *  \return A list of the commonly used text sizes
593  */
594 GtkListStore*
gschem_toplevel_get_text_size_list_store(GschemToplevel * w_current)595 gschem_toplevel_get_text_size_list_store (GschemToplevel *w_current)
596 {
597   g_return_val_if_fail (w_current != NULL, NULL);
598 
599   if (w_current->text_size_list_store == NULL)
600   {
601     gchar* cwd = g_get_current_dir();
602     EdaConfig* ctx = eda_config_get_context_for_path (cwd);
603     g_free (cwd);
604 
605     gsize len = 0;
606     gchar** vals = eda_config_get_string_list (ctx,
607                                                "schematic.gui",
608                                                "text-sizes",
609                                                &len,
610                                                NULL);
611 
612     if (vals != NULL && len > 0)
613     {
614       w_current->text_size_list_store = x_integerls_new_with_values ((const gchar**) vals, len);
615       g_strfreev (vals);
616 
617     }
618     else
619     {
620       w_current->text_size_list_store = x_integerls_new_with_values (routine_text_size, ROUTINE_TEXT_SIZE_COUNT);
621     }
622   }
623 
624   return w_current->text_size_list_store;
625 }
626 
627 
628 
629 /*! \brief Get the libgeda toplevel for this gschem toplevel
630  *
631  *  \param [in] w_current This gschem toplevel
632  *  \return The libgeda toplevel
633  */
634 LeptonToplevel*
gschem_toplevel_get_toplevel(GschemToplevel * w_current)635 gschem_toplevel_get_toplevel (GschemToplevel *w_current)
636 {
637   g_return_val_if_fail (w_current != NULL, NULL);
638 
639   return w_current->toplevel;
640 }
641 
642 
643 
644 /*! \brief Signal handler for a notify::page signal
645  *
646  *  \param [in] page_view The GschemPageView signal source
647  *  \param [in] w_current The current gschem toplevel
648  */
649 void
gschem_toplevel_notify_page_callback(GschemPageView * page_view,GParamSpec * pspec,GschemToplevel * w_current)650 gschem_toplevel_notify_page_callback (GschemPageView *page_view, GParamSpec *pspec, GschemToplevel *w_current)
651 {
652   g_return_if_fail (w_current != NULL);
653 
654   gschem_toplevel_page_changed (w_current);
655 }
656 
657 
658 
659 /*! \brief Temporary function to notify dialogs of a page change
660  *
661  *  This function is temporary until the toplevel can emit a
662  *  "notify::page_current" signal.
663  *
664  *  \param [in] w_current The current gschem toplevel
665  */
666 void
gschem_toplevel_page_changed(GschemToplevel * w_current)667 gschem_toplevel_page_changed (GschemToplevel *w_current)
668 {
669   g_return_if_fail (w_current != NULL);
670 
671   LeptonPage *active_page = schematic_window_get_active_page (w_current);
672   if ((w_current->selection_adapter != NULL) && (active_page != NULL))
673   {
674     gschem_selection_adapter_set_selection (w_current->selection_adapter,
675                                             active_page->selection_list);
676   }
677 }
678 
679 
680 
681 /*! \brief Temporary function to notify of page content change
682  *
683  *  This function is temporary until library functions can emit signals.
684  *
685  *  \param [in] w_current The current gschem toplevel.
686  *  \param [in] page      The page that underwent changes.
687  */
688 void
gschem_toplevel_page_content_changed(GschemToplevel * w_current,LeptonPage * page)689 gschem_toplevel_page_content_changed (GschemToplevel *w_current,
690                                       LeptonPage *page)
691 {
692   g_return_if_fail (page != NULL);
693   g_return_if_fail (w_current != NULL);
694 
695   lepton_page_set_changed (page, 1);
696 
697   page_select_widget_update (w_current);
698 }
699 
700 
701 /*! \brief Temp function to notify of active page content change.
702  *
703  *  This function is temporary until library functions can emit
704  *  signals.
705  *
706  *  \param [in] w_current The current schematic window.
707  */
708 void
schematic_window_active_page_changed(GschemToplevel * w_current)709 schematic_window_active_page_changed (GschemToplevel *w_current)
710 {
711   g_return_if_fail (w_current != NULL);
712   LeptonPage *active_page = schematic_window_get_active_page (w_current);
713 
714   gschem_toplevel_page_content_changed (w_current, active_page);
715 }
716 
717 
718 /*! \brief Set the libgeda toplevel for this gschem toplevel
719  *
720  *  \param [in] w_current This gschem toplevel
721  *  \param [in] toplevel The libgeda toplevel
722  */
723 void
gschem_toplevel_set_toplevel(GschemToplevel * w_current,LeptonToplevel * toplevel)724 gschem_toplevel_set_toplevel (GschemToplevel *w_current,
725                               LeptonToplevel *toplevel)
726 {
727   g_return_if_fail (w_current != NULL);
728 
729   w_current->toplevel = toplevel;
730 }
731 
732 /*! \brief Allow the undo manager to process changes
733  *
734  *  \param [in] w_current
735  */
736 static void
handle_undo(GschemToplevel * w_current)737 handle_undo (GschemToplevel *w_current)
738 {
739   g_return_if_fail (w_current != NULL);
740 
741   schematic_window_active_page_changed (w_current);
742   o_undo_savestate_old (w_current, UNDO_ALL);
743 }
744 
745 
746 
747 /*! \brief Property change notification for any/all settings
748  *
749  *  \param [in] w_current
750  */
751 static void
notify_options(GschemToplevel * w_current)752 notify_options (GschemToplevel *w_current)
753 {
754   g_return_if_fail (w_current != NULL);
755 
756   /* Events can occur before the drawing area is created */
757 
758   if (w_current->drawing_area != NULL)
759   {
760     i_update_grid_info (w_current);
761     gschem_page_view_invalidate_all (gschem_toplevel_get_current_page_view (w_current));
762   }
763 }
764 
765 
766 
767 /*! \brief Read configuration, set the font to render schematics
768  *
769  *  \param renderer A pointer to EdaRenderer to set font for
770  */
771 static void
renderer_load_font(EdaRenderer * renderer)772 renderer_load_font (EdaRenderer* renderer)
773 {
774   gchar*     cwd = g_get_current_dir();
775   EdaConfig* cfg = eda_config_get_context_for_path (cwd);
776   g_free (cwd);
777 
778   if (cfg != NULL)
779   {
780     GError* err = NULL;
781     gchar* font = eda_config_get_string (cfg,
782                                          "schematic.gui",
783                                          "font",
784                                           &err);
785 
786     if (font != NULL && strlen(font) > 0)
787     {
788       g_object_set (renderer, "font-name", font, NULL);
789       g_free (font);
790     }
791 
792     g_clear_error (&err);
793   }
794 }
795 
796 
797 /*! \brief Get visibility of hidden text
798  *
799  *  \param [in] w_current The current gschem toplevel
800  *  \return TRUE if hidden text should be visible, otherwise FALSE
801  */
802 gboolean
gschem_toplevel_get_show_hidden_text(GschemToplevel * w_current)803 gschem_toplevel_get_show_hidden_text (GschemToplevel *w_current)
804 {
805   g_return_val_if_fail (w_current != NULL, FALSE);
806 
807   GschemPageView *view = GSCHEM_PAGE_VIEW (w_current->drawing_area);
808 
809   /* On early stage, page view may not be created yet, so just
810      return FALSE in such cases. */
811   return (view == NULL) ? FALSE : gschem_page_view_get_show_hidden_text (view);
812 }
813 
814 
815 /*! \brief Get the active page for this schematic window.
816  *
817  *  \param [in] w_current The schematic window.
818  *  \return The currently active page.
819  */
820 LeptonPage*
schematic_window_get_active_page(GschemToplevel * w_current)821 schematic_window_get_active_page (GschemToplevel *w_current)
822 {
823   g_return_val_if_fail (w_current != NULL, NULL);
824 
825   LeptonToplevel *toplevel = gschem_toplevel_get_toplevel (w_current);
826   g_return_val_if_fail (toplevel != NULL, NULL);
827 
828   return toplevel->page_current;
829 }
830