summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorAndy Hertzfeld <andy@src.gnome.org>2000-03-06 00:22:44 +0000
committerAndy Hertzfeld <andy@src.gnome.org>2000-03-06 00:22:44 +0000
commitabb888bc679b6a81e9ebfd33d3c8febfa43d28a9 (patch)
tree979ab2468bf69af03c6f3ee8382c3c53a94adbfa /components
parent57ee999c6d9730becd2d460eedb5aa757808a255 (diff)
downloadnautilus-abb888bc679b6a81e9ebfd33d3c8febfa43d28a9.tar.gz
added a music view component for displaying directories of mp3 files, and
added a music view component for displaying directories of mp3 files, and also made a new mechanism for content view components to be explicitly specified in the metadata for a directory
Diffstat (limited to 'components')
-rw-r--r--components/Makefile.am2
-rw-r--r--components/music/Makefile.am33
-rw-r--r--components/music/main.c90
-rw-r--r--components/music/nautilus-music-view.c636
-rw-r--r--components/music/nautilus-music-view.goad11
-rw-r--r--components/music/nautilus-music-view.h65
6 files changed, 836 insertions, 1 deletions
diff --git a/components/Makefile.am b/components/Makefile.am
index 1d53ec9d0..d832aaaac 100644
--- a/components/Makefile.am
+++ b/components/Makefile.am
@@ -1 +1 @@
-SUBDIRS=history help html notes sample websearch
+SUBDIRS=history help html music notes sample websearch
diff --git a/components/music/Makefile.am b/components/music/Makefile.am
new file mode 100644
index 000000000..f0ee5b3ab
--- /dev/null
+++ b/components/music/Makefile.am
@@ -0,0 +1,33 @@
+
+
+CPPFLAGS = \
+ -DPREFIX=\"$(prefix)\"
+ -DG_LOG_DOMAIN=\"Nautilus-Music\"
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GNOMEUI_CFLAGS)
+
+gnorbadir = $(sysconfdir)/CORBA/servers
+
+gnorba_DATA = \
+ nautilus-music-view.goad
+
+
+bin_PROGRAMS = \
+ nautilus-music-view
+
+nautilus_music_view_SOURCES = \
+ nautilus-music-view.c \
+ nautilus-music-view.h \
+ main.c
+
+nautilus_music_view_LDFLAGS = \
+ $(top_builddir)/libnautilus/libnautilus.la \
+ $(BONOBO_LIBS) \
+ $(GNOMEUI_LIBS) \
+ $(VFS_LIBS) \
+ $(GNORBA_LIBS)
+
+EXTRA_DIST = nautilus-music-view.goad
diff --git a/components/music/main.c b/components/music/main.c
new file mode 100644
index 000000000..dfe254240
--- /dev/null
+++ b/components/music/main.c
@@ -0,0 +1,90 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 Eazel, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Andy Hertzfeld
+ */
+
+/* main.c - main function and object activation function for the music view component. */
+
+#include <config.h>
+
+#include "nautilus-music-view.h"
+
+#include <gnome.h>
+#include <libgnorba/gnorba.h>
+#include <bonobo.h>
+
+static int object_count = 0;
+
+static void
+music_view_object_destroyed(GtkObject *obj)
+{
+ object_count--;
+ if (object_count <= 0) {
+ gtk_main_quit ();
+ }
+}
+
+static BonoboObject *
+music_view_make_object (BonoboGenericFactory *factory,
+ const char *goad_id,
+ void *closure)
+{
+ NautilusMusicView *music_view;
+ NautilusViewFrame *view_frame;
+
+ if (strcmp (goad_id, "nautilus_music_view")) {
+ return NULL;
+ }
+
+ music_view = NAUTILUS_MUSIC_VIEW (gtk_object_new (NAUTILUS_TYPE_MUSIC_VIEW, NULL));
+
+ object_count++;
+
+ gtk_signal_connect (GTK_OBJECT (music_view), "destroy", music_view_object_destroyed, NULL);
+
+ view_frame = NAUTILUS_VIEW_FRAME (nautilus_music_view_get_view_frame (music_view));
+ return BONOBO_OBJECT (view_frame);
+}
+
+int main(int argc, char *argv[])
+{
+ BonoboGenericFactory *factory;
+ CORBA_ORB orb;
+ CORBA_Environment ev;
+
+ CORBA_exception_init(&ev);
+
+ orb = gnome_CORBA_init_with_popt_table ("nautilus-music-view", VERSION, &argc, argv, NULL, 0, NULL,
+ GNORBA_INIT_SERVER_FUNC, &ev);
+
+ bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL);
+
+ /* initialize gnome-vfs, etc */
+ g_thread_init (NULL);
+ gnome_vfs_init ();
+
+ factory = bonobo_generic_factory_new_multi ("nautilus_music_view_factory", music_view_make_object, NULL);
+
+ do {
+ bonobo_main ();
+ } while (object_count > 0);
+
+ return 0;
+}
diff --git a/components/music/nautilus-music-view.c b/components/music/nautilus-music-view.c
new file mode 100644
index 000000000..f03799360
--- /dev/null
+++ b/components/music/nautilus-music-view.c
@@ -0,0 +1,636 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+/*
+ * Copyright (C) 2000 Eazel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Andy Hertzfeld <andy@eazel.com>
+ *
+ */
+
+/* music view - presents the contents of the directory as an album of music */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+#include "nautilus-music-view.h"
+
+#include <libnautilus/libnautilus.h>
+#include <libnautilus/nautilus-background.h>
+#include <libnautilus/nautilus-file-utilities.h>
+#include <libnautilus/nautilus-glib-extensions.h>
+#include <libnautilus/nautilus-gtk-macros.h>
+#include <libnautilus/nautilus-metadata.h>
+#include <libnautilus/nautilus-string.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtksignal.h>
+#include <gnome.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libgnorba/gnorba.h>
+#include <limits.h>
+
+struct _NautilusMusicViewDetails {
+ gchar *current_uri;
+ NautilusContentViewFrame *view_frame;
+
+ GtkVBox *album_container;
+ GtkWidget *album_title;
+ GtkWidget *song_list;
+ GtkWidget *album_image;
+ int background_connection;
+};
+
+/* structure for holding song info */
+
+typedef struct {
+ gint track_number;
+ gchar *title;
+ gchar *artist;
+ gchar *album;
+ gchar *year;
+ gchar *comment;
+ gchar *path_name;
+} SongInfo;
+
+#define MUSIC_VIEW_DEFAULT_BACKGROUND_COLOR "rgb:BBBB/BBBB/FFFF"
+
+enum {
+ TARGET_URI_LIST,
+ TARGET_COLOR,
+ TARGET_GNOME_URI_LIST
+};
+
+static GtkTargetEntry music_dnd_target_table[] = {
+ { "text/uri-list", 0, TARGET_URI_LIST },
+ { "application/x-color", 0, TARGET_COLOR },
+ { "special/x-gnome-icon-list", 0, TARGET_GNOME_URI_LIST }
+};
+
+static void nautilus_music_view_background_changed (NautilusMusicView *music_view);
+static void nautilus_music_view_drag_data_received (GtkWidget *widget, GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data,
+ guint info, guint time);
+
+static void nautilus_music_view_initialize_class (NautilusMusicViewClass *klass);
+static void nautilus_music_view_initialize (NautilusMusicView *view);
+static void nautilus_music_view_destroy (GtkObject *object);
+static void nautilus_music_view_realize (GtkWidget *widget);
+static void setup_title_font (NautilusMusicView *music_view);
+
+NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusMusicView, nautilus_music_view, GTK_TYPE_EVENT_BOX)
+
+static void
+music_view_notify_location_change_cb(NautilusContentViewFrame *view,
+ Nautilus_NavigationInfo *navinfo,
+ NautilusMusicView *music_view);
+static void selection_callback(GtkCList * clist, gint row, gint column, GdkEventButton * event);
+
+static void
+nautilus_music_view_initialize_class (NautilusMusicViewClass *klass)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = GTK_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->destroy = nautilus_music_view_destroy;
+ widget_class->realize = nautilus_music_view_realize;
+ widget_class->drag_data_received = nautilus_music_view_drag_data_received;
+}
+
+/* initialize ourselves by connecting to the location change signal and allocating our subviews */
+
+static void
+nautilus_music_view_initialize (NautilusMusicView *music_view)
+{
+ NautilusBackground *background;
+ gchar *file_name;
+ GtkWidget *song_box, *scrollwindow;
+ gchar *titles[] = {"Track", "Title", "Artist", "Time"};
+
+ music_view->details = g_new0 (NautilusMusicViewDetails, 1);
+
+ music_view->details->view_frame = nautilus_content_view_frame_new (GTK_WIDGET (music_view));
+
+ gtk_signal_connect (GTK_OBJECT (music_view->details->view_frame),
+ "notify_location_change",
+ GTK_SIGNAL_FUNC (music_view_notify_location_change_cb),
+ music_view);
+
+ music_view->details->current_uri = NULL;
+ music_view->details->background_connection = 0;
+
+ /* set up the default background color */
+ background = nautilus_get_widget_background (GTK_WIDGET(music_view));
+ nautilus_background_set_color (background, MUSIC_VIEW_DEFAULT_BACKGROUND_COLOR);
+
+ /* allocate a vbox to contain all of the views */
+
+ music_view->details->album_container = GTK_VBOX(gtk_vbox_new(FALSE, 0));
+ gtk_container_add(GTK_CONTAINER(music_view), GTK_WIDGET(music_view->details->album_container));
+ gtk_widget_show(GTK_WIDGET(music_view->details->album_container));
+
+ /* allocate a widget for the album title */
+
+ music_view->details->album_title = gtk_label_new("Album Title");
+ gtk_box_pack_start(GTK_BOX(music_view->details->album_container), music_view->details->album_title, 0, 0, 0);
+ gtk_widget_show(music_view->details->album_title);
+
+ /* allocate an hbox to hold the optional album cover and the song list */
+
+ song_box = gtk_hbox_new(FALSE, 4);
+ gtk_box_pack_start(GTK_BOX(music_view->details->album_container), song_box, 0, 0, 2);
+ gtk_widget_show(song_box);
+
+ /* allocate a placeholder widget for the album cover, but don't show it yet */
+ file_name = gnome_pixmap_file ("nautilus/i-directory.png");
+ music_view->details->album_image = GTK_WIDGET (gnome_pixmap_new_from_file (file_name));
+ gtk_box_pack_start(GTK_BOX(song_box), music_view->details->album_image, 0, 0, 0);
+ g_free (file_name);
+
+ /* allocate a widget to hold the song list */
+
+ music_view->details->song_list = gtk_clist_new_with_titles(4, titles);
+
+ gtk_clist_set_column_width(GTK_CLIST(music_view->details->song_list), 0, 32);
+ gtk_clist_set_column_width(GTK_CLIST(music_view->details->song_list), 1, 176);
+ gtk_clist_set_column_width(GTK_CLIST(music_view->details->song_list), 2, 96);
+ gtk_clist_set_column_width(GTK_CLIST(music_view->details->song_list), 3, 42);
+
+ gtk_signal_connect(GTK_OBJECT(music_view->details->song_list), "select_row", GTK_SIGNAL_FUNC(selection_callback), NULL);
+
+ scrollwindow = gtk_scrolled_window_new(NULL, gtk_clist_get_vadjustment(GTK_CLIST(music_view->details->song_list)));
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_usize(scrollwindow, 384, 232);
+ gtk_container_add(GTK_CONTAINER (scrollwindow), music_view->details->song_list);
+ gtk_clist_set_selection_mode(GTK_CLIST(music_view->details->song_list), GTK_SELECTION_BROWSE);
+
+ gtk_box_pack_start(GTK_BOX(song_box), scrollwindow, 0, 0, 4);
+ gtk_widget_show(music_view->details->song_list);
+ gtk_widget_show(scrollwindow);
+
+ /* prepare ourselves to receive dropped objects */
+ gtk_drag_dest_set (GTK_WIDGET (music_view),
+ GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
+ music_dnd_target_table, NAUTILUS_N_ELEMENTS (music_dnd_target_table), GDK_ACTION_COPY);
+
+ /* finally, show the view itself */
+ gtk_widget_show (GTK_WIDGET (music_view));
+}
+
+static void
+nautilus_music_view_destroy (GtkObject *object)
+{
+ NautilusMusicView *music_view = NAUTILUS_MUSIC_VIEW (object);
+
+ g_free (music_view->details->current_uri);
+ g_free (music_view->details);
+
+ NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
+}
+
+/* handle a row being selected in the list view by playing the corresponding song */
+/* FIXME: xmms shouldn't be hardwired */
+static void
+selection_callback(GtkCList * clist, gint row, gint column, GdkEventButton * event)
+{
+ pid_t play_pid;
+ gchar* song_name = gtk_clist_get_row_data(clist, row);
+ if (!song_name)
+ return;
+
+ /* fork off a task to play the sound file */
+ if (!(play_pid = fork())) {
+ execlp("xmms", "xmms", song_name, NULL);
+ exit(0);
+ }
+}
+
+
+/* Component embedding support */
+NautilusContentViewFrame *
+nautilus_music_view_get_view_frame (NautilusMusicView *music_view)
+{
+ return music_view->details->view_frame;
+}
+
+
+/* utility routine to set up the font for the album title, called after we're realized */
+static void
+setup_title_font(NautilusMusicView *music_view)
+{
+ GtkStyle *temp_style = gtk_style_new();
+
+ gtk_widget_realize(music_view->details->album_title);
+ temp_style->font = gdk_font_load("-*-helvetica-medium-r-normal-*-18-*-*-*-*-*-*-*"); ;
+ gtk_widget_set_style(music_view->details->album_title, gtk_style_attach(temp_style, music_view->details->album_title->window));
+}
+
+/* set up fonts, colors, etc after we're realized */
+void
+nautilus_music_view_realize(GtkWidget *widget)
+{
+ NautilusMusicView *music_view;
+ NautilusBackground *background;
+
+ music_view = NAUTILUS_MUSIC_VIEW(widget);
+ NAUTILUS_CALL_PARENT_CLASS (GTK_WIDGET_CLASS, realize, (widget));
+
+ setup_title_font(music_view);
+
+ background = nautilus_get_widget_background (widget);
+ nautilus_background_set_color (background, MUSIC_VIEW_DEFAULT_BACKGROUND_COLOR);
+}
+
+/* here are some utility routines for reading ID3 tags from mp3 files */
+
+/* initialize a songinfo structure */
+
+static void
+initialize_song_info(SongInfo *info)
+{
+ info->track_number = -1;
+ info->title = '\0';
+ info->artist = '\0';
+ info->album = '\0';
+ info->year = '\0';
+ info->comment = '\0';
+ info->path_name = '\0';
+}
+
+/* deallocate a songinfo structure */
+
+static void
+release_song_info(SongInfo *info)
+{
+ if (info->title)
+ g_free(info->title);
+ if (info->artist)
+ g_free(info->artist);
+ if (info->album)
+ g_free(info->album);
+ if (info->year)
+ g_free(info->year);
+ if (info->comment)
+ g_free(info->comment);
+
+ g_free(info);
+}
+
+/* determine if the passed in filename is an mp3 file by looking at the extension */
+static gboolean
+is_mp3_file(gchar *song_path)
+{
+ gchar *last_dot = strrchr(song_path, '.');
+ if (last_dot == NULL)
+ return FALSE;
+ return !strcmp(last_dot, ".mp3") || !strcmp(last_dot, ".MP3");
+}
+
+/* read the id3 tag of the file if present */
+/* FIXME: need to use gnome vfs for this */
+
+static gboolean
+read_id_tag(gchar* song_path, SongInfo* song_info)
+{
+ gint mp3_file;
+
+ char tag_buffer[129];
+ char temp_str[255];
+
+ mp3_file = open(song_path, O_RDONLY);
+ if ( mp3_file == 0 )
+ return FALSE;
+
+ lseek(mp3_file, -128, SEEK_END);
+
+ if (read(mp3_file, tag_buffer, 129) <= 0) {
+ close(mp3_file);
+ return FALSE;
+ }
+ close(mp3_file);
+
+ if ((tag_buffer[0] != 'T') || (tag_buffer[1] != 'A') || (tag_buffer[2] != 'G'))
+ return FALSE;
+
+ temp_str[31] = '\0';
+ strncpy (temp_str, &tag_buffer[3], 30);
+ song_info->title = strdup(temp_str);
+
+ strncpy (temp_str, &tag_buffer[33], 30);
+ song_info->artist = strdup(temp_str);
+
+ strncpy (temp_str, &tag_buffer[63], 30);
+ song_info->album = strdup(temp_str);
+
+ strncpy (temp_str, &tag_buffer[93], 4);
+ song_info->year = strdup(temp_str);
+
+ strncpy (temp_str, &tag_buffer[97], 30);
+ song_info->comment = strdup(temp_str);
+
+ if (tag_buffer[97 + 28] == 0)
+ song_info->track_number = tag_buffer[97 + 29];
+ else song_info->track_number = -1;
+
+ return TRUE;
+}
+
+/* allocate a return a song info record, from an mp3 tag if present, or from intrinsic info */
+
+static SongInfo*
+fetch_song_info(gchar *song_path, gint file_order)
+{
+ gboolean has_info = FALSE;
+ SongInfo *info;
+
+ if (!is_mp3_file(song_path))
+ return NULL;
+
+ info = g_new0 (SongInfo, 1);
+ initialize_song_info(info);
+
+ if (is_mp3_file(song_path))
+ has_info = read_id_tag(song_path, info);
+
+ /* there was no id3 tag, so set up the info heuristically from the file name and file order */
+ if (!has_info) {
+ }
+
+ return info;
+}
+
+/* format_play_time takes the pathname to a file and returns the play time formated as mm:ss */
+/* FIXME: assumes 128k bits/second. Must read header and factor in bitrate */
+
+static gchar*
+format_play_time(gchar* song_path_name)
+{
+ NautilusFile *file = nautilus_file_get(song_path_name);
+ GnomeVFSFileSize file_size = nautilus_file_get_size(file);
+ gint seconds = (file_size - 512) / 16384;
+ gint minutes = seconds / 60;
+ gint remain_seconds = seconds - (60 * minutes);
+ gchar *result = g_strdup_printf("%d:%02d", minutes, remain_seconds);
+
+ nautilus_file_unref(file);
+ return result;
+}
+
+/* sort comparison routine - for now, just sort by track number */
+
+static int
+sort_by_track_number (gconstpointer ap, gconstpointer bp)
+{
+ SongInfo *a, *b;
+
+ a = (SongInfo *) ap;
+ b = (SongInfo *) bp;
+
+ return (int) a->track_number - b->track_number;
+}
+
+/* here's where we do most of the real work of populating the view with info from the new uri */
+/* FIXME: need to use gnome-vfs for iterating the directory */
+
+static void
+nautilus_music_view_update_from_uri (NautilusMusicView *music_view, const gchar *uri)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char* clist_entry[4];
+ char *background_color;
+ NautilusBackground *background;
+ NautilusDirectory *directory;
+ GList *this_song;
+ GList *song_list = NULL ;
+ SongInfo *info;
+ gchar *path_name;
+ gchar *image_path_name = NULL;
+ gint file_index = 0;
+ gint track_index = 0;
+ /* iterate through the directory, collecting mp3 files and extracting id3 data if present */
+ /* soon we'll use gnomevfs, but at first just the standard unix stuff */
+
+ if (!(dir = opendir(uri + 7)))
+ g_warning("cant open %s in music_view_update", uri);
+ else {
+ while ((entry = readdir(dir))) {
+ /* skip invisible files, for now */
+
+ if (entry->d_name[0] == '.')
+ continue;
+
+ path_name = nautilus_make_path(uri + 7, entry->d_name);
+
+ /* fetch info and queue it if it's an mp3 file */
+ info = fetch_song_info(path_name, file_index++);
+ if (info) {
+ info->path_name = path_name;
+ if (song_list)
+ song_list = g_list_append(song_list, info);
+ else {
+ song_list = g_list_alloc();
+ song_list->data = info;
+ }
+ }
+ else {
+ /* it's not an mp3 file, so see if it's an image */
+ NautilusFile *file = nautilus_file_get(path_name);
+ const gchar *mime_type = nautilus_file_get_mime_type (file);
+
+ if (nautilus_has_prefix(mime_type, "image/")) {
+ /* for now, just keep the first image */
+ if (image_path_name == NULL)
+ image_path_name = strdup(path_name);
+ }
+
+ nautilus_file_unref(file);
+ g_free(path_name);
+ }
+ }
+
+ closedir(dir);
+ }
+
+ /* sort by track number */
+ song_list = g_list_sort(song_list, sort_by_track_number);
+
+ /* populate the clist */
+
+ gtk_clist_clear(GTK_CLIST(music_view->details->song_list));
+
+ this_song = song_list;
+ while (this_song != NULL) {
+ info = (SongInfo*) this_song->data;
+
+ clist_entry[0] = malloc(4);
+ sprintf(clist_entry[0], "%d", info->track_number);
+
+ clist_entry[1] = NULL;
+ clist_entry[2] = NULL;
+ clist_entry[3] = NULL;
+
+ if (info->title)
+ clist_entry[1] = strdup(info->title);
+ if (info->artist)
+ clist_entry[2] = strdup(info->artist);
+ if (info->path_name)
+ clist_entry[3] = format_play_time(info->path_name);
+
+ gtk_clist_append(GTK_CLIST(music_view->details->song_list), clist_entry);
+ gtk_clist_set_row_data(GTK_CLIST(music_view->details->song_list), track_index, strdup(info->path_name));
+
+ track_index += 1;
+ this_song = this_song->next;
+ }
+
+ /* install the album cover */
+
+ if (image_path_name) {
+
+ gnome_pixmap_load_file(GNOME_PIXMAP(music_view->details->album_image), image_path_name);
+
+ /* show the pixmap widget */
+ gtk_widget_show(music_view->details->album_image);
+ g_free(image_path_name);
+ }
+ else
+ gtk_widget_hide(music_view->details->album_image);
+
+ /* set up background color */
+
+ background = nautilus_get_widget_background (GTK_WIDGET (music_view));
+ if (music_view->details->background_connection == 0)
+ music_view->details->background_connection =
+ gtk_signal_connect_object (GTK_OBJECT (background),
+ "changed",
+ nautilus_music_view_background_changed,
+ GTK_OBJECT (music_view));
+
+ /* Set up the background color from the metadata. */
+ directory = nautilus_directory_get(music_view->details->current_uri);
+ background_color = nautilus_directory_get_metadata (directory,
+ ICON_VIEW_BACKGROUND_COLOR_METADATA_KEY,
+ MUSIC_VIEW_DEFAULT_BACKGROUND_COLOR);
+ nautilus_background_set_color (background, background_color);
+ g_free (background_color);
+ gtk_object_unref(GTK_OBJECT(directory));
+
+ /* determine the album title/artist line */
+
+ /* set up the album title with the uri, for now */
+ if (music_view->details->album_title) {
+ gchar *base_name = g_basename(uri);
+ gtk_label_set(GTK_LABEL(music_view->details->album_title), base_name);
+ g_free(base_name);
+ }
+
+ /* release the song list */
+ this_song = song_list;
+ while (this_song != NULL) {
+ info = (SongInfo*) this_song->data;
+ release_song_info(info);
+ this_song = this_song->next;
+ }
+
+}
+
+
+void
+nautilus_music_view_load_uri (NautilusMusicView *music_view, const gchar *uri)
+{
+ if (music_view->details->current_uri != NULL)
+ g_free(music_view->details->current_uri);
+
+ music_view->details->current_uri = g_strdup (uri);
+ nautilus_music_view_update_from_uri(music_view, uri);
+}
+
+static void
+music_view_notify_location_change_cb (NautilusContentViewFrame *view,
+ Nautilus_NavigationInfo *navinfo,
+ NautilusMusicView *music_view)
+{
+ Nautilus_ProgressRequestInfo pri;
+
+ memset(&pri, 0, sizeof(pri));
+
+ /* send required PROGRESS_UNDERWAY signal */
+
+ pri.type = Nautilus_PROGRESS_UNDERWAY;
+ pri.amount = 0.0;
+ nautilus_view_frame_request_progress_change (NAUTILUS_VIEW_FRAME (music_view->details->view_frame), &pri);
+
+ /* do the actual work here */
+ nautilus_music_view_load_uri (music_view, navinfo->actual_uri);
+
+ /* send the required PROGRESS_DONE signal */
+ pri.type = Nautilus_PROGRESS_DONE_OK;
+ pri.amount = 100.0;
+ nautilus_view_frame_request_progress_change (NAUTILUS_VIEW_FRAME (music_view->details->view_frame), &pri);
+}
+
+/* handle drag and drop */
+
+static void
+nautilus_music_view_background_changed (NautilusMusicView *music_view)
+{
+ NautilusBackground *background;
+ NautilusDirectory *directory;
+ char *color_spec;
+
+ background = nautilus_get_widget_background (GTK_WIDGET (music_view));
+ color_spec = nautilus_background_get_color (background);
+ directory = nautilus_directory_get(music_view->details->current_uri);
+ nautilus_directory_set_metadata (directory,
+ ICON_VIEW_BACKGROUND_COLOR_METADATA_KEY,
+ MUSIC_VIEW_DEFAULT_BACKGROUND_COLOR,
+ color_spec);
+ g_free (color_spec);
+ gtk_object_unref(GTK_OBJECT(directory));
+}
+
+static void
+nautilus_music_view_drag_data_received (GtkWidget *widget, GdkDragContext *context,
+ gint x, gint y,
+ GtkSelectionData *selection_data, guint info, guint time)
+{
+ g_return_if_fail (NAUTILUS_IS_MUSIC_VIEW (widget));
+
+ switch (info)
+ {
+ case TARGET_GNOME_URI_LIST:
+ case TARGET_URI_LIST:
+ g_message("dropped data on music_view: %s", selection_data->data);
+ break;
+
+
+ case TARGET_COLOR:
+ /* Let the background change based on the dropped color. */
+ nautilus_background_receive_dropped_color(nautilus_get_widget_background (widget), widget, x, y, selection_data);
+ break;
+
+ default:
+ g_warning ("unknown drop type");
+ break;
+ }
+}
diff --git a/components/music/nautilus-music-view.goad b/components/music/nautilus-music-view.goad
new file mode 100644
index 000000000..9926a9806
--- /dev/null
+++ b/components/music/nautilus-music-view.goad
@@ -0,0 +1,11 @@
+[nautilus_music_view_factory]
+type=exe
+repo_id=IDL:GNOME/GenericFactory:1.0
+description=Factory for music view
+location_info=nautilus-music-view
+
+[nautilus_music_view]
+type=factory
+repo_id=IDL:GNOME/Control:1.0 IDL:Nautilus/ContentView:1.0 IDL:Nautilus/View:1.0
+description=music view
+location_info=nautilus_music_view_factory
diff --git a/components/music/nautilus-music-view.h b/components/music/nautilus-music-view.h
new file mode 100644
index 000000000..85bb7f637
--- /dev/null
+++ b/components/music/nautilus-music-view.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Copyright (C) 2000 Eazel, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Andy Hertzfeld
+ */
+
+/* header file for the music view component */
+
+#ifndef NAUTILUS_MUSIC_VIEW_H
+#define NAUTILUS_MUSIC_VIEW_H
+
+#include <libnautilus/ntl-content-view-frame.h>
+#include <gtk/gtkeventbox.h>
+
+
+typedef struct _NautilusMusicView NautilusMusicView;
+typedef struct _NautilusMusicViewClass NautilusMusicViewClass;
+
+#define NAUTILUS_TYPE_MUSIC_VIEW (nautilus_music_view_get_type ())
+#define NAUTILUS_MUSIC_VIEW(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_MUSIC_VIEW, NautilusMusicView))
+#define NAUTILUS_MUSIC_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_MUSIC_VIEW, NautilusMusicViewClass))
+#define NAUTILUS_IS_MUSIC_VIEW(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_MUSIC_VIEW))
+#define NAUTILUS_IS_MUSIC_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), NAUTILUS_TYPE_MUSIC_VIEW))
+
+typedef struct _NautilusMusicViewDetails NautilusMusicViewDetails;
+
+struct _NautilusMusicView {
+ GtkEventBox parent;
+ NautilusMusicViewDetails *details;
+};
+
+struct _NautilusMusicViewClass {
+ GtkEventBoxClass parent_class;
+};
+
+
+
+/* GtkObject support */
+GtkType nautilus_music_view_get_type (void);
+
+/* Component embedding support */
+NautilusContentViewFrame *nautilus_music_view_get_view_frame (NautilusMusicView *view);
+
+/* URI handling */
+void nautilus_music_view_load_uri (NautilusMusicView *view,
+ const char *uri);
+
+
+#endif /* NAUTILUS_MUSIC_VIEW_H */