1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2008 Ales Hvezda
4 * Copyright (C) 1998-2008 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
24 #ifdef HAVE_LIBDMALLOC
29 /*! \brief Creates filter for file chooser.
30 * \par Function Description
31 * This function adds file filters to <B>filechooser</B>.
33 * \param [in] filechooser The file chooser to add filter to.
36 x_fileselect_setup_filechooser_filters (GtkFileChooser
*filechooser
)
38 GtkFileFilter
*filter
;
40 /* file filter for schematic files (*.sch) */
41 filter
= gtk_file_filter_new ();
42 gtk_file_filter_set_name (filter
, _("Schematics"));
43 gtk_file_filter_add_pattern (filter
, "*.sch");
44 gtk_file_chooser_add_filter (filechooser
, filter
);
45 /* file filter for symbol files (*.sym) */
46 filter
= gtk_file_filter_new ();
47 gtk_file_filter_set_name (filter
, _("Symbols"));
48 gtk_file_filter_add_pattern (filter
, "*.sym");
49 gtk_file_chooser_add_filter (filechooser
, filter
);
50 /* file filter for both symbol and schematic files (*.sym+*.sch) */
51 filter
= gtk_file_filter_new ();
52 gtk_file_filter_set_name (filter
, _("Schematics and symbols"));
53 gtk_file_filter_add_pattern (filter
, "*.sym");
54 gtk_file_filter_add_pattern (filter
, "*.sch");
55 gtk_file_chooser_add_filter (filechooser
, filter
);
56 /* file filter that match any file */
57 filter
= gtk_file_filter_new ();
58 gtk_file_filter_set_name (filter
, _("All files"));
59 gtk_file_filter_add_pattern (filter
, "*");
60 gtk_file_chooser_add_filter (filechooser
, filter
);
64 /*! \brief Updates the preview when the selection changes.
65 * \par Function Description
66 * This is the callback function connected to the 'update-preview'
67 * signal of the <B>GtkFileChooser</B>.
69 * It updates the preview widget with the name of the newly selected
72 * \param [in] chooser The file chooser to add the preview to.
73 * \param [in] user_data A pointer on the preview widget.
76 x_fileselect_callback_update_preview (GtkFileChooser
*chooser
,
79 Preview
*preview
= PREVIEW (user_data
);
80 gchar
*filename
, *preview_filename
= NULL
;
82 filename
= gtk_file_chooser_get_preview_filename (chooser
);
83 if (filename
!= NULL
&&
84 !g_file_test (filename
, G_FILE_TEST_IS_DIR
)) {
85 preview_filename
= filename
;
89 g_object_set (preview
,
90 "filename", preview_filename
,
91 "active", (preview_filename
!= NULL
),
97 /*! \brief Adds a preview to a file chooser.
98 * \par Function Description
99 * This function adds a preview section to the stock
100 * <B>GtkFileChooser</B>.
102 * The <B>Preview</B> object is inserted in a frame and alignment
103 * widget for accurate positionning.
105 * Other widgets can be added to this preview area for example to
106 * enable/disable the preview. Currently, the preview is always
109 * Function <B>x_fileselect_callback_update_preview()</B> is
110 * connected to the signal 'update-preview' of <B>GtkFileChooser</B>
111 * so that it redraws the preview area every time a new file is
114 * \param [in] filechooser The file chooser to add the preview to.
117 x_fileselect_add_preview (GtkFileChooser
*filechooser
)
119 GtkWidget
*alignment
, *frame
, *preview
;
121 frame
= GTK_WIDGET (g_object_new (GTK_TYPE_FRAME
,
122 "label", _("Preview"),
124 alignment
= GTK_WIDGET (g_object_new (GTK_TYPE_ALIGNMENT
,
132 preview
= GTK_WIDGET (g_object_new (TYPE_PREVIEW
,
135 gtk_container_add (GTK_CONTAINER (alignment
), preview
);
136 gtk_container_add (GTK_CONTAINER (frame
), alignment
);
137 gtk_widget_show_all (frame
);
139 g_object_set (filechooser
,
141 "use-preview-label", FALSE
,
142 "preview-widget", frame
,
145 /* connect callback to update preview */
146 g_signal_connect (filechooser
,
148 G_CALLBACK (x_fileselect_callback_update_preview
),
153 /*! \brief Opens a file chooser for opening one or more schematics.
154 * \par Function Description
155 * This function opens a file chooser dialog and wait for the user to
156 * select at least one file to load as <B>w_current</B>'s new pages.
158 * The function updates the user interface.
160 * At the end of the function, the w_current->toplevel's current page
161 * is set to the page of the last loaded page.
163 * \param [in] w_current The GSCHEM_TOPLEVEL environment.
166 x_fileselect_open(GSCHEM_TOPLEVEL
*w_current
)
171 dialog
= gtk_file_chooser_dialog_new (_("Open..."),
172 GTK_WINDOW(w_current
->main_window
),
173 GTK_FILE_CHOOSER_ACTION_OPEN
,
174 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
175 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
178 /* Set the alternative button order (ok, cancel, help) for other systems */
179 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
184 x_fileselect_add_preview (GTK_FILE_CHOOSER (dialog
));
185 g_object_set (dialog
,
187 "select-multiple", TRUE
,
189 /* add file filters to dialog */
190 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog
));
191 gtk_widget_show (dialog
);
192 if (gtk_dialog_run ((GtkDialog
*)dialog
) == GTK_RESPONSE_ACCEPT
) {
193 GSList
*tmp
, *filenames
=
194 gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dialog
));
197 for (tmp
= filenames
; tmp
!= NULL
;tmp
= g_slist_next (tmp
)) {
198 page
= x_window_open_page (w_current
, (gchar
*)tmp
->data
);
200 /* Switch to the last page opened */
202 x_window_set_current_page (w_current
, page
);
204 /* free the list of filenames */
205 g_slist_foreach (filenames
, (GFunc
)g_free
, NULL
);
206 g_slist_free (filenames
);
208 gtk_widget_destroy (dialog
);
212 /*! \brief Opens a file chooser for saving the current page.
213 * \par Function Description
214 * This function opens a file chooser dialog and wait for the user to
215 * select a file where the <B>toplevel</B>'s current page will be
218 * If the user cancels the operation (with the cancel button), the
221 * The function updates the user interface.
223 * \param [in] w_current The GSCHEM_TOPLEVEL environment.
226 x_fileselect_save (GSCHEM_TOPLEVEL
*w_current
)
228 TOPLEVEL
*toplevel
= w_current
->toplevel
;
231 dialog
= gtk_file_chooser_dialog_new (_("Save as..."),
232 GTK_WINDOW(w_current
->main_window
),
233 GTK_FILE_CHOOSER_ACTION_SAVE
,
234 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
235 GTK_STOCK_SAVE
, GTK_RESPONSE_ACCEPT
,
238 /* Set the alternative button order (ok, cancel, help) for other systems */
239 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
244 /* set default response signal. This is usually triggered by the
246 gtk_dialog_set_default_response(GTK_DIALOG(dialog
),
247 GTK_RESPONSE_ACCEPT
);
249 g_object_set (dialog
,
251 "select-multiple", FALSE
,
252 /* only in GTK 2.8 */
253 /* "do-overwrite-confirmation", TRUE, */
255 /* add file filters to dialog */
256 x_fileselect_setup_filechooser_filters (GTK_FILE_CHOOSER (dialog
));
257 /* set the current filename or directory name if new document */
258 if ((toplevel
->page_current
->page_filename
!= NULL
) &&
259 g_file_test (toplevel
->page_current
->page_filename
,
260 G_FILE_TEST_EXISTS
)) {
261 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog
),
262 toplevel
->page_current
->page_filename
);
264 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog
),
268 gtk_dialog_set_default_response(GTK_DIALOG(dialog
),
269 GTK_RESPONSE_ACCEPT
);
270 gtk_widget_show (dialog
);
271 if (gtk_dialog_run ((GtkDialog
*)dialog
) == GTK_RESPONSE_ACCEPT
) {
273 gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog
));
275 /* If the file already exists, display a dialog box to check if
276 the user really wants to overwrite it. */
277 if ((filename
!= NULL
) && g_file_test (filename
, G_FILE_TEST_EXISTS
)) {
278 GtkWidget
*checkdialog
=
279 gtk_message_dialog_new (GTK_WINDOW(dialog
),
281 GTK_DIALOG_DESTROY_WITH_PARENT
),
282 GTK_MESSAGE_QUESTION
,
284 _("The selected file `%s' already exists.\n\n"
285 "Would you like to overwrite it?"),
287 gtk_window_set_title (GTK_WINDOW (checkdialog
), _("Overwrite file?"));
288 if (gtk_dialog_run (GTK_DIALOG (checkdialog
)) != GTK_RESPONSE_YES
) {
289 s_log_message (_("Save cancelled on user request\n"));
293 gtk_widget_destroy (checkdialog
);
295 /* try saving current page of toplevel to file filename */
296 if (filename
!= NULL
) {
297 x_window_save_page (w_current
,
298 w_current
->toplevel
->page_current
,
304 gtk_widget_destroy (dialog
);
308 /*! \brief Load/Backup selection dialog.
309 * \par Function Description
310 * This function opens a message dialog and wait for the user to choose
311 * if load the backup or the original file.
313 * \todo Make this a registered callback function with user data,
314 * as we'd rather be passed a GSCHEM_TOPLEVEL than a TOPLEVEL.
316 * \param [in] toplevel The TOPLEVEL object.
317 * \param [in] message Message to display to user.
318 * \return TRUE if the user wants to load the backup file, FALSE otherwise.
320 int x_fileselect_load_backup(void *user_data
, GString
*message
)
323 GSCHEM_TOPLEVEL
*w_current
= (GSCHEM_TOPLEVEL
*) user_data
;
325 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");
327 dialog
= gtk_message_dialog_new (GTK_WINDOW(w_current
->main_window
),
329 GTK_MESSAGE_QUESTION
,
333 /* Set the alternative button order (ok, cancel, help) for other systems */
334 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog
),
339 gtk_widget_show (dialog
);
340 if (gtk_dialog_run ((GtkDialog
*)dialog
) == GTK_RESPONSE_YES
) {
341 gtk_widget_destroy(dialog
);
345 gtk_widget_destroy(dialog
);