Bumped versions to 1.1.2/20070818/30:2:0 for the next development snapshot
[geda-gaf/whiteaudio.git] / gschem / src / x_fileselect.c
blobadc491ffbfa20244bd3a3db87bf13b9cf1b68b2e
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
22 #ifdef HAVE_LIBDMALLOC
23 #include <dmalloc.h>
24 #endif
26 #include <libgeda/libgeda.h>
27 #include <gtk/gtk.h>
29 #include "../include/globals.h"
30 #include "../include/prototype.h"
31 #include "../include/x_preview.h"
34 /*! \brief Creates filter for file chooser.
35 * \par Function Description
36 * This function adds file filters to <B>filechooser</B>.
38 * \param [in] filechooser The file chooser to add filter to.
40 static void
41 x_fileselect_setup_filechooser_filters (GtkFileChooser *filechooser)
43 GtkFileFilter *filter;
45 /* file filter for schematic files (*.sch) */
46 filter = gtk_file_filter_new ();
47 gtk_file_filter_set_name (filter, _("Schematics"));
48 gtk_file_filter_add_pattern (filter, "*.sch");
49 gtk_file_chooser_add_filter (filechooser, filter);
50 /* file filter for symbol files (*.sym) */
51 filter = gtk_file_filter_new ();
52 gtk_file_filter_set_name (filter, _("Symbols"));
53 gtk_file_filter_add_pattern (filter, "*.sym");
54 gtk_file_chooser_add_filter (filechooser, filter);
55 /* file filter for both symbol and schematic files (*.sym+*.sch) */
56 filter = gtk_file_filter_new ();
57 gtk_file_filter_set_name (filter, _("Schematics and symbols"));
58 gtk_file_filter_add_pattern (filter, "*.sym");
59 gtk_file_filter_add_pattern (filter, "*.sch");
60 gtk_file_chooser_add_filter (filechooser, filter);
61 /* file filter that match any file */
62 filter = gtk_file_filter_new ();
63 gtk_file_filter_set_name (filter, _("All files"));
64 gtk_file_filter_add_pattern (filter, "*");
65 gtk_file_chooser_add_filter (filechooser, filter);
69 /*! \brief Updates the preview when the selection changes.
70 * \par Function Description
71 * This is the callback function connected to the 'update-preview'
72 * signal of the <B>GtkFileChooser</B>.
74 * It updates the preview widget with the name of the newly selected
75 * file.
77 * \param [in] chooser The file chooser to add the preview to.
78 * \param [in] user_data A pointer on the preview widget.
80 static void
81 x_fileselect_callback_update_preview (GtkFileChooser *chooser,
82 gpointer user_data)
84 Preview *preview = PREVIEW (user_data);
85 gchar *filename, *preview_filename = NULL;
87 filename = gtk_file_chooser_get_preview_filename (chooser);
88 if (filename != NULL &&
89 !g_file_test (filename, G_FILE_TEST_IS_DIR)) {
90 preview_filename = filename;
93 /* update preview */
94 g_object_set (preview,
95 "filename", preview_filename,
96 "active", (preview_filename != NULL),
97 NULL);
99 g_free (filename);
102 /*! \brief Adds a preview to a file chooser.
103 * \par Function Description
104 * This function adds a preview section to the stock
105 * <B>GtkFileChooser</B>.
107 * The <B>Preview</B> object is inserted in a frame and alignment
108 * widget for accurate positionning.
110 * Other widgets can be added to this preview area for example to
111 * enable/disable the preview. Currently, the preview is always
112 * active.
114 * Function <B>x_fileselect_callback_update_preview()</B> is
115 * connected to the signal 'update-preview' of <B>GtkFileChooser</B>
116 * so that it redraws the preview area every time a new file is
117 * selected.
119 * \param [in] filechooser The file chooser to add the preview to.
121 static void
122 x_fileselect_add_preview (GtkFileChooser *filechooser)
124 GtkWidget *alignment, *frame, *preview;
126 frame = GTK_WIDGET (g_object_new (GTK_TYPE_FRAME,
127 "label", _("Preview"),
128 NULL));
129 alignment = GTK_WIDGET (g_object_new (GTK_TYPE_ALIGNMENT,
130 "right-padding", 5,
131 "left-padding", 5,
132 "xscale", 0.0,
133 "yscale", 0.0,
134 "xalign", 0.5,
135 "yalign", 0.5,
136 NULL));
137 preview = GTK_WIDGET (g_object_new (TYPE_PREVIEW,
138 "active", TRUE,
139 NULL));
140 gtk_container_add (GTK_CONTAINER (alignment), preview);
141 gtk_container_add (GTK_CONTAINER (frame), alignment);
142 gtk_widget_show_all (frame);
144 g_object_set (filechooser,
145 /* GtkFileChooser */
146 "use-preview-label", FALSE,
147 "preview-widget", frame,
148 NULL);
150 /* connect callback to update preview */
151 g_signal_connect (filechooser,
152 "update-preview",
153 G_CALLBACK (x_fileselect_callback_update_preview),
154 preview);
158 /*! \brief Opens a file chooser for opening one or more schematics.
159 * \par Function Description
160 * This function opens a file chooser dialog and wait for the user to
161 * select at least one file to load as <B>toplevel</B>'s new pages.
163 * The function updates the user interface.
165 * At the end of the function, the toplevel's current page is set to
166 * the page of the last loaded page.
168 * \param [in] toplevel The toplevel environment.
170 void
171 x_fileselect_open(TOPLEVEL *toplevel)
173 PAGE *page = NULL;
174 GtkWidget *dialog;
176 dialog = gtk_file_chooser_dialog_new (_("Open..."),
177 GTK_WINDOW(toplevel->main_window),
178 GTK_FILE_CHOOSER_ACTION_OPEN,
179 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
180 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
181 NULL);
183 #if GTK_CHECK_VERSION (2,6,0)
184 /* Set the alternative button order (ok, cancel, help) for other systems */
185 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
186 GTK_RESPONSE_ACCEPT,
187 GTK_RESPONSE_CANCEL,
188 -1);
189 #endif
191 x_fileselect_add_preview (GTK_FILE_CHOOSER (dialog));
192 g_object_set (dialog,
193 /* GtkFileChooser */
194 "select-multiple", TRUE,
195 NULL);
196 /* add file filters to dialog */
197 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog));
198 gtk_widget_show (dialog);
199 if (gtk_dialog_run ((GtkDialog*)dialog) == GTK_RESPONSE_ACCEPT) {
200 GSList *tmp, *filenames =
201 gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog));
203 /* open each file */
204 for (tmp = filenames; tmp != NULL;tmp = g_slist_next (tmp)) {
205 page = x_window_open_page (toplevel, (gchar*)tmp->data);
207 /* Switch to the last page opened */
208 if ( page != NULL )
209 x_window_set_current_page (toplevel, page);
211 /* free the list of filenames */
212 g_slist_foreach (filenames, (GFunc)g_free, NULL);
213 g_slist_free (filenames);
215 gtk_widget_destroy (dialog);
219 /*! \brief Opens a file chooser for saving the current page.
220 * \par Function Description
221 * This function opens a file chooser dialog and wait for the user to
222 * select a file where the <B>toplevel</B>'s current page will be
223 * saved.
225 * If the user cancels the operation (with the cancel button), the
226 * page is not saved.
228 * The function updates the user interface.
230 * \param [in] toplevel The toplevel environment.
232 void
233 x_fileselect_save (TOPLEVEL *toplevel)
235 GtkWidget *dialog;
237 dialog = gtk_file_chooser_dialog_new (_("Save as..."),
238 GTK_WINDOW(toplevel->main_window),
239 GTK_FILE_CHOOSER_ACTION_SAVE,
240 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
241 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
242 NULL);
244 #if GTK_CHECK_VERSION (2,6,0)
245 /* Set the alternative button order (ok, cancel, help) for other systems */
246 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
247 GTK_RESPONSE_ACCEPT,
248 GTK_RESPONSE_CANCEL,
249 -1);
250 #endif
252 /* set default response signal. This is usually triggered by the
253 "Return" key */
254 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
255 GTK_RESPONSE_ACCEPT);
257 g_object_set (dialog,
258 /* GtkFileChooser */
259 "select-multiple", FALSE,
260 /* only in GTK 2.8 */
261 /* "do-overwrite-confirmation", TRUE, */
262 NULL);
263 /* add file filters to dialog */
264 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog));
265 /* set the current filename or directory name if new document */
266 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog),
267 toplevel->page_current->page_filename);
269 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
270 GTK_RESPONSE_ACCEPT);
271 gtk_widget_show (dialog);
272 if (gtk_dialog_run ((GtkDialog*)dialog) == GTK_RESPONSE_ACCEPT) {
273 gchar *filename =
274 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
276 /* try saving current page of toplevel to file filename */
277 if (filename != NULL) {
278 x_window_save_page (toplevel,
279 toplevel->page_current,
280 filename);
283 gtk_widget_destroy (dialog);
287 /*! \brief Load/Backup selection dialog.
288 * \par Function Description
289 * This function opens a message dialog and wait for the user to choose
290 * if load the backup or the original file.
292 * \param [in] toplevel The TOPLEVEL object.
293 * \param [in] message Message to display to user.
294 * \return TRUE if the user wants to load the backup file, FALSE otherwise.
296 int x_fileselect_load_backup(TOPLEVEL *toplevel, GString *message)
298 GtkWidget *dialog;
300 g_string_append(message, "\nIf you load the original file, the backup file will be overwritten in the next autosave timeout and it will be lost.\n\nDo you want to load the backup file?\n");
302 dialog = gtk_message_dialog_new(GTK_WINDOW(toplevel->main_window),
303 GTK_DIALOG_MODAL,
304 GTK_MESSAGE_QUESTION,
305 GTK_BUTTONS_YES_NO,
306 message->str);
308 #if GTK_CHECK_VERSION (2,6,0)
309 /* Set the alternative button order (ok, cancel, help) for other systems */
310 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
311 GTK_RESPONSE_YES,
312 GTK_RESPONSE_NO,
313 -1);
314 #endif
316 gtk_widget_show (dialog);
317 if (gtk_dialog_run ((GtkDialog*)dialog) == GTK_RESPONSE_YES) {
318 gtk_widget_destroy(dialog);
319 return TRUE;
321 else {
322 gtk_widget_destroy(dialog);
323 return FALSE;