00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <dirent.h>
00023 #include <glib.h>
00024 #include <gtk/gtk.h>
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <sys/stat.h>
00028
00029 #include <libaudcore/audstrings.h>
00030
00031 #include "audconfig.h"
00032 #include "config.h"
00033 #include "i18n.h"
00034 #include "misc.h"
00035 #include "playback.h"
00036 #include "playlist.h"
00037
00038 static GList * add_queue = NULL;
00039 static gint add_source = 0;
00040 static gint add_playlist, add_at;
00041 static gboolean add_play;
00042 static GtkWidget * add_window = NULL, * add_progress_path, * add_progress_count;
00043
00044 static void show_progress (const gchar * path, gint count)
00045 {
00046 gchar scratch[128];
00047
00048 if (add_window == NULL)
00049 {
00050 GtkWidget * vbox;
00051
00052 add_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
00053 gtk_window_set_type_hint (GTK_WINDOW(add_window),
00054 GDK_WINDOW_TYPE_HINT_DIALOG);
00055 gtk_window_set_title (GTK_WINDOW(add_window), _("Searching ..."));
00056 gtk_window_set_resizable (GTK_WINDOW(add_window), FALSE);
00057 gtk_container_set_border_width (GTK_CONTAINER(add_window), 6);
00058
00059 vbox = gtk_vbox_new (FALSE, 6);
00060 gtk_container_add (GTK_CONTAINER(add_window), vbox);
00061
00062 add_progress_path = gtk_label_new ("");
00063 gtk_widget_set_size_request (add_progress_path, 320, -1);
00064 gtk_label_set_ellipsize (GTK_LABEL(add_progress_path),
00065 PANGO_ELLIPSIZE_MIDDLE);
00066 gtk_box_pack_start (GTK_BOX(vbox), add_progress_path, FALSE, FALSE, 0);
00067
00068 add_progress_count = gtk_label_new ("");
00069 gtk_widget_set_size_request (add_progress_count, 320, -1);
00070 gtk_box_pack_start (GTK_BOX(vbox), add_progress_count, FALSE, FALSE, 0);
00071
00072 gtk_widget_show_all (add_window);
00073
00074 g_signal_connect (G_OBJECT(add_window), "destroy",
00075 G_CALLBACK(gtk_widget_destroyed), & add_window);
00076 }
00077
00078 gtk_label_set_text (GTK_LABEL(add_progress_path), path);
00079 snprintf (scratch, sizeof scratch, dngettext (PACKAGE, "%d file found",
00080 "%d files found", count), count);
00081 gtk_label_set_text (GTK_LABEL(add_progress_count), scratch);
00082 }
00083
00084 static void show_done (void)
00085 {
00086 gtk_widget_destroy (add_window);
00087 }
00088
00089 static gboolean add_cb (void * unused)
00090 {
00091 static GList * stack = NULL;
00092 static struct index * index;
00093 gint count;
00094
00095 if (stack == NULL)
00096 {
00097 stack = g_list_prepend (stack, add_queue->data);
00098 index = index_new ();
00099 }
00100
00101 show_progress ((gchar *) stack->data, index_count (index));
00102
00103 for (count = 0; count < 30; count ++)
00104 {
00105 struct stat info;
00106 struct dirent * entry;
00107
00108 if (stat (stack->data, & info) == 0)
00109 {
00110 if (S_ISREG (info.st_mode))
00111 {
00112 gchar * filename = filename_to_uri (stack->data);
00113
00114 if (filename != NULL && file_find_decoder (filename, TRUE) !=
00115 NULL)
00116 index_append (index, filename);
00117 else
00118 g_free (filename);
00119 }
00120 else if (S_ISDIR (info.st_mode))
00121 {
00122 DIR * folder = opendir (stack->data);
00123
00124 if (folder != NULL)
00125 {
00126 stack = g_list_prepend (stack, folder);
00127 goto READ;
00128 }
00129 }
00130 }
00131
00132 g_free (stack->data);
00133 stack = g_list_delete_link (stack, stack);
00134
00135 READ:
00136 if (stack == NULL)
00137 break;
00138
00139 entry = readdir (stack->data);
00140
00141 if (entry != NULL)
00142 {
00143 if (entry->d_name[0] == '.')
00144 goto READ;
00145
00146 stack = g_list_prepend (stack, g_strdup_printf ("%s/%s", (gchar *)
00147 stack->next->data, entry->d_name));
00148 }
00149 else
00150 {
00151 closedir (stack->data);
00152 stack = g_list_delete_link (stack, stack);
00153 g_free (stack->data);
00154 stack = g_list_delete_link (stack, stack);
00155 goto READ;
00156 }
00157 }
00158
00159 if (stack == NULL)
00160 {
00161 index_sort (index, (gint (*) (const void *, const void *))
00162 string_compare_encoded);
00163
00164 count = playlist_count ();
00165
00166 if (add_playlist > count - 1)
00167 add_playlist = count - 1;
00168
00169 count = playlist_entry_count (add_playlist);
00170
00171 if (add_at < 0 || add_at > count)
00172 add_at = count;
00173
00174 playlist_entry_insert_batch (add_playlist, add_at, index, NULL);
00175
00176 if (add_play && playlist_entry_count (add_playlist) > count)
00177 {
00178 playlist_set_playing (add_playlist);
00179 if (! cfg.shuffle)
00180 playlist_set_position (add_playlist, add_at);
00181 playback_play (0, FALSE);
00182 add_play = FALSE;
00183 }
00184
00185 add_at += playlist_entry_count (add_playlist) - count;
00186
00187 add_queue = g_list_delete_link (add_queue, add_queue);
00188
00189 if (add_queue == NULL)
00190 {
00191 show_done ();
00192 add_source = 0;
00193 return FALSE;
00194 }
00195 }
00196
00197 return TRUE;
00198 }
00199
00200 void playlist_insert_folder (gint playlist, gint at, const gchar * folder,
00201 gboolean play)
00202 {
00203 gchar * unix_name = uri_to_filename (folder);
00204
00205 add_playlist = playlist;
00206 add_at = at;
00207 add_play |= play;
00208
00209 if (unix_name == NULL)
00210 return;
00211
00212 if (unix_name[strlen (unix_name) - 1] == '/')
00213 unix_name[strlen (unix_name) - 1] = 0;
00214
00215 add_queue = g_list_append (add_queue, unix_name);
00216
00217 if (add_source == 0)
00218 add_source = g_idle_add (add_cb, NULL);
00219 }