1# Copyright (C) 2008-2010 Adam Olsen 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 2, or (at your option) 6# any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16# 17# 18# The developers of the Exaile media player hereby grant permission 19# for non-GPL compatible GStreamer and Exaile plugins to be used and 20# distributed together with GStreamer and Exaile. This permission is 21# above and beyond the permissions granted by the GPL license by which 22# Exaile is covered. If you modify this code, you may extend this 23# exception to your version of the code, but you are not obligated to 24# do so. If you do not wish to do so, delete this exception statement 25# from your version. 26 27from gi.repository import GObject 28from gi.repository import Gtk 29 30from xl import trax 31from xl.nls import gettext as _ 32from xlgui import panel 33from xlgui.panel import menus 34from xlgui.widgets.common import DragTreeView 35 36 37class FlatPlaylistPanel(panel.Panel): 38 """ 39 Flat playlist panel; represents a single playlist 40 """ 41 42 __gsignals__ = { 43 'append-items': (GObject.SignalFlags.RUN_LAST, None, (object, bool)), 44 'replace-items': (GObject.SignalFlags.RUN_LAST, None, (object,)), 45 'queue-items': (GObject.SignalFlags.RUN_LAST, None, (object,)), 46 } 47 48 ui_info = ('flatplaylist.ui', 'FlatPlaylistPanel') 49 50 def __init__(self, parent, name, label): 51 panel.Panel.__init__(self, parent, name, label) 52 53 self.box = self.builder.get_object('FlatPlaylistPanel') 54 self.model = Gtk.ListStore(int, str, object) 55 self.tracks = [] 56 self._setup_tree() 57 if not hasattr(self.parent, 'do_import'): 58 self.builder.get_object("import_button").hide() 59 self.menu = menus.TrackPanelMenu(self) 60 self._connect_events() 61 62 def _connect_events(self): 63 self.builder.connect_signals( 64 { 65 'on_add_button_clicked': self._on_add_button_clicked, 66 'on_import_button_clicked': self._on_import_button_clicked, 67 } 68 ) 69 70 def _on_add_button_clicked(self, *e): 71 self.emit('append-items', self.tracks, False) 72 73 def _on_import_button_clicked(self, *e): 74 tracks = self.tree.get_selected_tracks() 75 if len(tracks) == 0: # nothing selected, do everything 76 tracks = self.tracks 77 self.parent.do_import(tracks) 78 79 def _setup_tree(self): 80 self.tree = FlatPlaylistDragTreeView(self, False, True) 81 selection = self.tree.get_selection() 82 selection.set_mode(Gtk.SelectionMode.MULTIPLE) 83 84 self.tree.set_headers_visible(True) 85 self.tree.set_model(self.model) 86 self.scroll = Gtk.ScrolledWindow() 87 self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) 88 self.scroll.add(self.tree) 89 self.scroll.set_shadow_type(Gtk.ShadowType.IN) 90 self.box.pack_start(self.scroll, True, True, 0) 91 92 text = Gtk.CellRendererText() 93 col = Gtk.TreeViewColumn(_('#')) 94 col.pack_start(text, False) 95 col.set_attributes(text, text=0) 96 col.set_fixed_width(50) 97 col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) 98 self.tree.append_column(col) 99 100 text = Gtk.CellRendererText() 101 col = Gtk.TreeViewColumn(_('Title')) 102 col.pack_start(text, True) 103 col.set_attributes(text, text=1) 104 col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) 105 col.set_cell_data_func(text, self._title_data_func) 106 self.tree.append_column(col) 107 self.box.show_all() 108 109 def _title_data_func(self, col, cell, model, iter, _unused): 110 if not model.iter_is_valid(iter): 111 return 112 item = model.get_value(iter, 2) 113 cell.set_property('text', item.get_tag_display("title")) 114 115 def set_playlist(self, playlist): 116 self.model.clear() 117 118 self.tracks = tracks = list(playlist) 119 for i, track in enumerate(tracks): 120 self.model.append([i + 1, track.get_tag_display("title"), track]) 121 122 def drag_data_received(self, *e): 123 """ 124 stub 125 """ 126 pass 127 128 def drag_data_delete(self, *e): 129 """ 130 stub 131 """ 132 pass 133 134 def drag_get_data(self, treeview, context, selection, target_id, etime): 135 """ 136 Called when a drag source wants data for this drag operation 137 """ 138 tracks = self.tree.get_selected_tracks() 139 if not tracks: 140 return 141 for track in tracks: 142 DragTreeView.dragged_data[track.get_loc_for_io()] = track 143 uris = trax.util.get_uris_from_tracks(tracks) 144 selection.set_uris(uris) 145 146 147class FlatPlaylistDragTreeView(DragTreeView): 148 """ 149 Custom DragTreeView to retrieve data from playlists 150 """ 151 152 def get_selected_tracks_count(self): 153 """ 154 Returns the count of selected tracks 155 """ 156 return self.get_selection().count_selected_rows() 157 158 def get_selected_tracks(self): 159 """ 160 Returns the currently selected tracks 161 """ 162 (model, paths) = self.get_selection().get_selected_rows() 163 tracks = [] 164 165 for path in paths: 166 iter = model.get_iter(path) 167 track = model.get_value(iter, 2) 168 tracks.append(track) 169 170 return tracks 171