# HG changeset patch # User nenolod # Date 1136321658 28800 # Node ID 5c457dac866af2bc42d06ef45cdf9acfd1ae1c27 # Parent a9c7793de60c0fc01e126ae4311bc5be2c4cabde [svn] - Rename playlistwin stuff to ui_playlist.* diff -r a9c7793de60c -r 5c457dac866a audacious/Makefile.am --- a/audacious/Makefile.am Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/Makefile.am Tue Jan 03 12:54:18 2006 -0800 @@ -60,7 +60,7 @@ mainwin.c mainwin.h \ skinwin.c skinwin.h \ prefswin.c prefswin.h \ - playlistwin.c playlistwin.h \ + ui_playlist.c ui_playlist.h \ equalizer.c equalizer.h \ glade.c glade.h \ hints.c hints.h \ diff -r a9c7793de60c -r 5c457dac866a audacious/controlsocket.c --- a/audacious/controlsocket.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/controlsocket.c Tue Jan 03 12:54:18 2006 -0800 @@ -38,7 +38,7 @@ #include "input.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "prefswin.h" #include "skin.h" #include "libaudacious/beepctrl.h" diff -r a9c7793de60c -r 5c457dac866a audacious/equalizer.c --- a/audacious/equalizer.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/equalizer.c Tue Jan 03 12:54:18 2006 -0800 @@ -46,7 +46,7 @@ #include "main.h" #include "pbutton.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "skin.h" #include "tbutton.h" #include "util.h" diff -r a9c7793de60c -r 5c457dac866a audacious/genevent.c --- a/audacious/genevent.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/genevent.c Tue Jan 03 12:54:18 2006 -0800 @@ -65,7 +65,7 @@ #include "output.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "pluginenum.h" #include "prefswin.h" #include "skin.h" diff -r a9c7793de60c -r 5c457dac866a audacious/hints.c --- a/audacious/hints.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/hints.c Tue Jan 03 12:54:18 2006 -0800 @@ -26,7 +26,7 @@ #include "equalizer.h" #include "mainwin.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include #include diff -r a9c7793de60c -r 5c457dac866a audacious/main.c --- a/audacious/main.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/main.c Tue Jan 03 12:54:18 2006 -0800 @@ -66,7 +66,7 @@ #include "output.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "pluginenum.h" #include "prefswin.h" #include "skin.h" diff -r a9c7793de60c -r 5c457dac866a audacious/mainwin.c --- a/audacious/mainwin.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/mainwin.c Tue Jan 03 12:54:18 2006 -0800 @@ -52,7 +52,7 @@ #include "equalizer.h" #include "hints.h" #include "input.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "prefswin.h" #include "skinwin.h" #include "genevent.h" diff -r a9c7793de60c -r 5c457dac866a audacious/playlist.c --- a/audacious/playlist.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/playlist.c Tue Jan 03 12:54:18 2006 -0800 @@ -49,7 +49,7 @@ #include "equalizer.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "playlist_list.h" #include "skin.h" #include "urldecode.h" diff -r a9c7793de60c -r 5c457dac866a audacious/playlist_list.c --- a/audacious/playlist_list.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/playlist_list.c Tue Jan 03 12:54:18 2006 -0800 @@ -42,7 +42,7 @@ #include "input.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "util.h" #include "debug.h" diff -r a9c7793de60c -r 5c457dac866a audacious/playlist_slider.c --- a/audacious/playlist_slider.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/playlist_slider.c Tue Jan 03 12:54:18 2006 -0800 @@ -24,7 +24,7 @@ #include #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "skin.h" #include "widget.h" diff -r a9c7793de60c -r 5c457dac866a audacious/playlistwin.c --- a/audacious/playlistwin.c Tue Jan 03 12:24:10 2006 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1974 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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. - */ - -#include "playlistwin.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "libaudacious/util.h" - -#include "dnd.h" -#include "dock.h" -#include "equalizer.h" -#include "hints.h" -#include "input.h" -#include "main.h" -#include "mainwin.h" -#include "libaudcore/playback.h" -#include "playlist.h" -#include "playlist_list.h" -#include "playlist_slider.h" -#include "playlist_popup.h" -#include "pbutton.h" -#include "sbutton.h" -#include "skin.h" -#include "textbox.h" -#include "util.h" - -#include "pixmaps.h" -#include "images/audacious_playlist.xpm" - - -#define ITEM_SEPARATOR {"/-", NULL, NULL, 0, ""} - - -enum { - ADD_URL, ADD_DIR, ADD_FILES, - SUB_MISC, SUB_ALL, SUB_CROP, SUB_SELECTED, - SEL_INV, SEL_ZERO, SEL_ALL, - MISC_SORT, MISC_FILEINFO, MISC_MISCOPTS, - PLIST_NEW, PLIST_SAVE_AS, PLIST_LOAD, - SEL_LOOKUP, CLOSE_PL_WINDOW, MOVE_UP, PLIST_SAVE, - MISC_QUEUE, PLIST_CQUEUE, PLIST_JTF, PLIST_JTT, - PLAYLISTWIN_REMOVE_DEAD_FILES, - PLAYLISTWIN_REFRESH -}; - -enum { - PLAYLISTWIN_SORT_BYTITLE, PLAYLISTWIN_SORT_BYFILENAME, - PLAYLISTWIN_SORT_BYPATH, PLAYLISTWIN_SORT_BYDATE, - PLAYLISTWIN_SORT_SEL_BYTITLE, PLAYLISTWIN_SORT_SEL_BYFILENAME, - PLAYLISTWIN_SORT_SEL_BYPATH, PLAYLISTWIN_SORT_SEL_BYDATE, - PLAYLISTWIN_SORT_RANDOMIZE, PLAYLISTWIN_SORT_REVERSE -}; - -GtkWidget *playlistwin; - -PlayList_List *playlistwin_list = NULL; -PButton *playlistwin_shade, *playlistwin_close; -Vis *playlistwin_vis; - -static gboolean playlistwin_resizing = FALSE; - -static GtkItemFactory *playlistwin_popup_menu; -static GtkItemFactory *pladd_menu, *pldel_menu; -static GtkItemFactory *plsel_menu, *plsort_menu; -static GtkItemFactory *pllist_menu; - -static GdkPixmap *playlistwin_bg; -static GdkBitmap *playlistwin_mask = NULL; -static GdkGC *playlistwin_gc; - -static GtkAccelGroup *playlistwin_accel; - -static gboolean playlistwin_hint_flag = FALSE; - -static PlaylistSlider *playlistwin_slider = NULL; -static TextBox *playlistwin_time_min, *playlistwin_time_sec; -static TextBox *playlistwin_info, *playlistwin_sinfo; -static SButton *playlistwin_srew, *playlistwin_splay; -static SButton *playlistwin_spause, *playlistwin_sstop; -static SButton *playlistwin_sfwd, *playlistwin_seject; -static SButton *playlistwin_sscroll_up, *playlistwin_sscroll_down; - -static GList *playlistwin_wlist = NULL; -static gboolean playlistwin_vis_enabled = FALSE; - -static void plsort_menu_callback(gpointer cb_data, guint action, - GtkWidget * w); -static void playlistwin_sub_menu_callback(gpointer cb_data, guint action, - GtkWidget * w); -static void playlistwin_popup_menu_callback(gpointer cb_data, guint action, - GtkWidget * w); - -static GtkItemFactoryEntry playlistwin_popup_menu_entries[] = { - {N_("/View Track Details"), NULL, - playlistwin_popup_menu_callback, - MISC_FILEINFO, "", my_pixbuf}, - - ITEM_SEPARATOR, - - {N_("/Remove Selected"), "Delete", - playlistwin_sub_menu_callback, - SUB_SELECTED, "", GTK_STOCK_DELETE}, - - {N_("/Remove Unselected"), NULL, - playlistwin_sub_menu_callback, - SUB_CROP, "", GTK_STOCK_CUT}, - - {N_("/Remove All"), NULL, - playlistwin_sub_menu_callback, - SUB_ALL, "", GTK_STOCK_DELETE}, - - ITEM_SEPARATOR, - - {N_("/Queue Toggle"), "q", - playlistwin_popup_menu_callback, - MISC_QUEUE, "", NULL}, -}; - -static GtkItemFactoryEntry pladd_menu_entries[] = { - {N_("/Add CD..."), "c", - mainwin_general_menu_callback, - MAINWIN_GENERAL_ADDCD, "", GTK_STOCK_CDROM}, - - {N_("/Add Internet Address..."), "h", - mainwin_general_menu_callback, - MAINWIN_GENERAL_PLAYLOCATION, "", GTK_STOCK_NETWORK}, - - {N_("/Add Files..."), "f", - mainwin_general_menu_callback, - MAINWIN_GENERAL_PLAYFILE, "", GTK_STOCK_OPEN}, -}; - -static GtkItemFactoryEntry pldel_menu_entries[] = { - {N_("/Clear Queue"), "Q", - playlistwin_popup_menu_callback, - PLIST_CQUEUE, ""}, - - ITEM_SEPARATOR, - - {N_("/Remove Unavailable Files"), NULL, - playlistwin_sub_menu_callback, - PLAYLISTWIN_REMOVE_DEAD_FILES, "", GTK_STOCK_DELETE}, - - ITEM_SEPARATOR, - - {N_("/Remove All"), NULL, - playlistwin_sub_menu_callback, - SUB_ALL, "", GTK_STOCK_DELETE}, - - {N_("/Remove Unselected"), NULL, - playlistwin_sub_menu_callback, - SUB_CROP, "", GTK_STOCK_DELETE}, - - {N_("/Remove Selected"), "Delete", - playlistwin_sub_menu_callback, - SUB_SELECTED, "", GTK_STOCK_DELETE} -}; - -static GtkItemFactoryEntry pllist_menu_entries[] = { - {N_("/New List"), NULL, - playlistwin_sub_menu_callback, - PLIST_NEW, "", GTK_STOCK_NEW}, - - ITEM_SEPARATOR, - - {N_("/Load List"), "o", - playlistwin_sub_menu_callback, - PLIST_LOAD, "", GTK_STOCK_OPEN}, - - {N_("/Save List"), "s", - playlistwin_sub_menu_callback, - PLIST_SAVE, "", GTK_STOCK_SAVE}, - - ITEM_SEPARATOR, - - {N_("/Update View"), "F5", - playlistwin_sub_menu_callback, - PLAYLISTWIN_REFRESH, "", GTK_STOCK_REFRESH} -}; - -static GtkItemFactoryEntry plsel_menu_entries[] = { - {N_("/Invert Selection"), NULL, - playlistwin_sub_menu_callback, - SEL_INV, "", GTK_STOCK_NETWORK}, - - ITEM_SEPARATOR, - - {N_("/Select None"),"A", - playlistwin_sub_menu_callback, - SEL_ZERO, "", GTK_STOCK_OPEN}, - - {N_("/Select All"), "A", - playlistwin_sub_menu_callback, - SEL_ALL, "", GTK_STOCK_OPEN}, -}; - -static GtkItemFactoryEntry plsort_menu_entries[] = { - {N_("/Randomize List"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_RANDOMIZE, ""}, - {N_("/Reverse List"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_REVERSE, ""}, - ITEM_SEPARATOR, - {N_("/Sort List"), NULL, NULL, 0, ""}, - {N_("/Sort List/By Title"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_BYTITLE, ""}, - {N_("/Sort List/By Filename"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_BYFILENAME, ""}, - {N_("/Sort List/By Path + Filename"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_BYPATH, ""}, - {N_("/Sort List/By Date"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_BYDATE, ""}, - {N_("/Sort Selection"), NULL, NULL, 0, ""}, - {N_("/Sort Selection/By Title"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_SEL_BYTITLE, ""}, - {N_("/Sort Selection/By Filename"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_SEL_BYFILENAME, ""}, - {N_("/Sort Selection/By Path + Filename"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_SEL_BYPATH, ""}, - {N_("/Sort Selection/By Date"), NULL, plsort_menu_callback, - PLAYLISTWIN_SORT_SEL_BYDATE, ""} -}; - - -static void playlistwin_draw_frame(void); - - -gboolean -playlistwin_is_shaded(void) -{ - return cfg.playlist_shaded; -} - -gint -playlistwin_get_width(void) -{ - return cfg.playlist_width; -} - -gint -playlistwin_get_height_unshaded(void) -{ - gint height = cfg.playlist_height; - return height; -} - -gint -playlistwin_get_height_shaded(void) -{ - return PLAYLISTWIN_SHADED_HEIGHT; -} - -gint -playlistwin_get_height(void) -{ - if (playlistwin_is_shaded()) - return playlistwin_get_height_shaded(); - else - return playlistwin_get_height_unshaded(); -} - -void -playlistwin_get_size(gint * width, gint * height) -{ - if (width) - *width = playlistwin_get_width(); - - if (height) - *height = playlistwin_get_height(); -} - -static void -playlistwin_update_info(void) -{ - gchar *text, *sel_text, *tot_text; - gulong selection, total; - gboolean selection_more, total_more; - - playlist_get_total_time(&total, &selection, &total_more, &selection_more); - - if (selection > 0 || (selection == 0 && !selection_more)) { - if (selection > 3600) - sel_text = - g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", selection / 3600, - (selection / 60) % 60, selection % 60, - (selection_more ? "+" : "")); - else - sel_text = - g_strdup_printf("%lu:%-2.2lu%s", selection / 60, - selection % 60, (selection_more ? "+" : "")); - } - else - sel_text = g_strdup("?"); - if (total > 0 || (total == 0 && !total_more)) { - if (total > 3600) - tot_text = - g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", total / 3600, - (total / 60) % 60, total % 60, - total_more ? "+" : ""); - else - tot_text = - g_strdup_printf("%lu:%-2.2lu%s", total / 60, total % 60, - total_more ? "+" : ""); - } - else - tot_text = g_strdup("?"); - text = g_strconcat(sel_text, "/", tot_text, NULL); - textbox_set_text(playlistwin_info, text); - g_free(text); - g_free(tot_text); - g_free(sel_text); -} - -static void -playlistwin_update_sinfo(void) -{ - gchar *posstr, *timestr, *title, *info, *dots; - gint pos, time, max_len; - - pos = playlist_get_position(); - title = playlist_get_songtitle(pos); - time = playlist_get_songtime(pos); - - if (!title) { - textbox_set_text(playlistwin_sinfo, ""); - return; - } - - if (cfg.show_numbers_in_pl) - posstr = g_strdup_printf("%d. ", pos + 1); - else - posstr = g_strdup(""); - - max_len = (playlistwin_get_width() - 35) / 5 - strlen(posstr); - - if (time != -1) { - timestr = g_strdup_printf(" %d:%-2.2d", time / 60000, - (time / 1000) % 60); - max_len -= strlen(timestr); - } - else - timestr = g_strdup(""); - - convert_title_text(title); - - if (strlen(title) > max_len) { - max_len -= 3; - dots = "..."; - } - else - dots = ""; - - info = g_strdup_printf("%s%-*.*s%s%s", posstr, max_len, max_len, - title, dots, timestr); - g_free(posstr); - g_free(title); - g_free(timestr); - - textbox_set_text(playlistwin_sinfo, info); - g_free(info); -} - -gboolean -playlistwin_item_visible(gint index) -{ - if (index >= playlistwin_list->pl_first - && index < - (playlistwin_list->pl_first + playlistwin_list->pl_num_visible)) - return TRUE; - return FALSE; -} - -gint -playlistwin_get_toprow(void) -{ - if (playlistwin_list) - return (playlistwin_list->pl_first); - return (-1); -} - -void -playlistwin_set_toprow(gint toprow) -{ - if (playlistwin_list) - playlistwin_list->pl_first = toprow; - playlistwin_update_list(); -} - -void -playlistwin_update_list(void) -{ - g_return_if_fail(playlistwin_list != NULL); - - widget_draw(WIDGET(playlistwin_list)); - widget_draw(WIDGET(playlistwin_slider)); - playlistwin_update_info(); - playlistwin_update_sinfo(); - /* mainwin_update_jtf(); */ -} - -#if 0 -static void -playlistwin_redraw_list(void) -{ - g_return_if_fail(playlistwin_list != NULL); - - draw_widget(playlistwin_list); - draw_widget(playlistwin_slider); -} -#endif - -static void -playlistwin_set_mask(void) -{ - GdkGC *gc; - GdkColor pattern; - - if (playlistwin_mask) - g_object_unref(playlistwin_mask); - - playlistwin_mask = - gdk_pixmap_new(playlistwin->window, playlistwin_get_width(), - playlistwin_get_height(), 1); - gc = gdk_gc_new(playlistwin_mask); - pattern.pixel = 1; - gdk_gc_set_foreground(gc, &pattern); - gdk_draw_rectangle(playlistwin_mask, gc, TRUE, 0, 0, - playlistwin_get_width(), playlistwin_get_height()); - gdk_gc_destroy(gc); - - gtk_widget_shape_combine_mask(playlistwin, playlistwin_mask, 0, 0); -} - -static void -playlistwin_set_geometry_hints(gboolean shaded) -{ - GdkGeometry geometry; - GdkWindowHints mask; - - geometry.min_width = PLAYLISTWIN_MIN_WIDTH; - geometry.max_width = G_MAXUINT16; - geometry.base_width = cfg.playlist_width; - - geometry.width_inc = PLAYLISTWIN_WIDTH_SNAP; - geometry.height_inc = PLAYLISTWIN_HEIGHT_SNAP; - - if (shaded) { - geometry.min_height = PLAYLISTWIN_SHADED_HEIGHT; - geometry.max_height = PLAYLISTWIN_SHADED_HEIGHT; - geometry.base_height = PLAYLISTWIN_SHADED_HEIGHT; - } - else { - geometry.min_height = PLAYLISTWIN_MIN_HEIGHT; - geometry.max_height = G_MAXUINT16; - geometry.base_height = cfg.playlist_height; - } - - mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_RESIZE_INC | - GDK_HINT_BASE_SIZE; - - gtk_window_set_geometry_hints(GTK_WINDOW(playlistwin), - playlistwin, &geometry, mask); -} - -void -playlistwin_set_shade(gboolean shaded) -{ - cfg.playlist_shaded = shaded; - - if (shaded) { - widget_show(WIDGET(playlistwin_sinfo)); - playlistwin_shade->pb_nx = 128; - playlistwin_shade->pb_ny = 45; - playlistwin_shade->pb_px = 150; - playlistwin_shade->pb_py = 42; - playlistwin_close->pb_nx = 138; - playlistwin_close->pb_ny = 45; - } - else { - widget_hide(WIDGET(playlistwin_sinfo)); - playlistwin_shade->pb_nx = 157; - playlistwin_shade->pb_ny = 3; - playlistwin_shade->pb_px = 62; - playlistwin_shade->pb_py = 42; - playlistwin_close->pb_nx = 167; - playlistwin_close->pb_ny = 3; - } - - dock_shade(dock_window_list, GTK_WINDOW(playlistwin), - playlistwin_get_height()); - - playlistwin_set_geometry_hints(cfg.playlist_shaded); - - gtk_window_resize(GTK_WINDOW(playlistwin), - cfg.playlist_width, - playlistwin_get_height()); - - playlistwin_set_mask(); - - widget_draw(WIDGET(playlistwin_list)); - widget_draw(WIDGET(playlistwin_slider)); - - draw_playlist_window(TRUE); -} - -static void -playlistwin_set_shade_menu(gboolean shaded) -{ - GtkWidget *item; - - item = gtk_item_factory_get_widget(mainwin_view_menu, - "/Roll up Playlist Editor"); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), shaded); - - playlistwin_set_shade(shaded); -} - -void -playlistwin_shade_toggle(void) -{ - playlistwin_set_shade_menu(!cfg.playlist_shaded); -} - -static void -playlistwin_release(GtkWidget * widget, - GdkEventButton * event, - gpointer callback_data) -{ - if (event->button == 3) - return; - - gdk_pointer_ungrab(GDK_CURRENT_TIME); - playlistwin_resizing = FALSE; - gdk_flush(); - - if (dock_is_moving(GTK_WINDOW(playlistwin))) { - dock_move_release(GTK_WINDOW(playlistwin)); -#if 0 - if (cfg.playlist_transparent) - playlistwin_update_list(); -#endif - } - else { - handle_release_cb(playlistwin_wlist, widget, event); - playlist_popup_destroy(); - draw_playlist_window(FALSE); - } -} - -void -playlistwin_scroll(gint num) -{ - playlistwin_list->pl_first += num; - playlistwin_update_list(); -} - -void -playlistwin_scroll_up_pushed(void) -{ - playlistwin_list->pl_first -= 3; - playlistwin_update_list(); -} - -void -playlistwin_scroll_down_pushed(void) -{ - playlistwin_list->pl_first += 3; - playlistwin_update_list(); -} - -static void -playlistwin_select_all(void) -{ - playlist_select_all(TRUE); - playlistwin_list->pl_prev_selected = 0; - playlistwin_list->pl_prev_min = 0; - playlistwin_list->pl_prev_max = playlist_get_length() - 1; - playlistwin_update_list(); -} - -static void -playlistwin_select_none(void) -{ - playlist_select_all(FALSE); - playlistwin_list->pl_prev_selected = -1; - playlistwin_list->pl_prev_min = -1; - playlistwin_update_list(); -} - -static void -playlistwin_inverse_selection(void) -{ - playlist_select_invert_all(); - playlistwin_list->pl_prev_selected = -1; - playlistwin_list->pl_prev_min = -1; - playlistwin_update_list(); -} - -static void -playlistwin_resize(gint width, gint height) -{ - gboolean redraw; - - g_return_if_fail(width > 0 && height > 0); - - cfg.playlist_width = width; - - if (!cfg.playlist_shaded) - cfg.playlist_height = height; - else - height = cfg.playlist_height; - - /* FIXME: why the fsck are we doing this manually? */ - /* adjust widget positions and sizes */ - - widget_resize(WIDGET(playlistwin_list), width - 31, height - 58); - - widget_move(WIDGET(playlistwin_slider), width - 15, 20); - widget_resize(WIDGET(playlistwin_slider), 8, height - 58); - - widget_resize(WIDGET(playlistwin_sinfo), width - 35, 14); - playlistwin_update_sinfo(); - - widget_move(WIDGET(playlistwin_shade), width - 21, 3); - widget_move(WIDGET(playlistwin_close), width - 11, 3); - widget_move(WIDGET(playlistwin_time_min), width - 82, height - 15); - widget_move(WIDGET(playlistwin_time_sec), width - 64, height - 15); - widget_move(WIDGET(playlistwin_info), width - 143, height - 28); - widget_move(WIDGET(playlistwin_srew), width - 144, height - 16); - widget_move(WIDGET(playlistwin_splay), width - 138, height - 16); - widget_move(WIDGET(playlistwin_spause), width - 128, height - 16); - widget_move(WIDGET(playlistwin_sstop), width - 118, height - 16); - widget_move(WIDGET(playlistwin_sfwd), width - 109, height - 16); - widget_move(WIDGET(playlistwin_seject), width - 100, height - 16); - widget_move(WIDGET(playlistwin_sscroll_up), width - 14, height - 35); - widget_move(WIDGET(playlistwin_sscroll_down), width - 14, height - 30); - - /* decide if we should show the mini visualizer */ - if (playlistwin_get_width() >= 350) { - widget_move(WIDGET(playlistwin_vis), width - 223, height - 26); - - if (playlistwin_vis_enabled) - widget_show(WIDGET(playlistwin_vis)); - } - else - widget_hide(WIDGET(playlistwin_vis)); - - g_object_unref(playlistwin_bg); - playlistwin_bg = gdk_pixmap_new(playlistwin->window, width, height, -1); - playlistwin_set_mask(); - - widget_list_lock(playlistwin_wlist); - - widget_list_change_pixmap(playlistwin_wlist, playlistwin_bg); - playlistwin_draw_frame(); - widget_list_draw(playlistwin_wlist, &redraw, TRUE); - widget_list_clear_redraw(playlistwin_wlist); - - widget_list_unlock(playlistwin_wlist); - - gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); - gdk_window_clear(playlistwin->window); -} - - - -static void -playlistwin_motion(GtkWidget * widget, - GdkEventMotion * event, - gpointer callback_data) -{ - XEvent ev; - - if (dock_is_moving(GTK_WINDOW(playlistwin))) { - dock_move_motion(GTK_WINDOW(playlistwin), event); - } - else { - handle_motion_cb(playlistwin_wlist, widget, event); - draw_playlist_window(FALSE); - } - gdk_flush(); - while (XCheckMaskEvent(GDK_DISPLAY(), ButtonMotionMask, &ev)); -} - -static void -playlistwin_show_filebrowser(void) -{ - util_run_filebrowser(NO_PLAY_BUTTON); -} - -#if 0 -static void -playlistwin_add_dir_handler(const gchar * dir) -{ - g_free(cfg.filesel_path); - cfg.filesel_path = g_strdup(dir); - playlist_add_dir(dir); -} -#endif - -static void -playlistwin_fileinfo(void) -{ - /* Show the first selected file, or the current file if nothing is - * selected */ - GList *list = playlist_get_selected(); - if (list) { - playlist_fileinfo(GPOINTER_TO_INT(list->data)); - g_list_free(list); - } - else - playlist_fileinfo_current(); -} - -static void -menu_set_item_sensitive(GtkItemFactory * item_factory, - const gchar * path, - gboolean sensitive) -{ - GtkWidget *item = gtk_item_factory_get_widget(item_factory, path); - gtk_widget_set_sensitive(item, sensitive); -} - -/* FIXME: broken */ -static void -playlistwin_set_sensitive_sortmenu(void) -{ - gboolean set = playlist_get_num_selected() > 1; - menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Title", set); - menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Filename", set); - menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Path + Filename", set); - menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Date", set); -} - -static void -show_playlist_save_error(GtkWindow * parent, - const gchar * filename) -{ - GtkWidget *dialog; - - g_return_if_fail(GTK_IS_WINDOW(parent)); - g_return_if_fail(filename != NULL); - - dialog = gtk_message_dialog_new(GTK_WINDOW(parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Error writing playlist \"%s\": %s"), - filename, strerror(errno)); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -} - -static gboolean -show_playlist_overwrite_prompt(GtkWindow * parent, - const gchar * filename) -{ - GtkWidget *dialog; - gint result; - - g_return_val_if_fail(GTK_IS_WINDOW(parent), FALSE); - g_return_val_if_fail(filename != NULL, FALSE); - - dialog = gtk_message_dialog_new(GTK_WINDOW(parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - _("%s already exist. Continue?"), - filename); - - result = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - return (result == GTK_RESPONSE_YES); -} - -static void -show_playlist_save_format_error(GtkWindow * parent, - const gchar * filename) -{ - const gchar *markup = - N_("Unable to save playlist.\n\n" - "Unknown file type for '%s'.\n"); - - GtkWidget *dialog; - - g_return_if_fail(GTK_IS_WINDOW(parent)); - g_return_if_fail(filename != NULL); - - dialog = - gtk_message_dialog_new_with_markup(GTK_WINDOW(parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _(markup), - filename); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -} - -static void -playlistwin_save_playlist(const gchar * filename) -{ - PlaylistFormat format; - - format = playlist_format_get_from_name(filename); - if (format == PLAYLIST_FORMAT_UNKNOWN) { - show_playlist_save_format_error(GTK_WINDOW(playlistwin), filename); - return; - } - - str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename)); - - if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) - if (!show_playlist_overwrite_prompt(GTK_WINDOW(playlistwin), filename)) - return; - - if (!playlist_save(filename, format)) - show_playlist_save_error(GTK_WINDOW(playlistwin), filename); -} - -#if 0 -static void -playlistwin_save_current(void) -{ - const gchar *filename; - - if (!(filename = playlist_get_current_name())) - return; - - playlistwin_save_playlist(filename); -} -#endif - -static void -playlistwin_load_playlist(const gchar * filename) -{ - g_return_if_fail(filename != NULL); - - str_replace_in(&cfg.playlist_path, g_strdup(filename)); - - playlist_clear(); - mainwin_clear_song_info(); - mainwin_set_info_text(); - - playlist_load(filename); - playlist_set_current_name(filename); -} - -static gchar * -playlist_file_selection(const gchar * title, - gboolean save, - const gchar * default_filename) -{ - GtkWidget *dialog, *button; - gchar *filename; - - g_return_val_if_fail(title != NULL, NULL); - - dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(mainwin), - save ? GTK_FILE_CHOOSER_ACTION_SAVE : - GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL); - if (default_filename) - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), - default_filename); - - button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, - GTK_RESPONSE_REJECT); - gtk_button_set_use_stock(GTK_BUTTON(button), TRUE); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - - button = gtk_dialog_add_button(GTK_DIALOG(dialog), - save ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, - GTK_RESPONSE_ACCEPT); - gtk_button_set_use_stock(GTK_BUTTON(button), TRUE); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - else - filename = NULL; - - gtk_widget_destroy(dialog); - - return filename; -} - -void -playlistwin_select_playlist_to_load(const gchar * default_filename) -{ - gchar *filename = - playlist_file_selection(_("Load Playlist"), FALSE, default_filename); - - if (filename) { - playlistwin_load_playlist(filename); - g_free(filename); - } -} - -static void -playlistwin_select_playlist_to_save(const gchar * default_filename) -{ - gchar *filename = - playlist_file_selection(_("Save Playlist"), TRUE, default_filename); - - if (filename) { - /* Default to M3U if no filename has extension */ - - /* NOTE: This doesn't work correctly for hidden files - - descender */ - if (!strchr(filename, '.')) { - gchar *tmpstr = filename; - filename = g_strconcat(filename, ".m3u", NULL); - g_free(tmpstr); - } - - playlistwin_save_playlist(filename); - g_free(filename); - } -} - -static gboolean -inside_sensitive_widgets(gint x, gint y) -{ - return (widget_contains(WIDGET(playlistwin_list), x, y) || - widget_contains(WIDGET(playlistwin_slider), x, y) || - widget_contains(WIDGET(playlistwin_close), x, y) || - widget_contains(WIDGET(playlistwin_shade), x, y) || - widget_contains(WIDGET(playlistwin_time_min), x, y) || - widget_contains(WIDGET(playlistwin_time_sec), x, y) || - widget_contains(WIDGET(playlistwin_info), x, y) || - widget_contains(WIDGET(playlistwin_vis), x, y) || - widget_contains(WIDGET(playlistwin_srew), x, y) || - widget_contains(WIDGET(playlistwin_splay), x, y) || - widget_contains(WIDGET(playlistwin_spause), x, y) || - widget_contains(WIDGET(playlistwin_sstop), x, y) || - widget_contains(WIDGET(playlistwin_sfwd), x, y) || - widget_contains(WIDGET(playlistwin_seject), x, y) || - widget_contains(WIDGET(playlistwin_sscroll_up), x, y) || - widget_contains(WIDGET(playlistwin_sscroll_down), x, y)); -} - -#define REGION_L(x1,x2,y1,y2) \ - (event->x >= (x1) && event->x < (x2) && \ - event->y >= cfg.playlist_height - (y1) && \ - event->y < cfg.playlist_height - (y2)) - -#define REGION_R(x1,x2,y1,y2) \ - (event->x >= playlistwin_get_width() - (x1) && \ - event->x < playlistwin_get_width() - (x2) && \ - event->y >= cfg.playlist_height - (y1) && \ - event->y < cfg.playlist_height - (y2)) - -static void -playlistwin_scrolled(GtkWidget * widget, - GdkEventScroll * event, - gpointer callback_data) -{ - - if (event->direction == GDK_SCROLL_DOWN) - playlistwin_scroll(cfg.scroll_pl_by); - - if (event->direction == GDK_SCROLL_UP) - playlistwin_scroll(-cfg.scroll_pl_by); - -} - - - - -static gboolean -playlistwin_press(GtkWidget * widget, - GdkEventButton * event, - gpointer callback_data) -{ - gboolean grab = TRUE; - gint xpos, ypos; - GtkWidget *_menu; - GtkRequisition req; - - gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos); - - if (event->button == 1 && !cfg.show_wm_decorations && - ((!cfg.playlist_shaded && - event->x > playlistwin_get_width() - 20 && - event->y > cfg.playlist_height - 20) || - (cfg.playlist_shaded && - event->x >= playlistwin_get_width() - 31 && - event->x < playlistwin_get_width() - 22))) { - - /* NOTE: Workaround for bug #214 */ - if (event->type != GDK_2BUTTON_PRESS && - event->type != GDK_3BUTTON_PRESS) { - /* resize area */ - playlistwin_resizing = TRUE; - gtk_window_begin_resize_drag(GTK_WINDOW(widget), - GDK_WINDOW_EDGE_SOUTH_EAST, - event->button, - event->x + xpos, event->y + ypos, - event->time); - } - grab = FALSE; - } - else if (event->button == 1 && REGION_L(12, 37, 29, 11)) { - /* ADD button menu */ - - _menu = GTK_WIDGET(pladd_menu->widget); - if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); - gtk_widget_size_request(_menu, &req); - gtk_item_factory_popup_with_data(pladd_menu, - NULL, NULL, - xpos+12, - (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); - grab = FALSE; - } - else if (event->button == 1 && REGION_L(41, 66, 29, 11)) { - /* SUB button menu */ - _menu = GTK_WIDGET(pldel_menu->widget); - if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); - gtk_widget_size_request(_menu, &req); - gtk_item_factory_popup_with_data(pldel_menu, - NULL, NULL, - xpos+40, - (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); - grab = FALSE; - } - else if (event->button == 1 && REGION_L(70, 95, 29, 11)) { - /* SEL button menu */ - _menu = GTK_WIDGET(plsel_menu->widget); - if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); - gtk_widget_size_request(_menu, &req); - gtk_item_factory_popup_with_data(plsel_menu, - NULL, NULL, - xpos+68, - (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); - - grab = FALSE; - } - else if (event->button == 1 && REGION_L(99, 124, 29, 11)) { - /* MISC button menu */ - _menu = GTK_WIDGET(plsort_menu->widget); - if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); - gtk_widget_size_request(_menu, &req); - gtk_item_factory_popup_with_data(plsort_menu, - NULL, NULL, - xpos+100, - (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); - grab = FALSE; - } - else if (event->button == 1 && REGION_R(46, 23, 29, 11)) { - /* LIST button menu */ - _menu = GTK_WIDGET(pllist_menu->widget); - if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); - gtk_widget_size_request(_menu, &req); - gtk_item_factory_popup_with_data(pllist_menu, - NULL, NULL, - xpos + playlistwin_get_width() - req.width - 12, - (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); - grab = FALSE; - } - else if (event->button == 1 && REGION_R(82, 54, 15, 9)) { - if (cfg.timer_mode == TIMER_ELAPSED) - cfg.timer_mode = TIMER_REMAINING; - else - cfg.timer_mode = TIMER_ELAPSED; - } - else if (event->button == 2 && (event->type == GDK_BUTTON_PRESS) && - widget_contains(WIDGET(playlistwin_list), event->x, event->y)) { - gtk_selection_convert(widget, GDK_SELECTION_PRIMARY, - GDK_TARGET_STRING, event->time); - } - else if (playlistwin_get_width() >= 350 && REGION_R(223, 151, 26, 10)) { - if (event->button == 1) { - cfg.vis_type++; - if (cfg.vis_type > VIS_OFF) - cfg.vis_type = VIS_ANALYZER; - mainwin_vis_set_type(cfg.vis_type); - } - else if (event->button == 3) { - gint mx, my; - GdkModifierType modmask; - - gdk_window_get_pointer(NULL, &mx, &my, &modmask); - util_item_factory_popup(mainwin_vis_menu, mx, my, 3, event->time); - grab = FALSE; - } - } - else if (event->button == 1 && event->type == GDK_BUTTON_PRESS && - !inside_sensitive_widgets(event->x, event->y) && event->y < 14) { - gdk_window_raise(playlistwin->window); - dock_move_press(dock_window_list, GTK_WINDOW(playlistwin), event, - FALSE); - } - else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS && - !inside_sensitive_widgets(event->x, event->y) - && event->y < 14) { - /* double click on title bar */ - playlistwin_shade_toggle(); - if (dock_is_moving(GTK_WINDOW(playlistwin))) - dock_move_release(GTK_WINDOW(playlistwin)); - return TRUE; - } - else if (event->button == 3 && - !(widget_contains(WIDGET(playlistwin_list), event->x, event->y) || - (event->y >= cfg.playlist_height - 29 && - event->y < cfg.playlist_height - 11 && - ((event->x >= 12 && event->x < 37) || - (event->x >= 41 && event->x < 66) || - (event->x >= 70 && event->x < 95) || - (event->x >= 99 && event->x < 124) || - (event->x >= playlistwin_get_width() - 46 && - event->x < playlistwin_get_width() - 23))))) { - /* - * Pop up the main menu a few pixels down to avoid - * anything to be selected initially. - */ - util_item_factory_popup(mainwin_general_menu, event->x_root, - event->y_root + 2, 3, event->time); - grab = FALSE; - } - else if (event->button == 3 && - widget_contains(WIDGET(playlistwin_list), event->x, event->y)) { - /* popup menu */ - playlistwin_set_sensitive_sortmenu(); - gtk_item_factory_popup(playlistwin_popup_menu, - event->x_root, event->y_root + 5, - 3, event->time); - grab = FALSE; - } - else { - handle_press_cb(playlistwin_wlist, widget, event); - draw_playlist_window(FALSE); - } - - if (grab) - gdk_pointer_grab(playlistwin->window, FALSE, - GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON1_MOTION_MASK, NULL, NULL, - GDK_CURRENT_TIME); - - return FALSE; -} - -static gboolean -playlistwin_focus_in(GtkWidget * widget, GdkEvent * event, gpointer data) -{ - playlistwin_close->pb_allow_draw = TRUE; - playlistwin_shade->pb_allow_draw = TRUE; - draw_playlist_window(TRUE); - return FALSE; -} - -static gboolean -playlistwin_focus_out(GtkWidget * widget, - GdkEventButton * event, gpointer data) -{ - playlistwin_close->pb_allow_draw = FALSE; - playlistwin_shade->pb_allow_draw = FALSE; - draw_playlist_window(TRUE); - return FALSE; -} - -static gboolean -playlistwin_configure(GtkWidget * window, - GdkEventConfigure * event, gpointer data) -{ - if (!GTK_WIDGET_VISIBLE(window)) - return FALSE; - - cfg.playlist_x = event->x; - cfg.playlist_y = event->y; - - if (playlistwin_resizing) { - if (event->width != playlistwin_get_width() || - event->height != playlistwin_get_height()) - playlistwin_resize(event->width, event->height); - } - return TRUE; -} - -void -playlistwin_set_back_pixmap(void) -{ - gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); - gdk_window_clear(playlistwin->window); -} - -static gboolean -playlistwin_delete(GtkWidget * w, gpointer data) -{ - playlistwin_hide(); - return TRUE; -} - -static void -playlistwin_keypress_up_down_handler(PlayList_List * pl, - gboolean up, guint state) -{ - if ((state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK)) - return; - if (!(state & GDK_MOD1_MASK)) - playlist_select_all(FALSE); - - if (pl->pl_prev_selected == -1 || - (!playlistwin_item_visible(pl->pl_prev_selected) && - !(state & GDK_SHIFT_MASK && pl->pl_prev_min != -1))) { - pl->pl_prev_selected = pl->pl_first; - } - else if (state & GDK_SHIFT_MASK) { - if (pl->pl_prev_min == -1) { - pl->pl_prev_max = pl->pl_prev_selected; - pl->pl_prev_min = pl->pl_prev_selected; - } - pl->pl_prev_max += (up ? -1 : 1); - pl->pl_prev_max = - CLAMP(pl->pl_prev_max, 0, playlist_get_length() - 1); - - pl->pl_first = MIN(pl->pl_first, pl->pl_prev_max); - pl->pl_first = MAX(pl->pl_first, pl->pl_prev_max - - pl->pl_num_visible + 1); - playlist_select_range(pl->pl_prev_min, pl->pl_prev_max, TRUE); - return; - } - else if (state & GDK_MOD1_MASK) { - if (up) - playlist_list_move_up(pl); - else - playlist_list_move_down(pl); - if (pl->pl_prev_min < pl->pl_first) - pl->pl_first = pl->pl_prev_min; - else if (pl->pl_prev_max >= (pl->pl_first + pl->pl_num_visible)) - pl->pl_first = pl->pl_prev_max - pl->pl_num_visible + 1; - return; - } - else if (up) - pl->pl_prev_selected--; - else - pl->pl_prev_selected++; - - pl->pl_prev_selected = - CLAMP(pl->pl_prev_selected, 0, playlist_get_length() - 1); - - if (pl->pl_prev_selected < pl->pl_first) - pl->pl_first--; - else if (pl->pl_prev_selected >= (pl->pl_first + pl->pl_num_visible)) - pl->pl_first++; - - playlist_select_range(pl->pl_prev_selected, pl->pl_prev_selected, TRUE); - pl->pl_prev_min = -1; - -} - -/* FIXME: Handle the keys through menu */ - -static gboolean -playlistwin_keypress(GtkWidget * w, GdkEventKey * event, gpointer data) -{ - guint keyval; - gboolean refresh = FALSE; - - if (cfg.playlist_shaded) - return FALSE; - - switch (keyval = event->keyval) { - case GDK_KP_Up: - case GDK_KP_Down: - case GDK_Up: - case GDK_Down: - playlistwin_keypress_up_down_handler(playlistwin_list, - keyval == GDK_Up - || keyval == GDK_KP_Up, - event->state); - refresh = TRUE; - break; - case GDK_Page_Up: - playlistwin_scroll(-playlistwin_list->pl_num_visible); - refresh = TRUE; - break; - case GDK_Page_Down: - playlistwin_scroll(playlistwin_list->pl_num_visible); - refresh = TRUE; - break; - case GDK_Home: - playlistwin_list->pl_first = 0; - refresh = TRUE; - break; - case GDK_End: - playlistwin_list->pl_first = - playlist_get_length() - playlistwin_list->pl_num_visible; - refresh = TRUE; - break; - case GDK_Return: - if (playlistwin_list->pl_prev_selected > -1 - && playlistwin_item_visible(playlistwin_list->pl_prev_selected)) { - playlist_set_position(playlistwin_list->pl_prev_selected); - if (!bmp_playback_get_playing()) - bmp_playback_initiate(); - } - break; - case GDK_3: - if (event->state & GDK_CONTROL_MASK) - playlistwin_fileinfo(); - break; - case GDK_Delete: - if (event->state & GDK_CONTROL_MASK) - playlist_delete(TRUE); - else - playlist_delete(FALSE); - break; - case GDK_Insert: - if (event->state & GDK_MOD1_MASK) - mainwin_show_add_url_window(); - else - playlistwin_show_filebrowser(); - break; - case GDK_Left: - case GDK_KP_Left: - case GDK_KP_7: - if (playlist_get_current_length() != -1) - bmp_playback_seek(CLAMP - (bmp_playback_get_time() - 5000, 0, - playlist_get_current_length()) / 1000); - break; - case GDK_Right: - case GDK_KP_Right: - case GDK_KP_9: - if (playlist_get_current_length() != -1) - bmp_playback_seek(CLAMP - (bmp_playback_get_time() + 5000, 0, - playlist_get_current_length()) / 1000); - break; - - case GDK_Escape: - mainwin_minimize_cb(); - break; - default: - return FALSE; - } - - if (refresh) - playlistwin_update_list(); - - return TRUE; -} - -static void -playlistwin_draw_frame(void) -{ - gboolean focus = - gtk_window_has_toplevel_focus(GTK_WINDOW(playlistwin)) || - !cfg.dim_titlebar; - - if (cfg.playlist_shaded) { - skin_draw_playlistwin_shaded(bmp_active_skin, - playlistwin_bg, playlistwin_gc, - playlistwin_get_width(), focus); - } - else { - skin_draw_playlistwin_frame(bmp_active_skin, - playlistwin_bg, playlistwin_gc, - playlistwin_get_width(), - cfg.playlist_height, focus); - } -} - -void -draw_playlist_window(gboolean force) -{ - gboolean redraw; - GList *wl; - Widget *w; - - if (force) - playlistwin_draw_frame(); - - widget_list_lock(playlistwin_wlist); - widget_list_draw(playlistwin_wlist, &redraw, force); - - if (redraw || force) { - if (force) { - gdk_window_clear(playlistwin->window); - } - else { - for (wl = playlistwin_wlist; wl; wl = g_list_next(wl)) { - w = WIDGET(wl->data); - if (w->redraw && w->visible) { - gdk_window_clear_area(playlistwin->window, w->x, w->y, - w->width, w->height); - w->redraw = FALSE; - } - } - } - - gdk_flush(); - } - - widget_list_unlock(playlistwin_wlist); -} - - -void -playlistwin_hide_timer(void) -{ - textbox_set_text(playlistwin_time_min, " "); - textbox_set_text(playlistwin_time_sec, " "); -} - -void -playlistwin_vis_enable(void) -{ - playlistwin_vis_enabled = TRUE; - - if (playlistwin_get_width() >= 350) - widget_show(WIDGET(playlistwin_vis)); -} - -void -playlistwin_vis_disable(void) -{ - playlistwin_vis_enabled = FALSE; - widget_hide(WIDGET(playlistwin_vis)); - draw_playlist_window(TRUE); -} - -void -playlistwin_set_time(gint time, gint length, TimerMode mode) -{ - gchar *text, sign; - - if (mode == TIMER_REMAINING && length != -1) { - time = length - time; - sign = '-'; - } - else - sign = ' '; - - time /= 1000; - - if (time < 0) - time = 0; - if (time > 99 * 60) - time /= 60; - - text = g_strdup_printf("%c%-2.2d", sign, time / 60); - textbox_set_text(playlistwin_time_min, text); - g_free(text); - - text = g_strdup_printf("%-2.2d", time % 60); - textbox_set_text(playlistwin_time_sec, text); - g_free(text); -} - -static void -playlistwin_drag_motion(GtkWidget * widget, - GdkDragContext * context, - gint x, gint y, - GtkSelectionData * selection_data, - guint info, guint time, gpointer user_data) -{ - playlistwin_list->pl_drag_motion = TRUE; - playlistwin_list->drag_motion_x = x; - playlistwin_list->drag_motion_y = y; - playlistwin_update_list(); - playlistwin_hint_flag = TRUE; -} - -static void -playlistwin_drag_end(GtkWidget * widget, - GdkDragContext * context, gpointer user_data) -{ - playlistwin_list->pl_drag_motion = FALSE; - playlistwin_hint_flag = FALSE; - playlistwin_update_list(); -} - -static void -playlistwin_drag_data_received(GtkWidget * widget, - GdkDragContext * context, - gint x, gint y, - GtkSelectionData * - selection_data, guint info, - guint time, gpointer user_data) -{ - guint pos; - - g_return_if_fail(selection_data != NULL); - - if (!selection_data->data) { - g_message("Received no DND data!"); - return; - } - - if (widget_contains(WIDGET(playlistwin_list), x, y)) { - pos = (y - WIDGET(playlistwin_list)->y) / - playlistwin_list->pl_fheight + playlistwin_list->pl_first; - - pos = MIN(pos, playlist_get_length()); - playlist_ins_url((gchar *) selection_data->data, pos); - } - else - playlist_add_url((gchar *) selection_data->data); -} - -static void -playlistwin_create_widgets(void) -{ - /* This function creates the custom widgets used by the playlist editor */ - - /* text box for displaying song title in shaded mode */ - playlistwin_sinfo = - create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - 4, 4, playlistwin_get_width() - 35, FALSE, SKIN_TEXT); - - if (!cfg.playlist_shaded) - widget_hide(WIDGET(playlistwin_sinfo)); - - /* shade/unshade window push button */ - if (cfg.playlist_shaded) - playlistwin_shade = - create_pbutton(&playlistwin_wlist, playlistwin_bg, - playlistwin_gc, playlistwin_get_width() - 21, 3, - 9, 9, 128, 45, 150, 42, - playlistwin_shade_toggle, SKIN_PLEDIT); - else - playlistwin_shade = - create_pbutton(&playlistwin_wlist, playlistwin_bg, - playlistwin_gc, playlistwin_get_width() - 21, 3, - 9, 9, 157, 3, 62, 42, playlistwin_shade_toggle, - SKIN_PLEDIT); - - playlistwin_shade->pb_allow_draw = FALSE; - - /* close window push button */ - playlistwin_close = - create_pbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 11, 3, 9, 9, - cfg.playlist_shaded ? 138 : 167, - cfg.playlist_shaded ? 45 : 3, 52, 42, - playlistwin_hide, SKIN_PLEDIT); - playlistwin_close->pb_allow_draw = FALSE; - - /* playlist list box */ - playlistwin_list = - create_playlist_list(&playlistwin_wlist, playlistwin_bg, - playlistwin_gc, 12, 20, - playlistwin_get_width() - 31, - cfg.playlist_height - 58); - playlist_list_set_font(cfg.playlist_font); - - /* playlist list box slider */ - playlistwin_slider = - create_playlistslider(&playlistwin_wlist, playlistwin_bg, - playlistwin_gc, playlistwin_get_width() - 15, - 20, cfg.playlist_height - 58, playlistwin_list); - /* track time (minute) */ - playlistwin_time_min = - create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 82, - cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT); - - /* track time (second) */ - playlistwin_time_sec = - create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 64, - cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT); - - /* playlist information (current track length / total track length) */ - playlistwin_info = - create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 143, - cfg.playlist_height - 28, 85, FALSE, SKIN_TEXT); - - /* mini visualizer */ - playlistwin_vis = - create_vis(&playlistwin_wlist, playlistwin_bg, playlistwin->window, - playlistwin_gc, playlistwin_get_width() - 223, - cfg.playlist_height - 26, 72); - widget_hide(WIDGET(playlistwin_vis)); - - /* mini play control buttons at right bottom corner */ - - /* rewind button */ - playlistwin_srew = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 144, - cfg.playlist_height - 16, 8, 7, playlist_prev); - - /* play button */ - playlistwin_splay = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 138, - cfg.playlist_height - 16, 10, 7, mainwin_play_pushed); - - /* pause button */ - playlistwin_spause = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 128, - cfg.playlist_height - 16, 10, 7, bmp_playback_pause); - - /* stop button */ - playlistwin_sstop = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 118, - cfg.playlist_height - 16, 9, 7, mainwin_stop_pushed); - - /* forward button */ - playlistwin_sfwd = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 109, - cfg.playlist_height - 16, 8, 7, playlist_next); - - /* eject button */ - playlistwin_seject = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 100, - cfg.playlist_height - 16, 9, 7, mainwin_eject_pushed); - - - playlistwin_sscroll_up = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 14, - cfg.playlist_height - 35, 8, 5, - playlistwin_scroll_up_pushed); - playlistwin_sscroll_down = - create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, - playlistwin_get_width() - 14, - cfg.playlist_height - 30, 8, 5, - playlistwin_scroll_down_pushed); - -} - -static void -selection_received(GtkWidget * widget, - GtkSelectionData * selection_data, gpointer data) -{ - if (selection_data->type == GDK_SELECTION_TYPE_STRING && - selection_data->length > 0) - playlist_add_url((gchar *) selection_data->data); -} - -static void -playlistwin_create_window(void) -{ - GdkPixbuf *icon; - - playlistwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor")); - gtk_window_set_role(GTK_WINDOW(playlistwin), "playlist"); - gtk_window_set_default_size(GTK_WINDOW(playlistwin), - playlistwin_get_width(), - playlistwin_get_height()); - gtk_window_set_resizable(GTK_WINDOW(playlistwin), TRUE); - playlistwin_set_geometry_hints(cfg.playlist_shaded); - dock_window_list = dock_window_set_decorated(dock_window_list, - GTK_WINDOW(playlistwin), - cfg.show_wm_decorations); - - gtk_window_set_transient_for(GTK_WINDOW(playlistwin), - GTK_WINDOW(mainwin)); - gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE); - - icon = gdk_pixbuf_new_from_xpm_data((const gchar **) bmp_playlist_icon); - gtk_window_set_icon(GTK_WINDOW(playlistwin), icon); - g_object_unref(icon); - - gtk_widget_set_app_paintable(playlistwin, TRUE); - - if (cfg.playlist_x != -1 && cfg.save_window_position) - gtk_window_move(GTK_WINDOW(playlistwin), - cfg.playlist_x, cfg.playlist_y); - - gtk_widget_add_events(playlistwin, - GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK); - gtk_widget_realize(playlistwin); - - util_set_cursor(playlistwin); - - g_signal_connect(playlistwin, "delete_event", - G_CALLBACK(playlistwin_delete), NULL); - g_signal_connect(playlistwin, "button_press_event", - G_CALLBACK(playlistwin_press), NULL); - g_signal_connect(playlistwin, "button_release_event", - G_CALLBACK(playlistwin_release), NULL); - g_signal_connect(playlistwin, "scroll_event", - G_CALLBACK(playlistwin_scrolled), NULL); - g_signal_connect(playlistwin, "motion_notify_event", - G_CALLBACK(playlistwin_motion), NULL); - g_signal_connect_after(playlistwin, "focus_in_event", - G_CALLBACK(playlistwin_focus_in), NULL); - g_signal_connect_after(playlistwin, "focus_out_event", - G_CALLBACK(playlistwin_focus_out), NULL); - g_signal_connect(playlistwin, "configure_event", - G_CALLBACK(playlistwin_configure), NULL); - g_signal_connect(playlistwin, "style_set", - G_CALLBACK(playlistwin_set_back_pixmap), NULL); - - bmp_drag_dest_set(playlistwin); - - /* DnD stuff */ - g_signal_connect(playlistwin, "drag-leave", - G_CALLBACK(playlistwin_drag_end), NULL); - g_signal_connect(playlistwin, "drag-data-delete", - G_CALLBACK(playlistwin_drag_end), NULL); - g_signal_connect(playlistwin, "drag-end", - G_CALLBACK(playlistwin_drag_end), NULL); - g_signal_connect(playlistwin, "drag-drop", - G_CALLBACK(playlistwin_drag_end), NULL); - g_signal_connect(playlistwin, "drag-data-received", - G_CALLBACK(playlistwin_drag_data_received), NULL); - g_signal_connect(playlistwin, "drag-motion", - G_CALLBACK(playlistwin_drag_motion), NULL); - - g_signal_connect(playlistwin, "key_press_event", - G_CALLBACK(playlistwin_keypress), NULL); - g_signal_connect(playlistwin, "selection_received", - G_CALLBACK(selection_received), NULL); - - playlistwin_set_mask(); -} - -void -playlistwin_create_popup_menus(void) -{ - playlistwin_accel = gtk_accel_group_new(); - - /* playlist window popup menu */ - playlistwin_popup_menu = create_menu(playlistwin_popup_menu_entries, - G_N_ELEMENTS(playlistwin_popup_menu_entries), - playlistwin_accel); - - pladd_menu = create_menu(pladd_menu_entries, G_N_ELEMENTS(pladd_menu_entries), - playlistwin_accel); - pldel_menu = create_menu(pldel_menu_entries, G_N_ELEMENTS(pldel_menu_entries), - playlistwin_accel); - plsel_menu = create_menu(plsel_menu_entries, G_N_ELEMENTS(plsel_menu_entries), - playlistwin_accel); - plsort_menu = create_menu(plsort_menu_entries, - G_N_ELEMENTS(plsort_menu_entries), - playlistwin_accel); - pllist_menu = create_menu(pllist_menu_entries, G_N_ELEMENTS(pllist_menu_entries), - playlistwin_accel); - -#if 0 - make_submenu(playlistwin_popup_menu, "/Playlist", - playlistwin_playlist_menu); - make_submenu(playlistwin_popup_menu, "/Playback", - playlistwin_playback_menu); - make_submenu(playlistwin_popup_menu, "/Add", - pladd_menu); -#endif -} - -void -playlistwin_create(void) -{ - playlistwin_create_window(); - playlistwin_create_popup_menus(); - - /* create GC and back pixmap for custom widget to draw on */ - playlistwin_gc = gdk_gc_new(playlistwin->window); - playlistwin_bg = gdk_pixmap_new(playlistwin->window, - playlistwin_get_width(), - playlistwin_get_height_unshaded(), -1); - gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); - - playlistwin_create_widgets(); - playlistwin_update_info(); - - gtk_window_add_accel_group(GTK_WINDOW(playlistwin), playlistwin_accel); - gtk_window_add_accel_group(GTK_WINDOW(playlistwin), mainwin_accel); -} - - -void -playlistwin_show(void) -{ - GtkWidget *item; - - item = gtk_item_factory_get_widget(mainwin_view_menu, - "/Show Playlist Editor"); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); - - tbutton_set_toggled(mainwin_pl, TRUE); - cfg.playlist_visible = TRUE; - - playlistwin_set_toprow(0); - playlist_check_pos_current(); - - gtk_widget_show(playlistwin); -} - -void -playlistwin_hide(void) -{ - GtkWidget *item; - - item = gtk_item_factory_get_widget(mainwin_view_menu, - "/Show Playlist Editor"); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), FALSE); - - gtk_widget_hide(playlistwin); - tbutton_set_toggled(mainwin_pl, FALSE); - cfg.playlist_visible = FALSE; - - gtk_window_present(GTK_WINDOW(mainwin)); - gtk_widget_grab_focus(mainwin); -} - - -static void -plsort_menu_callback(gpointer data, - guint action, - GtkWidget * widget) -{ - switch (action) { - case PLAYLISTWIN_SORT_BYTITLE: - playlist_sort(PLAYLIST_SORT_TITLE); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_BYPATH: - playlist_sort(PLAYLIST_SORT_PATH); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_BYDATE: - playlist_sort(PLAYLIST_SORT_DATE); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_BYFILENAME: - playlist_sort(PLAYLIST_SORT_FILENAME); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_SEL_BYTITLE: - playlist_sort_selected(PLAYLIST_SORT_TITLE); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_SEL_BYFILENAME: - playlist_sort_selected(PLAYLIST_SORT_FILENAME); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_SEL_BYPATH: - playlist_sort_selected(PLAYLIST_SORT_PATH); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_SEL_BYDATE: - playlist_sort_selected(PLAYLIST_SORT_DATE); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_REVERSE: - playlist_reverse(); - playlistwin_update_list(); - break; - case PLAYLISTWIN_SORT_RANDOMIZE: - playlist_random(); - playlistwin_update_list(); - break; - } -} - -static void -playlistwin_sub_menu_callback(gpointer data, - guint action, - GtkWidget * widget) -{ - switch (action) { - case PLIST_NEW: - playlist_set_current_name(NULL); - playlist_clear(); - mainwin_clear_song_info(); - mainwin_set_info_text(); - break; - case PLIST_SAVE: - playlistwin_select_playlist_to_save(playlist_get_current_name()); - break; - case PLIST_SAVE_AS: - playlistwin_select_playlist_to_save(playlist_get_current_name()); - break; - case PLIST_LOAD: - playlistwin_select_playlist_to_load(playlist_get_current_name()); - break; - case SEL_INV: - playlistwin_inverse_selection(); - break; - case SEL_ZERO: - playlistwin_select_none(); - break; - case SEL_ALL: - playlistwin_select_all(); - break; - case SUB_ALL: - playlist_clear(); - mainwin_clear_song_info(); - mainwin_set_info_text(); - break; - case SUB_CROP: - playlist_delete(TRUE); - break; - case SUB_SELECTED: - playlist_delete(FALSE); - break; - case PLAYLISTWIN_REMOVE_DEAD_FILES: - playlist_remove_dead_files(); - break; - case PLAYLISTWIN_REFRESH: - playlist_read_info_selection(); - playlistwin_update_list(); - break; - } -} - -static void -playlistwin_popup_menu_callback(gpointer data, - guint action, - GtkWidget * widget) -{ - switch (action) { - case ADD_FILES: - playlistwin_show_filebrowser(); - break; - case CLOSE_PL_WINDOW: - playlistwin_hide(); - break; - case MISC_FILEINFO: - playlistwin_fileinfo(); - break; - case SEL_LOOKUP: - playlist_read_info_selection(); - break; - case MISC_QUEUE: - playlist_queue(); - break; - case PLIST_CQUEUE: - playlist_clear_queue(); - break; - case PLIST_JTT: - mainwin_jump_to_time(); - break; - case PLIST_JTF: - mainwin_jump_to_file(); - break; - } -} diff -r a9c7793de60c -r 5c457dac866a audacious/playlistwin.h --- a/audacious/playlistwin.h Tue Jan 03 12:24:10 2006 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* BMP - Cross-platform multimedia player - * Copyright (C) 2003-2004 BMP development team. - * - * Based on XMMS: - * Copyright (C) 1998-2003 XMMS development team. - * - * 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. - */ - -#ifndef PLAYLISTWIN_H -#define PLAYLISTWIN_H - -#include - -#include "mainwin.h" -#include "pbutton.h" -#include "playlist_list.h" - - -#define PLAYLISTWIN_FRAME_TOP_HEIGHT 20 -#define PLAYLISTWIN_FRAME_BOTTOM_HEIGHT 38 -#define PLAYLISTWIN_FRAME_LEFT_WIDTH 12 -#define PLAYLISTWIN_FRAME_RIGHT_WIDTH 19 - -#define PLAYLISTWIN_MIN_WIDTH MAINWIN_WIDTH -#define PLAYLISTWIN_MIN_HEIGHT MAINWIN_HEIGHT -#define PLAYLISTWIN_WIDTH_SNAP 25 -#define PLAYLISTWIN_HEIGHT_SNAP 29 -#define PLAYLISTWIN_SHADED_HEIGHT MAINWIN_SHADED_HEIGHT -#define PLAYLISTWIN_WIDTH cfg.playlist_width -#define PLAYLISTWIN_HEIGHT \ - (cfg.playlist_shaded ? PLAYLISTWIN_SHADED_HEIGHT : cfg.playlist_height) - -#define PLAYLISTWIN_DEFAULT_WIDTH 275 -#define PLAYLISTWIN_DEFAULT_HEIGHT 232 -#define PLAYLISTWIN_DEFAULT_POS_X 295 -#define PLAYLISTWIN_DEFAULT_POS_Y 20 - -#define PLAYLISTWIN_DEFAULT_FONT "Sans Bold 8" - -void playlistwin_update_list(void); -gboolean playlistwin_item_visible(gint index); -gint playlistwin_get_toprow(void); -void playlistwin_set_toprow(gint top); -void playlistwin_set_shade_menu_cb(gboolean shaded); -void playlistwin_set_shade(gboolean shaded); -void playlistwin_shade_toggle(void); -void playlistwin_create(void); -void draw_playlist_window(gboolean force); -void playlistwin_hide_timer(void); -void playlistwin_set_time(gint time, gint length, TimerMode mode); -void playlistwin_show(void); -void playlistwin_hide(void); -void playlistwin_set_back_pixmap(void); -void playlistwin_scroll(gint num); -void playlistwin_scroll_up_pushed(void); -void playlistwin_scroll_down_pushed(void); -void playlistwin_vis_disable(void); -void playlistwin_vis_enable(void); -void playlistwin_select_playlist_to_load(const gchar * default_filename); - -extern GtkWidget *playlistwin; -extern Vis *playlistwin_vis; -extern PlayList_List *playlistwin_list; - -extern PButton *playlistwin_shade, *playlistwin_close; - -extern gboolean playlistwin_focus; - -#endif diff -r a9c7793de60c -r 5c457dac866a audacious/prefswin.c --- a/audacious/prefswin.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/prefswin.c Tue Jan 03 12:54:18 2006 -0800 @@ -44,7 +44,7 @@ #include "libaudacious/configdb.h" #include "mainwin.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "skinwin.h" #include "playlist_list.h" diff -r a9c7793de60c -r 5c457dac866a audacious/skin.c --- a/audacious/skin.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/skin.c Tue Jan 03 12:54:18 2006 -0800 @@ -33,7 +33,7 @@ #include "equalizer.h" #include "main.h" -#include "playlistwin.h" +#include "ui_playlist.h" #include "skin.h" #include "skinwin.h" #include "util.h" diff -r a9c7793de60c -r 5c457dac866a audacious/ui_playlist.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/ui_playlist.c Tue Jan 03 12:54:18 2006 -0800 @@ -0,0 +1,1974 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * 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. + */ + +#include "ui_playlist.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "libaudacious/util.h" + +#include "dnd.h" +#include "dock.h" +#include "equalizer.h" +#include "hints.h" +#include "input.h" +#include "main.h" +#include "mainwin.h" +#include "libaudcore/playback.h" +#include "playlist.h" +#include "playlist_list.h" +#include "playlist_slider.h" +#include "playlist_popup.h" +#include "pbutton.h" +#include "sbutton.h" +#include "skin.h" +#include "textbox.h" +#include "util.h" + +#include "pixmaps.h" +#include "images/audacious_playlist.xpm" + + +#define ITEM_SEPARATOR {"/-", NULL, NULL, 0, ""} + + +enum { + ADD_URL, ADD_DIR, ADD_FILES, + SUB_MISC, SUB_ALL, SUB_CROP, SUB_SELECTED, + SEL_INV, SEL_ZERO, SEL_ALL, + MISC_SORT, MISC_FILEINFO, MISC_MISCOPTS, + PLIST_NEW, PLIST_SAVE_AS, PLIST_LOAD, + SEL_LOOKUP, CLOSE_PL_WINDOW, MOVE_UP, PLIST_SAVE, + MISC_QUEUE, PLIST_CQUEUE, PLIST_JTF, PLIST_JTT, + PLAYLISTWIN_REMOVE_DEAD_FILES, + PLAYLISTWIN_REFRESH +}; + +enum { + PLAYLISTWIN_SORT_BYTITLE, PLAYLISTWIN_SORT_BYFILENAME, + PLAYLISTWIN_SORT_BYPATH, PLAYLISTWIN_SORT_BYDATE, + PLAYLISTWIN_SORT_SEL_BYTITLE, PLAYLISTWIN_SORT_SEL_BYFILENAME, + PLAYLISTWIN_SORT_SEL_BYPATH, PLAYLISTWIN_SORT_SEL_BYDATE, + PLAYLISTWIN_SORT_RANDOMIZE, PLAYLISTWIN_SORT_REVERSE +}; + +GtkWidget *playlistwin; + +PlayList_List *playlistwin_list = NULL; +PButton *playlistwin_shade, *playlistwin_close; +Vis *playlistwin_vis; + +static gboolean playlistwin_resizing = FALSE; + +static GtkItemFactory *playlistwin_popup_menu; +static GtkItemFactory *pladd_menu, *pldel_menu; +static GtkItemFactory *plsel_menu, *plsort_menu; +static GtkItemFactory *pllist_menu; + +static GdkPixmap *playlistwin_bg; +static GdkBitmap *playlistwin_mask = NULL; +static GdkGC *playlistwin_gc; + +static GtkAccelGroup *playlistwin_accel; + +static gboolean playlistwin_hint_flag = FALSE; + +static PlaylistSlider *playlistwin_slider = NULL; +static TextBox *playlistwin_time_min, *playlistwin_time_sec; +static TextBox *playlistwin_info, *playlistwin_sinfo; +static SButton *playlistwin_srew, *playlistwin_splay; +static SButton *playlistwin_spause, *playlistwin_sstop; +static SButton *playlistwin_sfwd, *playlistwin_seject; +static SButton *playlistwin_sscroll_up, *playlistwin_sscroll_down; + +static GList *playlistwin_wlist = NULL; +static gboolean playlistwin_vis_enabled = FALSE; + +static void plsort_menu_callback(gpointer cb_data, guint action, + GtkWidget * w); +static void playlistwin_sub_menu_callback(gpointer cb_data, guint action, + GtkWidget * w); +static void playlistwin_popup_menu_callback(gpointer cb_data, guint action, + GtkWidget * w); + +static GtkItemFactoryEntry playlistwin_popup_menu_entries[] = { + {N_("/View Track Details"), NULL, + playlistwin_popup_menu_callback, + MISC_FILEINFO, "", my_pixbuf}, + + ITEM_SEPARATOR, + + {N_("/Remove Selected"), "Delete", + playlistwin_sub_menu_callback, + SUB_SELECTED, "", GTK_STOCK_DELETE}, + + {N_("/Remove Unselected"), NULL, + playlistwin_sub_menu_callback, + SUB_CROP, "", GTK_STOCK_CUT}, + + {N_("/Remove All"), NULL, + playlistwin_sub_menu_callback, + SUB_ALL, "", GTK_STOCK_DELETE}, + + ITEM_SEPARATOR, + + {N_("/Queue Toggle"), "q", + playlistwin_popup_menu_callback, + MISC_QUEUE, "", NULL}, +}; + +static GtkItemFactoryEntry pladd_menu_entries[] = { + {N_("/Add CD..."), "c", + mainwin_general_menu_callback, + MAINWIN_GENERAL_ADDCD, "", GTK_STOCK_CDROM}, + + {N_("/Add Internet Address..."), "h", + mainwin_general_menu_callback, + MAINWIN_GENERAL_PLAYLOCATION, "", GTK_STOCK_NETWORK}, + + {N_("/Add Files..."), "f", + mainwin_general_menu_callback, + MAINWIN_GENERAL_PLAYFILE, "", GTK_STOCK_OPEN}, +}; + +static GtkItemFactoryEntry pldel_menu_entries[] = { + {N_("/Clear Queue"), "Q", + playlistwin_popup_menu_callback, + PLIST_CQUEUE, ""}, + + ITEM_SEPARATOR, + + {N_("/Remove Unavailable Files"), NULL, + playlistwin_sub_menu_callback, + PLAYLISTWIN_REMOVE_DEAD_FILES, "", GTK_STOCK_DELETE}, + + ITEM_SEPARATOR, + + {N_("/Remove All"), NULL, + playlistwin_sub_menu_callback, + SUB_ALL, "", GTK_STOCK_DELETE}, + + {N_("/Remove Unselected"), NULL, + playlistwin_sub_menu_callback, + SUB_CROP, "", GTK_STOCK_DELETE}, + + {N_("/Remove Selected"), "Delete", + playlistwin_sub_menu_callback, + SUB_SELECTED, "", GTK_STOCK_DELETE} +}; + +static GtkItemFactoryEntry pllist_menu_entries[] = { + {N_("/New List"), NULL, + playlistwin_sub_menu_callback, + PLIST_NEW, "", GTK_STOCK_NEW}, + + ITEM_SEPARATOR, + + {N_("/Load List"), "o", + playlistwin_sub_menu_callback, + PLIST_LOAD, "", GTK_STOCK_OPEN}, + + {N_("/Save List"), "s", + playlistwin_sub_menu_callback, + PLIST_SAVE, "", GTK_STOCK_SAVE}, + + ITEM_SEPARATOR, + + {N_("/Update View"), "F5", + playlistwin_sub_menu_callback, + PLAYLISTWIN_REFRESH, "", GTK_STOCK_REFRESH} +}; + +static GtkItemFactoryEntry plsel_menu_entries[] = { + {N_("/Invert Selection"), NULL, + playlistwin_sub_menu_callback, + SEL_INV, "", GTK_STOCK_NETWORK}, + + ITEM_SEPARATOR, + + {N_("/Select None"),"A", + playlistwin_sub_menu_callback, + SEL_ZERO, "", GTK_STOCK_OPEN}, + + {N_("/Select All"), "A", + playlistwin_sub_menu_callback, + SEL_ALL, "", GTK_STOCK_OPEN}, +}; + +static GtkItemFactoryEntry plsort_menu_entries[] = { + {N_("/Randomize List"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_RANDOMIZE, ""}, + {N_("/Reverse List"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_REVERSE, ""}, + ITEM_SEPARATOR, + {N_("/Sort List"), NULL, NULL, 0, ""}, + {N_("/Sort List/By Title"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_BYTITLE, ""}, + {N_("/Sort List/By Filename"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_BYFILENAME, ""}, + {N_("/Sort List/By Path + Filename"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_BYPATH, ""}, + {N_("/Sort List/By Date"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_BYDATE, ""}, + {N_("/Sort Selection"), NULL, NULL, 0, ""}, + {N_("/Sort Selection/By Title"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_SEL_BYTITLE, ""}, + {N_("/Sort Selection/By Filename"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_SEL_BYFILENAME, ""}, + {N_("/Sort Selection/By Path + Filename"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_SEL_BYPATH, ""}, + {N_("/Sort Selection/By Date"), NULL, plsort_menu_callback, + PLAYLISTWIN_SORT_SEL_BYDATE, ""} +}; + + +static void playlistwin_draw_frame(void); + + +gboolean +playlistwin_is_shaded(void) +{ + return cfg.playlist_shaded; +} + +gint +playlistwin_get_width(void) +{ + return cfg.playlist_width; +} + +gint +playlistwin_get_height_unshaded(void) +{ + gint height = cfg.playlist_height; + return height; +} + +gint +playlistwin_get_height_shaded(void) +{ + return PLAYLISTWIN_SHADED_HEIGHT; +} + +gint +playlistwin_get_height(void) +{ + if (playlistwin_is_shaded()) + return playlistwin_get_height_shaded(); + else + return playlistwin_get_height_unshaded(); +} + +void +playlistwin_get_size(gint * width, gint * height) +{ + if (width) + *width = playlistwin_get_width(); + + if (height) + *height = playlistwin_get_height(); +} + +static void +playlistwin_update_info(void) +{ + gchar *text, *sel_text, *tot_text; + gulong selection, total; + gboolean selection_more, total_more; + + playlist_get_total_time(&total, &selection, &total_more, &selection_more); + + if (selection > 0 || (selection == 0 && !selection_more)) { + if (selection > 3600) + sel_text = + g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", selection / 3600, + (selection / 60) % 60, selection % 60, + (selection_more ? "+" : "")); + else + sel_text = + g_strdup_printf("%lu:%-2.2lu%s", selection / 60, + selection % 60, (selection_more ? "+" : "")); + } + else + sel_text = g_strdup("?"); + if (total > 0 || (total == 0 && !total_more)) { + if (total > 3600) + tot_text = + g_strdup_printf("%lu:%-2.2lu:%-2.2lu%s", total / 3600, + (total / 60) % 60, total % 60, + total_more ? "+" : ""); + else + tot_text = + g_strdup_printf("%lu:%-2.2lu%s", total / 60, total % 60, + total_more ? "+" : ""); + } + else + tot_text = g_strdup("?"); + text = g_strconcat(sel_text, "/", tot_text, NULL); + textbox_set_text(playlistwin_info, text); + g_free(text); + g_free(tot_text); + g_free(sel_text); +} + +static void +playlistwin_update_sinfo(void) +{ + gchar *posstr, *timestr, *title, *info, *dots; + gint pos, time, max_len; + + pos = playlist_get_position(); + title = playlist_get_songtitle(pos); + time = playlist_get_songtime(pos); + + if (!title) { + textbox_set_text(playlistwin_sinfo, ""); + return; + } + + if (cfg.show_numbers_in_pl) + posstr = g_strdup_printf("%d. ", pos + 1); + else + posstr = g_strdup(""); + + max_len = (playlistwin_get_width() - 35) / 5 - strlen(posstr); + + if (time != -1) { + timestr = g_strdup_printf(" %d:%-2.2d", time / 60000, + (time / 1000) % 60); + max_len -= strlen(timestr); + } + else + timestr = g_strdup(""); + + convert_title_text(title); + + if (strlen(title) > max_len) { + max_len -= 3; + dots = "..."; + } + else + dots = ""; + + info = g_strdup_printf("%s%-*.*s%s%s", posstr, max_len, max_len, + title, dots, timestr); + g_free(posstr); + g_free(title); + g_free(timestr); + + textbox_set_text(playlistwin_sinfo, info); + g_free(info); +} + +gboolean +playlistwin_item_visible(gint index) +{ + if (index >= playlistwin_list->pl_first + && index < + (playlistwin_list->pl_first + playlistwin_list->pl_num_visible)) + return TRUE; + return FALSE; +} + +gint +playlistwin_get_toprow(void) +{ + if (playlistwin_list) + return (playlistwin_list->pl_first); + return (-1); +} + +void +playlistwin_set_toprow(gint toprow) +{ + if (playlistwin_list) + playlistwin_list->pl_first = toprow; + playlistwin_update_list(); +} + +void +playlistwin_update_list(void) +{ + g_return_if_fail(playlistwin_list != NULL); + + widget_draw(WIDGET(playlistwin_list)); + widget_draw(WIDGET(playlistwin_slider)); + playlistwin_update_info(); + playlistwin_update_sinfo(); + /* mainwin_update_jtf(); */ +} + +#if 0 +static void +playlistwin_redraw_list(void) +{ + g_return_if_fail(playlistwin_list != NULL); + + draw_widget(playlistwin_list); + draw_widget(playlistwin_slider); +} +#endif + +static void +playlistwin_set_mask(void) +{ + GdkGC *gc; + GdkColor pattern; + + if (playlistwin_mask) + g_object_unref(playlistwin_mask); + + playlistwin_mask = + gdk_pixmap_new(playlistwin->window, playlistwin_get_width(), + playlistwin_get_height(), 1); + gc = gdk_gc_new(playlistwin_mask); + pattern.pixel = 1; + gdk_gc_set_foreground(gc, &pattern); + gdk_draw_rectangle(playlistwin_mask, gc, TRUE, 0, 0, + playlistwin_get_width(), playlistwin_get_height()); + gdk_gc_destroy(gc); + + gtk_widget_shape_combine_mask(playlistwin, playlistwin_mask, 0, 0); +} + +static void +playlistwin_set_geometry_hints(gboolean shaded) +{ + GdkGeometry geometry; + GdkWindowHints mask; + + geometry.min_width = PLAYLISTWIN_MIN_WIDTH; + geometry.max_width = G_MAXUINT16; + geometry.base_width = cfg.playlist_width; + + geometry.width_inc = PLAYLISTWIN_WIDTH_SNAP; + geometry.height_inc = PLAYLISTWIN_HEIGHT_SNAP; + + if (shaded) { + geometry.min_height = PLAYLISTWIN_SHADED_HEIGHT; + geometry.max_height = PLAYLISTWIN_SHADED_HEIGHT; + geometry.base_height = PLAYLISTWIN_SHADED_HEIGHT; + } + else { + geometry.min_height = PLAYLISTWIN_MIN_HEIGHT; + geometry.max_height = G_MAXUINT16; + geometry.base_height = cfg.playlist_height; + } + + mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_RESIZE_INC | + GDK_HINT_BASE_SIZE; + + gtk_window_set_geometry_hints(GTK_WINDOW(playlistwin), + playlistwin, &geometry, mask); +} + +void +playlistwin_set_shade(gboolean shaded) +{ + cfg.playlist_shaded = shaded; + + if (shaded) { + widget_show(WIDGET(playlistwin_sinfo)); + playlistwin_shade->pb_nx = 128; + playlistwin_shade->pb_ny = 45; + playlistwin_shade->pb_px = 150; + playlistwin_shade->pb_py = 42; + playlistwin_close->pb_nx = 138; + playlistwin_close->pb_ny = 45; + } + else { + widget_hide(WIDGET(playlistwin_sinfo)); + playlistwin_shade->pb_nx = 157; + playlistwin_shade->pb_ny = 3; + playlistwin_shade->pb_px = 62; + playlistwin_shade->pb_py = 42; + playlistwin_close->pb_nx = 167; + playlistwin_close->pb_ny = 3; + } + + dock_shade(dock_window_list, GTK_WINDOW(playlistwin), + playlistwin_get_height()); + + playlistwin_set_geometry_hints(cfg.playlist_shaded); + + gtk_window_resize(GTK_WINDOW(playlistwin), + cfg.playlist_width, + playlistwin_get_height()); + + playlistwin_set_mask(); + + widget_draw(WIDGET(playlistwin_list)); + widget_draw(WIDGET(playlistwin_slider)); + + draw_playlist_window(TRUE); +} + +static void +playlistwin_set_shade_menu(gboolean shaded) +{ + GtkWidget *item; + + item = gtk_item_factory_get_widget(mainwin_view_menu, + "/Roll up Playlist Editor"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), shaded); + + playlistwin_set_shade(shaded); +} + +void +playlistwin_shade_toggle(void) +{ + playlistwin_set_shade_menu(!cfg.playlist_shaded); +} + +static void +playlistwin_release(GtkWidget * widget, + GdkEventButton * event, + gpointer callback_data) +{ + if (event->button == 3) + return; + + gdk_pointer_ungrab(GDK_CURRENT_TIME); + playlistwin_resizing = FALSE; + gdk_flush(); + + if (dock_is_moving(GTK_WINDOW(playlistwin))) { + dock_move_release(GTK_WINDOW(playlistwin)); +#if 0 + if (cfg.playlist_transparent) + playlistwin_update_list(); +#endif + } + else { + handle_release_cb(playlistwin_wlist, widget, event); + playlist_popup_destroy(); + draw_playlist_window(FALSE); + } +} + +void +playlistwin_scroll(gint num) +{ + playlistwin_list->pl_first += num; + playlistwin_update_list(); +} + +void +playlistwin_scroll_up_pushed(void) +{ + playlistwin_list->pl_first -= 3; + playlistwin_update_list(); +} + +void +playlistwin_scroll_down_pushed(void) +{ + playlistwin_list->pl_first += 3; + playlistwin_update_list(); +} + +static void +playlistwin_select_all(void) +{ + playlist_select_all(TRUE); + playlistwin_list->pl_prev_selected = 0; + playlistwin_list->pl_prev_min = 0; + playlistwin_list->pl_prev_max = playlist_get_length() - 1; + playlistwin_update_list(); +} + +static void +playlistwin_select_none(void) +{ + playlist_select_all(FALSE); + playlistwin_list->pl_prev_selected = -1; + playlistwin_list->pl_prev_min = -1; + playlistwin_update_list(); +} + +static void +playlistwin_inverse_selection(void) +{ + playlist_select_invert_all(); + playlistwin_list->pl_prev_selected = -1; + playlistwin_list->pl_prev_min = -1; + playlistwin_update_list(); +} + +static void +playlistwin_resize(gint width, gint height) +{ + gboolean redraw; + + g_return_if_fail(width > 0 && height > 0); + + cfg.playlist_width = width; + + if (!cfg.playlist_shaded) + cfg.playlist_height = height; + else + height = cfg.playlist_height; + + /* FIXME: why the fsck are we doing this manually? */ + /* adjust widget positions and sizes */ + + widget_resize(WIDGET(playlistwin_list), width - 31, height - 58); + + widget_move(WIDGET(playlistwin_slider), width - 15, 20); + widget_resize(WIDGET(playlistwin_slider), 8, height - 58); + + widget_resize(WIDGET(playlistwin_sinfo), width - 35, 14); + playlistwin_update_sinfo(); + + widget_move(WIDGET(playlistwin_shade), width - 21, 3); + widget_move(WIDGET(playlistwin_close), width - 11, 3); + widget_move(WIDGET(playlistwin_time_min), width - 82, height - 15); + widget_move(WIDGET(playlistwin_time_sec), width - 64, height - 15); + widget_move(WIDGET(playlistwin_info), width - 143, height - 28); + widget_move(WIDGET(playlistwin_srew), width - 144, height - 16); + widget_move(WIDGET(playlistwin_splay), width - 138, height - 16); + widget_move(WIDGET(playlistwin_spause), width - 128, height - 16); + widget_move(WIDGET(playlistwin_sstop), width - 118, height - 16); + widget_move(WIDGET(playlistwin_sfwd), width - 109, height - 16); + widget_move(WIDGET(playlistwin_seject), width - 100, height - 16); + widget_move(WIDGET(playlistwin_sscroll_up), width - 14, height - 35); + widget_move(WIDGET(playlistwin_sscroll_down), width - 14, height - 30); + + /* decide if we should show the mini visualizer */ + if (playlistwin_get_width() >= 350) { + widget_move(WIDGET(playlistwin_vis), width - 223, height - 26); + + if (playlistwin_vis_enabled) + widget_show(WIDGET(playlistwin_vis)); + } + else + widget_hide(WIDGET(playlistwin_vis)); + + g_object_unref(playlistwin_bg); + playlistwin_bg = gdk_pixmap_new(playlistwin->window, width, height, -1); + playlistwin_set_mask(); + + widget_list_lock(playlistwin_wlist); + + widget_list_change_pixmap(playlistwin_wlist, playlistwin_bg); + playlistwin_draw_frame(); + widget_list_draw(playlistwin_wlist, &redraw, TRUE); + widget_list_clear_redraw(playlistwin_wlist); + + widget_list_unlock(playlistwin_wlist); + + gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); + gdk_window_clear(playlistwin->window); +} + + + +static void +playlistwin_motion(GtkWidget * widget, + GdkEventMotion * event, + gpointer callback_data) +{ + XEvent ev; + + if (dock_is_moving(GTK_WINDOW(playlistwin))) { + dock_move_motion(GTK_WINDOW(playlistwin), event); + } + else { + handle_motion_cb(playlistwin_wlist, widget, event); + draw_playlist_window(FALSE); + } + gdk_flush(); + while (XCheckMaskEvent(GDK_DISPLAY(), ButtonMotionMask, &ev)); +} + +static void +playlistwin_show_filebrowser(void) +{ + util_run_filebrowser(NO_PLAY_BUTTON); +} + +#if 0 +static void +playlistwin_add_dir_handler(const gchar * dir) +{ + g_free(cfg.filesel_path); + cfg.filesel_path = g_strdup(dir); + playlist_add_dir(dir); +} +#endif + +static void +playlistwin_fileinfo(void) +{ + /* Show the first selected file, or the current file if nothing is + * selected */ + GList *list = playlist_get_selected(); + if (list) { + playlist_fileinfo(GPOINTER_TO_INT(list->data)); + g_list_free(list); + } + else + playlist_fileinfo_current(); +} + +static void +menu_set_item_sensitive(GtkItemFactory * item_factory, + const gchar * path, + gboolean sensitive) +{ + GtkWidget *item = gtk_item_factory_get_widget(item_factory, path); + gtk_widget_set_sensitive(item, sensitive); +} + +/* FIXME: broken */ +static void +playlistwin_set_sensitive_sortmenu(void) +{ + gboolean set = playlist_get_num_selected() > 1; + menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Title", set); + menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Filename", set); + menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Path + Filename", set); + menu_set_item_sensitive(plsort_menu, "/Sort Selection/By Date", set); +} + +static void +show_playlist_save_error(GtkWindow * parent, + const gchar * filename) +{ + GtkWidget *dialog; + + g_return_if_fail(GTK_IS_WINDOW(parent)); + g_return_if_fail(filename != NULL); + + dialog = gtk_message_dialog_new(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Error writing playlist \"%s\": %s"), + filename, strerror(errno)); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +static gboolean +show_playlist_overwrite_prompt(GtkWindow * parent, + const gchar * filename) +{ + GtkWidget *dialog; + gint result; + + g_return_val_if_fail(GTK_IS_WINDOW(parent), FALSE); + g_return_val_if_fail(filename != NULL, FALSE); + + dialog = gtk_message_dialog_new(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("%s already exist. Continue?"), + filename); + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + return (result == GTK_RESPONSE_YES); +} + +static void +show_playlist_save_format_error(GtkWindow * parent, + const gchar * filename) +{ + const gchar *markup = + N_("Unable to save playlist.\n\n" + "Unknown file type for '%s'.\n"); + + GtkWidget *dialog; + + g_return_if_fail(GTK_IS_WINDOW(parent)); + g_return_if_fail(filename != NULL); + + dialog = + gtk_message_dialog_new_with_markup(GTK_WINDOW(parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _(markup), + filename); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +} + +static void +playlistwin_save_playlist(const gchar * filename) +{ + PlaylistFormat format; + + format = playlist_format_get_from_name(filename); + if (format == PLAYLIST_FORMAT_UNKNOWN) { + show_playlist_save_format_error(GTK_WINDOW(playlistwin), filename); + return; + } + + str_replace_in(&cfg.playlist_path, g_path_get_dirname(filename)); + + if (g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + if (!show_playlist_overwrite_prompt(GTK_WINDOW(playlistwin), filename)) + return; + + if (!playlist_save(filename, format)) + show_playlist_save_error(GTK_WINDOW(playlistwin), filename); +} + +#if 0 +static void +playlistwin_save_current(void) +{ + const gchar *filename; + + if (!(filename = playlist_get_current_name())) + return; + + playlistwin_save_playlist(filename); +} +#endif + +static void +playlistwin_load_playlist(const gchar * filename) +{ + g_return_if_fail(filename != NULL); + + str_replace_in(&cfg.playlist_path, g_strdup(filename)); + + playlist_clear(); + mainwin_clear_song_info(); + mainwin_set_info_text(); + + playlist_load(filename); + playlist_set_current_name(filename); +} + +static gchar * +playlist_file_selection(const gchar * title, + gboolean save, + const gchar * default_filename) +{ + GtkWidget *dialog, *button; + gchar *filename; + + g_return_val_if_fail(title != NULL, NULL); + + dialog = gtk_file_chooser_dialog_new(title, GTK_WINDOW(mainwin), + save ? GTK_FILE_CHOOSER_ACTION_SAVE : + GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL); + if (default_filename) + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), + default_filename); + + button = gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT); + gtk_button_set_use_stock(GTK_BUTTON(button), TRUE); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + + button = gtk_dialog_add_button(GTK_DIALOG(dialog), + save ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, + GTK_RESPONSE_ACCEPT); + gtk_button_set_use_stock(GTK_BUTTON(button), TRUE); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + else + filename = NULL; + + gtk_widget_destroy(dialog); + + return filename; +} + +void +playlistwin_select_playlist_to_load(const gchar * default_filename) +{ + gchar *filename = + playlist_file_selection(_("Load Playlist"), FALSE, default_filename); + + if (filename) { + playlistwin_load_playlist(filename); + g_free(filename); + } +} + +static void +playlistwin_select_playlist_to_save(const gchar * default_filename) +{ + gchar *filename = + playlist_file_selection(_("Save Playlist"), TRUE, default_filename); + + if (filename) { + /* Default to M3U if no filename has extension */ + + /* NOTE: This doesn't work correctly for hidden files + - descender */ + if (!strchr(filename, '.')) { + gchar *tmpstr = filename; + filename = g_strconcat(filename, ".m3u", NULL); + g_free(tmpstr); + } + + playlistwin_save_playlist(filename); + g_free(filename); + } +} + +static gboolean +inside_sensitive_widgets(gint x, gint y) +{ + return (widget_contains(WIDGET(playlistwin_list), x, y) || + widget_contains(WIDGET(playlistwin_slider), x, y) || + widget_contains(WIDGET(playlistwin_close), x, y) || + widget_contains(WIDGET(playlistwin_shade), x, y) || + widget_contains(WIDGET(playlistwin_time_min), x, y) || + widget_contains(WIDGET(playlistwin_time_sec), x, y) || + widget_contains(WIDGET(playlistwin_info), x, y) || + widget_contains(WIDGET(playlistwin_vis), x, y) || + widget_contains(WIDGET(playlistwin_srew), x, y) || + widget_contains(WIDGET(playlistwin_splay), x, y) || + widget_contains(WIDGET(playlistwin_spause), x, y) || + widget_contains(WIDGET(playlistwin_sstop), x, y) || + widget_contains(WIDGET(playlistwin_sfwd), x, y) || + widget_contains(WIDGET(playlistwin_seject), x, y) || + widget_contains(WIDGET(playlistwin_sscroll_up), x, y) || + widget_contains(WIDGET(playlistwin_sscroll_down), x, y)); +} + +#define REGION_L(x1,x2,y1,y2) \ + (event->x >= (x1) && event->x < (x2) && \ + event->y >= cfg.playlist_height - (y1) && \ + event->y < cfg.playlist_height - (y2)) + +#define REGION_R(x1,x2,y1,y2) \ + (event->x >= playlistwin_get_width() - (x1) && \ + event->x < playlistwin_get_width() - (x2) && \ + event->y >= cfg.playlist_height - (y1) && \ + event->y < cfg.playlist_height - (y2)) + +static void +playlistwin_scrolled(GtkWidget * widget, + GdkEventScroll * event, + gpointer callback_data) +{ + + if (event->direction == GDK_SCROLL_DOWN) + playlistwin_scroll(cfg.scroll_pl_by); + + if (event->direction == GDK_SCROLL_UP) + playlistwin_scroll(-cfg.scroll_pl_by); + +} + + + + +static gboolean +playlistwin_press(GtkWidget * widget, + GdkEventButton * event, + gpointer callback_data) +{ + gboolean grab = TRUE; + gint xpos, ypos; + GtkWidget *_menu; + GtkRequisition req; + + gtk_window_get_position(GTK_WINDOW(playlistwin), &xpos, &ypos); + + if (event->button == 1 && !cfg.show_wm_decorations && + ((!cfg.playlist_shaded && + event->x > playlistwin_get_width() - 20 && + event->y > cfg.playlist_height - 20) || + (cfg.playlist_shaded && + event->x >= playlistwin_get_width() - 31 && + event->x < playlistwin_get_width() - 22))) { + + /* NOTE: Workaround for bug #214 */ + if (event->type != GDK_2BUTTON_PRESS && + event->type != GDK_3BUTTON_PRESS) { + /* resize area */ + playlistwin_resizing = TRUE; + gtk_window_begin_resize_drag(GTK_WINDOW(widget), + GDK_WINDOW_EDGE_SOUTH_EAST, + event->button, + event->x + xpos, event->y + ypos, + event->time); + } + grab = FALSE; + } + else if (event->button == 1 && REGION_L(12, 37, 29, 11)) { + /* ADD button menu */ + + _menu = GTK_WIDGET(pladd_menu->widget); + if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); + gtk_widget_size_request(_menu, &req); + gtk_item_factory_popup_with_data(pladd_menu, + NULL, NULL, + xpos+12, + (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); + grab = FALSE; + } + else if (event->button == 1 && REGION_L(41, 66, 29, 11)) { + /* SUB button menu */ + _menu = GTK_WIDGET(pldel_menu->widget); + if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); + gtk_widget_size_request(_menu, &req); + gtk_item_factory_popup_with_data(pldel_menu, + NULL, NULL, + xpos+40, + (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); + grab = FALSE; + } + else if (event->button == 1 && REGION_L(70, 95, 29, 11)) { + /* SEL button menu */ + _menu = GTK_WIDGET(plsel_menu->widget); + if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); + gtk_widget_size_request(_menu, &req); + gtk_item_factory_popup_with_data(plsel_menu, + NULL, NULL, + xpos+68, + (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); + + grab = FALSE; + } + else if (event->button == 1 && REGION_L(99, 124, 29, 11)) { + /* MISC button menu */ + _menu = GTK_WIDGET(plsort_menu->widget); + if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); + gtk_widget_size_request(_menu, &req); + gtk_item_factory_popup_with_data(plsort_menu, + NULL, NULL, + xpos+100, + (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); + grab = FALSE; + } + else if (event->button == 1 && REGION_R(46, 23, 29, 11)) { + /* LIST button menu */ + _menu = GTK_WIDGET(pllist_menu->widget); + if (!GTK_WIDGET_REALIZED(_menu)) gtk_widget_realize(_menu); + gtk_widget_size_request(_menu, &req); + gtk_item_factory_popup_with_data(pllist_menu, + NULL, NULL, + xpos + playlistwin_get_width() - req.width - 12, + (ypos + playlistwin_get_height()) - 8 - req.height, 1, event->time); + grab = FALSE; + } + else if (event->button == 1 && REGION_R(82, 54, 15, 9)) { + if (cfg.timer_mode == TIMER_ELAPSED) + cfg.timer_mode = TIMER_REMAINING; + else + cfg.timer_mode = TIMER_ELAPSED; + } + else if (event->button == 2 && (event->type == GDK_BUTTON_PRESS) && + widget_contains(WIDGET(playlistwin_list), event->x, event->y)) { + gtk_selection_convert(widget, GDK_SELECTION_PRIMARY, + GDK_TARGET_STRING, event->time); + } + else if (playlistwin_get_width() >= 350 && REGION_R(223, 151, 26, 10)) { + if (event->button == 1) { + cfg.vis_type++; + if (cfg.vis_type > VIS_OFF) + cfg.vis_type = VIS_ANALYZER; + mainwin_vis_set_type(cfg.vis_type); + } + else if (event->button == 3) { + gint mx, my; + GdkModifierType modmask; + + gdk_window_get_pointer(NULL, &mx, &my, &modmask); + util_item_factory_popup(mainwin_vis_menu, mx, my, 3, event->time); + grab = FALSE; + } + } + else if (event->button == 1 && event->type == GDK_BUTTON_PRESS && + !inside_sensitive_widgets(event->x, event->y) && event->y < 14) { + gdk_window_raise(playlistwin->window); + dock_move_press(dock_window_list, GTK_WINDOW(playlistwin), event, + FALSE); + } + else if (event->button == 1 && event->type == GDK_2BUTTON_PRESS && + !inside_sensitive_widgets(event->x, event->y) + && event->y < 14) { + /* double click on title bar */ + playlistwin_shade_toggle(); + if (dock_is_moving(GTK_WINDOW(playlistwin))) + dock_move_release(GTK_WINDOW(playlistwin)); + return TRUE; + } + else if (event->button == 3 && + !(widget_contains(WIDGET(playlistwin_list), event->x, event->y) || + (event->y >= cfg.playlist_height - 29 && + event->y < cfg.playlist_height - 11 && + ((event->x >= 12 && event->x < 37) || + (event->x >= 41 && event->x < 66) || + (event->x >= 70 && event->x < 95) || + (event->x >= 99 && event->x < 124) || + (event->x >= playlistwin_get_width() - 46 && + event->x < playlistwin_get_width() - 23))))) { + /* + * Pop up the main menu a few pixels down to avoid + * anything to be selected initially. + */ + util_item_factory_popup(mainwin_general_menu, event->x_root, + event->y_root + 2, 3, event->time); + grab = FALSE; + } + else if (event->button == 3 && + widget_contains(WIDGET(playlistwin_list), event->x, event->y)) { + /* popup menu */ + playlistwin_set_sensitive_sortmenu(); + gtk_item_factory_popup(playlistwin_popup_menu, + event->x_root, event->y_root + 5, + 3, event->time); + grab = FALSE; + } + else { + handle_press_cb(playlistwin_wlist, widget, event); + draw_playlist_window(FALSE); + } + + if (grab) + gdk_pointer_grab(playlistwin->window, FALSE, + GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON1_MOTION_MASK, NULL, NULL, + GDK_CURRENT_TIME); + + return FALSE; +} + +static gboolean +playlistwin_focus_in(GtkWidget * widget, GdkEvent * event, gpointer data) +{ + playlistwin_close->pb_allow_draw = TRUE; + playlistwin_shade->pb_allow_draw = TRUE; + draw_playlist_window(TRUE); + return FALSE; +} + +static gboolean +playlistwin_focus_out(GtkWidget * widget, + GdkEventButton * event, gpointer data) +{ + playlistwin_close->pb_allow_draw = FALSE; + playlistwin_shade->pb_allow_draw = FALSE; + draw_playlist_window(TRUE); + return FALSE; +} + +static gboolean +playlistwin_configure(GtkWidget * window, + GdkEventConfigure * event, gpointer data) +{ + if (!GTK_WIDGET_VISIBLE(window)) + return FALSE; + + cfg.playlist_x = event->x; + cfg.playlist_y = event->y; + + if (playlistwin_resizing) { + if (event->width != playlistwin_get_width() || + event->height != playlistwin_get_height()) + playlistwin_resize(event->width, event->height); + } + return TRUE; +} + +void +playlistwin_set_back_pixmap(void) +{ + gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); + gdk_window_clear(playlistwin->window); +} + +static gboolean +playlistwin_delete(GtkWidget * w, gpointer data) +{ + playlistwin_hide(); + return TRUE; +} + +static void +playlistwin_keypress_up_down_handler(PlayList_List * pl, + gboolean up, guint state) +{ + if ((state & GDK_MOD1_MASK) && (state & GDK_SHIFT_MASK)) + return; + if (!(state & GDK_MOD1_MASK)) + playlist_select_all(FALSE); + + if (pl->pl_prev_selected == -1 || + (!playlistwin_item_visible(pl->pl_prev_selected) && + !(state & GDK_SHIFT_MASK && pl->pl_prev_min != -1))) { + pl->pl_prev_selected = pl->pl_first; + } + else if (state & GDK_SHIFT_MASK) { + if (pl->pl_prev_min == -1) { + pl->pl_prev_max = pl->pl_prev_selected; + pl->pl_prev_min = pl->pl_prev_selected; + } + pl->pl_prev_max += (up ? -1 : 1); + pl->pl_prev_max = + CLAMP(pl->pl_prev_max, 0, playlist_get_length() - 1); + + pl->pl_first = MIN(pl->pl_first, pl->pl_prev_max); + pl->pl_first = MAX(pl->pl_first, pl->pl_prev_max - + pl->pl_num_visible + 1); + playlist_select_range(pl->pl_prev_min, pl->pl_prev_max, TRUE); + return; + } + else if (state & GDK_MOD1_MASK) { + if (up) + playlist_list_move_up(pl); + else + playlist_list_move_down(pl); + if (pl->pl_prev_min < pl->pl_first) + pl->pl_first = pl->pl_prev_min; + else if (pl->pl_prev_max >= (pl->pl_first + pl->pl_num_visible)) + pl->pl_first = pl->pl_prev_max - pl->pl_num_visible + 1; + return; + } + else if (up) + pl->pl_prev_selected--; + else + pl->pl_prev_selected++; + + pl->pl_prev_selected = + CLAMP(pl->pl_prev_selected, 0, playlist_get_length() - 1); + + if (pl->pl_prev_selected < pl->pl_first) + pl->pl_first--; + else if (pl->pl_prev_selected >= (pl->pl_first + pl->pl_num_visible)) + pl->pl_first++; + + playlist_select_range(pl->pl_prev_selected, pl->pl_prev_selected, TRUE); + pl->pl_prev_min = -1; + +} + +/* FIXME: Handle the keys through menu */ + +static gboolean +playlistwin_keypress(GtkWidget * w, GdkEventKey * event, gpointer data) +{ + guint keyval; + gboolean refresh = FALSE; + + if (cfg.playlist_shaded) + return FALSE; + + switch (keyval = event->keyval) { + case GDK_KP_Up: + case GDK_KP_Down: + case GDK_Up: + case GDK_Down: + playlistwin_keypress_up_down_handler(playlistwin_list, + keyval == GDK_Up + || keyval == GDK_KP_Up, + event->state); + refresh = TRUE; + break; + case GDK_Page_Up: + playlistwin_scroll(-playlistwin_list->pl_num_visible); + refresh = TRUE; + break; + case GDK_Page_Down: + playlistwin_scroll(playlistwin_list->pl_num_visible); + refresh = TRUE; + break; + case GDK_Home: + playlistwin_list->pl_first = 0; + refresh = TRUE; + break; + case GDK_End: + playlistwin_list->pl_first = + playlist_get_length() - playlistwin_list->pl_num_visible; + refresh = TRUE; + break; + case GDK_Return: + if (playlistwin_list->pl_prev_selected > -1 + && playlistwin_item_visible(playlistwin_list->pl_prev_selected)) { + playlist_set_position(playlistwin_list->pl_prev_selected); + if (!bmp_playback_get_playing()) + bmp_playback_initiate(); + } + break; + case GDK_3: + if (event->state & GDK_CONTROL_MASK) + playlistwin_fileinfo(); + break; + case GDK_Delete: + if (event->state & GDK_CONTROL_MASK) + playlist_delete(TRUE); + else + playlist_delete(FALSE); + break; + case GDK_Insert: + if (event->state & GDK_MOD1_MASK) + mainwin_show_add_url_window(); + else + playlistwin_show_filebrowser(); + break; + case GDK_Left: + case GDK_KP_Left: + case GDK_KP_7: + if (playlist_get_current_length() != -1) + bmp_playback_seek(CLAMP + (bmp_playback_get_time() - 5000, 0, + playlist_get_current_length()) / 1000); + break; + case GDK_Right: + case GDK_KP_Right: + case GDK_KP_9: + if (playlist_get_current_length() != -1) + bmp_playback_seek(CLAMP + (bmp_playback_get_time() + 5000, 0, + playlist_get_current_length()) / 1000); + break; + + case GDK_Escape: + mainwin_minimize_cb(); + break; + default: + return FALSE; + } + + if (refresh) + playlistwin_update_list(); + + return TRUE; +} + +static void +playlistwin_draw_frame(void) +{ + gboolean focus = + gtk_window_has_toplevel_focus(GTK_WINDOW(playlistwin)) || + !cfg.dim_titlebar; + + if (cfg.playlist_shaded) { + skin_draw_playlistwin_shaded(bmp_active_skin, + playlistwin_bg, playlistwin_gc, + playlistwin_get_width(), focus); + } + else { + skin_draw_playlistwin_frame(bmp_active_skin, + playlistwin_bg, playlistwin_gc, + playlistwin_get_width(), + cfg.playlist_height, focus); + } +} + +void +draw_playlist_window(gboolean force) +{ + gboolean redraw; + GList *wl; + Widget *w; + + if (force) + playlistwin_draw_frame(); + + widget_list_lock(playlistwin_wlist); + widget_list_draw(playlistwin_wlist, &redraw, force); + + if (redraw || force) { + if (force) { + gdk_window_clear(playlistwin->window); + } + else { + for (wl = playlistwin_wlist; wl; wl = g_list_next(wl)) { + w = WIDGET(wl->data); + if (w->redraw && w->visible) { + gdk_window_clear_area(playlistwin->window, w->x, w->y, + w->width, w->height); + w->redraw = FALSE; + } + } + } + + gdk_flush(); + } + + widget_list_unlock(playlistwin_wlist); +} + + +void +playlistwin_hide_timer(void) +{ + textbox_set_text(playlistwin_time_min, " "); + textbox_set_text(playlistwin_time_sec, " "); +} + +void +playlistwin_vis_enable(void) +{ + playlistwin_vis_enabled = TRUE; + + if (playlistwin_get_width() >= 350) + widget_show(WIDGET(playlistwin_vis)); +} + +void +playlistwin_vis_disable(void) +{ + playlistwin_vis_enabled = FALSE; + widget_hide(WIDGET(playlistwin_vis)); + draw_playlist_window(TRUE); +} + +void +playlistwin_set_time(gint time, gint length, TimerMode mode) +{ + gchar *text, sign; + + if (mode == TIMER_REMAINING && length != -1) { + time = length - time; + sign = '-'; + } + else + sign = ' '; + + time /= 1000; + + if (time < 0) + time = 0; + if (time > 99 * 60) + time /= 60; + + text = g_strdup_printf("%c%-2.2d", sign, time / 60); + textbox_set_text(playlistwin_time_min, text); + g_free(text); + + text = g_strdup_printf("%-2.2d", time % 60); + textbox_set_text(playlistwin_time_sec, text); + g_free(text); +} + +static void +playlistwin_drag_motion(GtkWidget * widget, + GdkDragContext * context, + gint x, gint y, + GtkSelectionData * selection_data, + guint info, guint time, gpointer user_data) +{ + playlistwin_list->pl_drag_motion = TRUE; + playlistwin_list->drag_motion_x = x; + playlistwin_list->drag_motion_y = y; + playlistwin_update_list(); + playlistwin_hint_flag = TRUE; +} + +static void +playlistwin_drag_end(GtkWidget * widget, + GdkDragContext * context, gpointer user_data) +{ + playlistwin_list->pl_drag_motion = FALSE; + playlistwin_hint_flag = FALSE; + playlistwin_update_list(); +} + +static void +playlistwin_drag_data_received(GtkWidget * widget, + GdkDragContext * context, + gint x, gint y, + GtkSelectionData * + selection_data, guint info, + guint time, gpointer user_data) +{ + guint pos; + + g_return_if_fail(selection_data != NULL); + + if (!selection_data->data) { + g_message("Received no DND data!"); + return; + } + + if (widget_contains(WIDGET(playlistwin_list), x, y)) { + pos = (y - WIDGET(playlistwin_list)->y) / + playlistwin_list->pl_fheight + playlistwin_list->pl_first; + + pos = MIN(pos, playlist_get_length()); + playlist_ins_url((gchar *) selection_data->data, pos); + } + else + playlist_add_url((gchar *) selection_data->data); +} + +static void +playlistwin_create_widgets(void) +{ + /* This function creates the custom widgets used by the playlist editor */ + + /* text box for displaying song title in shaded mode */ + playlistwin_sinfo = + create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + 4, 4, playlistwin_get_width() - 35, FALSE, SKIN_TEXT); + + if (!cfg.playlist_shaded) + widget_hide(WIDGET(playlistwin_sinfo)); + + /* shade/unshade window push button */ + if (cfg.playlist_shaded) + playlistwin_shade = + create_pbutton(&playlistwin_wlist, playlistwin_bg, + playlistwin_gc, playlistwin_get_width() - 21, 3, + 9, 9, 128, 45, 150, 42, + playlistwin_shade_toggle, SKIN_PLEDIT); + else + playlistwin_shade = + create_pbutton(&playlistwin_wlist, playlistwin_bg, + playlistwin_gc, playlistwin_get_width() - 21, 3, + 9, 9, 157, 3, 62, 42, playlistwin_shade_toggle, + SKIN_PLEDIT); + + playlistwin_shade->pb_allow_draw = FALSE; + + /* close window push button */ + playlistwin_close = + create_pbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 11, 3, 9, 9, + cfg.playlist_shaded ? 138 : 167, + cfg.playlist_shaded ? 45 : 3, 52, 42, + playlistwin_hide, SKIN_PLEDIT); + playlistwin_close->pb_allow_draw = FALSE; + + /* playlist list box */ + playlistwin_list = + create_playlist_list(&playlistwin_wlist, playlistwin_bg, + playlistwin_gc, 12, 20, + playlistwin_get_width() - 31, + cfg.playlist_height - 58); + playlist_list_set_font(cfg.playlist_font); + + /* playlist list box slider */ + playlistwin_slider = + create_playlistslider(&playlistwin_wlist, playlistwin_bg, + playlistwin_gc, playlistwin_get_width() - 15, + 20, cfg.playlist_height - 58, playlistwin_list); + /* track time (minute) */ + playlistwin_time_min = + create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 82, + cfg.playlist_height - 15, 15, FALSE, SKIN_TEXT); + + /* track time (second) */ + playlistwin_time_sec = + create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 64, + cfg.playlist_height - 15, 10, FALSE, SKIN_TEXT); + + /* playlist information (current track length / total track length) */ + playlistwin_info = + create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 143, + cfg.playlist_height - 28, 85, FALSE, SKIN_TEXT); + + /* mini visualizer */ + playlistwin_vis = + create_vis(&playlistwin_wlist, playlistwin_bg, playlistwin->window, + playlistwin_gc, playlistwin_get_width() - 223, + cfg.playlist_height - 26, 72); + widget_hide(WIDGET(playlistwin_vis)); + + /* mini play control buttons at right bottom corner */ + + /* rewind button */ + playlistwin_srew = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 144, + cfg.playlist_height - 16, 8, 7, playlist_prev); + + /* play button */ + playlistwin_splay = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 138, + cfg.playlist_height - 16, 10, 7, mainwin_play_pushed); + + /* pause button */ + playlistwin_spause = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 128, + cfg.playlist_height - 16, 10, 7, bmp_playback_pause); + + /* stop button */ + playlistwin_sstop = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 118, + cfg.playlist_height - 16, 9, 7, mainwin_stop_pushed); + + /* forward button */ + playlistwin_sfwd = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 109, + cfg.playlist_height - 16, 8, 7, playlist_next); + + /* eject button */ + playlistwin_seject = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 100, + cfg.playlist_height - 16, 9, 7, mainwin_eject_pushed); + + + playlistwin_sscroll_up = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 14, + cfg.playlist_height - 35, 8, 5, + playlistwin_scroll_up_pushed); + playlistwin_sscroll_down = + create_sbutton(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, + playlistwin_get_width() - 14, + cfg.playlist_height - 30, 8, 5, + playlistwin_scroll_down_pushed); + +} + +static void +selection_received(GtkWidget * widget, + GtkSelectionData * selection_data, gpointer data) +{ + if (selection_data->type == GDK_SELECTION_TYPE_STRING && + selection_data->length > 0) + playlist_add_url((gchar *) selection_data->data); +} + +static void +playlistwin_create_window(void) +{ + GdkPixbuf *icon; + + playlistwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(playlistwin), _("Audacious Playlist Editor")); + gtk_window_set_role(GTK_WINDOW(playlistwin), "playlist"); + gtk_window_set_default_size(GTK_WINDOW(playlistwin), + playlistwin_get_width(), + playlistwin_get_height()); + gtk_window_set_resizable(GTK_WINDOW(playlistwin), TRUE); + playlistwin_set_geometry_hints(cfg.playlist_shaded); + dock_window_list = dock_window_set_decorated(dock_window_list, + GTK_WINDOW(playlistwin), + cfg.show_wm_decorations); + + gtk_window_set_transient_for(GTK_WINDOW(playlistwin), + GTK_WINDOW(mainwin)); + gtk_window_set_skip_taskbar_hint(GTK_WINDOW(playlistwin), TRUE); + + icon = gdk_pixbuf_new_from_xpm_data((const gchar **) bmp_playlist_icon); + gtk_window_set_icon(GTK_WINDOW(playlistwin), icon); + g_object_unref(icon); + + gtk_widget_set_app_paintable(playlistwin, TRUE); + + if (cfg.playlist_x != -1 && cfg.save_window_position) + gtk_window_move(GTK_WINDOW(playlistwin), + cfg.playlist_x, cfg.playlist_y); + + gtk_widget_add_events(playlistwin, + GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_SCROLL_MASK | GDK_VISIBILITY_NOTIFY_MASK); + gtk_widget_realize(playlistwin); + + util_set_cursor(playlistwin); + + g_signal_connect(playlistwin, "delete_event", + G_CALLBACK(playlistwin_delete), NULL); + g_signal_connect(playlistwin, "button_press_event", + G_CALLBACK(playlistwin_press), NULL); + g_signal_connect(playlistwin, "button_release_event", + G_CALLBACK(playlistwin_release), NULL); + g_signal_connect(playlistwin, "scroll_event", + G_CALLBACK(playlistwin_scrolled), NULL); + g_signal_connect(playlistwin, "motion_notify_event", + G_CALLBACK(playlistwin_motion), NULL); + g_signal_connect_after(playlistwin, "focus_in_event", + G_CALLBACK(playlistwin_focus_in), NULL); + g_signal_connect_after(playlistwin, "focus_out_event", + G_CALLBACK(playlistwin_focus_out), NULL); + g_signal_connect(playlistwin, "configure_event", + G_CALLBACK(playlistwin_configure), NULL); + g_signal_connect(playlistwin, "style_set", + G_CALLBACK(playlistwin_set_back_pixmap), NULL); + + bmp_drag_dest_set(playlistwin); + + /* DnD stuff */ + g_signal_connect(playlistwin, "drag-leave", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-data-delete", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-end", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-drop", + G_CALLBACK(playlistwin_drag_end), NULL); + g_signal_connect(playlistwin, "drag-data-received", + G_CALLBACK(playlistwin_drag_data_received), NULL); + g_signal_connect(playlistwin, "drag-motion", + G_CALLBACK(playlistwin_drag_motion), NULL); + + g_signal_connect(playlistwin, "key_press_event", + G_CALLBACK(playlistwin_keypress), NULL); + g_signal_connect(playlistwin, "selection_received", + G_CALLBACK(selection_received), NULL); + + playlistwin_set_mask(); +} + +void +playlistwin_create_popup_menus(void) +{ + playlistwin_accel = gtk_accel_group_new(); + + /* playlist window popup menu */ + playlistwin_popup_menu = create_menu(playlistwin_popup_menu_entries, + G_N_ELEMENTS(playlistwin_popup_menu_entries), + playlistwin_accel); + + pladd_menu = create_menu(pladd_menu_entries, G_N_ELEMENTS(pladd_menu_entries), + playlistwin_accel); + pldel_menu = create_menu(pldel_menu_entries, G_N_ELEMENTS(pldel_menu_entries), + playlistwin_accel); + plsel_menu = create_menu(plsel_menu_entries, G_N_ELEMENTS(plsel_menu_entries), + playlistwin_accel); + plsort_menu = create_menu(plsort_menu_entries, + G_N_ELEMENTS(plsort_menu_entries), + playlistwin_accel); + pllist_menu = create_menu(pllist_menu_entries, G_N_ELEMENTS(pllist_menu_entries), + playlistwin_accel); + +#if 0 + make_submenu(playlistwin_popup_menu, "/Playlist", + playlistwin_playlist_menu); + make_submenu(playlistwin_popup_menu, "/Playback", + playlistwin_playback_menu); + make_submenu(playlistwin_popup_menu, "/Add", + pladd_menu); +#endif +} + +void +playlistwin_create(void) +{ + playlistwin_create_window(); + playlistwin_create_popup_menus(); + + /* create GC and back pixmap for custom widget to draw on */ + playlistwin_gc = gdk_gc_new(playlistwin->window); + playlistwin_bg = gdk_pixmap_new(playlistwin->window, + playlistwin_get_width(), + playlistwin_get_height_unshaded(), -1); + gdk_window_set_back_pixmap(playlistwin->window, playlistwin_bg, 0); + + playlistwin_create_widgets(); + playlistwin_update_info(); + + gtk_window_add_accel_group(GTK_WINDOW(playlistwin), playlistwin_accel); + gtk_window_add_accel_group(GTK_WINDOW(playlistwin), mainwin_accel); +} + + +void +playlistwin_show(void) +{ + GtkWidget *item; + + item = gtk_item_factory_get_widget(mainwin_view_menu, + "/Show Playlist Editor"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE); + + tbutton_set_toggled(mainwin_pl, TRUE); + cfg.playlist_visible = TRUE; + + playlistwin_set_toprow(0); + playlist_check_pos_current(); + + gtk_widget_show(playlistwin); +} + +void +playlistwin_hide(void) +{ + GtkWidget *item; + + item = gtk_item_factory_get_widget(mainwin_view_menu, + "/Show Playlist Editor"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), FALSE); + + gtk_widget_hide(playlistwin); + tbutton_set_toggled(mainwin_pl, FALSE); + cfg.playlist_visible = FALSE; + + gtk_window_present(GTK_WINDOW(mainwin)); + gtk_widget_grab_focus(mainwin); +} + + +static void +plsort_menu_callback(gpointer data, + guint action, + GtkWidget * widget) +{ + switch (action) { + case PLAYLISTWIN_SORT_BYTITLE: + playlist_sort(PLAYLIST_SORT_TITLE); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_BYPATH: + playlist_sort(PLAYLIST_SORT_PATH); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_BYDATE: + playlist_sort(PLAYLIST_SORT_DATE); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_BYFILENAME: + playlist_sort(PLAYLIST_SORT_FILENAME); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_SEL_BYTITLE: + playlist_sort_selected(PLAYLIST_SORT_TITLE); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_SEL_BYFILENAME: + playlist_sort_selected(PLAYLIST_SORT_FILENAME); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_SEL_BYPATH: + playlist_sort_selected(PLAYLIST_SORT_PATH); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_SEL_BYDATE: + playlist_sort_selected(PLAYLIST_SORT_DATE); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_REVERSE: + playlist_reverse(); + playlistwin_update_list(); + break; + case PLAYLISTWIN_SORT_RANDOMIZE: + playlist_random(); + playlistwin_update_list(); + break; + } +} + +static void +playlistwin_sub_menu_callback(gpointer data, + guint action, + GtkWidget * widget) +{ + switch (action) { + case PLIST_NEW: + playlist_set_current_name(NULL); + playlist_clear(); + mainwin_clear_song_info(); + mainwin_set_info_text(); + break; + case PLIST_SAVE: + playlistwin_select_playlist_to_save(playlist_get_current_name()); + break; + case PLIST_SAVE_AS: + playlistwin_select_playlist_to_save(playlist_get_current_name()); + break; + case PLIST_LOAD: + playlistwin_select_playlist_to_load(playlist_get_current_name()); + break; + case SEL_INV: + playlistwin_inverse_selection(); + break; + case SEL_ZERO: + playlistwin_select_none(); + break; + case SEL_ALL: + playlistwin_select_all(); + break; + case SUB_ALL: + playlist_clear(); + mainwin_clear_song_info(); + mainwin_set_info_text(); + break; + case SUB_CROP: + playlist_delete(TRUE); + break; + case SUB_SELECTED: + playlist_delete(FALSE); + break; + case PLAYLISTWIN_REMOVE_DEAD_FILES: + playlist_remove_dead_files(); + break; + case PLAYLISTWIN_REFRESH: + playlist_read_info_selection(); + playlistwin_update_list(); + break; + } +} + +static void +playlistwin_popup_menu_callback(gpointer data, + guint action, + GtkWidget * widget) +{ + switch (action) { + case ADD_FILES: + playlistwin_show_filebrowser(); + break; + case CLOSE_PL_WINDOW: + playlistwin_hide(); + break; + case MISC_FILEINFO: + playlistwin_fileinfo(); + break; + case SEL_LOOKUP: + playlist_read_info_selection(); + break; + case MISC_QUEUE: + playlist_queue(); + break; + case PLIST_CQUEUE: + playlist_clear_queue(); + break; + case PLIST_JTT: + mainwin_jump_to_time(); + break; + case PLIST_JTF: + mainwin_jump_to_file(); + break; + } +} diff -r a9c7793de60c -r 5c457dac866a audacious/ui_playlist.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audacious/ui_playlist.h Tue Jan 03 12:54:18 2006 -0800 @@ -0,0 +1,82 @@ +/* BMP - Cross-platform multimedia player + * Copyright (C) 2003-2004 BMP development team. + * + * Based on XMMS: + * Copyright (C) 1998-2003 XMMS development team. + * + * 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. + */ + +#ifndef PLAYLISTWIN_H +#define PLAYLISTWIN_H + +#include + +#include "mainwin.h" +#include "pbutton.h" +#include "playlist_list.h" + + +#define PLAYLISTWIN_FRAME_TOP_HEIGHT 20 +#define PLAYLISTWIN_FRAME_BOTTOM_HEIGHT 38 +#define PLAYLISTWIN_FRAME_LEFT_WIDTH 12 +#define PLAYLISTWIN_FRAME_RIGHT_WIDTH 19 + +#define PLAYLISTWIN_MIN_WIDTH MAINWIN_WIDTH +#define PLAYLISTWIN_MIN_HEIGHT MAINWIN_HEIGHT +#define PLAYLISTWIN_WIDTH_SNAP 25 +#define PLAYLISTWIN_HEIGHT_SNAP 29 +#define PLAYLISTWIN_SHADED_HEIGHT MAINWIN_SHADED_HEIGHT +#define PLAYLISTWIN_WIDTH cfg.playlist_width +#define PLAYLISTWIN_HEIGHT \ + (cfg.playlist_shaded ? PLAYLISTWIN_SHADED_HEIGHT : cfg.playlist_height) + +#define PLAYLISTWIN_DEFAULT_WIDTH 275 +#define PLAYLISTWIN_DEFAULT_HEIGHT 232 +#define PLAYLISTWIN_DEFAULT_POS_X 295 +#define PLAYLISTWIN_DEFAULT_POS_Y 20 + +#define PLAYLISTWIN_DEFAULT_FONT "Sans Bold 8" + +void playlistwin_update_list(void); +gboolean playlistwin_item_visible(gint index); +gint playlistwin_get_toprow(void); +void playlistwin_set_toprow(gint top); +void playlistwin_set_shade_menu_cb(gboolean shaded); +void playlistwin_set_shade(gboolean shaded); +void playlistwin_shade_toggle(void); +void playlistwin_create(void); +void draw_playlist_window(gboolean force); +void playlistwin_hide_timer(void); +void playlistwin_set_time(gint time, gint length, TimerMode mode); +void playlistwin_show(void); +void playlistwin_hide(void); +void playlistwin_set_back_pixmap(void); +void playlistwin_scroll(gint num); +void playlistwin_scroll_up_pushed(void); +void playlistwin_scroll_down_pushed(void); +void playlistwin_vis_disable(void); +void playlistwin_vis_enable(void); +void playlistwin_select_playlist_to_load(const gchar * default_filename); + +extern GtkWidget *playlistwin; +extern Vis *playlistwin_vis; +extern PlayList_List *playlistwin_list; + +extern PButton *playlistwin_shade, *playlistwin_close; + +extern gboolean playlistwin_focus; + +#endif diff -r a9c7793de60c -r 5c457dac866a audacious/util.c --- a/audacious/util.c Tue Jan 03 12:24:10 2006 -0800 +++ b/audacious/util.c Tue Jan 03 12:54:18 2006 -0800 @@ -54,7 +54,7 @@ #include "main.h" #include "libaudcore/playback.h" #include "playlist.h" -#include "playlistwin.h" +#include "ui_playlist.h" static GQuark quark_popup_data;