~mmcg069/software-center/cat-flags

68 by Michael Vogt
add copyrights information
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
85 by Michael Vogt
update COPYRIGHT to GPL-3
8
# Foundation; either version 3 of the License, or (at your option) any later
68 by Michael Vogt
add copyrights information
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
35 by Michael Vogt
add start of the pending view
20
21
import logging
22
import gtk
23
import gobject
24
import apt
25
import os
26
import xapian
27
import time
28
29
import aptdaemon.client
30
from aptdaemon.enums import *
31
32
class PendingStore(gtk.ListStore):
33
34
    # column names
35
    (COL_TID,
36
     COL_ICON, 
37
     COL_NAME, 
38
     COL_STATUS, 
47 by Michael Vogt
* AppCenter/view/catview.py:
39
     COL_PROGRESS,
40
     COL_CANCEL) = range(6)
41
42
    # icons
43
    PENDING_STORE_ICON_CANCEL = gtk.STOCK_CANCEL
44
    PENDING_STORE_ICON_NO_CANCEL = "" # gtk.STOCK_YES
35 by Michael Vogt
add start of the pending view
45
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
46
    def __init__(self, icons):
35 by Michael Vogt
add start of the pending view
47
        # icon, status, progress
47 by Michael Vogt
* AppCenter/view/catview.py:
48
        gtk.ListStore.__init__(self, str, gtk.gdk.Pixbuf, str, str, float, str)
35 by Michael Vogt
add start of the pending view
49
        # the apt-daemon stuff
50
        self.apt_client = aptdaemon.client.AptClient()
51
        self.apt_daemon = aptdaemon.client.get_aptdaemon()
52
        self.apt_daemon.connect_to_signal("ActiveTransactionsChanged",
53
                                          self.on_transactions_changed)
47 by Michael Vogt
* AppCenter/view/catview.py:
54
        # FIXME: reconnect if the daemon exists
35 by Michael Vogt
add start of the pending view
55
        self._signals = []
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
56
        self.icons = icons
35 by Michael Vogt
add start of the pending view
57
58
    def clear(self):
59
        super(PendingStore, self).clear()
60
        for sig in self._signals:
61
            gobject.source_remove(sig)
47 by Michael Vogt
* AppCenter/view/catview.py:
62
            del sig
35 by Michael Vogt
add start of the pending view
63
        self._signals = []
64
65
    def on_transactions_changed(self, current_tid, pending_tids):
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
66
        #print "on_transaction_changed", current_tid, len(pending_tids)
35 by Michael Vogt
add start of the pending view
67
        self.clear()
68
        for tid in [current_tid]+pending_tids:
69
            if not tid:
70
                continue
71
            trans = aptdaemon.client.get_transaction(tid)
72
            self._signals.append(
73
                trans.connect("progress", self._on_progress_changed))
74
            self._signals.append(
75
                trans.connect("status", self._on_status_changed))
47 by Michael Vogt
* AppCenter/view/catview.py:
76
            self._signals.append(
77
                trans.connect("allow-cancel", self._on_allow_cancel_changed))
35 by Michael Vogt
add start of the pending view
78
            #FIXME: role is always "Applying changes"
79
            #self._signals.append(
80
            #    trans.connect("role", self._on_role_changed))
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
81
            appname = trans.get_data("appname")
82
            iconname = trans.get_data("iconname")
80 by Michael Vogt
add COPYING.LGPL
83
            print "app: ", appname
84
            print "icon: ", iconname
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
85
            if iconname:
86
                icon = self.icons.load_icon(iconname, 24, 0)
87
            else:
88
                icon = None
47 by Michael Vogt
* AppCenter/view/catview.py:
89
            self.append([tid, icon, appname, "", 0.0, ""])
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
90
            del trans
35 by Michael Vogt
add start of the pending view
91
47 by Michael Vogt
* AppCenter/view/catview.py:
92
    def _on_allow_cancel_changed(self, trans, allow_cancel):
93
        #print "_on_allow_cancel: ", trans, allow_cancel
94
        for row in self:
95
            if row[self.COL_TID] == trans.tid:
96
                if allow_cancel:
97
                    row[self.COL_CANCEL] = self.PENDING_STORE_ICON_CANCEL
98
                else:
99
                    row[self.COL_CANCEL] = self.PENDING_STORE_ICON_NO_CANCEL
100
35 by Michael Vogt
add start of the pending view
101
    def _on_role_changed(self, trans, role):
102
        #print "_on_progress_changed: ", trans, progress
103
        for row in self:
104
            if row[self.COL_TID] == trans.tid:
105
                row[self.COL_NAME] = get_role_localised_present_from_enum(role)
106
107
    def _on_progress_changed(self, trans, progress):
108
        #print "_on_progress_changed: ", trans, progress
109
        for row in self:
110
            if row[self.COL_TID] == trans.tid:
111
                row[self.COL_PROGRESS] = progress
112
113
    def _on_status_changed(self, trans, status):
114
        #print "_on_progress_changed: ", trans, status
115
        for row in self:
116
            if row[self.COL_TID] == trans.tid:
117
                row[self.COL_STATUS] = get_status_string_from_enum(status)
118
119
120
class PendingView(gtk.TreeView):
47 by Michael Vogt
* AppCenter/view/catview.py:
121
    
122
    CANCEL_XPAD = 4
123
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
124
    def __init__(self, icons):
35 by Michael Vogt
add start of the pending view
125
        gtk.TreeView.__init__(self)
47 by Michael Vogt
* AppCenter/view/catview.py:
126
        # customization
36 by Michael Vogt
AppCenter/AppCenter.py: integrate the pending view into the main UI
127
        self.set_headers_visible(False)
47 by Michael Vogt
* AppCenter/view/catview.py:
128
        self.connect("button-press-event", self._on_button_pressed)
35 by Michael Vogt
add start of the pending view
129
        # icon
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
130
        self.icons = icons
35 by Michael Vogt
add start of the pending view
131
        tp = gtk.CellRendererPixbuf()
132
        column = gtk.TreeViewColumn("Icon", tp, pixbuf=PendingStore.COL_ICON)
133
        column.set_fixed_width(32)
134
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
135
        self.append_column(column)
136
        # name
137
        tr = gtk.CellRendererText()
138
        column = gtk.TreeViewColumn("Name", tr, markup=PendingStore.COL_NAME)
139
        self.append_column(column)
140
        # progress
141
        tp = gtk.CellRendererProgress()
142
        column = gtk.TreeViewColumn("Progress", tp, 
143
                                    value=PendingStore.COL_PROGRESS,
144
                                    text=PendingStore.COL_STATUS)
47 by Michael Vogt
* AppCenter/view/catview.py:
145
        column.set_fixed_width(200)
146
        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
147
        self.append_column(column)
148
        # cancel icon
149
        tp = gtk.CellRendererPixbuf()
150
        tp.set_property("xpad", self.CANCEL_XPAD)
151
        column = gtk.TreeViewColumn("Cancel", tp, 
152
                                    stock_id=PendingStore.COL_CANCEL)
153
        self.append_column(column)
154
        # fake columns that eats the extra space at the end
155
        tt = gtk.CellRendererText()
156
        column = gtk.TreeViewColumn("Cancel", tt)
35 by Michael Vogt
add start of the pending view
157
        self.append_column(column)
158
        # add it
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
159
        store = PendingStore(icons)
35 by Michael Vogt
add start of the pending view
160
        self.set_model(store)
47 by Michael Vogt
* AppCenter/view/catview.py:
161
    def _on_button_pressed(self, widget, event):
162
        """button press handler to capture clicks on the cancel button"""
163
        #print "_on_clicked: ", event
164
        if event == None or event.button != 1:
165
            return
166
        res = self.get_path_at_pos(event.x, event.y)
167
        if not res:
168
            return
169
        (path, column, wx, wy) = res
170
        # no path
171
        if not path:
172
            return
173
        # wrong column
174
        if column.get_title() != "Cancel":
175
            return
176
        # not cancelable (no icon)
177
        model = self.get_model()
178
        if model[path][PendingStore.COL_CANCEL] == "":
179
            return 
180
        # get tid
181
        tid = model[path][PendingStore.COL_TID]
182
        trans = aptdaemon.client.get_transaction(tid)
183
        trans.cancel()
35 by Michael Vogt
add start of the pending view
184
185
if __name__ == "__main__":
186
    logging.basicConfig(level=logging.DEBUG)
187
39 by Michael Vogt
* AppCenter/view/appdetailsview.py:
188
    icons = gtk.icon_theme_get_default()
189
    view = PendingView(icons)
35 by Michael Vogt
add start of the pending view
190
191
    # gui
192
    scroll = gtk.ScrolledWindow()
193
    scroll.add(view)
194
195
    win = gtk.Window()
196
    win.add(scroll)
197
    view.grab_focus()
198
    win.set_size_request(500,200)
199
    win.show_all()
200
201
    gtk.main()