~ubuntu-branches/ubuntu/natty/miro/natty

« back to all changes in this revision

Viewing changes to portable/frontends/widgets/tablistmanager.py

  • Committer: Bazaar Package Importer
  • Author(s): Bryce Harrington
  • Date: 2011-01-22 02:46:33 UTC
  • mfrom: (1.4.10 upstream) (1.7.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110122024633-kjme8u93y2il5nmf
Tags: 3.5.1-1ubuntu1
* Merge from debian.  Remaining ubuntu changes:
  - Use python 2.7 instead of python 2.6
  - Relax dependency on python-dbus to >= 0.83.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Miro - an RSS based video player application
2
 
# Copyright (C) 2005-2010 Participatory Culture Foundation
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17
 
#
18
 
# In addition, as a special exception, the copyright holders give
19
 
# permission to link the code of portions of this program with the OpenSSL
20
 
# library.
21
 
#
22
 
# You must obey the GNU General Public License in all respects for all of
23
 
# the code used other than OpenSSL. If you modify file(s) with this
24
 
# exception, you may extend this exception to your version of the file(s),
25
 
# but you are not obligated to do so. If you do not wish to do so, delete
26
 
# this exception statement from your version. If you delete this exception
27
 
# statement from all source files in the program, then also delete it here.
28
 
 
29
 
"""Manages the tab lists from a high level perspective."""
30
 
 
31
 
from miro import app
32
 
from miro import config
33
 
from miro import prefs
34
 
 
35
 
from miro.frontends.widgets import tablist
36
 
from miro.plat.frontends.widgets import widgetset
37
 
 
38
 
class TabListManager(object):
39
 
    def __init__(self):
40
 
        self.static_tab_list = tablist.StaticTabList()
41
 
        self.library_tab_list = tablist.LibraryTabList()
42
 
        self.site_list = tablist.SiteList()
43
 
        self.feed_list = tablist.FeedList()
44
 
        self.audio_feed_list = tablist.AudioFeedList()
45
 
        self.playlist_list = tablist.PlaylistList()
46
 
        self.widget_to_tablist = {}
47
 
        for tab_list in self.all_tab_lists():
48
 
            self.widget_to_tablist[tab_list.view] = tab_list
49
 
        self.__table_view = None
50
 
 
51
 
    def populate_tab_list(self):
52
 
        self.static_tab_list.build_tabs()
53
 
        self.library_tab_list.build_tabs()
54
 
        self.select_startup_default()
55
 
        for tab_list in self.all_tab_lists():
56
 
            tab_list.view.connect('selection-changed',
57
 
                    self.on_selection_changed)
58
 
 
59
 
    def _select_from_tab_list(self, tab_list, iter):
60
 
        view = tab_list.view
61
 
        previous_selection = view.get_selection()
62
 
        for previously_selected in previous_selection:
63
 
            if (view.model[previously_selected][0] == view.model[iter][0]):
64
 
                return # The tab is already selected
65
 
        view.select(iter)
66
 
        for previously_selected in previous_selection:
67
 
            # We unselect *after* having made the new selection because if we
68
 
            # unselect first and the selection is empty, the on_selection_changed
69
 
            # callback forces the guide to be selected.
70
 
            view.unselect(previously_selected)
71
 
        self.selected_tab_list = tab_list
72
 
        self.selected_tabs = [view.model[iter][0]]
73
 
        self.handle_new_selection()
74
 
 
75
 
    def handle_startup_selection(self):
76
 
        self.handle_new_selection()
77
 
 
78
 
    def handle_new_selection(self):
79
 
        app.display_manager.select_display_for_tabs(self.selected_tab_list,
80
 
                self.selected_tabs)
81
 
 
82
 
    def which_tablist_has_id(self, feed_id):
83
 
        """
84
 
        Find out whether the video feed list or the audio feed list has this id
85
 
        """
86
 
        for tablist in self.feed_list, self.audio_feed_list:
87
 
            if tablist.has_info(feed_id):
88
 
                return tablist
89
 
        raise ValueError("Unknown feed id.  %s" % feed_id)
90
 
 
91
 
    def all_tab_lists(self):
92
 
        return (
93
 
            self.static_tab_list, self.library_tab_list, self.site_list,
94
 
            self.feed_list, self.audio_feed_list, self.playlist_list)
95
 
 
96
 
    def select_guide(self):
97
 
        self.select_static_tab(0)
98
 
 
99
 
    def select_search(self):
100
 
        self.select_static_tab(1)
101
 
 
102
 
 
103
 
    def select_startup_default(self):
104
 
        if config.get(prefs.OPEN_CHANNEL_ON_STARTUP) is not None:
105
 
            # try regular feeds first, followed by audio feeds
106
 
            for tab_list in self.feed_list, self.audio_feed_list:
107
 
                info = tab_list.find_feed_with_url(
108
 
                    config.get(prefs.OPEN_CHANNEL_ON_STARTUP))
109
 
                if info is not None:
110
 
                    self._select_from_tab_list(
111
 
                        tab_list,
112
 
                        tab_list.iter_map[info.id])
113
 
                    return
114
 
 
115
 
        if config.get(prefs.OPEN_FOLDER_ON_STARTUP) is not None:
116
 
            for tab_list in self.feed_list, self.audio_feed_list:
117
 
                for iter in tab_list.iter_map.values():
118
 
                    info = tab_list.view.model[iter][0]
119
 
                    if info.is_folder and info.name == config.get(
120
 
                        prefs.OPEN_FOLDER_ON_STARTUP):
121
 
                        self._select_from_tab_list(tab_list, iter)
122
 
                        return
123
 
        # if we get here, the fallback default is the Guide
124
 
        self.select_guide()
125
 
 
126
 
    def select_static_tab(self, index):
127
 
        iter = self.static_tab_list.view.model.nth_iter(index)
128
 
        self._select_from_tab_list(self.static_tab_list, iter)
129
 
 
130
 
    def handle_tablist_change(self, new_tablist):
131
 
        self.selected_tab_list = new_tablist
132
 
        for tab_list in self.all_tab_lists():
133
 
            if tab_list is not new_tablist:
134
 
                tab_list.view.unselect_all()
135
 
 
136
 
    def update_selected_tabs(self):
137
 
        table_view = self.selected_tab_list.view
138
 
        self.__table_view = table_view
139
 
        self.selected_tabs = [table_view.model[i][0] for i in
140
 
                table_view.get_selection()]
141
 
 
142
 
    def on_selection_changed(self, table_view):
143
 
        if (table_view is not self.selected_tab_list.view and
144
 
                table_view.num_rows_selected() == 0):
145
 
            # This is the result of us calling unselect_all() in
146
 
            # handle_tablist_change
147
 
            return
148
 
 
149
 
        tab_list = self.widget_to_tablist[table_view]
150
 
        if tab_list.doing_change:
151
 
            return
152
 
        if tab_list is not self.selected_tab_list:
153
 
            self.handle_tablist_change(tab_list)
154
 
        if table_view.num_rows_selected() > 0:
155
 
            self.update_selected_tabs()
156
 
        else:
157
 
            self.handle_no_tabs_selected()
158
 
        self.handle_new_selection()
159
 
 
160
 
    def recalc_selection(self):
161
 
        self.on_selection_changed(self.selected_tab_list.view)
162
 
 
163
 
    def handle_no_tabs_selected(self):
164
 
        model = self.selected_tab_list.view.model
165
 
        iter = model.first_iter()
166
 
        if iter is None:
167
 
            # We deleted all the feeds/playlists, select the guide instead
168
 
            self.select_guide()
169
 
        else:
170
 
            self.selected_tab_list.view.select(iter)
171
 
            self.selected_tabs = [model[iter][0]]
172
 
 
173
 
    def get_selection(self):
174
 
        if self.__table_view is not None:
175
 
            return self.selected_tab_list.type, self.selected_tabs
176
 
        else:
177
 
            return None, []
178
 
 
179
 
    def get_selection_and_children(self):
180
 
        """This returns the selection and, in the case of parent rows, returns
181
 
        all children, too.  This is particularly useful for getting selections
182
 
        that include children of folders.
183
 
 
184
 
        This returns a list generated from a set--so there are no repeated
185
 
        elements.
186
 
        """
187
 
        table_view = self.__table_view
188
 
        if table_view is not None:
189
 
            selected_tabs = set()
190
 
            for mem in table_view.get_selection():
191
 
                row = table_view.model[mem]
192
 
                # sort children before parents
193
 
                selected_tabs.add((1, row[0]))
194
 
                for children in row.iterchildren():
195
 
                    selected_tabs.add((0, children[0]))
196
 
            return self.selected_tab_list.type, [obj for index, obj in
197
 
                                                 sorted(selected_tabs)]
198
 
        else:
199
 
            return None, []