Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * folder-add.c 00003 * Copyright 2009 John Lindgren 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 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 }