~awn-extras/awn-extras/0.2.1

« back to all changes in this revision

Viewing changes to awn-applets/awn-extras-applets/src/stacks/stacks_vfs.py

  • Committer: Neil Jagdish Patel
  • Date: 2007-11-03 16:47:35 UTC
  • Revision ID: njp@galactic-20071103164735-l7qils9pjg01kw3z
* Restore the stacks applet (I am such a twit sometimes)
* make dist fails hard because people aren't their extra_dist in their applet Makefile.am properly. 60 % fixed, some more to go.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
# Copyright (c) 2007 Timon ter Braak
 
4
#
 
5
# This library is free software; you can redistribute it and/or
 
6
# modify it under the terms of the GNU Lesser General Public
 
7
# License as published by the Free Software Foundation; either
 
8
# version 2 of the License, or (at your option) any later version.
 
9
#
 
10
# This library is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
# Lesser General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU Lesser General Public
 
16
# License along with this library; if not, write to the
 
17
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
# Boston, MA 02111-1307, USA.
 
19
 
 
20
import gobject
 
21
import gnomevfs
 
22
import gtk
 
23
import pango
 
24
import os
 
25
 
 
26
class GUITransfer(object):
 
27
 
 
28
    def __init__(self, src, dst, options):
 
29
        self.__progress = None
 
30
        self.dialog_visible = False
 
31
        self.cancel = False
 
32
        self.txt_operation = ""
 
33
        self.label_under = None
 
34
        if not (options & gnomevfs.XFER_LINK_ITEMS):
 
35
            if (options & gnomevfs.XFER_REMOVESOURCE):
 
36
                self.txt_operation = "Moving"
 
37
            elif (options & gnomevfs.XFER_EMPTY_DIRECTORIES):
 
38
                self.txt_operation = "Deleting"
 
39
            else:
 
40
                self.txt_operation = "Copying"
 
41
            self.dialog = gtk.Dialog(title=self.txt_operation + " files",
 
42
                                     buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT))
 
43
            self.dialog.set_border_width(12)
 
44
            self.dialog.set_has_separator(False)
 
45
            self.dialog.vbox.set_spacing(2)
 
46
            hbox_copy = gtk.HBox(False, 0)
 
47
            label_copy = gtk.Label("")
 
48
            label_copy.set_markup("<big><b>" + self.txt_operation + " files</b></big>\n")
 
49
            hbox_copy.pack_start(label_copy, False, False, 0)
 
50
            self.dialog.vbox.add(hbox_copy)
 
51
            hbox_info = gtk.HBox(False, 0)
 
52
            label_fromto = gtk.Label("")
 
53
            label_fromto.set_markup("<b>From:</b>\n<b>To:</b>")
 
54
            label_fromto.set_justify(gtk.JUSTIFY_RIGHT)
 
55
            hbox_info.pack_start(label_fromto, False, False, 0)
 
56
            try:
 
57
                srcdir = src[0].parent.path
 
58
                dstdir = dst[0].parent.path
 
59
                label_srcdst = gtk.Label("")
 
60
                label_srcdst.set_alignment(0.0, 0.5)
 
61
                label_srcdst.set_ellipsize(pango.ELLIPSIZE_START)
 
62
                label_srcdst.set_markup("%s\n%s" % (srcdir, dstdir))
 
63
                hbox_info.pack_start(label_srcdst, True, True, 4)
 
64
            except:
 
65
                label_fromto.hide()
 
66
            self.dialog.vbox.add(hbox_info)
 
67
            self.progress_bar = gtk.ProgressBar()
 
68
            self.dialog.vbox.add(self.progress_bar)
 
69
            hbox_under = gtk.HBox(False, 0)
 
70
            self.label_under = gtk.Label("")
 
71
            self.label_under.set_justify(gtk.JUSTIFY_LEFT)
 
72
            self.label_under.set_ellipsize(pango.ELLIPSIZE_MIDDLE)
 
73
            self.label_under.xalign = 0.0
 
74
            hbox_under.pack_start(self.label_under, True, True, 0)
 
75
            self.dialog.vbox.add(hbox_under)
 
76
 
 
77
            self.status_label = gtk.Label()
 
78
            self.dialog.vbox.add(self.status_label)
 
79
            self.dialog.set_size_request(400,180)
 
80
            self.dialog.connect("response", self.__dialog_response)
 
81
            self.dialog.show_all()
 
82
 
 
83
        self.handle = gnomevfs.async.xfer(
 
84
            source_uri_list=src, target_uri_list=dst,
 
85
            xfer_options=options,
 
86
            error_mode=gnomevfs.XFER_ERROR_MODE_ABORT,
 
87
            overwrite_mode=gnomevfs.XFER_OVERWRITE_MODE_ABORT,
 
88
            progress_update_callback=self.update_info_cb,
 
89
            update_callback_data=options,
 
90
            progress_sync_callback=None,
 
91
            sync_callback_data=None
 
92
            )
 
93
 
 
94
 
 
95
    def __dialog_response(self, dialog, response):
 
96
        if response == gtk.RESPONSE_REJECT or \
 
97
           response == gtk.RESPONSE_DELETE_EVENT:
 
98
            self.cancel = True
 
99
 
 
100
 
 
101
    def update_info_cb(self, _reserved, info, data):
 
102
        if info.status == gnomevfs.XFER_PROGRESS_STATUS_VFSERROR:
 
103
            uri = gnomevfs.URI(info.source_name)
 
104
 
 
105
            if xfer_opts & gnomevfs.XFER_REMOVESOURCE:
 
106
                msg = _("Error while moving.")
 
107
                msg2 = _('Cannot move "%s" to the trash because you do not have permissions to change it or its parent folder.' % uri.short_name)
 
108
            elif xfer_opts & gnomevfs.XFER_DELETE_ITEMS:
 
109
                msg = _("Error while deleting.")
 
110
                msg2 = _('"%s" cannot be deleted because you do not have permissions to modify its parent folder.') % uri.short_name
 
111
            else:
 
112
                msg = _("Error while performing file operation.")
 
113
                msg2 = _('Cannot perform file operation %d on "%s".')  % (xfer_opts, uri.short_name)
 
114
            dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR,
 
115
                    message_format = msg)
 
116
            dialog.format_secondary_text(msg2)
 
117
            if info.files_total > 1:
 
118
                button = gtk.Button(label=_("_Skip"))
 
119
                button.show()
 
120
                dialog.add_action_widget(button, gtk.RESPONSE_REJECT)
 
121
 
 
122
            dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
 
123
            button = gtk.Button(label=_("_Retry"))
 
124
            button.set_property("can-default", True)
 
125
            button.show()
 
126
            dialog.add_action_widget(button, gtk.RESPONSE_ACCEPT)
 
127
            dialog.set_default_response(gtk.RESPONSE_ACCEPT)
 
128
 
 
129
            response = dialog.run()
 
130
            dialog.destroy()
 
131
 
 
132
            if response == gtk.RESPONSE_ACCEPT:
 
133
                return gnomevfs.XFER_ERROR_ACTION_RETRY
 
134
            elif response == gtk.RESPONSE_REJECT:
 
135
                return gnomevfs.XFER_ERROR_ACTION_SKIP
 
136
 
 
137
            return gnomevfs.XFER_ERROR_ACTION_ABORT
 
138
 
 
139
        if (data & gnomevfs.XFER_LINK_ITEMS):
 
140
            return 1
 
141
        if info.phase == gnomevfs.XFER_PHASE_COMPLETED:
 
142
            self.dialog.destroy()
 
143
        if info.status == gnomevfs.XFER_PROGRESS_STATUS_OK:
 
144
            self.label_under.set_markup(
 
145
                    "<i>%s %s</i>" % (self.txt_operation, str(info.source_name)))
 
146
            self.progress_bar.set_text(self.txt_operation + " " +
 
147
                    str(info.file_index) + " of " + str(info.files_total))
 
148
            if info.bytes_copied > 0 and info.bytes_total > 0:
 
149
                fraction = float(info.bytes_copied)/float(info.bytes_total)
 
150
                if not self.dialog_visible: # TODO: and enough time..
 
151
                    self.dialog_visible = True
 
152
                    self.dialog.show_all()
 
153
                self.progress_bar.set_fraction(fraction)
 
154
        if self.cancel:
 
155
            # TODO: remove partial target?
 
156
            return 0
 
157
        return 1
 
158
 
 
159
 
 
160
class VfsUri(gobject.GObject):
 
161
 
 
162
    uri = None
 
163
 
 
164
    def __init__(self, uri):
 
165
        gobject.GObject.__init__(self)
 
166
        if isinstance(uri, gnomevfs.URI):
 
167
            self.uri = uri
 
168
        else:
 
169
            self.uri = gnomevfs.URI(uri.strip())
 
170
 
 
171
 
 
172
    def equals(self, uri2):
 
173
        return gnomevfs.uris_match(self.as_string(), uri2.as_string())
 
174
 
 
175
 
 
176
    def as_uri(self):
 
177
        return self.uri
 
178
 
 
179
 
 
180
    def as_string(self):
 
181
        ustr = self.uri.scheme + "://"
 
182
        if self.uri.user_name is not None:
 
183
            ustr += self.uri.user_name
 
184
            if self.uri.password is not None:
 
185
                ustr += ":" + self.uri.password 
 
186
            ustr += "@"
 
187
        if self.uri.host_name is not None:
 
188
            ustr += self.uri.host_name
 
189
            if self.uri.host_port > 0:
 
190
                ustr += ":" + str(self.uri.host_port)
 
191
        if self.uri.path is not None:
 
192
            ustr += self.uri.path
 
193
        return ustr
 
194
 
 
195
 
 
196
class Monitor(gobject.GObject):
 
197
 
 
198
    __gsignals__ = {
 
199
        "event" :   (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
 
200
                    (gobject.TYPE_STRING, gobject.TYPE_INT)),
 
201
        "created" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)),
 
202
        "deleted" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)),
 
203
        "changed" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,))
 
204
    }
 
205
 
 
206
    event_mapping = {
 
207
        gnomevfs.MONITOR_EVENT_CREATED : "created",
 
208
        gnomevfs.MONITOR_EVENT_DELETED : "deleted",
 
209
        gnomevfs.MONITOR_EVENT_CHANGED : "changed",
 
210
        gnomevfs.MONITOR_EVENT_METADATA_CHANGED : "changed"
 
211
    }
 
212
 
 
213
    monitor = None
 
214
    vfs_uri = None
 
215
    monitor_type = None
 
216
 
 
217
    def __init__(self, vfs_uri):
 
218
        assert isinstance(vfs_uri, VfsUri)
 
219
        gobject.GObject.__init__(self)
 
220
        self.vfs_uri = vfs_uri
 
221
        type = gnomevfs.get_file_info(vfs_uri.as_uri(),
 
222
                gnomevfs.FILE_INFO_DEFAULT | 
 
223
                gnomevfs.FILE_INFO_FOLLOW_LINKS).type
 
224
        if type == gnomevfs.FILE_TYPE_DIRECTORY:
 
225
            self.monitor_type = gnomevfs.MONITOR_DIRECTORY
 
226
        elif type == gnomevfs.FILE_TYPE_REGULAR:
 
227
            self.monitor_type = gnomevfs.MONITOR_FILE
 
228
        else:
 
229
            raise gnomevfs.NotSupportedError
 
230
        try:
 
231
            self.monitor = gnomevfs.monitor_add(
 
232
                    vfs_uri.as_string(),
 
233
                    self.monitor_type,
 
234
                    self._monitor_cb)
 
235
        except gnomevfs.NotSupportedError:
 
236
            return None
 
237
 
 
238
 
 
239
    def _monitor_cb(self, monitor_uri, info_uri, event):
 
240
        signal = self.event_mapping[event]
 
241
        if signal:
 
242
            if self.monitor_type == gnomevfs.MONITOR_FILE:
 
243
                self.emit(signal, self.vfs_uri)
 
244
            else:
 
245
                self.emit(signal, VfsUri(info_uri))
 
246
 
 
247
 
 
248
    def close(self):
 
249
        try: 
 
250
            gnomevfs.monitor_cancel(self.monitor)
 
251
            self.monitor = None
 
252
        except:
 
253
            return