gliv-1.3.1
[gliv.git] / open_dialog.c
blob2383f572b86acb04c6ed89152a3bcdfbb1cfe76a
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * See the COPYING file for license information.
18 * Guillaume Chazarain <booh@altern.org>
21 /*******************
22 * The Open dialog *
23 *******************/
25 #include <glob.h>
26 #include <gdk/gdkkeysyms.h>
27 #include "gliv.h"
29 static GtkCheckButton *shuffle_button;
31 /* A GtkFileSelection with a shuffle button. */
32 static GtkFileSelection *decorated_dialog(void)
34 GtkFileSelection *dialog;
36 dialog = GTK_FILE_SELECTION(gtk_file_selection_new
37 ("GLiv : Select files or use wildcards"));
39 /* Allow multiple selections. */
40 gtk_clist_set_selection_mode(GTK_CLIST(dialog->file_list),
41 GTK_SELECTION_EXTENDED);
43 shuffle_button =
44 GTK_CHECK_BUTTON(gtk_check_button_new_with_label("Shuffle"));
46 /* Add the button in the dialog. */
47 gtk_container_add(GTK_CONTAINER(dialog->action_area),
48 GTK_WIDGET(shuffle_button));
50 return dialog;
53 /* Processes selection made by the GtkFileSelection. */
54 static void add_selected(GtkFileSelection * dialog, gboolean append)
56 gboolean shuffle_flag;
57 gchar *dirname;
58 glob_t pglob;
59 GPtrArray *files_array;
60 GList *node;
61 gchar *buf;
62 gchar **glob_res;
63 gint i;
65 shuffle_flag =
66 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(shuffle_button));
68 if (GTK_CLIST(dialog->file_list)->selection == NULL
69 || GTK_CLIST(dialog->file_list)->selection->next == NULL) {
71 /* Use what is in the entry. */
72 glob(gtk_file_selection_get_filename(dialog),
73 GLOB_NOSORT, NULL, &pglob);
75 if (pglob.gl_pathc == 1) {
76 /* No wildcard expansion. */
77 if (append == TRUE)
78 open_file(g_strdup(pglob.gl_pathv[0]), TRUE, shuffle_flag);
79 else {
80 dirname = g_dirname(pglob.gl_pathv[0]);
81 init_list(&dirname, 1, FALSE, shuffle_flag);
82 place_at_position(g_strdup(pglob.gl_pathv[0]), 0);
83 g_free(dirname);
85 } else {
86 /* Add all expansions from glob(). */
88 glob_res = g_new(gchar *, pglob.gl_pathc);
89 for (i = 0; i < pglob.gl_pathc; i++)
90 glob_res[i] = g_strdup(pglob.gl_pathv[i]);
92 if (append == TRUE) {
93 insert_at_current_position(glob_res, pglob.gl_pathc,
94 shuffle_flag);
95 open_file(pglob.gl_pathv[0], FALSE, FALSE);
96 } else
97 init_list(glob_res, pglob.gl_pathc, FALSE, shuffle_flag);
99 g_free(glob_res);
101 globfree(&pglob);
102 } else {
103 /* Multiple files were selected. */
104 files_array = g_ptr_array_new();
105 dirname = g_dirname(gtk_file_selection_get_filename(dialog));
107 node = GTK_CLIST(dialog->file_list)->selection;
108 while (node != NULL) {
109 gtk_clist_get_text(GTK_CLIST(dialog->file_list),
110 GPOINTER_TO_INT(node->data), 0, &buf);
111 g_ptr_array_add(files_array, g_strconcat(dirname, "/", buf, NULL));
112 node = node->next;
115 g_free(dirname);
116 if (append == TRUE) {
117 insert_at_current_position((gchar **) files_array->pdata,
118 files_array->len, shuffle_flag);
119 open_file(g_ptr_array_index(files_array, 0), FALSE, FALSE);
120 g_free(g_ptr_array_index(files_array, 0));
121 } else
122 init_list((gchar **) files_array->pdata, files_array->len, FALSE,
123 shuffle_flag);
125 g_ptr_array_free(files_array, TRUE);
129 /* Callback for the File->Open dialog. */
130 static void file_selected(GtkFileSelection * widget)
132 add_selected(widget, TRUE);
133 gtk_widget_destroy(GTK_WIDGET(widget));
136 /* Leaves if ESC is pressed. */
137 static void key_press_event(GtkWidget * widget, GdkEventKey * event,
138 gpointer data)
140 if (event->keyval == GDK_Escape) {
141 if (GPOINTER_TO_INT(data) == TRUE)
142 gtk_exit(0);
143 else
144 gtk_widget_destroy(widget);
148 /* Called if there is no filename on the command line. */
149 void show_open_dialog_first(void)
151 GtkFileSelection *dialog;
153 dialog = decorated_dialog();
155 gtk_signal_connect_object(GTK_OBJECT(dialog->cancel_button), "clicked",
156 GTK_SIGNAL_FUNC(gtk_exit), NULL);
158 gtk_signal_connect_object(GTK_OBJECT(dialog), "delete_event",
159 GTK_SIGNAL_FUNC(gtk_exit), NULL);
161 gtk_signal_connect(GTK_OBJECT(dialog->ok_button), "clicked",
162 GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
164 gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event",
165 GTK_SIGNAL_FUNC(key_press_event), GINT_TO_POINTER(TRUE));
167 gtk_widget_show_all(GTK_WIDGET(dialog));
168 gtk_main();
170 /* The dialog widget has gone. */
172 add_selected(dialog, FALSE);
173 gtk_widget_destroy(GTK_WIDGET(dialog));
176 /* Called by File->Open (or the 'o' key). */
177 void menu_open(void)
179 static GtkFileSelection *dialog = NULL;
181 if (dialog != NULL && GTK_IS_WIDGET(dialog) == TRUE)
182 return;
184 dialog = decorated_dialog();
186 gtk_signal_connect_object(GTK_OBJECT(dialog->ok_button), "clicked",
187 GTK_SIGNAL_FUNC(file_selected),
188 GTK_OBJECT(dialog));
190 gtk_signal_connect_object(GTK_OBJECT(dialog->cancel_button), "clicked",
191 GTK_SIGNAL_FUNC(gtk_widget_destroy),
192 GTK_OBJECT(dialog));
194 gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event",
195 GTK_SIGNAL_FUNC(key_press_event),
196 GINT_TO_POINTER(FALSE));
198 show_dialog(GTK_WIDGET(dialog), TRUE);