add copyrights information
[appstream:software-center.git] / appcenter / view / viewswitcher.py
1 # Copyright (C) 2009 Canonical
2 #
3 # Authors:
4 #  Michael Vogt
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; either version 2 of the License, or (at your option) any later
9 # version.
10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14 # details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20 import logging
21 import gtk
22 import gobject
23 import apt
24 import os
25 import xapian
26 import time
27 import dbus
28
29 from gettext import gettext as _
30
31 class ViewSwitcher(gtk.TreeView):
32     def __init__(self, store=None):
33         if not store:
34             store = ViewSwitcherList()
35             self.set_model(store)
36         gtk.TreeView.__init__(self)
37         self.set_fixed_height_mode(True)
38         tp = gtk.CellRendererPixbuf()
39         column = gtk.TreeViewColumn("Icon", tp, pixbuf=store.COL_ICON)
40         column.set_fixed_width(32)
41         column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
42         self.append_column(column)
43         tr = gtk.CellRendererText()
44         column = gtk.TreeViewColumn("Name", tr, markup=store.COL_NAME)
45         column.set_fixed_width(200)
46         column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
47         self.append_column(column)
48         self.set_model(store)
49         self.set_headers_visible(False)
50         #self.set_headers_visible(False)
51         #self.set_grid_lines(False)
52         #self.set_enable_tree_lines(False)
53         #self.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_NONE)
54         # single click
55         #self.cursor_hand = gtk.gdk.Cursor(gtk.gdk.HAND2)
56         #self.connect("motion-notify-event", self.on_motion_notify_event)
57         self.connect("button-press-event", self.on_button_press_event)
58     def on_motion_notify_event(self, widget, event):
59         #print "on_motion_notify_event: ", event
60         path = self.get_path_at_pos(event.x, event.y)
61         if path is None:
62             self.window.set_cursor(None)
63         else:
64             self.window.set_cursor(self.cursor_hand)
65     def on_button_press_event(self, widget, event):
66         #print "on_button_press_event: ", event
67         res = self.get_path_at_pos(event.x, event.y)
68         if not res:
69             return
70         (path, column, wx, wy) = res
71         if event.button != 1 or path is None:
72             return
73         self.emit("row-activated", path, column)
74
75 class ViewSwitcherList(gtk.ListStore):
76     
77     # columns
78     (COL_ICON,
79      COL_NAME,
80      COL_ACTION) = range(3)
81
82     # items in the treeview
83     (ACTION_ITEM_AVAILABLE,
84      ACTION_ITEM_INSTALLED,
85      ACTION_ITEM_PENDING) = range(3)
86
87     def __init__(self):
88         gtk.ListStore.__init__(self, gtk.gdk.Pixbuf, str, int)
89         # setup the normal stuff
90         self.append([None, _("Get new software"), self.ACTION_ITEM_AVAILABLE])
91         self.append([None, _("Installed software"), self.ACTION_ITEM_INSTALLED])
92         # setup dbus, its ok if aptdaemon is not available, we just
93         # do not show the pending changes tab then
94
95         # FIXME: use ActiveTransactionChanged callback from the daemon
96         #        here instead of polling
97         try:
98             self.system_bus = dbus.SystemBus()
99             obj = self.system_bus.get_object("org.debian.apt",
100                                              "/org/debian/apt")
101             self.aptd = dbus.Interface(obj, 'org.debian.apt')
102             # check for pending aptdaemon actions
103             self.check_pending()
104             gobject.timeout_add_seconds(1, self.check_pending)
105         except dbus.exceptions.DBusException, e:
106             logging.exception("aptdaemon dbus error")
107
108     def check_pending(self):
109         #print "check_pending"
110         pending = 0
111         (current, queue) = self.aptd.GetActiveTransactions()
112         if current or len(queue) > 0:
113             pending = 1 + len(queue)
114         # if we have a pending item, show it in the action view
115         # and if not, delete any items we added already
116         if pending > 0:
117             for row in self:
118                 if row[self.COL_ACTION] == self.ACTION_ITEM_PENDING:
119                     row[self.COL_NAME] = _("Pending (%i)") % pending
120                     break
121             else:
122                 self.append([None, _("Pending (%i)") % pending, 
123                              self.ACTION_ITEM_PENDING])
124         else:
125             for (i, row) in enumerate(self):
126                 if row[self.COL_ACTION] == self.ACTION_ITEM_PENDING:
127                     del self[(i,)]
128         return True
129
130 if __name__ == "__main__":
131     logging.basicConfig(level=logging.DEBUG)
132
133     # now the store
134     store = ViewSwitcherList()
135
136     # gui
137     scroll = gtk.ScrolledWindow()
138     view = ViewSwitcher(store)
139
140     box = gtk.VBox()
141     box.pack_start(scroll)
142
143     win = gtk.Window()
144     scroll.add(view)
145     win.add(box)
146     win.set_size_request(400,400)
147     win.show_all()
148
149     gtk.main()