1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003-2007 Stuart D. Brorson.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
19 /*------------------------------------------------------------------
20 * This file holds fcns used to display the file open/save dialog box.
21 * It was cloned from x_fileselect.c in gschem/src, and then hacked
22 * by SDB for use in gattrib.
23 *------------------------------------------------------------------*/
29 /*------------------------------------------------------------------
30 * Includes required to run graphical widgets.
31 *------------------------------------------------------------------*/
36 #include <gdk/gdkkeysyms.h>
39 #include <glib-object.h>
41 #include <sys/types.h>
43 #ifdef HAVE_SYS_PARAM_H
44 #include <sys/param.h>
63 #include "gtksheet_2_2.h"
64 #include "gtkitementry_2_2.h"
66 /*------------------------------------------------------------------
67 * Gattrib specific includes
68 *------------------------------------------------------------------*/
70 #include <libgeda/libgeda.h> /* geda library fcns */
71 #include "../include/struct.h" /* typdef and struct declarations */
72 #include "../include/prototype.h" /* function prototypes */
73 #include "../include/globals.h"
75 #ifdef HAVE_LIBDMALLOC
80 /* ----- x_fileselect stuff begins here ----- */
82 /*------------------------------------------------------------------
83 * This fcn creates and sets the file filter for the filechooser.
84 *------------------------------------------------------------------*/
86 x_fileselect_setup_filechooser_filters (GtkFileChooser
*filechooser
)
88 GtkFileFilter
*filter
;
90 /* file filter for schematic files (*.sch) */
91 filter
= gtk_file_filter_new ();
92 gtk_file_filter_set_name (filter
, "Schematics");
93 gtk_file_filter_add_pattern (filter
, "*.sch");
94 gtk_file_chooser_add_filter (filechooser
, filter
);
95 /* file filter for symbol files (*.sym) */
96 filter
= gtk_file_filter_new ();
97 gtk_file_filter_set_name (filter
, "Symbols");
98 gtk_file_filter_add_pattern (filter
, "*.sym");
99 gtk_file_chooser_add_filter (filechooser
, filter
);
100 /* file filter for both symbol and schematic files (*.sym+*.sch) */
101 filter
= gtk_file_filter_new ();
102 gtk_file_filter_set_name (filter
, "Schematics and symbols");
103 gtk_file_filter_add_pattern (filter
, "*.sym");
104 gtk_file_filter_add_pattern (filter
, "*.sch");
105 gtk_file_chooser_add_filter (filechooser
, filter
);
106 /* file filter that match any file */
107 filter
= gtk_file_filter_new ();
108 gtk_file_filter_set_name (filter
, "All files");
109 gtk_file_filter_add_pattern (filter
, "*");
110 gtk_file_chooser_add_filter (filechooser
, filter
);
114 /*! \brief Open all files specified in the list. The caller
115 * is responsible for freeing the strings and the list
118 * \par Function Description
119 * The function updates the user interface. At the end of the function,
120 * the toplevel's current page is set to the page of the last loaded page.
122 * \param [in] filenames list of files to be opened
123 * \returns FALSE if any of the files could not be opened, TRUE otherwise
126 x_fileselect_load_files (GSList
*filenames
)
132 /* iterate over selected files */
133 for (filename
= filenames
;
135 filename
= g_slist_next (filename
)) {
136 gchar
*string
= (gchar
*)filename
->data
;
139 s_log_message("Loading file [%s]\n", string
);
142 s_page_goto (pr_current
, s_page_new (pr_current
, string
));
144 if(s_toplevel_read_page(string
) == 0) {
145 fprintf(stderr
, "Couldn't load schematic [%s]\n", string
);
149 /* Now add all items found to the master lists */
150 s_sheet_data_add_master_comp_list_items(pr_current
->page_current
->object_head
);
151 s_sheet_data_add_master_comp_attrib_list_items(pr_current
->page_current
->object_head
);
153 /* Note that this must be changed. We need to input the entire project
154 * before doing anything with the nets because we need to first
155 * determine where they are all connected! */
156 s_sheet_data_add_master_net_list_items(pr_current
->page_current
->object_head
);
157 s_sheet_data_add_master_net_attrib_list_items(pr_current
->page_current
->object_head
);
160 s_sheet_data_add_master_pin_list_items(pr_current
->page_current
->object_head
);
161 s_sheet_data_add_master_pin_attrib_list_items(pr_current
->page_current
->object_head
);
162 } /* end of loop over files */
165 /* ---------- Sort the master lists ---------- */
166 s_string_list_sort_master_comp_list();
167 s_string_list_sort_master_comp_attrib_list();
170 /* Note that this must be changed. We need to input the entire project
171 * before doing anything with the nets because we need to first
172 * determine where they are all connected! */
173 s_string_list_sort_master_net_list();
174 s_string_list_sort_master_net_attrib_list();
177 s_string_list_sort_master_pin_list();
178 s_string_list_sort_master_pin_attrib_list();
180 /* ---------- Create and load the tables ---------- */
181 sheet_head
->component_table
= s_table_new(sheet_head
->comp_count
, sheet_head
->comp_attrib_count
);
182 sheet_head
->net_table
= s_table_new(sheet_head
->net_count
, sheet_head
->net_attrib_count
);
183 sheet_head
->pin_table
= s_table_new(sheet_head
->pin_count
, sheet_head
->pin_attrib_count
);
185 /* must iterate over all pages in design */
186 for ( iter
= geda_list_get_glist( pr_current
->pages
);
188 iter
= g_list_next( iter
) ) {
189 p_local
= (PAGE
*)iter
->data
;
191 /* only traverse pages which are toplevel */
192 if (p_local
->object_head
&& p_local
->page_control
== 0) {
193 /* adds all components from page to comp_table */
194 s_table_add_toplevel_comp_items_to_comp_table(p_local
->object_head
);
196 /* Note that this must be changed. We need to input the entire project
197 * before doing anything with the nets because we need to first
198 * determine where they are all connected! */
200 /* adds all nets from page to net_table */
201 s_table_add_toplevel_net_items_to_net_table(p_local
->object_head
);
204 /* adds all pins from page to pin_table */
205 s_table_add_toplevel_pin_items_to_pin_table(p_local
->object_head
);
207 } /* for loop over pages */
209 /* -------------- update windows --------------- */
210 x_window_add_items(); /* This updates the top level stuff,
211 * and then calls another fcn to update
212 * the GtkSheet itself. */
215 /* ---------- Now verify correctness of entire design. ---------- */
216 s_toplevel_verify_design(pr_current
); /* pr_current is a global */
221 /*! \brief This function opens a file chooser dialog and waits for the user
222 * to select at least one file to load as toplevel's new pages.
224 * \returns list of files to be opened, or NULL if the user cancelled
228 x_fileselect_open (void)
231 GSList
*filenames
= NULL
;
233 dialog
= gtk_file_chooser_dialog_new ("Open...",
235 GTK_FILE_CHOOSER_ACTION_OPEN
,
236 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
237 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
240 #if GTK_CHECK_VERSION (2,6,0)
241 /* Set the alternative button order (ok, cancel, help) for other systems */
242 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
248 g_object_set (dialog
,
250 "select-multiple", TRUE
,
252 /* add file filters to dialog */
253 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog
));
254 gtk_widget_show (dialog
);
256 if(gtk_dialog_run (GTK_DIALOG(dialog
)) == GTK_RESPONSE_ACCEPT
)
257 filenames
= gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog
));
259 gtk_widget_destroy (dialog
);
263 /*------------------------------------------------------------------
264 * This function opens a file chooser dialog and wait for the user to
265 * select a file where the toplevel's current page will be
268 * If the user cancels the operation (with the cancel button), the
271 * The function updates the user interface.
272 *------------------------------------------------------------------*/
274 x_fileselect_save (void)
278 dialog
= gtk_file_chooser_dialog_new ("Save as...",
280 GTK_FILE_CHOOSER_ACTION_SAVE
,
281 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
282 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
285 #if GTK_CHECK_VERSION (2,6,0)
286 /* Set the alternative button order (ok, cancel, help) for other systems */
287 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
293 g_object_set (dialog
,
295 "select-multiple", FALSE
,
296 /* only in GTK 2.8 */
297 /* "do-overwrite-confirmation", TRUE, */
299 /* add file filters to dialog */
300 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog
));
301 gtk_widget_show (dialog
);
302 if (gtk_dialog_run ((GtkDialog
*)dialog
) == GTK_RESPONSE_ACCEPT
) {
304 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog
));
306 /* try saving current page of toplevel to file filename */
307 if (filename
!= NULL
&&
308 f_save (pr_current
, filename
)) {
309 s_log_message ("Saved As [%s]\n", filename
);
311 /* replace page filename with new one, do not free filename */
312 g_free (pr_current
->page_current
->page_filename
);
313 pr_current
->page_current
->page_filename
= filename
;
315 /* reset the changed flag of current page*/
316 pr_current
->page_current
->CHANGED
= 0;
319 /* report error in log and status bar */
320 s_log_message ("Could NOT save [%s]\n",
321 pr_current
->page_current
->page_filename
);
327 gtk_widget_destroy (dialog
);