~gary-lasker/software-center/fix-lp913756-for-5.0

« back to all changes in this revision

Viewing changes to softwarecenter/view/channelpane.py

merged (and fixed conflicts) from  lp:~gary-lasker/software-center/sourcesview  

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009 Canonical
 
2
#
 
3
# Authors:
 
4
#  Michael Vogt, Gary Lasker
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify it under
 
7
# the terms of the GNU General Public License as published by the Free Software
 
8
# Foundation; version 3.
 
9
#
 
10
# This program is distributed in the hope that it will be useful, but WITHOUT
 
11
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
12
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
13
# details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License along with
 
16
# this program; if not, write to the Free Software Foundation, Inc.,
 
17
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 
 
19
import apt
 
20
import gettext
 
21
import gtk
 
22
import logging
 
23
import os
 
24
import sys
 
25
import xapian
 
26
 
 
27
from gettext import gettext as _
 
28
 
 
29
from softwarecenter.enums import *
 
30
 
 
31
from appview import AppView, AppStore
 
32
 
 
33
from softwarepane import SoftwarePane, wait_for_apt_cache_ready
 
34
 
 
35
class ChannelPane(SoftwarePane):
 
36
    """Widget that represents the channel pane for display of
 
37
       individual channels (PPAs, partner repositories, etc.)
 
38
       in software-center.
 
39
       It contains a search entry and navigation buttons.
 
40
    """
 
41
 
 
42
    (PAGE_APPLIST,
 
43
     PAGE_APP_DETAILS) = range(2)
 
44
 
 
45
    def __init__(self, cache, db, distro, icons, datadir):
 
46
        # parent
 
47
        SoftwarePane.__init__(self, cache, db, distro, icons, datadir, show_ratings=False)
 
48
        # state
 
49
        self.apps_filter = None
 
50
        self.channel_name = ""
 
51
        self.search_terms = ""
 
52
        self.current_appview_selection = None
 
53
        # UI
 
54
        self._build_ui()
 
55
        
 
56
    def _build_ui(self):
 
57
        self.notebook.append_page(self.scroll_app_list, gtk.Label("channel"))
 
58
        # details
 
59
        self.notebook.append_page(self.scroll_details, gtk.Label("details"))
 
60
        self.navigation_bar.add_with_id("empty", self.on_navigation_list,
 
61
                                        "list")
 
62
 
 
63
    def _show_channel_overview(self):
 
64
        " helper that goes back to the overview page "
 
65
        self.navigation_bar.remove_id("details")
 
66
        self.notebook.set_current_page(self.PAGE_APPLIST)
 
67
        self.searchentry.show()
 
68
        
 
69
    def _clear_search(self):
 
70
        # remove the details and clear the search
 
71
        self.searchentry.clear()
 
72
        self.navigation_bar.remove_id("search")
 
73
 
 
74
    @wait_for_apt_cache_ready
 
75
    def refresh_apps(self):
 
76
        """refresh the applist after search changes and update the 
 
77
           navigation bar
 
78
        """
 
79
        if self.search_terms:
 
80
            query = self.db.get_query_list_from_search_entry(self.search_terms,
 
81
                                                             xapian.Query("XOL"+self.channel_name))
 
82
            self.navigation_bar.add_with_id(_("Search Results"),
 
83
                                            self.on_navigation_search, 
 
84
                                            "search")
 
85
        else:
 
86
            self.navigation_bar.remove_all()
 
87
            self.navigation_bar.add_with_id(self.channel_name, 
 
88
                                        self.on_navigation_list,
 
89
                                        "list")
 
90
            query = xapian.Query("XOL"+self.channel_name)
 
91
        print "channelpane query: %s" % query
 
92
        # get a new store and attach it to the view
 
93
        new_model = AppStore(self.cache,
 
94
                             self.db, 
 
95
                             self.icons, 
 
96
                             query)
 
97
        self.app_view.set_model(new_model)
 
98
        self.emit("app-list-changed", len(new_model))
 
99
        return False
 
100
        
 
101
    def on_search_terms_changed(self, searchentry, terms):
 
102
        """callback when the search entry widget changes"""
 
103
        logging.debug("on_search_terms_changed: '%s'" % terms)
 
104
        self.search_terms = terms
 
105
        if not self.search_terms:
 
106
            self._clear_search()
 
107
        self.refresh_apps()
 
108
        self.notebook.set_current_page(self.PAGE_APPLIST)
 
109
        
 
110
    def on_db_reopen(self, db):
 
111
        self.refresh_apps()
 
112
        self._show_channel_overview()
 
113
 
 
114
    def on_navigation_search(self, button, part):
 
115
        logging.debug("on_navigation_search")
 
116
        pass
 
117
 
 
118
    def on_navigation_list(self, button, part):
 
119
        """callback when the navigation button with id 'list' is clicked"""
 
120
        if not button.get_active():
 
121
            return
 
122
        self._clear_search()
 
123
        self._show_channel_overview()
 
124
        # only emit something if the model is there
 
125
        model = self.app_view.get_model()
 
126
        if model:
 
127
            self.emit("app-list-changed", len(model))
 
128
 
 
129
    def on_navigation_details(self, button, part):
 
130
        """callback when the navigation button with id 'details' is clicked"""
 
131
        if not button.get_active():
 
132
            return
 
133
        self.notebook.set_current_page(self.PAGE_APP_DETAILS)
 
134
        self.searchentry.hide()
 
135
        
 
136
    def on_application_selected(self, appview, app):
 
137
        """callback when an app is selected"""
 
138
        logging.debug("on_application_selected: '%s'" % app)
 
139
        self.current_appview_selection = app
 
140
    
 
141
    def get_status_text(self):
 
142
        """return user readable status text suitable for a status bar"""
 
143
        # no status text in the details page
 
144
        if self.notebook.get_current_page() == self.PAGE_APP_DETAILS:
 
145
            return ""
 
146
        # otherwise, show status based on search or not
 
147
        length = len(self.app_view.get_model())
 
148
        if len(self.searchentry.get_text()) > 0:
 
149
            return gettext.ngettext("%s matching item",
 
150
                                    "%s matching items",
 
151
                                    length) % length
 
152
        else:
 
153
            return gettext.ngettext("%s application",
 
154
                                    "%s applications",
 
155
                                    length) % length
 
156
                                    
 
157
    def get_current_app(self):
 
158
        """return the current active application object applicable
 
159
           to the context"""
 
160
        return self.current_appview_selection
 
161
        
 
162
    def is_category_view_showing(self):
 
163
        # there is no category view in the channel pane
 
164
        return False
 
165
 
 
166
    def set_channel_name(self, channel_name):
 
167
        self.channel_name = channel_name;
 
168
 
 
169
if __name__ == "__main__":
 
170
    #logging.basicConfig(level=logging.DEBUG)
 
171
    xapian_base_path = XAPIAN_BASE_PATH
 
172
    pathname = os.path.join(xapian_base_path, "xapian")
 
173
 
 
174
    if len(sys.argv) > 1:
 
175
        datadir = sys.argv[1]
 
176
    elif os.path.exists("./data"):
 
177
        datadir = "./data"
 
178
    else:
 
179
        datadir = "/usr/share/software-center"
 
180
 
 
181
    db = xapian.Database(pathname)
 
182
    icons = gtk.icon_theme_get_default()
 
183
    icons.append_search_path("/usr/share/app-install/icons/")
 
184
    cache = apt.Cache(apt.progress.OpTextProgress())
 
185
    cache.ready = True
 
186
 
 
187
    w = ChannelPane(cache, db, icons, datadir)
 
188
    w.show()
 
189
 
 
190
    win = gtk.Window()
 
191
    win.add(w)
 
192
    win.set_size_request(400, 600)
 
193
    win.show_all()
 
194
 
 
195
    gtk.main()
 
196