/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
2
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
7
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
0.8.46 by Szilveszter Farkas (Phanatic)
Modified OliveDialog class interface; huge cleanups.
12
#
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
try:
18
    import pygtk
19
    pygtk.require("2.0")
20
except:
21
    pass
0.13.13 by Jelmer Vernooij
Update TODO
22
    
0.13.10 by Jelmer Vernooij
Don't pass around gladefile all the time.
23
import gtk
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
24
25
from errors import show_bzr_error
26
27
from bzrlib.config import LocationConfig
0.11.1 by Jelmer Vernooij
Eliminate olive.backend.errors.
28
import bzrlib.errors as errors
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
29
153 by Jelmer Vernooij
Fix references to dialog.
30
from dialog import error_dialog, info_dialog, question_dialog
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
31
153 by Jelmer Vernooij
Fix references to dialog.
32
from olive import delimiter
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
33
34
class PushDialog(gtk.Dialog):
35
    """ New implementation of the Push dialog. """
36
    def __init__(self, branch, parent=None):
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
37
        """ Initialize the Push dialog. """
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
38
        gtk.Dialog.__init__(self, title="Push - Olive",
39
                                  parent=parent,
40
                                  flags=0,
41
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
42
        
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
43
        # Get arguments
0.13.13 by Jelmer Vernooij
Update TODO
44
        self.branch = branch
0.8.19 by Szilveszter Farkas (Phanatic)
2006-07-21 Szilveszter Farkas <Szilveszter.Farkas@gmail.com>
45
        
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
46
        # Create the widgets
47
        self._label_location = gtk.Label(_("Location:"))
48
        self._label_test = gtk.Label(_("(click the Test button to check write access)"))
49
        self._check_remember = gtk.CheckButton(_("_Remember as default location"),
50
                                               use_underline=True)
51
        self._check_prefix = gtk.CheckButton(_("Create the path _leading up to the location"),
52
                                             use_underline=True)
53
        self._check_overwrite = gtk.CheckButton(_("_Overwrite target if diverged"),
54
                                                use_underline=True)
55
        self._combo = gtk.ComboBoxEntry()
56
        self._button_test = gtk.Button(_("_Test"), use_underline=True)
57
        self._button_push = gtk.Button(_("_Push"), use_underline=True)
58
        self._hbox_location = gtk.HBox()
59
        self._hbox_test = gtk.HBox()
60
        self._image_test = gtk.Image()
61
        
62
        # Set callbacks
63
        self._button_test.connect('clicked', self._on_test_clicked)
64
        self._button_push.connect('clicked', self._on_push_clicked)
65
        
66
        # Set properties
67
        self._image_test.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
68
        self._label_location.set_alignment(0, 0.5)
69
        self._label_test.set_alignment(0, 0.5)
70
        self._hbox_location.set_spacing(3)
71
        self._hbox_test.set_spacing(3)
72
        self.vbox.set_spacing(3)
73
        
74
        # Pack widgets
75
        self._hbox_location.pack_start(self._label_location, False, False)
76
        self._hbox_location.pack_start(self._combo, True, True)
77
        self._hbox_test.pack_start(self._image_test, False, False)
78
        self._hbox_test.pack_start(self._label_test, True, True)
79
        self.vbox.pack_start(self._hbox_location)
80
        self.vbox.pack_start(self._check_remember)
81
        self.vbox.pack_start(self._check_prefix)
82
        self.vbox.pack_start(self._check_overwrite)
83
        self.vbox.pack_start(self._hbox_test)
84
        self.action_area.pack_start(self._button_test)
85
        self.action_area.pack_end(self._button_push)
86
        
87
        # Show the dialog
88
        self.vbox.show_all()
89
        
90
        # Build location history
91
        self._build_history()
92
        
93
    def _build_history(self):
94
        """ Build up the location history. """
95
        config = LocationConfig(self.branch.base)
96
        history = config.get_user_option('gpush_history')
97
        if history is not None:
98
            self._combo_model = gtk.ListStore(str)
99
            for item in history.split(delimiter):
100
                self._combo_model.append([ item ])
101
            self._combo.set_model(self._combo_model)
102
            self._combo.set_text_column(0)
103
        
104
        location = self.branch.get_push_location()
105
        if location:
106
            self._combo.get_child().set_text(location)
107
    
108
    def _add_to_history(self, location):
109
        """ Add specified location to the history (if not yet added). """
110
        config = LocationConfig(self.branch.base)
111
        history = config.get_user_option('gpush_history')
112
        if history is None:
113
            config.set_user_option('gpush_history', location)
114
        else:
115
            h = history.split(delimiter)
116
            if location not in h:
117
                h.append(location)
118
            config.set_user_option('gpush_history', delimiter.join(h))
119
    
120
    def _on_test_clicked(self, widget):
121
        """ Test button clicked handler. """
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
122
        import re
123
        _urlRE = re.compile(r'^(?P<proto>[^:/\\]+)://(?P<path>.*)$')
124
        
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
125
        url = self._combo.get_child().get_text()
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
126
        
127
        m = _urlRE.match(url)
128
        if m:
129
            proto = m.groupdict()['proto']
0.8.59 by Szilveszter Farkas (Phanatic)
Added README; some small fixes.
130
            if (proto == 'sftp') or (proto == 'file') or (proto == 'ftp'):
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
131
                # have write acces (most probably)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
132
                self._image_test.set_from_stock(gtk.STOCK_YES, 4)
133
                self._label_test.set_markup(_('<b>Write access is probably available</b>'))
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
134
            else:
135
                # no write access
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
136
                self._image_test.set_from_stock(gtk.STOCK_NO, 4)
137
                self._label_test.set_markup(_('<b>No write access</b>'))
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
138
        else:
139
            # couldn't determine
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
140
            self._image_test.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
141
            self._label_test.set_markup(_('<b>Could not determine</b>'))
0.8.58 by Szilveszter Farkas (Phanatic)
Added Test write access functionality to the Push dialog.
142
    
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
143
    @show_bzr_error
144
    def _on_push_clicked(self, widget):
145
        """ Push button clicked handler. """
146
        location = self._combo.get_child().get_text()
147
        revs = 0
148
        try:
149
            revs = do_push(self.branch,
150
                           location=location,
151
                           overwrite=self._check_overwrite.get_active(),
152
                           remember=self._check_remember.get_active(),
153
                           create_prefix=self._check_prefix.get_active())
154
        except errors.DivergedBranches:
155
            response = question_dialog(_('Branches have been diverged'),
156
                                       _('You cannot push if branches have diverged.\nOverwrite?'))
157
            if response == gtk.RESPONSE_OK:
158
                revs = do_push(self.branch, overwrite=True)
159
            return
160
        
161
        self._add_to_history(location)
162
        info_dialog(_('Push successful'),
163
                    _("%d revision(s) pushed.") % revs)
164
        
165
        self.response(gtk.RESPONSE_OK)
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
166
167
def do_push(branch, location=None, remember=False, overwrite=False,
168
         create_prefix=False):
169
    """ Update a mirror of a branch.
170
    
171
    :param branch: the source branch
172
    
173
    :param location: the location of the branch that you'd like to update
174
    
175
    :param remember: if set, the location will be stored
176
    
177
    :param overwrite: overwrite target location if it diverged
178
    
179
    :param create_prefix: create the path leading up to the branch if it doesn't exist
180
    
181
    :return: number of revisions pushed
182
    """
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
183
    from bzrlib.bzrdir import BzrDir
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
184
    from bzrlib.transport import get_transport
185
        
99 by Szilveszter Farkas (Phanatic)
Fixed bug: #66656 (Push doesn't work).
186
    br_from = branch
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
187
    
188
    stored_loc = br_from.get_push_location()
189
    if location is None:
190
        if stored_loc is None:
0.13.6 by Jelmer Vernooij
Don't pass along dialog context everywhere.
191
            error_dialog(_('Push location is unknown'),
99 by Szilveszter Farkas (Phanatic)
Fixed bug: #66656 (Push doesn't work).
192
                         _('Please specify a location manually.'))
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
193
            return
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
194
        else:
195
            location = stored_loc
196
197
    transport = get_transport(location)
198
    location_url = transport.base
199
200
    if br_from.get_push_location() is None or remember:
201
        br_from.set_push_location(location_url)
202
203
    old_rh = []
204
205
    try:
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
206
        dir_to = BzrDir.open(location_url)
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
207
        br_to = dir_to.open_branch()
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
208
    except errors.NotBranchError:
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
209
        # create a branch.
210
        transport = transport.clone('..')
211
        if not create_prefix:
212
            try:
213
                relurl = transport.relpath(location_url)
214
                transport.mkdir(relurl)
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
215
            except errors.NoSuchFile:
0.13.6 by Jelmer Vernooij
Don't pass along dialog context everywhere.
216
                error_dialog(_('Non existing parent directory'),
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
217
                             _("The parent directory (%s)\ndoesn't exist.") % location)
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
218
                return
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
219
        else:
220
            current = transport.base
221
            needed = [(transport, transport.relpath(location_url))]
222
            while needed:
223
                try:
224
                    transport, relpath = needed[-1]
225
                    transport.mkdir(relpath)
226
                    needed.pop()
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
227
                except errors.NoSuchFile:
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
228
                    new_transport = transport.clone('..')
229
                    needed.append((new_transport,
230
                                   new_transport.relpath(transport.base)))
231
                    if new_transport.base == transport.base:
0.13.6 by Jelmer Vernooij
Don't pass along dialog context everywhere.
232
                        error_dialog(_('Path prefix not created'),
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
233
                                     _("The path leading up to the specified location couldn't\nbe created."))
0.8.85 by Szilveszter Farkas (Phanatic)
Fix Push functionality.
234
                        return
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
235
        dir_to = br_from.bzrdir.clone(location_url,
236
            revision_id=br_from.last_revision())
237
        br_to = dir_to.open_branch()
238
        count = len(br_to.revision_history())
239
    else:
240
        old_rh = br_to.revision_history()
241
        try:
0.13.13 by Jelmer Vernooij
Update TODO
242
            tree_to = dir_to.open_workingtree()
243
        except errors.NotLocalUrl:
244
            # FIXME - what to do here? how should we warn the user?
245
            #warning('This transport does not update the working '
246
            #        'tree of: %s' % (br_to.base,))
247
            count = br_to.pull(br_from, overwrite)
248
        except errors.NoWorkingTree:
249
            count = br_to.pull(br_from, overwrite)
250
        else:
251
            count = tree_to.pull(br_from, overwrite)
252
0.11.9 by Jelmer Vernooij
Remove last few bits from backend and integrate them where necessary.
253
    return count