Audacious $Id:Doxyfile42802007-03-2104:39:00Znenolod$

folder-add.c

Go to the documentation of this file.
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 }