📄 playlistwin.c
字号:
/* XMMS - Cross-platform multimedia player * Copyright (C) 1998-2002 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies * Copyright (C) 1999-2004 Haavard Kvaalen * * 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 "xmms.h"#include "libxmms/dirbrowser.h"#include "libxmms/util.h"GtkWidget *playlistwin;static GtkWidget *playlistwin_url_window = NULL;static GtkItemFactory *playlistwin_sort_menu, *playlistwin_sub_menu;static GtkItemFactory *playlistwin_popup_menu, *playlistwin_save_menu;static GtkAccelGroup *playlistwin_accel;static GdkPixmap *playlistwin_bg;static GdkBitmap *playlistwin_mask;static GdkGC *playlistwin_gc;static int playlistwin_resizing, playlistwin_resize_x, playlistwin_resize_y;static int playlistwin_save_type;gboolean playlistwin_focus = FALSE;PlayList_List *playlistwin_list = NULL;PButton *playlistwin_shade, *playlistwin_close;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;Vis *playlistwin_vis;static GList *playlistwin_wlist = NULL;static gboolean playlistwin_vis_enabled = FALSE;static struct { int w, h;} playlistwin_resizeq = {-1, -1};struct overwrite_data { char *filename; int pls; GtkWidget *fsel;};extern TButton *mainwin_pl;enum{ ADD_URL, ADD_DIR, ADD_FILE, SUB_MISC, SUB_ALL, SUB_CROP, SUB_SELECTED, SEL_INV, SEL_ZERO, SEL_ALL, MISC_SORT, MISC_FILEINFO, MISC_MISCOPTS, MISC_QUEUE, PLIST_NEW, PLIST_SAVE, PLIST_LOAD, SEL_LOOKUP,};static void playlistwin_sort_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_save_type_cb(gpointer cb_data, guint action, GtkWidget * w);static void playlistwin_set_hints(void);static void playlistwin_set_shade(gboolean shaded);static void playlistwin_popup_menu_callback(gpointer cb_data, guint action, GtkWidget * w);static void playlistwin_draw_frame(void);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};GtkItemFactoryEntry playlistwin_sort_menu_entries[] ={ {N_("/Sort List"), NULL, NULL, 0, "<Branch>"}, {N_("/Sort List/By Title"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_BYTITLE, "<Item>"}, {N_("/Sort List/By Filename"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_BYFILENAME, "<Item>"}, {N_("/Sort List/By Path + Filename"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_BYPATH, "<Item>"}, {N_("/Sort List/By Date"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_BYDATE, "<Item>"}, {N_("/Sort Selection"), NULL, NULL, 0, "<Branch>"}, {N_("/Sort Selection/By Title"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_SEL_BYTITLE, "<Item>"}, {N_("/Sort Selection/By Filename"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_SEL_BYFILENAME, "<Item>"}, {N_("/Sort Selection/By Path + Filename"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_SEL_BYPATH, "<Item>"}, {N_("/Sort Selection/By Date"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_SEL_BYDATE, "<Item>"}, {"/-", NULL, NULL, 0, "<Separator>"}, {N_("/Randomize List"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_RANDOMIZE, "<Item>"}, {N_("/Reverse List"), NULL, playlistwin_sort_menu_callback, PLAYLISTWIN_SORT_REVERSE, "<Item>"},};static const int playlistwin_sort_menu_entries_num = sizeof(playlistwin_sort_menu_entries) / sizeof(playlistwin_sort_menu_entries[0]);enum { PLAYLISTWIN_SAVE_EXTENSION = 0, PLAYLISTWIN_SAVE_M3U, PLAYLISTWIN_SAVE_PLS};static GtkItemFactoryEntry playlistwin_playlist_filetypes[] = { {N_("/By extension"), NULL, playlistwin_save_type_cb, PLAYLISTWIN_SAVE_EXTENSION, NULL}, {"/-", NULL, NULL, 0, "<Separator>"}, {"/m3u", NULL, playlistwin_save_type_cb, PLAYLISTWIN_SAVE_M3U, NULL}, {"/pls", NULL, playlistwin_save_type_cb, PLAYLISTWIN_SAVE_PLS, NULL},};static const int playlistwin_playlist_filetypes_num = sizeof(playlistwin_playlist_filetypes) / sizeof(playlistwin_playlist_filetypes[0]);enum{ PLAYLISTWIN_REMOVE_DEAD_FILES, PLAYLISTWIN_PHYSICALLY_DELETE};GtkItemFactoryEntry playlistwin_sub_menu_entries[] ={ {N_("/Remove Dead Files"), NULL, playlistwin_sub_menu_callback, PLAYLISTWIN_REMOVE_DEAD_FILES, "<Item>"}, {N_("/Physically Delete Files"), NULL, playlistwin_sub_menu_callback, PLAYLISTWIN_PHYSICALLY_DELETE, "<Item>"},};static const int playlistwin_sub_menu_entries_num = sizeof(playlistwin_sub_menu_entries) / sizeof(playlistwin_sub_menu_entries[0]);GtkItemFactoryEntry playlistwin_popup_menu_entries[] ={ {N_("/View File Info"), "<control>3", playlistwin_popup_menu_callback, MISC_FILEINFO, "<Item>"}, {N_("/Queue - Unqueue"), "Q", playlistwin_popup_menu_callback, MISC_QUEUE, "<Item>"}, {N_("/-"), NULL, NULL, 0, "<Separator>"}, {N_("/Add"), NULL, NULL, 0, "<Branch>"}, {N_("/Add/File"), NULL, playlistwin_popup_menu_callback, ADD_FILE, "<Item>"}, {N_("/Add/Directory"), NULL, playlistwin_popup_menu_callback, ADD_DIR, "<Item>"}, {N_("/Add/Url"), NULL, playlistwin_popup_menu_callback, ADD_URL, "<Item>"}, {N_("/Remove"), NULL, NULL, 0, "<Branch>"}, {N_("/Remove/Selected"), NULL, playlistwin_popup_menu_callback, SUB_SELECTED, "<Item>"}, {N_("/Remove/Crop"), NULL, playlistwin_popup_menu_callback, SUB_CROP, "<Item>"}, {N_("/Remove/All"), NULL, playlistwin_popup_menu_callback, SUB_ALL, "<Item>"}, {N_("/Remove/Misc"), NULL, NULL, 0, "<Item>"}, {N_("/Selection"), NULL, NULL, 0, "<Branch>"}, {N_("/Selection/Select All"), NULL, playlistwin_popup_menu_callback, SEL_ALL, "<Item>"}, {N_("/Selection/Select None"), NULL, playlistwin_popup_menu_callback, SEL_ZERO, "<Item>"}, {N_("/Selection/Invert Selection"), NULL, playlistwin_popup_menu_callback, SEL_INV, "<Item>"}, {N_("/Selection/-"), NULL, NULL, 0, "<Separator>"}, {N_("/Selection/Read Extended Info"), NULL, playlistwin_popup_menu_callback, SEL_LOOKUP, "<Item>"}, {N_("/Sort"), NULL, NULL, 0, "<Item>"}, {N_("/Playlist"), NULL, NULL, 0, "<Branch>"}, {N_("/Playlist/Load List"), NULL, playlistwin_popup_menu_callback, PLIST_LOAD, "<Item>"}, {N_("/Playlist/Save List"), NULL, playlistwin_popup_menu_callback, PLIST_SAVE, "<Item>"}, {N_("/Playlist/New List"), NULL, playlistwin_popup_menu_callback, PLIST_NEW, "<Item>"},};static const int playlistwin_popup_menu_entries_num = sizeof(playlistwin_popup_menu_entries) / sizeof(playlistwin_popup_menu_entries[0]);static void playlistwin_update_info(void){ char *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){ char *posstr, *timestr, *title, *info, *dots; int pos, time, max_len; pos = get_playlist_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 = (cfg.playlist_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(""); if (cfg.convert_underscore) { char *tmp; while ((tmp = strchr(title, '_')) != NULL) *tmp = ' '; } if (cfg.convert_twenty) { char *tmp, *tmp2; while ((tmp = strstr(title, "%20")) != NULL) { tmp2 = tmp + 3; *(tmp++) = ' '; while (*tmp2) *(tmp++) = *(tmp2++); *tmp = '\0'; } } 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(int index){ if (index >= playlistwin_list->pl_first && index < (playlistwin_list->pl_first + playlistwin_list->pl_num_visible)) return TRUE; return FALSE;}int playlistwin_get_toprow(void){ if (playlistwin_list) return (playlistwin_list->pl_first); return (-1);}void playlistwin_set_toprow(int toprow){ if (playlistwin_list) playlistwin_list->pl_first = toprow; playlistwin_update_list();}void playlistwin_update_list(void){ g_return_if_fail(playlistwin_list != NULL); draw_widget(playlistwin_list); draw_widget(playlistwin_slider); playlistwin_update_info(); playlistwin_update_sinfo();}static void playlistwin_create_mask(void){ GdkBitmap *tmp; GdkGC *gc; GdkColor pattern; if (cfg.show_wm_decorations) return; tmp = playlistwin_mask; playlistwin_mask = gdk_pixmap_new(playlistwin->window, cfg.playlist_width, PLAYLIST_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, cfg.playlist_width, PLAYLIST_HEIGHT); gdk_gc_destroy(gc); gtk_widget_shape_combine_mask(playlistwin, playlistwin_mask, 0, 0); if (tmp) gdk_bitmap_unref(tmp);}void playlistwin_set_shade_menu_cb(gboolean shaded){ cfg.playlist_shaded = shaded; if (!cfg.show_wm_decorations) dock_shade(dock_window_list, playlistwin, PLAYLIST_HEIGHT); else gtk_window_set_default_size(GTK_WINDOW(playlistwin), cfg.playlist_width, PLAYLIST_HEIGHT); if (shaded) { 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 { 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; } playlistwin_create_mask(); playlistwin_set_hints(); draw_playlist_window(TRUE);}static void playlistwin_shade_toggle(void){ playlistwin_set_shade(!cfg.playlist_shaded);}static void playlistwin_set_shade(gboolean shaded){ GtkWidget *widget; widget = gtk_item_factory_get_widget(mainwin_options_menu, "/Playlist WindowShade Mode"); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), shaded);}void playlistwin_raise(void){ if (cfg.playlist_visible) gdk_window_raise(playlistwin->window);}static void playlistwin_release(GtkWidget * widget, GdkEventButton * event, gpointer callback_data){ if (event->button == 3) return; gdk_pointer_ungrab(GDK_CURRENT_TIME); gdk_flush(); if (playlistwin_resizing) playlistwin_resizing = FALSE; else if (dock_is_moving(playlistwin)) dock_move_release(playlistwin); else { handle_release_cb(playlistwin_wlist, widget, event); playlist_popup_destroy(); draw_playlist_window(FALSE); }}void playlistwin_scroll(int num){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -