14
15
# along with this program; if not, write to the Free Software
 
15
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
20
    pygtk.require("2.0")
 
31
 
import olive.backend.commit as commit
 
32
 
import olive.backend.errors as errors
 
33
 
import olive.backend.info as info
 
36
 
    """ Display Push dialog and perform the needed actions. """
 
37
 
    def __init__(self, gladefile, comm, dialog):
 
 
26
from errors import show_bzr_error
 
 
28
# FIXME: This needs to be public JRV 20070714
 
 
29
from bzrlib.builtins import _create_prefix
 
 
30
from bzrlib.config import LocationConfig
 
 
31
import bzrlib.errors as errors
 
 
33
from dialog import error_dialog, info_dialog, question_dialog
 
 
35
from history import UrlHistory
 
 
37
class PushDialog(gtk.Dialog):
 
 
38
    """ New implementation of the Push dialog. """
 
 
39
    def __init__(self, repository, revid, branch=None, parent=None):
 
38
40
        """ Initialize the Push dialog. """
 
39
 
        self.gladefile = gladefile
 
40
 
        self.glade = gtk.glade.XML(self.gladefile, 'window_push')
 
42
 
        # Communication object
 
47
 
        self.window = self.glade.get_widget('window_push')
 
49
 
        # Dictionary for signal_autoconnect
 
50
 
        dic = { "on_button_push_push_clicked": self.push,
 
51
 
                "on_button_push_cancel_clicked": self.close,
 
52
 
                "on_radiobutton_push_stored_toggled": self.stored_toggled,
 
53
 
                "on_radiobutton_push_specific_toggled": self.specific_toggled, }
 
55
 
        # Connect the signals to the handlers
 
56
 
        self.glade.signal_autoconnect(dic)
 
58
 
        # Get some useful widgets
 
59
 
        self.entry_stored = self.glade.get_widget('entry_push_stored')
 
60
 
        self.entry_location = self.glade.get_widget('entry_push_location')
 
61
 
        self.check_remember = self.glade.get_widget('checkbutton_push_remember')
 
62
 
        self.check_overwrite = self.glade.get_widget('checkbutton_push_overwrite')
 
63
 
        self.check_create = self.glade.get_widget('checkbutton_push_create')
 
66
 
        self.notbranch = False
 
68
 
            loc = info.get_push_location(self.comm.get_path())
 
69
 
        except errors.NotBranchError:
 
74
 
            self.entry_stored.set_text(loc)
 
77
 
        """ Display the Push dialog. """
 
79
 
            self.dialog.error_dialog('Directory is not a branch',
 
80
 
                                     'You can perform this action only in a branch.')
 
84
 
            self.width, self.height = self.window.get_size()
 
86
 
    def stored_toggled(self, widget):
 
87
 
        if widget.get_active():
 
88
 
            self.entry_stored.show()
 
89
 
            self.entry_location.hide()
 
90
 
            self.check_remember.hide()
 
91
 
            self.check_create.hide()
 
92
 
            self.window.resize(self.width, self.height)
 
94
 
            self.entry_stored.hide()
 
95
 
            self.entry_location.show()
 
96
 
            self.check_remember.show()
 
97
 
            self.check_create.show()
 
99
 
    def specific_toggled(self, widget):
 
100
 
        if widget.get_active():
 
101
 
            self.entry_stored.hide()
 
102
 
            self.entry_location.show()
 
103
 
            self.check_remember.show()
 
104
 
            self.check_create.show()
 
106
 
            self.entry_stored.show()
 
107
 
            self.entry_location.hide()
 
108
 
            self.check_remember.hide()
 
109
 
            self.check_create.hide()
 
111
 
    def push(self, widget):
 
112
 
        radio_stored = self.glade.get_widget('radiobutton_push_stored')
 
113
 
        radio_specific = self.glade.get_widget('radiobutton_push_specific')
 
 
41
        gtk.Dialog.__init__(self, title="Push - Olive",
 
 
44
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
 
 
47
        self.repository = repository
 
 
52
        self._label_location = gtk.Label(_("Location:"))
 
 
53
        self._combo = gtk.ComboBoxEntry()
 
 
54
        self._button_push = gtk.Button(_("_Push"), use_underline=True)
 
 
55
        self._hbox_location = gtk.HBox()
 
 
58
        self._button_push.connect('clicked', self._on_push_clicked)
 
 
61
        self._label_location.set_alignment(0, 0.5)
 
 
62
        self._hbox_location.set_spacing(3)
 
 
63
        self.vbox.set_spacing(3)
 
 
66
        self._hbox_location.pack_start(self._label_location, False, False)
 
 
67
        self._hbox_location.pack_start(self._combo, True, True)
 
 
68
        self.vbox.pack_start(self._hbox_location)
 
 
69
        self.action_area.pack_end(self._button_push)
 
 
74
        # Build location history
 
 
75
        self._history = UrlHistory(self.branch.get_config(), 'push_history')
 
 
78
    def _build_history(self):
 
 
79
        """ Build up the location history. """
 
 
80
        self._combo_model = gtk.ListStore(str)
 
 
81
        for item in self._history.get_entries():
 
 
82
            self._combo_model.append([ item ])
 
 
83
        self._combo.set_model(self._combo_model)
 
 
84
        self._combo.set_text_column(0)
 
 
86
        if self.branch is not None:
 
 
87
            location = self.branch.get_push_location()
 
 
88
            if location is not None:
 
 
89
                self._combo.get_child().set_text(location)
 
 
92
    def _on_push_clicked(self, widget):
 
 
93
        """ Push button clicked handler. """
 
 
94
        location = self._combo.get_child().get_text()
 
116
 
        self.comm.set_busy(self.window)
 
117
 
        if radio_stored.get_active():
 
119
 
                revs = commit.push(self.comm.get_path(),
 
120
 
                                   overwrite=self.check_overwrite.get_active())
 
121
 
            except errors.NotBranchError:
 
122
 
                self.dialog.error_dialog('Directory is not a branch',
 
123
 
                                         'You can perform this action only in a branch.')
 
125
 
            except errors.NoLocationKnown:
 
126
 
                self.dialog.error_dialog('Push location is unknown',
 
127
 
                                         'Please specify a location manually.')
 
129
 
            except errors.NonExistingParent, errmsg:
 
130
 
                self.dialog.error_dialog("Non existing parent directory",
 
131
 
                                         "The parent directory (%s)\ndoesn't exist." % errmsg)
 
133
 
            except errors.DivergedBranchesError:
 
134
 
                self.dialog.error_dialog('Branches have been diverged',
 
135
 
                                         'You cannot push if branches have diverged. Use the\noverwrite option if you want to push anyway.')
 
139
 
        elif radio_specific.get_active():
 
140
 
            location = self.entry_location.get_text()
 
142
 
                self.dialog.error_dialog('No location specified',
 
143
 
                                         'Please specify a location or use the default.')
 
147
 
                revs = commit.push(self.comm.get_path(), location,
 
148
 
                                   self.check_remember.get_active(),
 
149
 
                                   self.check_overwrite.get_active(),
 
150
 
                                   self.check_create.get_active())
 
151
 
            except errors.NotBranchError:
 
152
 
                self.dialog.error_dialog('Directory is not a branch',
 
153
 
                                         'You can perform this action only in a branch.')
 
154
 
                self.comm.set_busy(self.window, False)
 
156
 
            except errors.NonExistingParent, errmsg:
 
157
 
                self.dialog.error_dialog("Non existing parent directory",
 
158
 
                                         "The parent directory (%s)\ndoesn't exist." % errmsg)
 
159
 
                self.comm.set_busy(self.window, False)
 
161
 
            except errors.DivergedBranchesError:
 
162
 
                self.dialog.error_dialog('Branches have been diverged',
 
163
 
                                         'You cannot push if branches have diverged. Use the\noverwrite option if you want to push anyway.')
 
164
 
                self.comm.set_busy(self.window, False)
 
166
 
            except errors.PathPrefixNotCreated:
 
167
 
                self.dialog.error_dialog("Path prefix not created",
 
168
 
                                         "The path leading up to the specified location couldn't\nbe created.")
 
169
 
                self.comm.set_busy(self.window, False)
 
 
96
        if self.branch is not None and self.branch.get_push_location() is None:
 
 
97
            response = question_dialog(_('Set default push location'),
 
 
98
                                       _('There is no default push location set.\nSet %r as default now?') % location)
 
 
99
            if response == gtk.RESPONSE_OK:
 
 
100
                self.branch.set_push_location(location)
 
 
103
            revs = do_push(self.branch, location=location, overwrite=False)
 
 
104
        except errors.DivergedBranches:
 
 
105
            response = question_dialog(_('Branches have been diverged'),
 
 
106
                                       _('You cannot push if branches have diverged.\nOverwrite?'))
 
 
107
            if response == gtk.RESPONSE_YES:
 
 
108
                revs = do_push(self.branch, location=location, overwrite=True)
 
 
110
        self._history.add_entry(location)
 
 
111
        info_dialog(_('Push successful'),
 
 
112
                    _("%d revision(s) pushed.") % revs)
 
 
114
        self.response(gtk.RESPONSE_OK)
 
 
116
def do_push(br_from, location, overwrite):
 
 
117
    """ Update a mirror of a branch.
 
 
119
    :param br_from: the source branch
 
 
121
    :param location: the location of the branch that you'd like to update
 
 
123
    :param overwrite: overwrite target location if it diverged
 
 
125
    :return: number of revisions pushed
 
 
127
    from bzrlib.bzrdir import BzrDir
 
 
128
    from bzrlib.transport import get_transport
 
 
130
    transport = get_transport(location)
 
 
131
    location_url = transport.base
 
 
136
        dir_to = BzrDir.open(location_url)
 
 
137
        br_to = dir_to.open_branch()
 
 
138
    except errors.NotBranchError:
 
 
140
        transport = transport.clone('..')
 
 
142
            relurl = transport.relpath(location_url)
 
 
143
            transport.mkdir(relurl)
 
 
144
        except errors.NoSuchFile:
 
 
145
            response = question_dialog(_('Non existing parent directory'),
 
 
146
                         _("The parent directory (%s)\ndoesn't exist. Create?") % location)
 
 
147
            if response == gtk.RESPONSE_OK:
 
 
148
                _create_prefix(transport)
 
 
151
        dir_to = br_from.bzrdir.clone(location_url,
 
 
152
            revision_id=br_from.last_revision())
 
 
153
        br_to = dir_to.open_branch()
 
 
154
        count = len(br_to.revision_history())
 
 
156
        old_rh = br_to.revision_history()
 
 
158
            tree_to = dir_to.open_workingtree()
 
 
159
        except errors.NotLocalUrl:
 
 
160
            # FIXME - what to do here? how should we warn the user?
 
 
161
            count = br_to.pull(br_from, overwrite)
 
 
162
        except errors.NoWorkingTree:
 
 
163
            count = br_to.pull(br_from, overwrite)
 
174
 
            # This should really never happen
 
178
 
        self.dialog.info_dialog('Push successful',
 
179
 
                                '%d revision(s) pushed.' % revs)
 
181
 
    def close(self, widget=None):
 
182
 
        self.window.destroy()
 
 
165
            count = tree_to.pull(br_from, overwrite)