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