1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
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.
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.
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
29 #include <glib/gstdio.h>
33 build_menu (SCM s_menu
, gboolean is_main_menu
, GschemToplevel
*w_current
)
35 GtkWidget
*menu
= gtk_menu_new ();
38 GtkWidget
*tearoff_menu_item
= gtk_tearoff_menu_item_new ();
39 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), tearoff_menu_item
);
40 gtk_widget_show (tearoff_menu_item
);
43 for (SCM l0
= s_menu
; scm_is_pair (l0
); l0
= scm_cdr (l0
)) {
44 SCM s_section
= scm_car (l0
);
45 SCM_ASSERT (scm_is_true (scm_list_p (s_section
)),
46 s_section
, SCM_ARGn
, "build_menu section");
48 for (SCM l1
= s_section
; scm_is_pair (l1
); l1
= scm_cdr (l1
)) {
49 SCM s_item
= scm_car (l1
);
50 SCM_ASSERT (scm_is_action (s_item
),
51 s_item
, SCM_ARGn
, "build_menu item");
53 /* make sure the action won't ever be garbage collected
54 since we're going to point to it from C data structures */
55 scm_permanent_object (s_item
);
57 GschemAction
*action
= scm_to_action (s_item
);
58 GtkWidget
*menu_item
=
59 gschem_action_create_menu_item (action
, is_main_menu
, w_current
);
60 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menu_item
);
61 gtk_widget_show (menu_item
);
64 if (scm_is_pair (scm_cdr (l0
))) {
66 GtkWidget
*menu_item
= gtk_menu_item_new ();
67 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menu_item
);
68 gtk_widget_show (menu_item
);
75 /*! \todo Finish function documentation!!!
77 * \par Function Description
81 x_menus_create_main_menu (GschemToplevel
*w_current
)
83 SCM s_var
= scm_module_variable (scm_current_module (),
84 scm_from_utf8_symbol ("menubar"));
85 if (!scm_is_true (s_var
)) {
86 g_critical (_("No menubar definition found\n"));
90 SCM s_menubar
= scm_variable_ref (s_var
);
91 if (scm_is_null (s_menubar
) || !scm_is_true (scm_list_p (s_menubar
))) {
92 g_critical (_("Empty or malformed menubar definition\n"));
96 w_current
->menubar
= gtk_menu_bar_new ();
98 for (SCM l
= s_menubar
; scm_is_pair (l
); l
= scm_cdr (l
)) {
99 SCM s_menu
= scm_car (l
);
100 SCM_ASSERT (scm_is_pair (s_menu
),
101 s_menu
, SCM_ARGn
, "get_main_menu menu");
103 SCM s_title
= scm_car (s_menu
);
104 SCM_ASSERT (scm_is_string (s_title
),
105 s_title
, SCM_ARGn
, "get_main_menu menu title");
107 GtkWidget
*menu
= build_menu (scm_cdr (s_menu
), TRUE
, w_current
);
109 scm_dynwind_begin (0);
111 char *title
= scm_to_utf8_string (s_title
);
112 scm_dynwind_free (title
);
114 /* store lower-case title without underscores as settings name
115 for saving/restoring torn-off menus */
116 gchar
*settings_name
= g_ascii_strdown (title
, -1);
117 gchar
*i
= settings_name
, *j
= settings_name
;
121 } while (*i
++ != '\0');
122 g_object_set_data (G_OBJECT (menu
), "settings-name", settings_name
);
124 GtkWidget
*root_menu
= gtk_menu_item_new_with_mnemonic (title
);
125 gtk_widget_show (root_menu
);
126 gtk_menu_item_set_submenu (GTK_MENU_ITEM (root_menu
), menu
);
127 /* no longer right justify the help menu since that has gone out
129 gtk_menu_shell_append (GTK_MENU_SHELL (w_current
->menubar
), root_menu
);
136 x_menus_create_main_popup (GschemToplevel
*w_current
)
138 SCM s_var
= scm_module_variable (scm_current_module (),
139 scm_from_utf8_symbol ("context-menu"));
140 if (!scm_is_true (s_var
)) {
141 g_warning (_("No context menu definition found\n"));
145 SCM s_menu
= scm_variable_ref (s_var
);
146 if (scm_is_null (s_menu
) || !scm_is_true (scm_list_p (s_menu
))) {
147 g_warning (_("Empty or malformed context menu definition\n"));
151 w_current
->popup_menu
= build_menu (s_menu
, FALSE
, w_current
);
154 #define MAX_RECENT_FILES 10
155 /*! \brief Callback for recent-chooser.
157 * Will be called if element of recent-file-list is activated
160 recent_chooser_item_activated (GtkRecentChooser
*chooser
, GschemToplevel
*w_current
)
165 uri
= gtk_recent_chooser_get_current_uri (chooser
);
166 filename
= g_filename_from_uri(uri
, NULL
, NULL
);
167 x_highlevel_open_page (w_current
, (char *) filename
);
173 /*! \brief Create a submenu with filenames for the 'Open Recent'
177 create_recent_chooser_menu (GschemToplevel
*w_current
)
179 GtkRecentFilter
*recent_filter
;
180 GtkWidget
*menuitem_file_recent_items
;
181 recent_manager
= gtk_recent_manager_get_default();
183 menuitem_file_recent_items
= gtk_recent_chooser_menu_new_for_manager(recent_manager
);
185 /* Show only schematic- and symbol-files (*.sch and *.sym) in list */
186 recent_filter
= gtk_recent_filter_new();
187 gtk_recent_filter_add_mime_type(recent_filter
, "application/x-geda-schematic");
188 gtk_recent_filter_add_mime_type(recent_filter
, "application/x-geda-symbol");
189 gtk_recent_filter_add_pattern(recent_filter
, "*.sch");
190 gtk_recent_filter_add_pattern(recent_filter
, "*.sym");
191 gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(menuitem_file_recent_items
), recent_filter
);
193 gtk_recent_chooser_set_show_tips(GTK_RECENT_CHOOSER(menuitem_file_recent_items
), TRUE
);
194 gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(menuitem_file_recent_items
),
195 GTK_RECENT_SORT_MRU
);
196 gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(menuitem_file_recent_items
), MAX_RECENT_FILES
);
197 gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(menuitem_file_recent_items
), FALSE
);
198 gtk_recent_chooser_menu_set_show_numbers(GTK_RECENT_CHOOSER_MENU(menuitem_file_recent_items
), TRUE
);
199 g_signal_connect(GTK_OBJECT(menuitem_file_recent_items
), "item-activated",
200 G_CALLBACK(recent_chooser_item_activated
), w_current
);
202 return menuitem_file_recent_items
;
205 /*! \brief Create submenus for various menu items.
207 * Called from x_window_setup().
210 x_menus_create_submenus (GschemToplevel
*w_current
)
212 /* create recent files menu */
213 w_current
->recent_chooser_menu
= create_recent_chooser_menu (w_current
);
214 g_object_set_data (G_OBJECT (w_current
->recent_chooser_menu
),
215 "settings-name", "recent-files");
217 /* create left docking area menu */
218 w_current
->left_docking_area_menu
= gtk_menu_new ();
219 g_object_set_data (G_OBJECT (w_current
->left_docking_area_menu
),
220 "settings-name", "left-docking-area");
221 gtk_menu_shell_append (GTK_MENU_SHELL (w_current
->left_docking_area_menu
),
222 gtk_tearoff_menu_item_new ());
223 gtk_widget_show_all (w_current
->left_docking_area_menu
);
225 /* create bottom docking area menu */
226 w_current
->bottom_docking_area_menu
= gtk_menu_new ();
227 g_object_set_data (G_OBJECT (w_current
->bottom_docking_area_menu
),
228 "settings-name", "bottom-docking-area");
229 gtk_menu_shell_append (GTK_MENU_SHELL (w_current
->bottom_docking_area_menu
),
230 gtk_tearoff_menu_item_new ());
231 gtk_widget_show_all (w_current
->bottom_docking_area_menu
);
233 /* create right docking area menu */
234 w_current
->right_docking_area_menu
= gtk_menu_new ();
235 g_object_set_data (G_OBJECT (w_current
->right_docking_area_menu
),
236 "settings-name", "right-docking-area");
237 gtk_menu_shell_append (GTK_MENU_SHELL (w_current
->right_docking_area_menu
),
238 gtk_tearoff_menu_item_new ());
239 gtk_widget_show_all (w_current
->right_docking_area_menu
);
243 x_menus_create_toolbar (GschemToplevel
*w_current
)
245 SCM s_var
= scm_module_variable (scm_current_module (),
246 scm_from_utf8_symbol ("toolbar"));
247 if (!scm_is_true (s_var
)) {
248 g_warning (_("No toolbar definition found\n"));
252 SCM s_toolbar
= scm_variable_ref (s_var
);
253 if (scm_is_null (s_toolbar
) || !scm_is_true (scm_list_p (s_toolbar
))) {
254 g_warning (_("Empty or malformed toolbar definition\n"));
258 w_current
->toolbar
= gtk_toolbar_new ();
259 gtk_orientable_set_orientation (GTK_ORIENTABLE (w_current
->toolbar
),
260 GTK_ORIENTATION_HORIZONTAL
);
261 gtk_toolbar_set_style (GTK_TOOLBAR (w_current
->toolbar
), GTK_TOOLBAR_ICONS
);
263 for (SCM l0
= s_toolbar
; scm_is_pair (l0
); l0
= scm_cdr (l0
)) {
264 SCM s_section
= scm_car (l0
);
265 SCM_ASSERT (scm_is_true (scm_list_p (s_section
)),
266 s_section
, SCM_ARGn
, "x_menus_create_toolbar section");
268 for (SCM l1
= s_section
; scm_is_pair (l1
); l1
= scm_cdr (l1
)) {
269 SCM s_item
= scm_car (l1
);
270 SCM_ASSERT (scm_is_action (s_item
),
271 s_item
, SCM_ARGn
, "x_menus_create_toolbar item");
273 /* make sure the action won't ever be garbage collected
274 since we're going to point to it from C data structures */
275 scm_permanent_object (s_item
);
277 GschemAction
*action
= scm_to_action (s_item
);
278 GtkToolItem
*button
=
279 gschem_action_create_tool_button (action
, w_current
);
280 gtk_toolbar_insert (GTK_TOOLBAR (w_current
->toolbar
), button
, -1);
283 if (scm_is_pair (scm_cdr (l0
)))
284 gtk_toolbar_insert (GTK_TOOLBAR (w_current
->toolbar
),
285 gtk_separator_tool_item_new (), -1);
288 gtk_widget_show_all (w_current
->toolbar
);
290 /* activate 'select' button at start-up */
291 i_update_toolbar (w_current
);