1
# Copyright (C) 2009 Canonical
4
# Michael Vogt, Gary Lasker
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.
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
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
27
from gettext import gettext as _
29
from softwarecenter.enums import *
31
from appview import AppView, AppStore
33
from softwarepane import SoftwarePane, wait_for_apt_cache_ready
35
class ChannelPane(SoftwarePane):
36
"""Widget that represents the channel pane for display of
37
individual channels (PPAs, partner repositories, etc.)
39
It contains a search entry and navigation buttons.
43
PAGE_APP_DETAILS) = range(2)
45
def __init__(self, cache, db, distro, icons, datadir):
47
SoftwarePane.__init__(self, cache, db, distro, icons, datadir, show_ratings=False)
49
self.apps_filter = None
50
self.channel_name = ""
51
self.search_terms = ""
52
self.current_appview_selection = None
57
self.notebook.append_page(self.scroll_app_list, gtk.Label("channel"))
59
self.notebook.append_page(self.scroll_details, gtk.Label("details"))
60
self.navigation_bar.add_with_id("empty", self.on_navigation_list,
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()
69
def _clear_search(self):
70
# remove the details and clear the search
71
self.searchentry.clear()
72
self.navigation_bar.remove_id("search")
74
@wait_for_apt_cache_ready
75
def refresh_apps(self):
76
"""refresh the applist after search changes and update the
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,
86
self.navigation_bar.remove_all()
87
self.navigation_bar.add_with_id(self.channel_name,
88
self.on_navigation_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,
97
self.app_view.set_model(new_model)
98
self.emit("app-list-changed", len(new_model))
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:
108
self.notebook.set_current_page(self.PAGE_APPLIST)
110
def on_db_reopen(self, db):
112
self._show_channel_overview()
114
def on_navigation_search(self, button, part):
115
logging.debug("on_navigation_search")
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():
123
self._show_channel_overview()
124
# only emit something if the model is there
125
model = self.app_view.get_model()
127
self.emit("app-list-changed", len(model))
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():
133
self.notebook.set_current_page(self.PAGE_APP_DETAILS)
134
self.searchentry.hide()
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
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:
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",
153
return gettext.ngettext("%s application",
157
def get_current_app(self):
158
"""return the current active application object applicable
160
return self.current_appview_selection
162
def is_category_view_showing(self):
163
# there is no category view in the channel pane
166
def set_channel_name(self, channel_name):
167
self.channel_name = channel_name;
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")
174
if len(sys.argv) > 1:
175
datadir = sys.argv[1]
176
elif os.path.exists("./data"):
179
datadir = "/usr/share/software-center"
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())
187
w = ChannelPane(cache, db, icons, datadir)
192
win.set_size_request(400, 600)