1 /* gEDA - GPL Electronic Design Automation
2  * gschem - gEDA Schematic Capture
3  * Copyright (C) 1998-2010 Ales Hvezda
4  * Copyright (C) 1998-2011 gEDA Contributors (see ChangeLog for details)
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 <stdio.h>
23 #ifdef HAVE_STRING_H
24 #include <string.h>
25 #endif
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 
30 #include "gschem.h"
31 
32 #ifdef HAVE_LIBDMALLOC
33 #include <dmalloc.h>
34 #endif
35 
36 /*! \brief */
37 #define DELIMITERS ", "
38 
39 /*! \todo Finish function documentation!!!
40  *  \brief
41  *  \par Function Description
42  *
43  */
44 /* every i_callback functions have the same footprint */
45 #define DEFINE_I_CALLBACK(name)				\
46 	void i_callback_ ## name(gpointer data,		\
47 			         guint callback_action,	\
48 			         GtkWidget *widget)
49 
50 /*! \section callback-intro Callback Functions
51  * right now, all callbacks except for the ones on the File menu have
52  * the middle button shortcut. Let me (Ales) know if we should also
53  * shortcut the File button
54  */
55 
56 /*! \section file-menu File Menu Callback Functions */
57 /*! \todo Finish function documentation!!!
58  *  \brief
59  *  \par Function Description
60  *
61  *  \note
62  *  don't use the widget parameter on this function, or do some checking...
63  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
64  *  \todo This should be renamed to page_new perhaps...
65  */
DEFINE_I_CALLBACK(file_new)66 DEFINE_I_CALLBACK(file_new)
67 {
68   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*)data;
69   PAGE *page;
70 
71   g_return_if_fail (w_current != NULL);
72 
73   /* create a new page */
74   page = x_window_open_page (w_current, NULL);
75   x_window_set_current_page (w_current, page);
76   s_log_message (_("New page created [%s]\n"), page->page_filename);
77 }
78 
79 /*! \todo Finish function documentation!!!
80  *  \brief
81  *  \par Function Description
82  *
83  *  \note
84  *  don't use the widget parameter on this function, or do some checking...
85  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
86  */
i_callback_toolbar_file_new(GtkWidget * widget,gpointer data)87 void i_callback_toolbar_file_new(GtkWidget* widget, gpointer data)
88 {
89   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
90   g_return_if_fail (w_current != NULL);
91   if (!w_current->window) return;
92 
93   i_callback_file_new(data, 0, NULL);
94 }
95 
96 /*! \todo Finish function documentation!!!
97  *  \brief
98  *  \par Function Description
99  *
100  */
DEFINE_I_CALLBACK(file_new_window)101 DEFINE_I_CALLBACK(file_new_window)
102 {
103   GSCHEM_TOPLEVEL *w_current;
104   PAGE *page;
105 
106   w_current = gschem_toplevel_new ();
107   gschem_toplevel_alloc_libgeda_toplevel (w_current);
108 
109   w_current->toplevel->load_newer_backup_func = x_fileselect_load_backup;
110   w_current->toplevel->load_newer_backup_data = w_current;
111 
112   o_text_set_rendered_bounds_func (w_current->toplevel,
113                                    o_text_get_rendered_bounds, w_current);
114 
115   /* Damage notifications should invalidate the object on screen */
116   o_add_change_notify (w_current->toplevel,
117                        (ChangeNotifyFunc) o_invalidate,
118                        (ChangeNotifyFunc) o_invalidate, w_current);
119 
120   x_window_setup (w_current);
121 
122   page = x_window_open_page (w_current, NULL);
123   x_window_set_current_page (w_current, page);
124   s_log_message (_("New Window created [%s]\n"), page->page_filename);
125 }
126 
127 /*! \todo Finish function documentation!!!
128  *  \brief
129  *  \par Function Description
130  *
131  *  \note
132  *  don't use the widget parameter on this function, or do some
133  *  checking...
134  *  since there is a call: widget = NULL, data = 0 (will be w_current)
135  *  \todo This should be renamed to page_open perhaps...
136  */
DEFINE_I_CALLBACK(file_open)137 DEFINE_I_CALLBACK(file_open)
138 {
139   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
140 
141   g_return_if_fail (w_current != NULL);
142 
143   x_fileselect_open (w_current);
144 }
145 
146 /*! \todo Finish function documentation!!!
147  *  \brief
148  *  \par Function Description
149  *
150  *  \note
151  *  don't use the widget parameter on this function, or do some
152  *  checking...
153  *  since there is a call: widget = NULL, data = 0 (will be w_current)
154  *  \todo This should be renamed to page_open perhaps...
155  */
i_callback_toolbar_file_open(GtkWidget * widget,gpointer data)156 void i_callback_toolbar_file_open(GtkWidget* widget, gpointer data)
157 {
158   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
159   g_return_if_fail (w_current != NULL);
160   if (!w_current->window) return;
161 
162   i_callback_file_open(data, 0, NULL);
163 }
164 
165 /*! \todo Finish function documentation!!!
166  *  \brief
167  *  \par Function Description
168  *
169  */
DEFINE_I_CALLBACK(file_script)170 DEFINE_I_CALLBACK(file_script)
171 {
172   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
173 
174   g_return_if_fail (w_current != NULL);
175   setup_script_selector(w_current);
176 }
177 
178 /*! \todo Finish function documentation!!!
179  *  \brief
180  *  \par Function Description
181  *
182  *  \note
183  *  don't use the widget parameter on this function, or do some
184  *  checking...
185  *  since there is a call: widget = NULL, data = 0 (will be w_current)
186  */
DEFINE_I_CALLBACK(file_save)187 DEFINE_I_CALLBACK(file_save)
188 {
189   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
190 
191   g_return_if_fail (w_current != NULL);
192 
193   /*! \todo probably there should be a flag that says whether
194    *   page_filename is derived from untitled_name or specified by
195    *   a user. Some twisted people might name their files like
196    *   untitled_name. :-)
197    */
198   if (strstr(w_current->toplevel->page_current->page_filename,
199              w_current->toplevel->untitled_name)) {
200     x_fileselect_save (w_current);
201   } else {
202     x_window_save_page (w_current,
203                         w_current->toplevel->page_current,
204                         w_current->toplevel->page_current->page_filename);
205   }
206 }
207 
208 /*! \todo Finish function documentation!!!
209  *  \brief
210  *  \par Function Description
211  *
212  *  \note
213  *  don't use the widget parameter on this function, or do some
214  *  checking...
215  *  since there is a call: widget = NULL, data = 0 (will be w_current)
216  *  \todo This should be renamed to page_open perhaps...
217  */
i_callback_toolbar_file_save(GtkWidget * widget,gpointer data)218 void i_callback_toolbar_file_save(GtkWidget* widget, gpointer data)
219 {
220   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
221   g_return_if_fail (w_current != NULL);
222   if (!w_current->window) return;
223 
224   i_callback_file_save(data, 0, NULL);
225 }
226 
227 /*! \todo Finish function documentation!!!
228  *  \brief
229  *  \par Function Description
230  *
231  *  \note
232  *  don't use the widget parameter on this function, or do some checking...
233  *  since there is a call: widget = NULL, data = 0 (will be w_current)
234  */
DEFINE_I_CALLBACK(file_save_all)235 DEFINE_I_CALLBACK(file_save_all)
236 {
237   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
238 
239   g_return_if_fail (w_current != NULL);
240 
241   if (s_page_save_all(w_current->toplevel)) {
242      i_set_state_msg(w_current, SELECT, _("Failed to Save All"));
243   } else {
244      i_set_state_msg(w_current, SELECT, _("Saved All"));
245   }
246 
247   i_update_toolbar(w_current);
248   x_pagesel_update (w_current);
249   i_update_menus(w_current);
250 }
251 
252 /*! \todo Finish function documentation!!!
253  *  \brief
254  *  \par Function Description
255  *
256  */
DEFINE_I_CALLBACK(file_save_as)257 DEFINE_I_CALLBACK(file_save_as)
258 {
259   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
260 
261   g_return_if_fail (w_current != NULL);
262   x_fileselect_save (w_current);
263 }
264 
265 /*! \todo Finish function documentation!!!
266  *  \brief
267  *  \par Function Description
268  *
269  */
DEFINE_I_CALLBACK(file_print)270 DEFINE_I_CALLBACK(file_print)
271 {
272   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
273   char *base=NULL, *filename;
274   char *ps_filename=NULL;
275 
276   g_return_if_fail (w_current != NULL);
277   g_return_if_fail (w_current->toplevel->page_current->page_filename != NULL);
278 
279   /* shortcut */
280   filename = w_current->toplevel->page_current->page_filename;
281 
282   /* get the base file name */
283   if (g_str_has_suffix(filename, ".sch")) {
284     /* the filename ends with ".sch", remove it */
285     base = g_strndup(filename, strlen(filename) - strlen(".sch"));
286   } else {
287     /* the filename does not end with .sch */
288     base = g_strdup (filename);
289   }
290 
291   /* add ".ps" tp the base filename */
292   ps_filename = g_strconcat (base, ".ps", NULL);
293   g_free(base);
294 
295   if (output_filename) {
296     x_print_setup(w_current, output_filename);
297   } else {
298     x_print_setup(w_current, ps_filename);
299   }
300 
301   g_free(ps_filename);
302 }
303 
304 /*! \todo Finish function documentation!!!
305  *  \brief
306  *  \par Function Description
307  *
308  */
DEFINE_I_CALLBACK(file_write_png)309 DEFINE_I_CALLBACK(file_write_png)
310 {
311   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
312 
313   g_return_if_fail (w_current != NULL);
314 
315   x_image_setup(w_current);
316 }
317 
318 /*! \todo Finish function documentation!!!
319  *  \brief
320  *  \par Function Description
321  *
322  *  \note
323  *  don't use the widget parameter on this function, or do some
324  *  checking...
325  *  since there is a call: widget = NULL, data = 0 (will be w_current)
326  *  this function closes a window
327  */
DEFINE_I_CALLBACK(file_close)328 DEFINE_I_CALLBACK(file_close)
329 {
330   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
331 
332   g_return_if_fail (w_current != NULL);
333 
334   s_log_message(_("Closing Window\n"));
335   x_window_close(w_current);
336 }
337 
338 /*! \todo Finish function documentation!!!
339  *  \brief
340  *  \par Function Description
341  *  This function is called when you send a delete event to gschem
342  *
343  *  \note
344  *  Also DON'T ref the widget parameter since they can be null
345  *  \todo Need a cleaner way of doing this. This routine is used by the
346  *  delete event signals
347  */
i_callback_close(gpointer data,guint callback_action,GtkWidget * widget)348 int i_callback_close(gpointer data, guint callback_action, GtkWidget *widget)
349 {
350   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
351 
352   g_return_val_if_fail ((w_current != NULL), FALSE);
353   i_callback_file_close(w_current, 0, widget);
354   return(FALSE);
355 }
356 
357 /*! \todo Finish function documentation!!!
358  *  \brief
359  *  \par Function Description
360  *
361  */
DEFINE_I_CALLBACK(file_quit)362 DEFINE_I_CALLBACK(file_quit)
363 {
364   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
365 
366   g_return_if_fail (w_current != NULL);
367   x_window_close_all(w_current);
368 }
369 
370 /*! \section edit-menu Edit Menu Callback Functions */
371 /*! \todo Finish function documentation!!!
372  *  \brief
373  *  \par Function Description
374  *
375  */
DEFINE_I_CALLBACK(edit_undo)376 DEFINE_I_CALLBACK(edit_undo)
377 {
378   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
379 
380   /* If we're cancelling from a move action, re-wind the
381    * page contents back to their state before we started.
382    *
383    * It "might" be nice to sub-undo rotates / zoom changes
384    * made whilst moving components, but when the undo code
385    * hits s_page_delete(), the place list objects are free'd.
386    * Since they are also contained in the schematic page, a
387    * crash occurs when the page objects are free'd.
388    * */
389   if (w_current->inside_action &&
390       (w_current->event_state == MOVE ||
391        w_current->event_state == ENDMOVE)) {
392     i_callback_cancel (w_current, 0, NULL);
393   } else {
394     o_undo_callback(w_current, UNDO_ACTION);
395   }
396 }
397 
398 /*! \todo Finish function documentation!!!
399  *  \brief
400  *  \par Function Description
401  *
402  *  \note
403  *  don't use the widget parameter on this function, or do some checking...
404  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
405  */
i_callback_toolbar_edit_undo(GtkWidget * widget,gpointer data)406 void i_callback_toolbar_edit_undo(GtkWidget* widget, gpointer data)
407 {
408   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
409   g_return_if_fail (w_current != NULL);
410   if (!w_current->window) return;
411 
412   i_callback_edit_undo(data, 0, NULL);
413 }
414 
415 /*! \todo Finish function documentation!!!
416  *  \brief
417  *  \par Function Description
418  *
419  */
DEFINE_I_CALLBACK(edit_redo)420 DEFINE_I_CALLBACK(edit_redo)
421 {
422   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
423 
424   o_undo_callback(w_current, REDO_ACTION);
425 }
426 
427 /*! \todo Finish function documentation!!!
428  *  \brief
429  *  \par Function Description
430  *
431  *  \note
432  *  don't use the widget parameter on this function, or do some checking...
433  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
434  */
i_callback_toolbar_edit_redo(GtkWidget * widget,gpointer data)435 void i_callback_toolbar_edit_redo(GtkWidget* widget, gpointer data)
436 {
437   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
438   g_return_if_fail (w_current != NULL);
439   if (!w_current->window) return;
440 
441   i_callback_edit_redo(data, 0, NULL);
442 }
443 
444 /*! \todo Finish function documentation!!!
445  *  \brief
446  *  \par Function Description
447  *
448  *  \note
449  *  Select also does not update the middle button shortcut.
450  */
DEFINE_I_CALLBACK(edit_select)451 DEFINE_I_CALLBACK(edit_select)
452 {
453   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
454   o_redraw_cleanstates(w_current);
455 
456   /* this is probably the only place this should be */
457   i_set_state(w_current, SELECT);
458   i_update_toolbar(w_current);
459   w_current->inside_action = 0;
460 }
461 
462 /*! \todo Finish function documentation!!!
463  *  \brief
464  *  \par Function Description
465  *
466  *  \note
467  *  don't use the widget parameter on this function, or do some checking...
468  * since there is a call: widget = NULL, data = 0 (will be w_current hack)
469  */
i_callback_toolbar_edit_select(GtkWidget * widget,gpointer data)470 void i_callback_toolbar_edit_select(GtkWidget* widget, gpointer data)
471 {
472   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
473   g_return_if_fail (w_current != NULL);
474   if (!w_current->window) return;
475 
476   if (GTK_TOGGLE_BUTTON (widget)->active) {
477     if (!o_invalidate_rubber (w_current)) {
478       i_callback_cancel(w_current, 0, NULL);
479     }
480     i_callback_edit_select(data, 0, NULL);
481   }
482 }
483 
484 /*! \brief Select all objects on page.
485  * \par Function Description
486  * Sets all objects on page as selected.
487  */
DEFINE_I_CALLBACK(edit_select_all)488 DEFINE_I_CALLBACK (edit_select_all)
489 {
490   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data;
491   o_redraw_cleanstates (w_current);
492 
493   o_select_visible_unlocked (w_current);
494 
495   i_set_state (w_current, SELECT);
496   w_current->inside_action = 0;
497   i_update_toolbar (w_current);
498   i_update_menus (w_current);
499 }
500 
501 /*! \brief Deselect all objects on page.
502  * \par Function Description
503  * Sets all objects on page as deselected.
504  */
DEFINE_I_CALLBACK(edit_deselect)505 DEFINE_I_CALLBACK (edit_deselect)
506 {
507   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data;
508   o_redraw_cleanstates (w_current);
509 
510   o_select_unselect_all (w_current);
511 
512   i_set_state (w_current, SELECT);
513   w_current->inside_action = 0;
514   i_update_toolbar (w_current);
515   i_update_menus (w_current);
516 }
517 
518 /*! \todo Finish function documentation!!!
519  *  \brief
520  *  \par Function Description
521  *
522  */
DEFINE_I_CALLBACK(edit_copy)523 DEFINE_I_CALLBACK(edit_copy)
524 {
525   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
526 
527   g_return_if_fail (w_current != NULL);
528 
529   i_update_middle_button(w_current, i_callback_edit_copy, _("Copy"));
530   if (o_select_return_first_object(w_current)) {
531     o_redraw_cleanstates(w_current);
532     i_set_state(w_current, STARTCOPY);
533   } else {
534     i_set_state_msg(w_current, SELECT, _("Select objs first"));
535   }
536 }
537 
538 /*! \todo Finish function documentation!!!
539  *  \brief
540  *  \par Function Description
541  *
542  */
DEFINE_I_CALLBACK(edit_copy_hotkey)543 DEFINE_I_CALLBACK(edit_copy_hotkey)
544 {
545   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
546   gint wx, wy;
547 
548   g_return_if_fail (w_current != NULL);
549 
550   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
551     return;
552 
553   i_update_middle_button(w_current, i_callback_edit_copy_hotkey, _("Copy"));
554   if (o_select_return_first_object(w_current)) {
555     o_redraw_cleanstates(w_current);
556     w_current->event_state = COPY;
557     o_copy_start(w_current, wx, wy);
558     w_current->event_state = ENDCOPY;
559     w_current->inside_action = 1;
560   }
561 }
562 
563 /*! \todo Finish function documentation!!!
564  *  \brief
565  *  \par Function Description
566  *
567  */
DEFINE_I_CALLBACK(edit_mcopy)568 DEFINE_I_CALLBACK(edit_mcopy)
569 {
570   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
571 
572   g_return_if_fail (w_current != NULL);
573 
574   i_update_middle_button(w_current, i_callback_edit_copy, _("Multiple Copy"));
575   if (o_select_return_first_object(w_current)) {
576     o_redraw_cleanstates(w_current);
577     i_set_state(w_current, STARTMCOPY);
578   } else {
579     i_set_state_msg(w_current, SELECT, _("Select objs first"));
580   }
581 }
582 
583 /*! \todo Finish function documentation!!!
584  *  \brief
585  *  \par Function Description
586  *
587  */
DEFINE_I_CALLBACK(edit_mcopy_hotkey)588 DEFINE_I_CALLBACK(edit_mcopy_hotkey)
589 {
590   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
591   gint wx, wy;
592 
593   g_return_if_fail (w_current != NULL);
594 
595   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
596     return;
597 
598   i_update_middle_button(w_current, i_callback_edit_mcopy_hotkey, _("Multiple Copy"));
599   if (o_select_return_first_object(w_current)) {
600     o_redraw_cleanstates(w_current);
601     w_current->event_state = MCOPY;
602     o_copy_start(w_current, wx, wy);
603     w_current->event_state = ENDMCOPY;
604     w_current->inside_action = 1;
605   }
606 }
607 
608 /*! \todo Finish function documentation!!!
609  *  \brief
610  *  \par Function Description
611  *
612  */
DEFINE_I_CALLBACK(edit_move)613 DEFINE_I_CALLBACK(edit_move)
614 {
615   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
616 
617   g_return_if_fail (w_current != NULL);
618 
619   i_update_middle_button(w_current, i_callback_edit_move, _("Move"));
620   if (o_select_return_first_object(w_current)) {
621     o_redraw_cleanstates(w_current);
622     i_set_state(w_current, STARTMOVE);
623   } else {
624     i_set_state_msg(w_current, SELECT, _("Select objs first"));
625   }
626 }
627 
628 /*! \todo Finish function documentation!!!
629  *  \brief
630  *  \par Function Description
631  *
632  */
DEFINE_I_CALLBACK(edit_move_hotkey)633 DEFINE_I_CALLBACK(edit_move_hotkey)
634 {
635   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
636   gint wx, wy;
637 
638   g_return_if_fail (w_current != NULL);
639 
640   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
641     return;
642 
643   i_update_middle_button(w_current, i_callback_edit_move_hotkey, _("Move"));
644   if (o_select_return_first_object(w_current)) {
645     o_redraw_cleanstates(w_current);
646     o_move_start(w_current, wx, wy);
647     w_current->event_state = ENDMOVE;
648     w_current->inside_action = 1;
649   }
650 }
651 
652 /*! \todo Finish function documentation!!!
653  *  \brief
654  *  \par Function Description
655  *
656  */
DEFINE_I_CALLBACK(edit_delete)657 DEFINE_I_CALLBACK(edit_delete)
658 {
659   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
660 
661   g_return_if_fail (w_current != NULL);
662 
663   i_update_middle_button(w_current, i_callback_edit_delete, _("Delete"));
664 
665   if (o_select_return_first_object(w_current)) {
666     o_redraw_cleanstates(w_current);
667     o_delete_selected(w_current);
668     /* if you delete the objects you must go into select
669      * mode after the delete */
670     w_current->inside_action = 0;
671     i_set_state(w_current, SELECT);
672     i_update_toolbar(w_current);
673     i_update_menus(w_current);
674   }
675 }
676 
677 /*! \todo Finish function documentation!!!
678  *  \brief
679  *  \par Function Description
680  *
681  */
DEFINE_I_CALLBACK(edit_edit)682 DEFINE_I_CALLBACK(edit_edit)
683 {
684   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
685 
686   g_return_if_fail (w_current != NULL);
687 
688   i_update_middle_button(w_current, i_callback_edit_edit, _("Edit"));
689   o_edit(w_current, geda_list_get_glist( w_current->toplevel->page_current->selection_list ) );
690 }
691 
692 /*! \todo Finish function documentation!!!
693  *  \brief
694  *  \par Function Description
695  *
696  */
DEFINE_I_CALLBACK(edit_pin_type)697 DEFINE_I_CALLBACK(edit_pin_type)
698 {
699   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
700 
701   g_return_if_fail (w_current != NULL);
702 
703   i_update_middle_button (w_current, i_callback_edit_pin_type, _("Edit pin type"));
704 
705   x_dialog_edit_pin_type (w_current,
706                           geda_list_get_glist (w_current->toplevel->
707                                                  page_current->selection_list));
708 }
709 
710 /*! \todo Finish function documentation!!!
711  *  \brief
712  *  \par Function Description
713  *
714  */
DEFINE_I_CALLBACK(edit_text)715 DEFINE_I_CALLBACK(edit_text)
716 {
717   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
718   OBJECT *object;
719 
720   g_return_if_fail (w_current != NULL);
721 
722   i_update_middle_button(w_current, i_callback_edit_text, _("Edit Text"));
723   object = o_select_return_first_object(w_current);
724   if (object) {
725     if (object->type == OBJ_TEXT) {
726       o_text_edit(w_current, object);
727     }
728   }
729 }
730 
731 /*! \todo Finish function documentation!!!
732  *  \brief
733  *  \par Function Description
734  *
735  */
DEFINE_I_CALLBACK(edit_slot)736 DEFINE_I_CALLBACK(edit_slot)
737 {
738   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
739   OBJECT *object;
740 
741   g_return_if_fail (w_current != NULL);
742 
743   object = o_select_return_first_object(w_current);
744 
745   i_update_middle_button(w_current, i_callback_edit_slot, _("Slot"));
746   if (object) {
747     o_slot_start(w_current, object);
748   }
749 }
750 
751 /*! \todo Finish function documentation!!!
752  *  \brief
753  *  \par Function Description
754  *
755  */
DEFINE_I_CALLBACK(edit_color)756 DEFINE_I_CALLBACK(edit_color)
757 {
758   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
759 
760   g_return_if_fail (w_current != NULL);
761 
762   i_update_middle_button(w_current, i_callback_edit_color, _("Color"));
763 
764   color_edit_dialog(w_current);
765 }
766 
767 /*! \todo Finish function documentation!!!
768  *  \brief
769  *  \par Function Description
770  *  This function rotate all objects in the selection list by 90 degrees.
771  *
772  */
DEFINE_I_CALLBACK(edit_rotate_90)773 DEFINE_I_CALLBACK(edit_rotate_90)
774 {
775   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
776 
777   g_return_if_fail (w_current != NULL);
778 
779   /* If inside an appropriate action, send a button 2 released,
780    * so rotating will be handled by x_event.c */
781   if ( w_current->inside_action &&
782        (w_current->event_state == ENDCOMP ||
783         w_current->event_state == ENDTEXT ||
784         w_current->event_state == ENDMOVE ||
785         w_current->event_state == ENDCOPY ||
786         w_current->event_state == ENDMCOPY ||
787         w_current->event_state == ENDPASTE )) {
788       GdkEvent* event;
789 
790       event = gdk_event_new(GDK_BUTTON_RELEASE);
791       ((GdkEventButton*) event)->button = 2;
792       x_event_button_released (NULL, (GdkEventButton *) event, w_current);
793       gdk_event_free(event);
794 
795       return;
796     }
797 
798   i_set_state(w_current, ENDROTATEP);
799   i_update_middle_button(w_current, i_callback_edit_rotate_90, _("Rotate"));
800 }
801 
802 /*! \todo Finish function documentation!!!
803  *  \brief
804  *  \par Function Description
805  *  This function rotate all objects in the selection list by 90 degrees.
806  *
807  */
DEFINE_I_CALLBACK(edit_rotate_90_hotkey)808 DEFINE_I_CALLBACK(edit_rotate_90_hotkey)
809 {
810   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
811   GList *object_list;
812   gint wx, wy;
813 
814   g_return_if_fail (w_current != NULL);
815 
816   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
817     return;
818 
819   /* If inside an appropriate action, send a button 2 released,
820    * so rotating will be handled by x_event.c */
821   if ( w_current->inside_action &&
822        (w_current->event_state == ENDCOMP ||
823         w_current->event_state == ENDTEXT ||
824         w_current->event_state == ENDMOVE ||
825         w_current->event_state == ENDCOPY ||
826         w_current->event_state == ENDMCOPY ||
827         w_current->event_state == ENDPASTE )) {
828       GdkEvent* event;
829 
830       event = gdk_event_new(GDK_BUTTON_RELEASE);
831       ((GdkEventButton*) event)->button = 2;
832       x_event_button_released (NULL, (GdkEventButton *) event, w_current);
833       gdk_event_free(event);
834 
835       return;
836     }
837 
838   o_redraw_cleanstates(w_current);
839 
840   object_list = geda_list_get_glist( w_current->toplevel->page_current->selection_list );
841 
842   if (object_list) {
843     i_update_middle_button(w_current,
844                            i_callback_edit_rotate_90_hotkey, _("Rotate"));
845     /* Allow o_rotate_world_update to redraw the objects */
846     o_rotate_world_update(w_current, wx, wy, 90, object_list);
847   }
848 
849   w_current->event_state = SELECT;
850   w_current->inside_action = 0;
851   i_update_toolbar(w_current);
852 }
853 
854 /*! \todo Finish function documentation!!!
855  *  \brief
856  *  \par Function Description
857  *
858  */
DEFINE_I_CALLBACK(edit_mirror)859 DEFINE_I_CALLBACK(edit_mirror)
860 {
861   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
862 
863   g_return_if_fail (w_current != NULL);
864 
865   i_set_state(w_current, ENDMIRROR);
866   i_update_middle_button(w_current, i_callback_edit_mirror, _("Mirror"));
867 }
868 
869 /*! \todo Finish function documentation!!!
870  *  \brief
871  *  \par Function Description
872  *
873  */
DEFINE_I_CALLBACK(edit_mirror_hotkey)874 DEFINE_I_CALLBACK(edit_mirror_hotkey)
875 {
876   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
877   GList *object_list;
878   gint wx, wy;
879 
880   g_return_if_fail (w_current != NULL);
881 
882   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
883     return;
884 
885   o_redraw_cleanstates(w_current);
886 
887   object_list = geda_list_get_glist( w_current->toplevel->page_current->selection_list );
888 
889   if (object_list) {
890     i_update_middle_button(w_current,
891                            i_callback_edit_mirror_hotkey, _("Mirror"));
892     o_mirror_world_update(w_current, wx, wy, object_list);
893   }
894 
895   w_current->event_state = SELECT;
896   w_current->inside_action = 0;
897   i_update_toolbar(w_current);
898 }
899 
900 /*! \todo Finish function documentation!!!
901  *  \brief
902  *  \par Function Description
903  *  This function locks all objects in selection list.
904  *
905  */
DEFINE_I_CALLBACK(edit_lock)906 DEFINE_I_CALLBACK(edit_lock)
907 {
908   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
909 
910   g_return_if_fail (w_current != NULL);
911 
912   i_update_middle_button(w_current, i_callback_edit_lock, _("Lock"));
913 
914   if (o_select_return_first_object(w_current)) {
915     o_lock(w_current);
916   }
917 }
918 
919 /*! \todo Finish function documentation!!!
920  *  \brief
921  *  \par Function Description
922  *  Thus function unlocks all objects in selection list.
923  */
DEFINE_I_CALLBACK(edit_unlock)924 DEFINE_I_CALLBACK(edit_unlock)
925 {
926   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
927 
928   g_return_if_fail (w_current != NULL);
929 
930   i_update_middle_button(w_current, i_callback_edit_unlock, _("Unlock"));
931   if (o_select_return_first_object(w_current)) {
932     o_unlock(w_current);
933   }
934 }
935 
936 /*! \todo Finish function documentation!!!
937  *  \brief
938  *  \par Function Description
939  *
940  */
DEFINE_I_CALLBACK(edit_translate)941 DEFINE_I_CALLBACK(edit_translate)
942 {
943   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
944 
945   g_return_if_fail (w_current != NULL);
946 
947   i_update_middle_button(w_current,
948                          i_callback_edit_translate, _("Translate"));
949 
950   if (w_current->snap == SNAP_OFF) {
951     s_log_message(_("WARNING: Do not translate with snap off!\n"));
952     s_log_message(_("WARNING: Turning snap on and continuing "
953                   "with translate.\n"));
954     w_current->snap = SNAP_GRID;
955     i_show_state(w_current, NULL); /* update status on screen */
956   }
957 
958   if (w_current->snap_size != 100) {
959     s_log_message(_("WARNING: Snap grid size is "
960                   "not equal to 100!\n"));
961     s_log_message(_("WARNING: If you are translating a symbol "
962                   "to the origin, the snap grid size should be "
963                   "set to 100\n"));
964   }
965 
966   translate_dialog(w_current);
967 }
968 
DEFINE_I_CALLBACK(edit_invoke_macro)969 DEFINE_I_CALLBACK(edit_invoke_macro)
970 {
971   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
972 
973   g_return_if_fail (w_current != NULL);
974 
975   gtk_widget_show(w_current->macro_box);
976   gtk_widget_grab_focus(w_current->macro_entry);
977 }
978 
979 /*! \todo Finish function documentation!!!
980  *  \brief
981  *  \par Function Description
982  *  This function embedds all objects in selection list
983  *
984  */
DEFINE_I_CALLBACK(edit_embed)985 DEFINE_I_CALLBACK(edit_embed)
986 {
987   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
988   OBJECT *o_current;
989 
990   g_return_if_fail (w_current != NULL);
991 
992   i_update_middle_button(w_current, i_callback_edit_embed, _("Embed"));
993   /* anything selected ? */
994   if (o_select_selected(w_current)) {
995     /* yes, embed each selected component */
996     GList *s_current =
997       geda_list_get_glist( w_current->toplevel->page_current->selection_list );
998 
999     while (s_current != NULL) {
1000       o_current = (OBJECT *) s_current->data;
1001       g_assert (o_current != NULL);
1002       if ( (o_current->type == OBJ_COMPLEX) ||
1003 	   (o_current->type == OBJ_PICTURE) ) {
1004         o_embed (w_current->toplevel, o_current);
1005       }
1006       s_current = g_list_next(s_current);
1007     }
1008     o_undo_savestate(w_current, UNDO_ALL);
1009   } else {
1010     /* nothing selected, go back to select state */
1011     o_redraw_cleanstates(w_current);
1012     w_current->inside_action = 0;
1013     i_set_state(w_current, SELECT);
1014   }
1015 
1016 }
1017 
1018 /*! \todo Finish function documentation!!!
1019  *  \brief
1020  *  \par Function Description
1021  *  This function unembedds all objects in selection list.
1022  *
1023  */
DEFINE_I_CALLBACK(edit_unembed)1024 DEFINE_I_CALLBACK(edit_unembed)
1025 {
1026   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1027   OBJECT *o_current;
1028 
1029   g_return_if_fail (w_current != NULL);
1030 
1031   i_update_middle_button(w_current, i_callback_edit_unembed, _("Unembed"));
1032   /* anything selected ? */
1033   if (o_select_selected(w_current)) {
1034     /* yes, unembed each selected component */
1035     GList *s_current =
1036       geda_list_get_glist( w_current->toplevel->page_current->selection_list );
1037 
1038     while (s_current != NULL) {
1039       o_current = (OBJECT *) s_current->data;
1040       g_assert (o_current != NULL);
1041       if ( (o_current->type == OBJ_COMPLEX) ||
1042            (o_current->type == OBJ_PICTURE) ) {
1043         o_unembed (w_current->toplevel, o_current);
1044       }
1045       s_current = g_list_next(s_current);
1046     }
1047     o_undo_savestate(w_current, UNDO_ALL);
1048   } else {
1049     /* nothing selected, go back to select state */
1050     o_redraw_cleanstates(w_current);
1051     w_current->inside_action = 0;
1052     i_set_state(w_current, SELECT);
1053   }
1054 
1055 }
1056 
1057 /*! \todo Finish function documentation!!!
1058  *  \brief
1059  *  \par Function Description
1060  *  This function updates components
1061  *
1062  */
DEFINE_I_CALLBACK(edit_update)1063 DEFINE_I_CALLBACK(edit_update)
1064 {
1065   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1066   TOPLEVEL *toplevel = w_current->toplevel;
1067   GList *selection;
1068   GList *selected_components = NULL;
1069   GList *iter;
1070 
1071   g_return_if_fail (w_current != NULL);
1072 
1073   i_update_middle_button(w_current, i_callback_edit_update, _("Update"));
1074   if (o_select_selected(w_current)) {
1075 
1076     /* Updating components modifies the selection. Therefore, create a
1077      * new list of only the OBJECTs we want to update from the current
1078      * selection, then iterate over that new list to perform the
1079      * update. */
1080     selection = geda_list_get_glist (toplevel->page_current->selection_list);
1081     for (iter = selection; iter != NULL; iter = g_list_next (iter)) {
1082       OBJECT *o_current = (OBJECT *) iter->data;
1083       if (o_current != NULL && o_current->type == OBJ_COMPLEX) {
1084         selected_components = g_list_prepend (selected_components, o_current);
1085       }
1086     }
1087     for (iter = selected_components; iter != NULL; iter = g_list_next (iter)) {
1088       OBJECT *o_current = (OBJECT *) iter->data;
1089       iter->data = o_update_component (w_current, o_current);
1090     }
1091     g_list_free (selected_components);
1092 
1093   } else {
1094     /* nothing selected, go back to select state */
1095     o_redraw_cleanstates(w_current);
1096     w_current->inside_action = 0;
1097     i_set_state(w_current, SELECT);
1098   }
1099 
1100 }
1101 
1102 /*! \todo Finish function documentation!!!
1103  *  \brief
1104  *  \par Function Description
1105  *
1106  */
DEFINE_I_CALLBACK(edit_show_hidden)1107 DEFINE_I_CALLBACK(edit_show_hidden)
1108 {
1109   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1110 
1111   g_return_if_fail (w_current != NULL);
1112 
1113   /* This is a new addition 3/15 to prevent this from executing
1114    * inside an action */
1115   if (w_current->inside_action)
1116     return;
1117 
1118   i_update_middle_button(w_current,
1119                          i_callback_edit_show_hidden,
1120                          _("ShowHidden"));
1121 
1122   o_edit_show_hidden (w_current,
1123                       s_page_objects (w_current->toplevel->page_current));
1124 }
1125 
1126 /*! \todo Finish function documentation!!!
1127  *  \brief
1128  *  \par Function Description
1129  *
1130  */
DEFINE_I_CALLBACK(edit_find)1131 DEFINE_I_CALLBACK(edit_find)
1132 {
1133   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1134 
1135   g_return_if_fail (w_current != NULL);
1136 
1137   /* This is a new addition 3/15 to prevent this from executing
1138    * inside an action */
1139   if (w_current->inside_action)
1140     return;
1141 
1142   find_text_dialog(w_current);
1143 }
1144 
1145 /*! \todo Finish function documentation!!!
1146  *  \brief
1147  *  \par Function Description
1148  *
1149  */
DEFINE_I_CALLBACK(edit_hide_text)1150 DEFINE_I_CALLBACK(edit_hide_text)
1151 {
1152   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1153 
1154   g_return_if_fail (w_current != NULL);
1155 
1156   /* This is a new addition 3/15 to prevent this from executing
1157    * inside an action */
1158   if (w_current->inside_action)
1159     return;
1160 
1161   hide_text_dialog(w_current);
1162 }
1163 
1164 /*! \todo Finish function documentation!!!
1165  *  \brief
1166  *  \par Function Description
1167  *
1168  */
DEFINE_I_CALLBACK(edit_show_text)1169 DEFINE_I_CALLBACK(edit_show_text)
1170 {
1171   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1172 
1173   g_return_if_fail (w_current != NULL);
1174 
1175   /* This is a new addition 3/15 to prevent this from executing
1176    * inside an action */
1177   if (w_current->inside_action)
1178     return;
1179 
1180   show_text_dialog(w_current);
1181 }
1182 
1183 /*! \todo Finish function documentation!!!
1184  *  \brief
1185  *  \par Function Description
1186  *
1187  */
DEFINE_I_CALLBACK(edit_autonumber_text)1188 DEFINE_I_CALLBACK(edit_autonumber_text)
1189 {
1190   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1191 
1192   g_return_if_fail (w_current != NULL);
1193 
1194   /* This is a new addition 3/15 to prevent this from executing
1195    * inside an action */
1196   if (w_current->inside_action)
1197     return;
1198 
1199   autonumber_text_dialog(w_current);
1200 }
1201 
1202 /*! \todo Finish function documentation!!!
1203  *  \brief
1204  *  \par Function Description
1205  *
1206  */
DEFINE_I_CALLBACK(edit_linetype)1207 DEFINE_I_CALLBACK(edit_linetype)
1208 {
1209   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1210 
1211   g_return_if_fail (w_current != NULL);
1212 
1213   line_type_dialog(w_current);
1214 }
1215 
1216 /*! \todo Finish function documentation!!!
1217  *  \brief
1218  *  \par Function Description
1219  *
1220  */
DEFINE_I_CALLBACK(edit_filltype)1221 DEFINE_I_CALLBACK(edit_filltype)
1222 {
1223   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1224 
1225   g_return_if_fail (w_current != NULL);
1226 
1227   fill_type_dialog(w_current);
1228 }
1229 
1230 /*! \section view-menu View Menu Callback Functions */
1231 /*! \todo Finish function documentation!!!
1232  *  \brief
1233  *  \par Function Description
1234  *
1235  *  \note
1236  *  repeat middle shortcut doesn't make sense on redraw, just hit right
1237  *  button
1238  */
DEFINE_I_CALLBACK(view_redraw)1239 DEFINE_I_CALLBACK(view_redraw)
1240 {
1241   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1242 
1243   g_return_if_fail (w_current != NULL);
1244   o_invalidate_all (w_current);
1245 }
1246 
1247 /*! \todo Finish function documentation!!!
1248  *  \brief
1249  *  \par Function Description
1250  *
1251  *  \note
1252  *  repeat middle shortcut would get into the way of what user is try to do
1253  */
DEFINE_I_CALLBACK(view_zoom_full)1254 DEFINE_I_CALLBACK(view_zoom_full)
1255 {
1256   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1257 
1258   g_return_if_fail (w_current != NULL);
1259 
1260   /* scroll bar stuff */
1261   a_zoom(w_current, ZOOM_FULL, DONTCARE, 0);
1262 
1263   if (w_current->undo_panzoom) {
1264     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1265   }
1266 }
1267 
1268 /*! \todo Finish function documentation!!!
1269  *  \brief
1270  *  \par Function Description
1271  *
1272  *  \note
1273  *  repeat middle shortcut would get into the way of what user is try to do
1274  */
DEFINE_I_CALLBACK(view_zoom_extents)1275 DEFINE_I_CALLBACK(view_zoom_extents)
1276 {
1277   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1278 
1279   g_return_if_fail (w_current != NULL);
1280 
1281   /* scroll bar stuff */
1282   a_zoom_extents (w_current,
1283                   s_page_objects (w_current->toplevel->page_current), 0);
1284   if (w_current->undo_panzoom) {
1285     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1286   }
1287 }
1288 
1289 /*! \todo Finish function documentation!!!
1290  *  \brief
1291  *  \par Function Description
1292  *
1293  *  \note
1294  *  repeat middle shortcut would get into the way of what user is try to do
1295  */
DEFINE_I_CALLBACK(view_zoom_box)1296 DEFINE_I_CALLBACK(view_zoom_box)
1297 {
1298   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1299 
1300   g_return_if_fail (w_current != NULL);
1301 
1302   o_redraw_cleanstates(w_current);
1303   w_current->inside_action = 0;
1304   i_set_state(w_current, ZOOMBOXSTART);
1305 }
1306 
1307 /*! \todo Finish function documentation!!!
1308  *  \brief
1309  *  \par Function Description
1310  *
1311  */
DEFINE_I_CALLBACK(view_zoom_box_hotkey)1312 DEFINE_I_CALLBACK(view_zoom_box_hotkey)
1313 {
1314   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1315   gint wx, wy;
1316 
1317   g_return_if_fail (w_current != NULL);
1318 
1319   if (!x_event_get_pointer_position(w_current, FALSE, &wx, &wy))
1320     return;
1321 
1322   o_redraw_cleanstates(w_current);
1323   a_zoom_box_start(w_current, wx, wy);
1324 
1325   w_current->inside_action = 1;
1326   i_set_state(w_current, ZOOMBOXEND);
1327 }
1328 
1329 /*! \todo Finish function documentation!!!
1330  *  \brief
1331  *  \par Function Description
1332  *
1333  *  \note
1334  *  repeat middle shortcut would get into the way of what user is try to do
1335  */
DEFINE_I_CALLBACK(view_zoom_in)1336 DEFINE_I_CALLBACK(view_zoom_in)
1337 {
1338   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1339 
1340   g_return_if_fail (w_current != NULL);
1341 
1342   a_zoom(w_current, ZOOM_IN, MENU, 0);
1343 
1344   if (w_current->undo_panzoom) {
1345     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1346   }
1347 }
1348 
1349 /*! \todo Finish function documentation!!!
1350  *  \brief
1351  *  \par Function Description
1352  *
1353  *  \note
1354  *  repeat middle shortcut would get into the way of what user is try to do
1355  */
DEFINE_I_CALLBACK(view_zoom_out)1356 DEFINE_I_CALLBACK(view_zoom_out)
1357 {
1358   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1359 
1360   g_return_if_fail (w_current != NULL);
1361 
1362   a_zoom(w_current, ZOOM_OUT, MENU, 0);
1363 
1364   if (w_current->undo_panzoom) {
1365     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1366   }
1367 }
1368 
1369 /*! \todo Finish function documentation!!!
1370  *  \brief
1371  *  \par Function Description
1372  *
1373  *  \note
1374  *  repeat middle shortcut would get into the way of what user is try
1375  *  to do
1376  */
DEFINE_I_CALLBACK(view_zoom_in_hotkey)1377 DEFINE_I_CALLBACK(view_zoom_in_hotkey)
1378 {
1379   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1380 
1381   g_return_if_fail (w_current != NULL);
1382 
1383   a_zoom(w_current, ZOOM_IN, HOTKEY, 0);
1384 
1385   if (w_current->undo_panzoom) {
1386     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1387   }
1388 }
1389 
1390 /*! \todo Finish function documentation!!!
1391  *  \brief
1392  *  \par Function Description
1393  *
1394  *  \note
1395  *  repeat middle shortcut would get into the way of what user is try to do
1396  */
DEFINE_I_CALLBACK(view_zoom_out_hotkey)1397 DEFINE_I_CALLBACK(view_zoom_out_hotkey)
1398 {
1399   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1400 
1401   g_return_if_fail (w_current != NULL);
1402 
1403   a_zoom(w_current, ZOOM_OUT, HOTKEY, 0);
1404 
1405   if (w_current->undo_panzoom) {
1406     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1407   }
1408 }
1409 
1410 /*! \todo Finish function documentation!!!
1411  *  \brief
1412  *  \par Function Description
1413  *
1414  */
DEFINE_I_CALLBACK(view_pan)1415 DEFINE_I_CALLBACK(view_pan)
1416 {
1417   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1418 
1419   g_return_if_fail (w_current != NULL);
1420 
1421   o_redraw_cleanstates(w_current);
1422   w_current->inside_action = 0;
1423   i_set_state(w_current, STARTPAN);
1424 
1425   /* I don't know if this would get in the way */
1426   i_update_middle_button(w_current, i_callback_view_pan, _("Pan"));
1427 }
1428 
1429 /*! \brief Scheme callback function that moves the viewport to the left.
1430  *
1431  * The distance can be set with "keyboardpan-gain" scheme callback.
1432  */
DEFINE_I_CALLBACK(view_pan_left)1433 DEFINE_I_CALLBACK(view_pan_left)
1434 {
1435   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1436 
1437   g_return_if_fail (w_current != NULL);
1438 
1439   a_pan_mouse(w_current, w_current->keyboardpan_gain, 0);
1440 }
1441 
1442 /*! \brief Scheme callback function that moves the viewport to the right.
1443  *
1444  * The distance can be set with "keyboardpan-gain" scheme callback.
1445  */
DEFINE_I_CALLBACK(view_pan_right)1446 DEFINE_I_CALLBACK(view_pan_right)
1447 {
1448   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1449 
1450   g_return_if_fail (w_current != NULL);
1451 
1452   /* yes, that's a negative sign there */
1453   a_pan_mouse(w_current, -w_current->keyboardpan_gain, 0);
1454 }
1455 
1456 /*! \brief Scheme callback function that moves the viewport up.
1457  *
1458  * The distance can be set with "keyboardpan-gain" scheme callback.
1459  */
DEFINE_I_CALLBACK(view_pan_up)1460 DEFINE_I_CALLBACK(view_pan_up)
1461 {
1462   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1463 
1464   g_return_if_fail (w_current != NULL);
1465 
1466   a_pan_mouse(w_current, 0, w_current->keyboardpan_gain);
1467 }
1468 
1469 /*! \brief Scheme callback function that moves the viewport down.
1470  *
1471  * The distance can be set with "keyboardpan-gain" scheme callback.
1472  */
DEFINE_I_CALLBACK(view_pan_down)1473 DEFINE_I_CALLBACK(view_pan_down)
1474 {
1475   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1476 
1477   g_return_if_fail (w_current != NULL);
1478 
1479   /* yes, that's a negative sign there */
1480   a_pan_mouse(w_current, 0, -w_current->keyboardpan_gain);
1481 }
1482 
1483 /*! \todo Finish function documentation!!!
1484  *  \brief
1485  *  \par Function Description
1486  *
1487  */
DEFINE_I_CALLBACK(view_pan_hotkey)1488 DEFINE_I_CALLBACK(view_pan_hotkey)
1489 {
1490   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1491   gint wx, wy;
1492 
1493   g_return_if_fail (w_current != NULL);
1494 
1495   if (!x_event_get_pointer_position(w_current, FALSE, &wx, &wy))
1496     return;
1497 
1498   i_update_middle_button(w_current, i_callback_view_pan_hotkey, _("Pan"));
1499 
1500   a_pan(w_current, wx, wy);
1501 
1502   if (w_current->undo_panzoom) {
1503     o_undo_savestate(w_current, UNDO_VIEWPORT_ONLY);
1504   }
1505 }
1506 
1507 /*! \todo Finish function documentation!!!
1508  *  \brief
1509  *  \par Function Description
1510  *
1511  */
DEFINE_I_CALLBACK(view_dark_colors)1512 DEFINE_I_CALLBACK (view_dark_colors)
1513 {
1514   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1515 
1516   x_color_free ();
1517   /* Change the scheme here */
1518   g_scm_c_eval_string_protected ("(load (build-path geda-rc-path \"gschem-colormap-darkbg\"))");
1519   x_color_allocate ();
1520 
1521   o_invalidate_all (w_current);
1522 }
1523 
1524 /*! \todo Finish function documentation!!!
1525  *  \brief
1526  *  \par Function Description
1527  *
1528  */
DEFINE_I_CALLBACK(view_light_colors)1529 DEFINE_I_CALLBACK (view_light_colors)
1530 {
1531   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1532 
1533   x_color_free ();
1534   /* Change the scheme here */
1535   g_scm_c_eval_string_protected ("(load (build-path geda-rc-path \"gschem-colormap-lightbg\"))");
1536   x_color_allocate ();
1537 
1538   o_invalidate_all (w_current);
1539 }
1540 
1541 /*! \todo Finish function documentation!!!
1542  *  \brief
1543  *  \par Function Description
1544  *
1545  */
DEFINE_I_CALLBACK(view_bw_colors)1546 DEFINE_I_CALLBACK (view_bw_colors)
1547 {
1548   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1549 
1550   x_color_free ();
1551   /* Change the scheme here */
1552   g_scm_c_eval_string_protected ("(load (build-path geda-rc-path \"gschem-colormap-bw\"))");
1553   x_color_allocate ();
1554 
1555   o_invalidate_all (w_current);
1556 }
1557 
1558 /*! \section page-menu Page Menu Callback Functions */
1559 /*! \todo Finish function documentation!!!
1560  *  \brief
1561  *  \par Function Description
1562  *
1563  */
DEFINE_I_CALLBACK(page_manager)1564 DEFINE_I_CALLBACK(page_manager)
1565 {
1566   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1567 
1568   g_return_if_fail (w_current != NULL);
1569 
1570   x_pagesel_open (w_current);
1571 }
1572 
1573 /*! \todo Finish function documentation!!!
1574  *  \brief
1575  *  \par Function Description
1576  *
1577  */
DEFINE_I_CALLBACK(page_next)1578 DEFINE_I_CALLBACK(page_next)
1579 {
1580   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*)data;
1581   TOPLEVEL *toplevel = w_current->toplevel;
1582   PAGE *p_current = toplevel->page_current;
1583   PAGE *p_new;
1584   GList *iter;
1585 
1586   g_return_if_fail (w_current != NULL);
1587 
1588   iter = g_list_find( geda_list_get_glist( toplevel->pages ), p_current );
1589   iter = g_list_next( iter );
1590 
1591   if (iter == NULL) {
1592     return;
1593   }
1594 
1595   if (w_current->enforce_hierarchy) {
1596     p_new = s_hierarchy_find_next_page(toplevel->pages, p_current);
1597   } else {
1598     p_new = (PAGE *)iter->data;
1599   }
1600 
1601   if (p_new == NULL || p_new == p_current) {
1602     return;
1603   }
1604 
1605   x_window_set_current_page (w_current, p_new);
1606 }
1607 
1608 /*! \todo Finish function documentation!!!
1609  *  \brief
1610  *  \par Function Description
1611  *
1612  */
DEFINE_I_CALLBACK(page_prev)1613 DEFINE_I_CALLBACK(page_prev)
1614 {
1615   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*)data;
1616   TOPLEVEL *toplevel = w_current->toplevel;
1617   PAGE *p_current = toplevel->page_current;
1618   PAGE *p_new;
1619   GList *iter;
1620 
1621   g_return_if_fail (w_current != NULL);
1622 
1623   iter = g_list_find( geda_list_get_glist( toplevel->pages ), p_current );
1624   iter = g_list_previous( iter );
1625 
1626   if ( iter == NULL  )
1627     return;
1628 
1629   p_new = (PAGE *)iter->data;
1630 
1631   if (w_current->enforce_hierarchy) {
1632     p_new = s_hierarchy_find_prev_page(toplevel->pages, p_current);
1633   } else {
1634     p_new = (PAGE *)iter->data;
1635   }
1636 
1637   if (p_new == NULL || p_new == p_current) {
1638     return;
1639   }
1640 
1641   x_window_set_current_page (w_current, p_new);
1642 }
1643 
1644 /*! \todo Finish function documentation!!!
1645  *  \brief
1646  *  \par Function Description
1647  *
1648  */
DEFINE_I_CALLBACK(page_new)1649 DEFINE_I_CALLBACK(page_new)
1650 {
1651   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*)data;
1652   PAGE *page;
1653 
1654   g_return_if_fail (w_current != NULL);
1655 
1656   /* create a new page */
1657   page = x_window_open_page (w_current, NULL);
1658   x_window_set_current_page (w_current, page);
1659   s_log_message (_("New page created [%s]\n"), page->page_filename);
1660 }
1661 
1662 /*! \todo Finish function documentation!!!
1663  *  \brief
1664  *  \par Function Description
1665  *
1666  */
DEFINE_I_CALLBACK(page_close)1667 DEFINE_I_CALLBACK(page_close)
1668 {
1669   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1670 
1671   g_return_if_fail (w_current != NULL);
1672 
1673   if (w_current->toplevel->page_current->CHANGED) {
1674     x_dialog_close_changed_page (w_current, w_current->toplevel->page_current);
1675   } else {
1676     x_window_close_page (w_current, w_current->toplevel->page_current);
1677   }
1678 
1679 }
1680 
1681 /*! \todo Finish function documentation!!!
1682  *  \brief
1683  *  \par Function Description
1684  *
1685  *  \bug may have memory leak?
1686  */
DEFINE_I_CALLBACK(page_revert)1687 DEFINE_I_CALLBACK(page_revert)
1688 {
1689   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1690   PAGE *page;
1691   gchar *filename;
1692   int page_control;
1693   int up;
1694   int response;
1695   GtkWidget* dialog;
1696 
1697   g_return_if_fail (w_current != NULL);
1698 
1699   dialog = gtk_message_dialog_new ((GtkWindow*) w_current->main_window,
1700                                    GTK_DIALOG_DESTROY_WITH_PARENT,
1701                                    GTK_MESSAGE_QUESTION,
1702                                    GTK_BUTTONS_YES_NO,
1703                                    _("Really revert page?"));
1704 
1705   /* Set the alternative button order (ok, cancel, help) for other systems */
1706   gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
1707 					  GTK_RESPONSE_YES,
1708 					  GTK_RESPONSE_NO,
1709 					  -1);
1710 
1711   response = gtk_dialog_run (GTK_DIALOG (dialog));
1712   gtk_widget_destroy (dialog);
1713 
1714   if (response != GTK_RESPONSE_YES )
1715     return;
1716 
1717   /* save this for later */
1718   filename = g_strdup (w_current->toplevel->page_current->page_filename);
1719   page_control = w_current->toplevel->page_current->page_control;
1720   up = w_current->toplevel->page_current->up;
1721 
1722   /* delete the page, then re-open the file as a new page */
1723   s_page_delete (w_current->toplevel, w_current->toplevel->page_current);
1724 
1725   page = x_window_open_page (w_current, filename);
1726 
1727   /* make sure we maintain the hierarchy info */
1728   page->page_control = page_control;
1729   page->up = up;
1730 
1731   x_window_set_current_page (w_current, page);
1732 }
1733 
1734 /*! \todo Finish function documentation!!!
1735  *  \brief
1736  *  \par Function Description
1737  *
1738  */
DEFINE_I_CALLBACK(page_discard)1739 DEFINE_I_CALLBACK(page_discard)
1740 {
1741   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*)data;
1742 
1743   g_return_if_fail (w_current != NULL);
1744 
1745   x_window_close_page (w_current, w_current->toplevel->page_current);
1746 }
1747 
1748 /*! \todo Finish function documentation!!!
1749  *  \brief
1750  *  \par Function Description
1751  *
1752  */
DEFINE_I_CALLBACK(page_print)1753 DEFINE_I_CALLBACK(page_print)
1754 {
1755   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1756 
1757   s_page_print_all(w_current->toplevel);
1758 }
1759 
1760 /*! \section clipboard-menu Clipboard Menu Callback Functions */
1761 /*! \brief Copy selection to clipboard.
1762  *  \par Function Description
1763  * Copies the current selection to the clipboard, via buffer 0.
1764  */
DEFINE_I_CALLBACK(clipboard_copy)1765 DEFINE_I_CALLBACK(clipboard_copy)
1766 {
1767   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1768 
1769   g_return_if_fail (w_current != NULL);
1770   if (!o_select_selected (w_current)) return;
1771 
1772   i_update_middle_button (w_current, i_callback_clipboard_copy,
1773                           _("Copy to clipboard"));
1774 
1775   o_buffer_copy (w_current, 0);
1776   x_clipboard_set (w_current, object_buffer[0]);
1777 }
1778 
1779 /*! \brief Cut selection to clipboard.
1780  *  \par Function Description
1781  * Cut the current selection to the clipboard, via buffer 0.
1782  */
DEFINE_I_CALLBACK(clipboard_cut)1783 DEFINE_I_CALLBACK(clipboard_cut)
1784 {
1785   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1786 
1787   g_return_if_fail (w_current != NULL);
1788   if (!o_select_selected (w_current)) return;
1789 
1790   i_update_middle_button (w_current, i_callback_clipboard_cut,
1791                           _("Cut to clipboard"));
1792 
1793   o_buffer_cut (w_current, 0);
1794   x_clipboard_set (w_current, object_buffer[0]);
1795 }
1796 
1797 /*! \brief Start pasting clipboard contents.
1798  *  \par Function Description
1799  * Cut the current selection to the clipboard, via buffer 0.
1800  */
DEFINE_I_CALLBACK(clipboard_paste)1801 DEFINE_I_CALLBACK(clipboard_paste)
1802 {
1803   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data;
1804   TOPLEVEL *toplevel = w_current->toplevel;
1805   GList *object_list = NULL;
1806 
1807   g_return_if_fail (w_current != NULL);
1808 
1809   i_update_middle_button (w_current, i_callback_buffer_paste1, _("Paste from clipboard"));
1810 
1811   object_list = x_clipboard_get (w_current);
1812 
1813   if (object_list != NULL) {
1814     s_delete_object_glist (toplevel, object_buffer[0]);
1815     object_buffer[0] = object_list;
1816     o_redraw_cleanstates (w_current);
1817     w_current->buffer_number = 0;
1818     w_current->inside_action = 1;
1819     i_set_state (w_current, STARTPASTE);
1820   } else {
1821     i_set_state_msg (w_current, SELECT, _("Empty buffer"));
1822   }
1823 }
1824 
1825 /*! \brief Start pasting clipboard contents (hotkey version)
1826  *  \par Function Description
1827  *  It's not entirely clear what the difference is between this and
1828  *  i_callback_clipboard_paste()...
1829  */
DEFINE_I_CALLBACK(clipboard_paste_hotkey)1830 DEFINE_I_CALLBACK(clipboard_paste_hotkey)
1831 {
1832   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data;
1833   TOPLEVEL *toplevel = w_current->toplevel;
1834   GList *object_list = NULL;
1835   gint wx, wy;
1836 
1837   g_return_if_fail (w_current != NULL);
1838 
1839   if (!x_event_get_pointer_position (w_current, TRUE, &wx, &wy))
1840     return;
1841 
1842   object_list = x_clipboard_get (w_current);
1843 
1844   if (object_list == NULL) return;
1845   s_delete_object_glist (toplevel, object_buffer[0]);
1846   object_buffer[0] = object_list;
1847 
1848   o_buffer_paste_start (w_current, wx, wy, 0);
1849 }
1850 
1851 /*! \section buffer-menu Buffer Menu Callback Functions */
1852 /*! \todo Finish function documentation!!!
1853  *  \brief
1854  *  \par Function Description
1855  *
1856  */
DEFINE_I_CALLBACK(buffer_copy1)1857 DEFINE_I_CALLBACK(buffer_copy1)
1858 {
1859   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1860 
1861   g_return_if_fail (w_current != NULL);
1862 
1863   if (!o_select_selected (w_current))
1864     return;
1865 
1866   i_update_middle_button(w_current, i_callback_buffer_copy1, _("Copy 1"));
1867   o_buffer_copy(w_current, 0);
1868   i_update_menus(w_current);
1869 }
1870 
1871 /*! \todo Finish function documentation!!!
1872  *  \brief
1873  *  \par Function Description
1874  *
1875  */
DEFINE_I_CALLBACK(buffer_copy2)1876 DEFINE_I_CALLBACK(buffer_copy2)
1877 {
1878   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1879 
1880   g_return_if_fail (w_current != NULL);
1881 
1882   if (!o_select_selected (w_current))
1883     return;
1884 
1885   i_update_middle_button(w_current, i_callback_buffer_copy2, _("Copy 2"));
1886   o_buffer_copy(w_current, 1);
1887   i_update_menus(w_current);
1888 }
1889 
1890 /*! \todo Finish function documentation!!!
1891  *  \brief
1892  *  \par Function Description
1893  *
1894  */
DEFINE_I_CALLBACK(buffer_copy3)1895 DEFINE_I_CALLBACK(buffer_copy3)
1896 {
1897   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1898 
1899   g_return_if_fail (w_current != NULL);
1900 
1901   if (!o_select_selected (w_current))
1902     return;
1903 
1904   i_update_middle_button(w_current, i_callback_buffer_copy3, _("Copy 3"));
1905   o_buffer_copy(w_current, 2);
1906   i_update_menus(w_current);
1907 }
1908 
1909 /*! \todo Finish function documentation!!!
1910  *  \brief
1911  *  \par Function Description
1912  *
1913  */
DEFINE_I_CALLBACK(buffer_copy4)1914 DEFINE_I_CALLBACK(buffer_copy4)
1915 {
1916   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1917 
1918   g_return_if_fail (w_current != NULL);
1919 
1920   if (!o_select_selected (w_current))
1921     return;
1922 
1923   i_update_middle_button(w_current, i_callback_buffer_copy4, _("Copy 4"));
1924   o_buffer_copy(w_current, 3);
1925   i_update_menus(w_current);
1926 }
1927 
1928 /*! \todo Finish function documentation!!!
1929  *  \brief
1930  *  \par Function Description
1931  *
1932  */
DEFINE_I_CALLBACK(buffer_copy5)1933 DEFINE_I_CALLBACK(buffer_copy5)
1934 {
1935   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1936 
1937   g_return_if_fail (w_current != NULL);
1938 
1939   if (!o_select_selected (w_current))
1940     return;
1941 
1942   i_update_middle_button(w_current, i_callback_buffer_copy5, _("Copy 5"));
1943   o_buffer_copy(w_current, 4);
1944   i_update_menus(w_current);
1945 }
1946 
1947 /*! \todo Finish function documentation!!!
1948  *  \brief
1949  *  \par Function Description
1950  *
1951  */
DEFINE_I_CALLBACK(buffer_cut1)1952 DEFINE_I_CALLBACK(buffer_cut1)
1953 {
1954   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1955 
1956   g_return_if_fail (w_current != NULL);
1957 
1958   if (!o_select_selected (w_current))
1959     return;
1960 
1961   i_update_middle_button(w_current, i_callback_buffer_cut1, _("Cut 1"));
1962   o_buffer_cut(w_current, 0);
1963   i_update_menus(w_current);
1964 }
1965 
1966 /*! \todo Finish function documentation!!!
1967  *  \brief
1968  *  \par Function Description
1969  *
1970  */
DEFINE_I_CALLBACK(buffer_cut2)1971 DEFINE_I_CALLBACK(buffer_cut2)
1972 {
1973   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1974 
1975   g_return_if_fail (w_current != NULL);
1976 
1977   if (!o_select_selected (w_current))
1978     return;
1979 
1980   i_update_middle_button(w_current, i_callback_buffer_cut2, _("Cut 2"));
1981   o_buffer_cut(w_current, 1);
1982   i_update_menus(w_current);
1983 }
1984 
1985 /*! \todo Finish function documentation!!!
1986  *  \brief
1987  *  \par Function Description
1988  *
1989  */
DEFINE_I_CALLBACK(buffer_cut3)1990 DEFINE_I_CALLBACK(buffer_cut3)
1991 {
1992   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
1993 
1994   g_return_if_fail (w_current != NULL);
1995 
1996   if (!o_select_selected (w_current))
1997     return;
1998 
1999   i_update_middle_button(w_current, i_callback_buffer_cut3, _("Cut 3"));
2000   o_buffer_cut(w_current, 2);
2001   i_update_menus(w_current);
2002 }
2003 
2004 /*! \todo Finish function documentation!!!
2005  *  \brief
2006  *  \par Function Description
2007  *
2008  */
DEFINE_I_CALLBACK(buffer_cut4)2009 DEFINE_I_CALLBACK(buffer_cut4)
2010 {
2011   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2012 
2013   g_return_if_fail (w_current != NULL);
2014 
2015   if (!o_select_selected (w_current))
2016     return;
2017 
2018   i_update_middle_button(w_current, i_callback_buffer_cut4, _("Cut 4"));
2019   o_buffer_cut(w_current, 3);
2020   i_update_menus(w_current);
2021 }
2022 
2023 /*! \todo Finish function documentation!!!
2024  *  \brief
2025  *  \par Function Description
2026  *
2027  */
DEFINE_I_CALLBACK(buffer_cut5)2028 DEFINE_I_CALLBACK(buffer_cut5)
2029 {
2030   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2031 
2032   g_return_if_fail (w_current != NULL);
2033 
2034   if (!o_select_selected (w_current))
2035     return;
2036 
2037   i_update_middle_button(w_current, i_callback_buffer_cut5, _("Cut 5"));
2038   o_buffer_cut(w_current, 4);
2039   i_update_menus(w_current);
2040 }
2041 
2042 /*! \todo Finish function documentation!!!
2043  *  \brief
2044  *  \par Function Description
2045  *
2046  */
DEFINE_I_CALLBACK(buffer_paste1)2047 DEFINE_I_CALLBACK(buffer_paste1)
2048 {
2049   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2050 
2051   g_return_if_fail (w_current != NULL);
2052 
2053   i_update_middle_button(w_current, i_callback_buffer_paste1, _("Paste 1"));
2054   if (object_buffer[0] != NULL) {
2055     o_redraw_cleanstates(w_current);
2056     w_current->buffer_number = 0;
2057     w_current->inside_action = 1;
2058     i_set_state(w_current, STARTPASTE);
2059   } else {
2060     i_set_state_msg(w_current, SELECT, _("Empty buffer"));
2061   }
2062 }
2063 
2064 /*! \todo Finish function documentation!!!
2065  *  \brief
2066  *  \par Function Description
2067  *
2068  */
DEFINE_I_CALLBACK(buffer_paste2)2069 DEFINE_I_CALLBACK(buffer_paste2)
2070 {
2071   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2072 
2073   g_return_if_fail (w_current != NULL);
2074 
2075   i_update_middle_button(w_current, i_callback_buffer_paste2, _("Paste 2"));
2076   if (object_buffer[1] != NULL) {
2077     o_redraw_cleanstates(w_current);
2078     w_current->buffer_number = 1;
2079     w_current->inside_action = 1;
2080     i_set_state(w_current, STARTPASTE);
2081   } else {
2082     i_set_state_msg(w_current, SELECT, _("Empty buffer"));
2083   }
2084 }
2085 
2086 /*! \todo Finish function documentation!!!
2087  *  \brief
2088  *  \par Function Description
2089  *
2090  */
DEFINE_I_CALLBACK(buffer_paste3)2091 DEFINE_I_CALLBACK(buffer_paste3)
2092 {
2093   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2094 
2095   g_return_if_fail (w_current != NULL);
2096 
2097   i_update_middle_button(w_current, i_callback_buffer_paste3, _("Paste 3"));
2098   if (object_buffer[2] != NULL) {
2099     o_redraw_cleanstates(w_current);
2100     w_current->buffer_number = 2;
2101     w_current->inside_action = 1;
2102     i_set_state(w_current, STARTPASTE);
2103   } else {
2104     i_set_state_msg(w_current, SELECT, _("Empty buffer"));
2105   }
2106 }
2107 
2108 /*! \todo Finish function documentation!!!
2109  *  \brief
2110  *  \par Function Description
2111  *
2112  */
DEFINE_I_CALLBACK(buffer_paste4)2113 DEFINE_I_CALLBACK(buffer_paste4)
2114 {
2115   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2116 
2117   g_return_if_fail (w_current != NULL);
2118 
2119   i_update_middle_button(w_current, i_callback_buffer_paste4, _("Paste 4"));
2120   if (object_buffer[3] != NULL) {
2121     o_redraw_cleanstates(w_current);
2122     w_current->buffer_number = 3;
2123     w_current->inside_action = 1;
2124     i_set_state(w_current, STARTPASTE);
2125   } else {
2126     i_set_state_msg(w_current, SELECT, _("Empty buffer"));
2127   }
2128 }
2129 
2130 /*! \todo Finish function documentation!!!
2131  *  \brief
2132  *  \par Function Description
2133  *
2134  */
DEFINE_I_CALLBACK(buffer_paste5)2135 DEFINE_I_CALLBACK(buffer_paste5)
2136 {
2137   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2138 
2139   g_return_if_fail (w_current != NULL);
2140 
2141   i_update_middle_button(w_current, i_callback_buffer_paste5, _("Paste 5"));
2142   if (object_buffer[4] != NULL) {
2143     o_redraw_cleanstates(w_current);
2144     w_current->buffer_number = 4;
2145     w_current->inside_action = 1;
2146     i_set_state(w_current, STARTPASTE);
2147   } else {
2148     i_set_state_msg(w_current, SELECT, _("Empty buffer"));
2149   }
2150 }
2151 
2152 /*! \todo Finish function documentation!!!
2153  *  \brief
2154  *  \par Function Description
2155  *
2156  */
DEFINE_I_CALLBACK(buffer_paste1_hotkey)2157 DEFINE_I_CALLBACK(buffer_paste1_hotkey)
2158 {
2159   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2160   gint wx, wy;
2161 
2162   g_return_if_fail (w_current != NULL);
2163 
2164   if (object_buffer[0] == NULL) {
2165     return;
2166   }
2167 
2168   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2169     return;
2170 
2171   o_buffer_paste_start(w_current, wx, wy, 0);
2172 }
2173 
2174 /*! \todo Finish function documentation!!!
2175  *  \brief
2176  *  \par Function Description
2177  *
2178  */
DEFINE_I_CALLBACK(buffer_paste2_hotkey)2179 DEFINE_I_CALLBACK(buffer_paste2_hotkey)
2180 {
2181   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2182   gint wx, wy;
2183 
2184   g_return_if_fail (w_current != NULL);
2185 
2186   if (object_buffer[1] == NULL) {
2187     return;
2188   }
2189 
2190   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2191     return;
2192 
2193   o_buffer_paste_start(w_current, wx, wy, 1);
2194 }
2195 
2196 /*! \todo Finish function documentation!!!
2197  *  \brief
2198  *  \par Function Description
2199  *
2200  */
DEFINE_I_CALLBACK(buffer_paste3_hotkey)2201 DEFINE_I_CALLBACK(buffer_paste3_hotkey)
2202 {
2203   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2204   gint wx, wy;
2205 
2206   g_return_if_fail (w_current != NULL);
2207 
2208   if (object_buffer[2] == NULL) {
2209     return;
2210   }
2211 
2212   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2213     return;
2214 
2215   o_buffer_paste_start(w_current, wx, wy, 2);
2216 }
2217 
2218 /*! \todo Finish function documentation!!!
2219  *  \brief
2220  *  \par Function Description
2221  *
2222  */
DEFINE_I_CALLBACK(buffer_paste4_hotkey)2223 DEFINE_I_CALLBACK(buffer_paste4_hotkey)
2224 {
2225   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2226   gint wx, wy;
2227 
2228   g_return_if_fail (w_current != NULL);
2229 
2230   if (object_buffer[3] == NULL) {
2231     return;
2232   }
2233 
2234   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2235     return;
2236 
2237   o_buffer_paste_start(w_current, wx, wy, 3);
2238 }
2239 
2240 /*! \todo Finish function documentation!!!
2241  *  \brief
2242  *  \par Function Description
2243  *
2244  */
DEFINE_I_CALLBACK(buffer_paste5_hotkey)2245 DEFINE_I_CALLBACK(buffer_paste5_hotkey)
2246 {
2247   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2248   gint wx, wy;
2249 
2250   g_return_if_fail (w_current != NULL);
2251 
2252   if (object_buffer[4] == NULL) {
2253     return;
2254   }
2255 
2256   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2257     return;
2258 
2259   o_buffer_paste_start(w_current, wx, wy, 4);
2260 }
2261 
2262 /*! \section add-menu Add Menu Callback Functions */
2263 /*! \todo Finish function documentation!!!
2264  *  \brief
2265  *  \par Function Description
2266  *
2267  */
DEFINE_I_CALLBACK(add_component)2268 DEFINE_I_CALLBACK(add_component)
2269 {
2270   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2271 
2272   g_return_if_fail (w_current != NULL);
2273 
2274   o_redraw_cleanstates (w_current);
2275   x_compselect_open (w_current);
2276 
2277   i_update_middle_button(w_current,
2278                          i_callback_add_component, _("Component"));
2279 
2280   i_set_state(w_current, SELECT);
2281   i_update_toolbar(w_current);
2282 }
2283 
2284 /*! \todo Finish function documentation!!!
2285  *  \brief
2286  *  \par Function Description
2287  *
2288  *  \note
2289  *  don't use the widget parameter on this function, or do some checking...
2290  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
2291  */
i_callback_toolbar_add_component(GtkWidget * widget,gpointer data)2292 void i_callback_toolbar_add_component(GtkWidget* widget, gpointer data)
2293 {
2294   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2295   g_return_if_fail (w_current != NULL);
2296   if (!w_current->window) return;
2297 
2298   i_callback_add_component(data, 0, NULL);
2299 }
2300 
2301 /*! \todo Finish function documentation!!!
2302  *  \brief
2303  *  \par Function Description
2304  *
2305  */
DEFINE_I_CALLBACK(add_attribute)2306 DEFINE_I_CALLBACK(add_attribute)
2307 {
2308   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2309 
2310   g_return_if_fail (w_current != NULL);
2311 
2312   attrib_edit_dialog(w_current, NULL, FROM_MENU);
2313   i_update_middle_button(w_current, i_callback_add_attribute,
2314                          _("Attribute"));
2315 
2316   i_set_state(w_current, SELECT);
2317   i_update_toolbar(w_current);
2318 }
2319 
2320 /*! \todo Finish function documentation!!!
2321  *  \brief
2322  *  \par Function Description
2323  *
2324  */
DEFINE_I_CALLBACK(add_attribute_hotkey)2325 DEFINE_I_CALLBACK(add_attribute_hotkey)
2326 {
2327   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2328 
2329   g_return_if_fail (w_current != NULL);
2330 
2331   attrib_edit_dialog(w_current, NULL, FROM_HOTKEY);
2332   i_update_middle_button(w_current, i_callback_add_attribute_hotkey,
2333                          _("Attribute"));
2334 
2335   i_set_state(w_current, SELECT);
2336   i_update_toolbar(w_current);
2337 }
2338 
2339 /*! \todo Finish function documentation!!!
2340  *  \brief
2341  *  \par Function Description
2342  *
2343  */
DEFINE_I_CALLBACK(add_net)2344 DEFINE_I_CALLBACK(add_net)
2345 {
2346   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2347 
2348   g_return_if_fail (w_current != NULL);
2349 
2350   o_redraw_cleanstates(w_current);
2351   o_invalidate_rubber (w_current);
2352   o_net_reset(w_current);
2353 
2354   /* need to click */
2355   i_update_middle_button(w_current, i_callback_add_net, _("Net"));
2356   i_set_state(w_current, STARTDRAWNET);
2357   i_update_toolbar(w_current);
2358   /* somewhere you need to nearest point locking... */
2359   w_current->inside_action = 0;
2360 }
2361 
2362 /*! \todo Finish function documentation!!!
2363  *  \brief
2364  *  \par Function Description
2365  *
2366  */
DEFINE_I_CALLBACK(add_net_hotkey)2367 DEFINE_I_CALLBACK(add_net_hotkey)
2368 {
2369   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2370   gint wx, wy;
2371 
2372   g_return_if_fail (w_current != NULL);
2373 
2374   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2375     return;
2376 
2377   o_redraw_cleanstates(w_current);
2378   o_invalidate_rubber (w_current);
2379   o_net_reset(w_current);
2380 
2381   /* need to click */
2382   i_update_middle_button(w_current, i_callback_add_net_hotkey, _("Net"));
2383   i_set_state(w_current, STARTDRAWNET);
2384   i_update_toolbar(w_current);
2385 
2386   o_net_start(w_current, wx, wy);
2387 
2388   w_current->event_state=DRAWNET;
2389   w_current->inside_action = 1;
2390 }
2391 
2392 /*! \todo Finish function documentation!!!
2393  *  \brief
2394  *  \par Function Description
2395  *
2396  *  \note
2397  *  don't use the widget parameter on this function, or do some checking...
2398  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
2399  */
i_callback_toolbar_add_net(GtkWidget * widget,gpointer data)2400 void i_callback_toolbar_add_net(GtkWidget* widget, gpointer data)
2401 {
2402   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2403   g_return_if_fail (w_current != NULL);
2404   if (!w_current->window) return;
2405 
2406   if (GTK_TOGGLE_BUTTON (widget)->active) {
2407     i_callback_add_net(data, 0, NULL);
2408   }
2409 }
2410 
2411 /*! \todo Finish function documentation!!!
2412  *  \brief
2413  *  \par Function Description
2414  *
2415  */
DEFINE_I_CALLBACK(add_bus)2416 DEFINE_I_CALLBACK(add_bus)
2417 {
2418   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2419 
2420   g_return_if_fail (w_current != NULL);
2421 
2422   o_redraw_cleanstates(w_current);
2423   o_invalidate_rubber (w_current);
2424 
2425   /* need to click */
2426   i_update_middle_button(w_current, i_callback_add_bus, _("Bus"));
2427   i_set_state(w_current, STARTDRAWBUS);
2428   i_update_toolbar(w_current);
2429 
2430   /* somewhere you need to nearest point locking... */
2431   w_current->inside_action = 0;
2432 }
2433 
2434 /*! \todo Finish function documentation!!!
2435  *  \brief
2436  *  \par Function Description
2437  *
2438  */
DEFINE_I_CALLBACK(add_bus_hotkey)2439 DEFINE_I_CALLBACK(add_bus_hotkey)
2440 {
2441   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2442   gint wx, wy;
2443 
2444   g_return_if_fail (w_current != NULL);
2445 
2446   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2447     return;
2448 
2449   o_redraw_cleanstates(w_current);
2450   o_invalidate_rubber (w_current);
2451 
2452   /* need to click */
2453   i_update_middle_button(w_current, i_callback_add_bus_hotkey, _("Bus"));
2454   i_set_state(w_current, STARTDRAWBUS);
2455   i_update_toolbar(w_current);
2456 
2457   o_bus_start(w_current, wx, wy);
2458 
2459   w_current->event_state=DRAWBUS;
2460   w_current->inside_action = 1;
2461 }
2462 
2463 /*! \todo Finish function documentation!!!
2464  *  \brief
2465  *  \par Function Description
2466  *
2467  *  \note
2468  *  don't use the widget parameter on this function, or do some checking...
2469  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
2470  */
i_callback_toolbar_add_bus(GtkWidget * widget,gpointer data)2471 void i_callback_toolbar_add_bus(GtkWidget* widget, gpointer data)
2472 {
2473   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2474   g_return_if_fail (w_current != NULL);
2475   if (!w_current->window) return;
2476 
2477   if (GTK_TOGGLE_BUTTON (widget)->active) {
2478      i_callback_add_bus(data, 0, NULL);
2479   }
2480 }
2481 
2482 /*! \todo Finish function documentation!!!
2483  *  \brief
2484  *  \par Function Description
2485  *
2486  */
DEFINE_I_CALLBACK(add_text)2487 DEFINE_I_CALLBACK(add_text)
2488 {
2489   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2490 
2491   g_return_if_fail (w_current != NULL);
2492 
2493   o_redraw_cleanstates(w_current);
2494   o_invalidate_rubber (w_current);
2495 
2496   w_current->inside_action = 0;
2497   i_set_state(w_current, SELECT);
2498   i_update_toolbar(w_current);
2499 
2500   text_input_dialog(w_current);
2501 }
2502 
2503 /*! \todo Finish function documentation!!!
2504  *  \brief
2505  *  \par Function Description
2506  *
2507  *  \note
2508  *  don't use the widget parameter on this function, or do some checking...
2509  *  since there is a call: widget = NULL, data = 0 (will be w_current hack)
2510  */
i_callback_toolbar_add_text(GtkWidget * widget,gpointer data)2511 void i_callback_toolbar_add_text(GtkWidget* widget, gpointer data)
2512 {
2513   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2514   g_return_if_fail (w_current != NULL);
2515   if (!w_current->window) return;
2516 
2517   i_callback_add_text(data, 0, NULL);
2518 }
2519 
2520 /*! \todo Finish function documentation!!!
2521  *  \brief
2522  *  \par Function Description
2523  *
2524  */
DEFINE_I_CALLBACK(add_line)2525 DEFINE_I_CALLBACK(add_line)
2526 {
2527   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2528 
2529   g_return_if_fail (w_current != NULL);
2530 
2531   o_redraw_cleanstates(w_current);
2532   o_invalidate_rubber (w_current);
2533 
2534   i_update_middle_button(w_current, i_callback_add_line, _("Line"));
2535   i_set_state(w_current, DRAWLINE);
2536   w_current->inside_action = 0;
2537 }
2538 
2539 /*! \todo Finish function documentation!!!
2540  *  \brief
2541  *  \par Function Description
2542  *
2543  */
DEFINE_I_CALLBACK(add_line_hotkey)2544 DEFINE_I_CALLBACK(add_line_hotkey)
2545 {
2546   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2547   gint wx, wy;
2548 
2549   g_return_if_fail (w_current != NULL);
2550 
2551   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2552     return;
2553 
2554   o_redraw_cleanstates(w_current);
2555   o_invalidate_rubber (w_current);
2556 
2557   i_update_middle_button(w_current, i_callback_add_line_hotkey, _("Line"));
2558 
2559   o_line_start(w_current, wx, wy);
2560 
2561   w_current->inside_action = 1;
2562   i_set_state(w_current, ENDLINE);
2563 }
2564 
2565 /*! \todo Finish function documentation!!!
2566  *  \brief
2567  *  \par Function Description
2568  *
2569  */
DEFINE_I_CALLBACK(add_box)2570 DEFINE_I_CALLBACK(add_box)
2571 {
2572   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2573 
2574   g_return_if_fail (w_current != NULL);
2575 
2576   o_redraw_cleanstates(w_current);
2577   o_invalidate_rubber (w_current);
2578 
2579   i_update_middle_button(w_current, i_callback_add_box, _("Box"));
2580   w_current->inside_action = 0;
2581   i_set_state(w_current, DRAWBOX);
2582 }
2583 
2584 /*! \todo Finish function documentation!!!
2585  *  \brief
2586  *  \par Function Description
2587  *
2588  */
DEFINE_I_CALLBACK(add_box_hotkey)2589 DEFINE_I_CALLBACK(add_box_hotkey)
2590 {
2591   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2592   gint wx, wy;
2593 
2594   g_return_if_fail (w_current != NULL);
2595 
2596   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2597     return;
2598 
2599   o_redraw_cleanstates(w_current);
2600   o_invalidate_rubber (w_current);
2601 
2602   i_update_middle_button(w_current, i_callback_add_box_hotkey, _("Box"));
2603 
2604   o_box_start(w_current, wx, wy);
2605 
2606   w_current->inside_action = 1;
2607   i_set_state(w_current, ENDBOX);
2608 }
2609 
2610 /*! \todo Finish function documentation!!!
2611  *  \brief
2612  *  \par Function Description
2613  *
2614  */
DEFINE_I_CALLBACK(add_picture)2615 DEFINE_I_CALLBACK(add_picture)
2616 {
2617   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2618 
2619   g_return_if_fail (w_current != NULL);
2620 
2621   o_redraw_cleanstates(w_current);
2622   o_invalidate_rubber (w_current);
2623 
2624   w_current->inside_action = 0;
2625   i_set_state(w_current, SELECT);
2626   i_update_toolbar(w_current);
2627 
2628   picture_selection_dialog(w_current);
2629 }
2630 
2631 /*! \todo Finish function documentation!!!
2632  *  \brief
2633  *  \par Function Description
2634  *
2635  */
DEFINE_I_CALLBACK(add_picture_hotkey)2636 DEFINE_I_CALLBACK(add_picture_hotkey)
2637 {
2638   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2639 
2640   /* If this function necessary? Yes, if you want the hotkey to work. */
2641   i_callback_add_picture(w_current, 0, NULL);
2642 }
2643 
2644 /*! \todo Finish function documentation!!!
2645  *  \brief
2646  *  \par Function Description
2647  *
2648  */
DEFINE_I_CALLBACK(add_circle)2649 DEFINE_I_CALLBACK(add_circle)
2650 {
2651   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2652 
2653   g_return_if_fail (w_current != NULL);
2654 
2655   o_redraw_cleanstates(w_current);
2656   o_invalidate_rubber (w_current);
2657 
2658   i_update_middle_button(w_current, i_callback_add_circle, _("Circle"));
2659   w_current->inside_action = 0;
2660   i_set_state(w_current, DRAWCIRCLE);
2661 }
2662 
2663 /*! \todo Finish function documentation!!!
2664  *  \brief
2665  *  \par Function Description
2666  *
2667  */
DEFINE_I_CALLBACK(add_circle_hotkey)2668 DEFINE_I_CALLBACK(add_circle_hotkey)
2669 {
2670   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2671   gint wx, wy;
2672 
2673   g_return_if_fail (w_current != NULL);
2674 
2675   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2676     return;
2677 
2678   o_redraw_cleanstates(w_current);
2679   o_invalidate_rubber (w_current);
2680 
2681   i_update_middle_button(w_current, i_callback_add_circle_hotkey,
2682                          _("Circle"));
2683 
2684   o_circle_start(w_current, wx, wy);
2685 
2686   w_current->inside_action = 1;
2687   i_set_state(w_current, ENDCIRCLE);
2688 }
2689 
2690 /*! \todo Finish function documentation!!!
2691  *  \brief
2692  *  \par Function Description
2693  *
2694  */
DEFINE_I_CALLBACK(add_arc)2695 DEFINE_I_CALLBACK(add_arc)
2696 {
2697   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2698 
2699   g_return_if_fail (w_current != NULL);
2700 
2701   o_redraw_cleanstates(w_current);
2702   o_invalidate_rubber (w_current);
2703 
2704   i_update_middle_button(w_current, i_callback_add_arc, _("Arc"));
2705   w_current->inside_action = 0;
2706   i_set_state(w_current, DRAWARC);
2707 }
2708 
2709 /*! \todo Finish function documentation!!!
2710  *  \brief
2711  *  \par Function Description
2712  *
2713  */
DEFINE_I_CALLBACK(add_arc_hotkey)2714 DEFINE_I_CALLBACK(add_arc_hotkey)
2715 {
2716   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2717   gint wx, wy;
2718 
2719   g_return_if_fail (w_current != NULL);
2720 
2721   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2722     return;
2723 
2724   o_redraw_cleanstates(w_current);
2725   o_invalidate_rubber (w_current);
2726 
2727   i_update_middle_button(w_current, i_callback_add_arc_hotkey, _("Arc"));
2728 
2729   o_arc_start(w_current, wx, wy);
2730 
2731   w_current->inside_action = 1;
2732   i_set_state(w_current, ENDARC);
2733 }
2734 
2735 /*! \todo Finish function documentation!!!
2736  *  \brief
2737  *  \par Function Description
2738  *
2739  */
DEFINE_I_CALLBACK(add_pin)2740 DEFINE_I_CALLBACK(add_pin)
2741 {
2742   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2743 
2744   g_return_if_fail (w_current != NULL);
2745 
2746   o_redraw_cleanstates(w_current);
2747   o_invalidate_rubber (w_current);
2748 
2749   i_update_middle_button(w_current, i_callback_add_pin, _("Pin"));
2750   w_current->inside_action = 0;
2751   i_set_state(w_current, DRAWPIN);
2752 }
2753 
2754 /*! \todo Finish function documentation!!!
2755  *  \brief
2756  *  \par Function Description
2757  *
2758  */
DEFINE_I_CALLBACK(add_pin_hotkey)2759 DEFINE_I_CALLBACK(add_pin_hotkey)
2760 {
2761   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2762   gint wx, wy;
2763 
2764   g_return_if_fail (w_current != NULL);
2765 
2766   if (!x_event_get_pointer_position(w_current, TRUE, &wx, &wy))
2767     return;
2768 
2769   o_redraw_cleanstates(w_current);
2770   o_invalidate_rubber (w_current);
2771 
2772   i_update_middle_button(w_current, i_callback_add_pin_hotkey, _("Pin"));
2773 
2774   o_pin_start(w_current, wx, wy);
2775 
2776   w_current->inside_action = 1;
2777   i_set_state(w_current, ENDPIN);
2778 }
2779 
2780 /*! \section hierarchy-menu Hierarchy Menu Callback Functions */
2781 /*! \todo Finish function documentation!!!
2782  *  \brief
2783  *  \par Function Description
2784  *
2785  */
DEFINE_I_CALLBACK(hierarchy_down_schematic)2786 DEFINE_I_CALLBACK(hierarchy_down_schematic)
2787 {
2788   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2789   char *attrib=NULL;
2790   char *current_filename=NULL;
2791   int count=0;
2792   OBJECT *object=NULL;
2793   PAGE *save_first_page=NULL;
2794   PAGE *parent=NULL;
2795   PAGE *child = NULL;
2796   int loaded_flag=FALSE;
2797   int page_control = 0;
2798   int pcount = 0;
2799   int looking_inside=FALSE;
2800 
2801   g_return_if_fail (w_current != NULL);
2802 
2803   object = o_select_return_first_object(w_current);
2804 
2805   /* only allow going into symbols */
2806   if (object == NULL || object->type != OBJ_COMPLEX)
2807     return;
2808 
2809   parent = w_current->toplevel->page_current;
2810   attrib = o_attrib_search_attached_attribs_by_name (object, "source", count);
2811 
2812   /* if above is null, then look inside symbol */
2813   if (attrib == NULL) {
2814     attrib =
2815       o_attrib_search_inherited_attribs_by_name (object, "source", count);
2816     looking_inside = TRUE;
2817 #if DEBUG
2818     printf("going to look inside now\n");
2819 #endif
2820   }
2821 
2822   while (attrib) {
2823 
2824     /* look for source=filename,filename, ... */
2825     pcount = 0;
2826     current_filename = u_basic_breakup_string(attrib, ',', pcount);
2827 
2828     /* loop over all filenames */
2829     while(current_filename != NULL) {
2830 
2831       s_log_message(_("Searching for source [%s]\n"), current_filename);
2832       child = s_hierarchy_down_schematic_single(w_current->toplevel,
2833                                                 current_filename,
2834                                                 parent,
2835                                                 page_control,
2836                                                 HIERARCHY_NORMAL_LOAD);
2837 
2838       /* s_hierarchy_down_schematic_single() will not zoom the loaded page */
2839       if (child != NULL) {
2840         s_page_goto (w_current->toplevel, child);
2841         a_zoom_extents(w_current,
2842                        s_page_objects (w_current->toplevel->page_current),
2843                        A_PAN_DONT_REDRAW);
2844         o_undo_savestate(w_current, UNDO_ALL);
2845         s_page_goto (w_current->toplevel, parent);
2846       }
2847 
2848       /* save the first page */
2849       if ( !loaded_flag && (child != NULL)) {
2850         save_first_page = child;
2851       }
2852 
2853       /* now do some error fixing */
2854       if (child == NULL) {
2855         s_log_message(_("Cannot find source [%s]\n"), current_filename);
2856       } else {
2857         /* this only signifies that we tried */
2858         loaded_flag = TRUE;
2859         page_control = child->page_control;
2860       }
2861 
2862       g_free(current_filename);
2863       pcount++;
2864       current_filename = u_basic_breakup_string(attrib, ',', pcount);
2865     }
2866 
2867     g_free(attrib);
2868     g_free(current_filename);
2869 
2870     count++;
2871 
2872     /* continue looking outside first */
2873     if (!looking_inside) {
2874       attrib =
2875         o_attrib_search_attached_attribs_by_name (object, "source", count);
2876     }
2877 
2878     /* okay we were looking outside and didn't find anything,
2879      * so now we need to look inside the symbol */
2880     if (!looking_inside && attrib == NULL && !loaded_flag ) {
2881       looking_inside = TRUE;
2882 #if DEBUG
2883       printf("switching to go to look inside\n");
2884 #endif
2885     }
2886 
2887     if (looking_inside) {
2888 #if DEBUG
2889       printf("looking inside\n");
2890 #endif
2891       attrib =
2892         o_attrib_search_inherited_attribs_by_name (object, "source", count);
2893     }
2894   }
2895 
2896   if (loaded_flag && (save_first_page != NULL)) {
2897     x_window_set_current_page (w_current, save_first_page);
2898   }
2899 }
2900 
2901 /*! \todo Finish function documentation!!!
2902  *  \brief
2903  *  \par Function Description
2904  *  \bug may cause problems with non-directory symbols
2905  */
DEFINE_I_CALLBACK(hierarchy_down_symbol)2906 DEFINE_I_CALLBACK(hierarchy_down_symbol)
2907 {
2908   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2909   OBJECT *object;
2910   const CLibSymbol *sym;
2911 
2912   g_return_if_fail (w_current != NULL);
2913 
2914   object = o_select_return_first_object(w_current);
2915   if (object != NULL) {
2916     /* only allow going into symbols */
2917     if (object->type == OBJ_COMPLEX) {
2918       s_log_message(_("Searching for symbol [%s]\n"),
2919 		    object->complex_basename);
2920       sym = s_clib_get_symbol_by_name (object->complex_basename);
2921       if (sym == NULL)
2922 	return;
2923       if (s_clib_symbol_get_filename(sym) == NULL) {
2924 	s_log_message(_("Symbol is not a real file."
2925 			" Symbol cannot be loaded.\n"));
2926 	return;
2927       }
2928       s_hierarchy_down_symbol(w_current->toplevel, sym,
2929 			      w_current->toplevel->page_current);
2930       /* s_hierarchy_down_symbol() will not zoom the loaded page */
2931       a_zoom_extents(w_current,
2932                      s_page_objects (w_current->toplevel->page_current),
2933                      A_PAN_DONT_REDRAW);
2934       o_undo_savestate(w_current, UNDO_ALL);
2935       x_window_set_current_page(w_current, w_current->toplevel->page_current);
2936     }
2937   }
2938 }
2939 
2940 /*! \todo Finish function documentation!!!
2941  *  \brief
2942  *  \par Function Description
2943  *
2944  */
DEFINE_I_CALLBACK(hierarchy_up)2945 DEFINE_I_CALLBACK(hierarchy_up)
2946 {
2947   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2948   PAGE *up_page;
2949 
2950   g_return_if_fail (w_current != NULL);
2951 
2952   up_page = s_hierarchy_find_up_page (w_current->toplevel->pages,
2953                                       w_current->toplevel->page_current);
2954   if (up_page == NULL) {
2955     s_log_message(_("Cannot find any schematics above the current one!\n"));
2956   } else {
2957     x_window_set_current_page(w_current, up_page);
2958   }
2959 }
2960 
2961 /*! \section attributes-menu Attributes Menu Callback Functions */
2962 /*! \todo Finish function documentation!!!
2963  *  \brief
2964  *  \par Function Description
2965  *
2966  */
DEFINE_I_CALLBACK(attributes_attach)2967 DEFINE_I_CALLBACK(attributes_attach)
2968 {
2969   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
2970   OBJECT *first_object;
2971   GList *s_current;
2972   GList *attached_objects = NULL;
2973 
2974   g_return_if_fail (w_current != NULL);
2975 
2976   /* This is a new addition 3/15 to prevent this from executing
2977    * inside an action */
2978   if (w_current->inside_action) {
2979     return;
2980   }
2981 
2982   /* do we want to update the shortcut outside of the ifs? */
2983   /* probably, if this fails the user may want to try again */
2984   i_update_middle_button(w_current, i_callback_attributes_attach,
2985                          _("Attach"));
2986 
2987   /* skip over head */
2988   s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list );
2989   if (!s_current) {
2990     return;
2991   }
2992 
2993   first_object = (OBJECT *) s_current->data;
2994   if (!first_object) {
2995     return;
2996   }
2997 
2998   /* skip over first object */
2999   s_current = g_list_next(s_current);
3000   while (s_current != NULL) {
3001     OBJECT *object = s_current->data;
3002     if (object != NULL) {
3003       o_attrib_attach (w_current->toplevel, object, first_object, TRUE);
3004       attached_objects = g_list_prepend (attached_objects, object);
3005       w_current->toplevel->page_current->CHANGED=1;
3006     }
3007     s_current = g_list_next(s_current);
3008   }
3009 
3010   if (attached_objects != NULL) {
3011     g_run_hook_object_list (w_current, "%attach-attribs-hook",
3012                             attached_objects);
3013     g_list_free (attached_objects);
3014   }
3015 
3016   o_undo_savestate(w_current, UNDO_ALL);
3017 }
3018 
3019 /*! \todo Finish function documentation!!!
3020  *  \brief
3021  *  \par Function Description
3022  *
3023  */
DEFINE_I_CALLBACK(attributes_detach)3024 DEFINE_I_CALLBACK(attributes_detach)
3025 {
3026   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3027   GList *s_current;
3028   OBJECT *o_current;
3029   GList *detached_attribs = NULL;
3030 
3031   g_return_if_fail (w_current != NULL);
3032 
3033   /* This is a new addition 3/15 to prevent this from executing
3034    * inside an action */
3035   if (w_current->inside_action) {
3036     return;
3037   }
3038 
3039   /* same note as above on i_update_middle_button */
3040   i_update_middle_button(w_current, i_callback_attributes_detach,
3041                          _("Detach"));
3042 
3043   s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list );
3044   while (s_current != NULL) {
3045     o_current = (OBJECT *) s_current->data;
3046     if (o_current) {
3047       if (o_current->attribs) {
3048         detached_attribs = g_list_concat (g_list_copy (o_current->attribs),
3049                                           detached_attribs);
3050         o_attrib_detach_all (w_current->toplevel, o_current);
3051         w_current->toplevel->page_current->CHANGED=1;
3052       }
3053     }
3054     s_current = g_list_next(s_current);
3055   }
3056 
3057   if (detached_attribs != NULL) {
3058     g_run_hook_object_list (w_current, "%detach-attribs-hook",
3059                             detached_attribs);
3060     g_list_free (detached_attribs);
3061   }
3062 
3063   o_undo_savestate(w_current, UNDO_ALL);
3064 }
3065 
3066 /*! \todo Finish function documentation!!!
3067  *  \brief
3068  *  \par Function Description
3069  *
3070  */
DEFINE_I_CALLBACK(attributes_show_name)3071 DEFINE_I_CALLBACK(attributes_show_name)
3072 {
3073   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3074   TOPLEVEL *toplevel = w_current->toplevel;
3075 
3076   g_return_if_fail (w_current != NULL);
3077 
3078   /* This is a new addition 3/15 to prevent this from executing
3079    * inside an action */
3080   if (w_current->inside_action) {
3081     return;
3082   }
3083 
3084   i_update_middle_button(w_current, i_callback_attributes_show_name,
3085                          _("ShowN"));
3086 
3087   if (o_select_selected (w_current)) {
3088     SELECTION *selection = toplevel->page_current->selection_list;
3089     GList *s_current;
3090 
3091     for (s_current = geda_list_get_glist (selection);
3092          s_current != NULL;
3093          s_current = g_list_next (s_current)) {
3094       OBJECT *object = (OBJECT*)s_current->data;
3095       if (object->type == OBJ_TEXT)
3096         o_attrib_toggle_show_name_value (w_current, object, SHOW_NAME);
3097     }
3098 
3099     o_undo_savestate (w_current, UNDO_ALL);
3100   }
3101 }
3102 
3103 /*! \todo Finish function documentation!!!
3104  *  \brief
3105  *  \par Function Description
3106  *
3107  */
DEFINE_I_CALLBACK(attributes_show_value)3108 DEFINE_I_CALLBACK(attributes_show_value)
3109 {
3110   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3111   TOPLEVEL *toplevel = w_current->toplevel;
3112 
3113   g_return_if_fail (w_current != NULL);
3114 
3115   /* This is a new addition 3/15 to prevent this from executing
3116    * inside an action */
3117   if (w_current->inside_action) {
3118     return;
3119   }
3120 
3121   i_update_middle_button(w_current, i_callback_attributes_show_value,
3122                          _("ShowV"));
3123 
3124   if (o_select_selected (w_current)) {
3125     SELECTION *selection = toplevel->page_current->selection_list;
3126     GList *s_current;
3127 
3128     for (s_current = geda_list_get_glist (selection);
3129          s_current != NULL;
3130          s_current = g_list_next (s_current)) {
3131       OBJECT *object = (OBJECT*)s_current->data;
3132       if (object->type == OBJ_TEXT)
3133         o_attrib_toggle_show_name_value (w_current, object, SHOW_VALUE);
3134     }
3135 
3136     o_undo_savestate (w_current, UNDO_ALL);
3137   }
3138 }
3139 
3140 /*! \todo Finish function documentation!!!
3141  *  \brief
3142  *  \par Function Description
3143  *
3144  */
DEFINE_I_CALLBACK(attributes_show_both)3145 DEFINE_I_CALLBACK(attributes_show_both)
3146 {
3147   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3148   TOPLEVEL *toplevel = w_current->toplevel;
3149 
3150   g_return_if_fail (w_current != NULL);
3151 
3152   /* This is a new addition 3/15 to prevent this from executing
3153    * inside an action */
3154   if (w_current->inside_action) {
3155     return;
3156   }
3157 
3158   i_update_middle_button(w_current, i_callback_attributes_show_both,
3159                          _("ShowB"));
3160 
3161   if (o_select_selected (w_current)) {
3162     SELECTION *selection = toplevel->page_current->selection_list;
3163     GList *s_current;
3164 
3165     for (s_current = geda_list_get_glist (selection);
3166          s_current != NULL;
3167          s_current = g_list_next (s_current)) {
3168       OBJECT *object = (OBJECT*)s_current->data;
3169       if (object->type == OBJ_TEXT)
3170         o_attrib_toggle_show_name_value (w_current, object, SHOW_NAME_VALUE);
3171     }
3172 
3173     o_undo_savestate (w_current, UNDO_ALL);
3174   }
3175 }
3176 
3177 /*! \todo Finish function documentation!!!
3178  *  \brief
3179  *  \par Function Description
3180  *
3181  */
DEFINE_I_CALLBACK(attributes_visibility_toggle)3182 DEFINE_I_CALLBACK(attributes_visibility_toggle)
3183 {
3184   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3185   TOPLEVEL *toplevel = w_current->toplevel;
3186 
3187   g_return_if_fail (w_current != NULL);
3188 
3189   /* This is a new addition 3/15 to prevent this from executing
3190    * inside an action */
3191   if (w_current->inside_action) {
3192     return;
3193   }
3194 
3195   i_update_middle_button(w_current,
3196                          i_callback_attributes_visibility_toggle,
3197                          _("VisToggle"));
3198 
3199   if (o_select_selected (w_current)) {
3200     SELECTION *selection = toplevel->page_current->selection_list;
3201     GList *s_current;
3202 
3203     for (s_current = geda_list_get_glist (selection);
3204          s_current != NULL;
3205          s_current = g_list_next (s_current)) {
3206       OBJECT *object = (OBJECT*)s_current->data;
3207       if (object->type == OBJ_TEXT)
3208         o_attrib_toggle_visibility (w_current, object);
3209     }
3210 
3211     o_undo_savestate (w_current, UNDO_ALL);
3212   }
3213 }
3214 
3215 /*! \section script-menu Script Menu Callback Functions */
3216 /*! \todo Finish function documentation!!!
3217  *  \brief
3218  *  \par Function Description
3219  *
3220  *  \note
3221  *  not currently implemented
3222  */
DEFINE_I_CALLBACK(script_console)3223 DEFINE_I_CALLBACK(script_console)
3224 {
3225   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3226 
3227   g_return_if_fail (w_current != NULL);
3228   printf(_("Sorry but this is a non-functioning menu option\n"));
3229 }
3230 
3231 /*! \section layers-menu Layers Menu Callback Functions */
3232 
3233 /*! \section options-menu Options Menu Callback Functions */
3234 /*! \todo Finish function documentation!!!
3235  *  \brief
3236  *  \par Function Description
3237  *
3238  *  \note
3239  *  repeat last command doesn't make sense on options either??? (does it?)
3240  */
DEFINE_I_CALLBACK(options_text_size)3241 DEFINE_I_CALLBACK(options_text_size)
3242 {
3243   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3244 
3245   g_return_if_fail (w_current != NULL);
3246   text_size_dialog(w_current);
3247 }
3248 
3249 /*! \todo Finish function documentation!!!
3250  *  \brief
3251  *  \par Function Description
3252  *
3253  */
DEFINE_I_CALLBACK(options_snap_size)3254 DEFINE_I_CALLBACK(options_snap_size)
3255 {
3256   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3257 
3258   g_return_if_fail (w_current != NULL);
3259   snap_size_dialog(w_current);
3260 }
3261 
3262 /*! \brief Multiply by two the snap grid size.
3263  *  \par Function Description
3264  *  Callback function for the scale-up snap grid size hotkey.
3265  *  Multiply by two the snap grid size.
3266  */
DEFINE_I_CALLBACK(options_scale_up_snap_size)3267 DEFINE_I_CALLBACK(options_scale_up_snap_size)
3268 {
3269   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3270 
3271   g_return_if_fail (w_current != NULL);
3272 
3273   w_current->snap_size *= 2;
3274   w_current->toplevel->page_current->CHANGED=1;  /* maybe remove those two lines */
3275   o_undo_savestate(w_current, UNDO_ALL);
3276 
3277   i_update_grid_info (w_current);
3278   o_invalidate_all (w_current);
3279 }
3280 
3281 /*! \brief Divide by two the snap grid size.
3282  *  \par Function Description
3283  *  Callback function for the scale-down snap grid size hotkey.
3284  *  Divide by two the snap grid size (if it's and even number).
3285  */
DEFINE_I_CALLBACK(options_scale_down_snap_size)3286 DEFINE_I_CALLBACK(options_scale_down_snap_size)
3287 {
3288   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3289 
3290   g_return_if_fail (w_current != NULL);
3291 
3292   if (w_current->snap_size % 2 == 0)
3293     w_current->snap_size /= 2;
3294   w_current->toplevel->page_current->CHANGED=1;  /* maybe remove those two lines */
3295   o_undo_savestate(w_current, UNDO_ALL);
3296 
3297   i_update_grid_info (w_current);
3298   o_invalidate_all (w_current);
3299 
3300 }
3301 
3302 /*! \todo Finish function documentation!!!
3303  *  \brief
3304  *  \par Function Description
3305  *
3306  *  \note
3307  *  repeat last command doesn't make sense on options either??? (does
3308  *  it?)
3309  */
DEFINE_I_CALLBACK(options_afeedback)3310 DEFINE_I_CALLBACK(options_afeedback)
3311 {
3312   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3313 
3314   g_return_if_fail (w_current != NULL);
3315 
3316   if (w_current->actionfeedback_mode == BOUNDINGBOX) {
3317     w_current->actionfeedback_mode = OUTLINE;
3318     s_log_message(_("Action feedback mode set to OUTLINE\n"));
3319   } else {
3320     w_current->actionfeedback_mode = BOUNDINGBOX;
3321     s_log_message(_("Action feedback mode set to BOUNDINGBOX\n"));
3322   }
3323   if (w_current->inside_action &&
3324       w_current->toplevel->page_current->place_list != NULL)
3325     o_place_invalidate_rubber (w_current, FALSE);
3326 }
3327 
3328 /*! \todo Finish function documentation!!!
3329  *  \brief
3330  *  \par Function Description
3331  *
3332  */
DEFINE_I_CALLBACK(options_grid)3333 DEFINE_I_CALLBACK(options_grid)
3334 {
3335   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3336 
3337   g_return_if_fail (w_current != NULL);
3338 
3339   switch (w_current->grid) {
3340     case GRID_NONE: w_current->grid = GRID_DOTS; break;
3341     case GRID_DOTS: w_current->grid = GRID_MESH; break;
3342     case GRID_MESH: w_current->grid = GRID_NONE; break;
3343   }
3344 
3345   switch (w_current->grid) {
3346     case GRID_NONE: s_log_message (_("Grid OFF\n"));           break;
3347     case GRID_DOTS: s_log_message (_("Dot grid selected\n"));  break;
3348     case GRID_MESH: s_log_message (_("Mesh grid selected\n")); break;
3349   }
3350 
3351   i_update_grid_info (w_current);
3352   o_invalidate_all (w_current);
3353 }
3354 
3355 /*! \todo Finish function documentation!!!
3356  *  \brief
3357  *  \par Function Description
3358  *
3359  */
DEFINE_I_CALLBACK(options_snap)3360 DEFINE_I_CALLBACK(options_snap)
3361 {
3362   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3363 
3364   /* toggle to the next snap state */
3365   w_current->snap = (w_current->snap+1) % SNAP_STATE_COUNT;
3366 
3367   switch (w_current->snap) {
3368   case SNAP_OFF:
3369     s_log_message(_("Snap OFF (CAUTION!)\n"));
3370     break;
3371   case SNAP_GRID:
3372     s_log_message(_("Snap ON\n"));
3373     break;
3374   case SNAP_RESNAP:
3375     s_log_message(_("Snap back to the grid (CAUTION!)\n"));
3376     break;
3377   default:
3378     g_critical("options_snap: toplevel->snap out of range: %d\n",
3379                w_current->snap);
3380   }
3381 
3382   i_show_state(w_current, NULL); /* update status on screen */
3383   i_update_grid_info (w_current);
3384 }
3385 
3386 /*! \todo Finish function documentation!!!
3387  *  \brief
3388  *  \par Function Description
3389  *
3390  *  \note
3391  *  Rubber band is cool !
3392  *  Added on/off option from the pull down menu
3393  *  Chris Ellec - January 2001
3394  */
DEFINE_I_CALLBACK(options_rubberband)3395 DEFINE_I_CALLBACK(options_rubberband)
3396 {
3397   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3398 
3399   if (w_current->netconn_rubberband) {
3400     w_current->netconn_rubberband = 0;
3401     s_log_message(_("Rubber band OFF \n"));
3402   } else {
3403     w_current->netconn_rubberband = 1;
3404     s_log_message(_("Rubber band ON\n"));
3405   }
3406 }
3407 
3408 
3409 /*! \brief callback function for setting the magnetic net option
3410  *  \par Function Description
3411  *  This function just toggles a variable to switch the magnetic net
3412  *  mode ON and OFF
3413  */
DEFINE_I_CALLBACK(options_magneticnet)3414 DEFINE_I_CALLBACK(options_magneticnet)
3415 {
3416   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3417 
3418   if ((w_current->magneticnet_mode = !w_current->magneticnet_mode)) {
3419     s_log_message(_("magnetic net mode: ON\n"));
3420   }
3421   else {
3422     s_log_message(_("magnetic net mode: OFF\n"));
3423   }
3424   i_show_state(w_current, NULL);
3425 }
3426 
3427 
3428 /*! \todo Finish function documentation!!!
3429  *  \brief
3430  *  \par Function Description
3431  *
3432  */
DEFINE_I_CALLBACK(options_show_log_window)3433 DEFINE_I_CALLBACK(options_show_log_window)
3434 {
3435   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3436 
3437   g_return_if_fail (w_current != NULL);
3438   x_log_open ();
3439 }
3440 
3441 /*! \todo Finish function documentation!!!
3442  *  \brief
3443  *  \par Function Description
3444  *
3445  *  \note
3446  *  this is Ales' catch all misc callback
3447  */
DEFINE_I_CALLBACK(misc)3448 DEFINE_I_CALLBACK(misc)
3449 {
3450 }
3451 
3452 /*! \todo Finish function documentation!!!
3453  *  \brief
3454  *  \par Function Description
3455  *
3456  *  \note
3457  *  this is Ales' second catch all misc callback
3458  */
DEFINE_I_CALLBACK(misc2)3459 DEFINE_I_CALLBACK(misc2)
3460 {
3461 }
3462 
3463 /*! \todo Finish function documentation!!!
3464  *  \brief
3465  *  \par Function Description
3466  *
3467  *  \note
3468  *  this is Ales' third catch all misc callback
3469  */
DEFINE_I_CALLBACK(misc3)3470 DEFINE_I_CALLBACK(misc3)
3471 {
3472 }
3473 
3474 /*! \todo Finish function documentation!!!
3475  *  \brief
3476  *  \par Function Description
3477  *
3478  *  \note
3479  *  HACK: be sure that you don't use the widget parameter in this one,
3480  *  since it is being called with a null, I suppose we should call it
3481  *  with the right param.
3482  */
DEFINE_I_CALLBACK(cancel)3483 DEFINE_I_CALLBACK(cancel)
3484 {
3485   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3486   TOPLEVEL *toplevel = w_current->toplevel;
3487   GValue value = { 0, };
3488 
3489   g_return_if_fail (w_current != NULL);
3490 
3491   if (w_current->event_state == ENDCOMP &&
3492       w_current->cswindow) {
3493     /* user hit escape key when placing components */
3494 
3495     /* Undraw any outline of the place list */
3496     o_place_invalidate_rubber (w_current, FALSE);
3497     w_current->rubber_visible = 0;
3498 
3499     /* De-select the lists in the component selector */
3500     x_compselect_deselect (w_current);
3501 
3502     /* Present the component selector again */
3503     g_value_init (&value, G_TYPE_BOOLEAN);
3504     g_value_set_boolean (&value, FALSE);
3505     g_object_set_property (G_OBJECT(w_current->cswindow), "hidden", &value);
3506   }
3507 
3508   if (w_current->inside_action) {
3509     /* If we're cancelling from a move action, re-wind the
3510      * page contents back to their state before we started */
3511     if (w_current->event_state == MOVE ||
3512         w_current->event_state == ENDMOVE)
3513       o_move_cancel (w_current);
3514 
3515     /* If we're cancelling from a grip action, call the specific cancel
3516      * routine to reset the visibility of the object being modified */
3517     if (w_current->event_state == GRIPS)
3518       o_grips_cancel (w_current);
3519   }
3520 
3521   /* Free the place list and its contents. If we were in a move
3522    * action, the list (refering to objects on the page) would
3523    * already have been cleared in o_move_cancel(), so this is OK. */
3524   s_delete_object_glist(toplevel, toplevel->page_current->place_list);
3525   toplevel->page_current->place_list = NULL;
3526 
3527   /* leave this on for now... but it might have to change */
3528   /* this is problematic since we don't know what the right mode */
3529   /* (when you cancel inside an action) should be */
3530   i_set_state(w_current, SELECT);
3531   i_update_toolbar(w_current);
3532 
3533   /* clear the key guile command-sequence */
3534   g_keys_reset (w_current);
3535 
3536   if (w_current->inside_action) {
3537      o_invalidate_all (w_current);
3538   }
3539 
3540   w_current->inside_action=0;
3541 }
3542 
3543 /*! \section help-menu Help Menu Callback Functions */
3544 /*! \todo Finish function documentation!!!
3545  *  \brief
3546  *  \par Function Description
3547  *
3548  */
DEFINE_I_CALLBACK(help_about)3549 DEFINE_I_CALLBACK(help_about)
3550 {
3551   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3552 
3553   g_return_if_fail (w_current != NULL);
3554   about_dialog(w_current);
3555 }
3556 
3557 /*! \todo Finish function documentation!!!
3558  *  \brief
3559  *  \par Function Description
3560  *
3561  */
DEFINE_I_CALLBACK(help_hotkeys)3562 DEFINE_I_CALLBACK(help_hotkeys)
3563 {
3564   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3565 
3566   g_return_if_fail (w_current != NULL);
3567   x_dialog_hotkeys(w_current);
3568 }
3569 
3570 /*! \todo Finish function documentation!!!
3571  *  \brief
3572  *  \par Function Description
3573  *
3574  */
DEFINE_I_CALLBACK(options_show_coord_window)3575 DEFINE_I_CALLBACK(options_show_coord_window)
3576 {
3577   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3578 
3579   g_return_if_fail (w_current != NULL);
3580   coord_dialog (w_current, 0, 0);
3581 }
3582 
3583 /* these is a special wrapper function which cannot use the above */
3584 /* DEFINE_I_CALLBACK macro */
3585 
3586 /*! \todo Finish function documentation!!!
3587  *  \brief
3588  *  \par Function Description
3589  *
3590  *  \note
3591  *  When invoked (via signal delete_event), closes the current window
3592  *  if this is the last window, quit gschem
3593  *  used when you click the close button on the window which sends a DELETE
3594  *  signal to the app
3595  */
i_callback_close_wm(GtkWidget * widget,GdkEvent * event,gpointer data)3596 gboolean i_callback_close_wm ( GtkWidget *widget, GdkEvent *event,
3597 	                   gpointer data )
3598 {
3599 
3600   GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL*) data;
3601   g_return_val_if_fail ((w_current != NULL), TRUE);
3602 
3603   x_window_close(w_current);
3604 
3605   /* stop further propagation of the delete_event signal for window: */
3606   /*   - if user has cancelled the close the window should obvioulsy */
3607   /*   not be destroyed */
3608   /*   - otherwise window has already been destroyed, nothing more to */
3609   /*   do */
3610   return TRUE;
3611 }
3612