1
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
# Copyright (C) 2007 by Jelmer Vernooij <jelmer@samba.org>
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
5
6
# the Free Software Foundation; either version 2 of the License, or
6
7
# (at your option) any later version.
8
9
# This program is distributed in the hope that it will be useful,
9
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
12
# GNU General Public License for more details.
13
14
# You should have received a copy of the GNU General Public License
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
35
from dialog import OliveDialog
38
""" Display Push dialog and perform the needed actions. """
39
def __init__(self, gladefile, comm):
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 bzrlib.plugins.gtk import _i18n
34
from dialog import error_dialog, info_dialog, question_dialog
36
from history import UrlHistory
38
class PushDialog(gtk.Dialog):
39
""" New implementation of the Push dialog. """
40
def __init__(self, repository, revid, branch=None, parent=None):
40
41
""" Initialize the Push dialog. """
41
self.gladefile = gladefile
42
self.glade = gtk.glade.XML(self.gladefile, 'window_push')
45
self.dialog = OliveDialog(self.gladefile)
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.')
83
self.width, self.height = self.window.get_size()
85
def stored_toggled(self, widget):
86
if widget.get_active():
87
self.entry_stored.show()
88
self.entry_location.hide()
89
self.check_remember.hide()
90
self.check_create.hide()
91
self.window.resize(self.width, self.height)
93
self.entry_stored.hide()
94
self.entry_location.show()
95
self.check_remember.show()
96
self.check_create.show()
98
def specific_toggled(self, widget):
99
if widget.get_active():
100
self.entry_stored.hide()
101
self.entry_location.show()
102
self.check_remember.show()
103
self.check_create.show()
105
self.entry_stored.show()
106
self.entry_location.hide()
107
self.check_remember.hide()
108
self.check_create.hide()
110
def push(self, widget):
111
radio_stored = self.glade.get_widget('radiobutton_push_stored')
112
radio_specific = self.glade.get_widget('radiobutton_push_specific')
42
gtk.Dialog.__init__(self, title="Push - Olive",
45
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
48
self.repository = repository
53
self._label_location = gtk.Label(_i18n("Location:"))
54
self._combo = gtk.ComboBoxEntry()
55
self._button_push = gtk.Button(_i18n("_Push"), use_underline=True)
56
self._hbox_location = gtk.HBox()
59
self._button_push.connect('clicked', self._on_push_clicked)
62
self._label_location.set_alignment(0, 0.5)
63
self._hbox_location.set_spacing(3)
64
self.vbox.set_spacing(3)
67
self._hbox_location.pack_start(self._label_location, False, False)
68
self._hbox_location.pack_start(self._combo, True, True)
69
self.vbox.pack_start(self._hbox_location)
70
self.action_area.pack_end(self._button_push)
75
# Build location history
76
self._history = UrlHistory(self.branch.get_config(), 'push_history')
79
def _build_history(self):
80
""" Build up the location history. """
81
self._combo_model = gtk.ListStore(str)
82
for item in self._history.get_entries():
83
self._combo_model.append([ item ])
84
self._combo.set_model(self._combo_model)
85
self._combo.set_text_column(0)
87
if self.branch is not None:
88
location = self.branch.get_push_location()
89
if location is not None:
90
self._combo.get_child().set_text(location)
93
def _on_push_clicked(self, widget):
94
""" Push button clicked handler. """
95
location = self._combo.get_child().get_text()
115
self.comm.set_busy(self.window)
116
if radio_stored.get_active():
118
revs = commit.push(self.comm.get_path(),
119
overwrite=self.check_overwrite.get_active())
120
except errors.NotBranchError:
121
self.dialog.error_dialog('Directory is not a branch.')
123
except errors.NoLocationKnown:
124
self.dialog.error_dialog('No location known.')
126
except errors.NonExistingParent, errmsg:
127
self.dialog.error_dialog('Parent directory doesn\'t exist: %s', errmsg)
129
except errors.DivergedBranchesError:
130
self.dialog.error_dialog('Branches have been diverged.')
134
elif radio_specific.get_active():
135
location = self.entry_location.get_text()
137
self.dialog.error_dialog('No location specified.')
141
revs = commit.push(self.comm.get_path(), location,
142
self.check_remember.get_active(),
143
self.check_overwrite.get_active(),
144
self.check_create.get_active())
145
except errors.NotBranchError:
146
self.dialog.error_dialog('Directory is not a branch.')
147
self.comm.set_busy(self.window, False)
149
except errors.NonExistingParent, errmsg:
150
self.dialog.error_dialog('Parent directory doesn\'t exist: %s', errmsg)
151
self.comm.set_busy(self.window, False)
153
except errors.DivergedBranchesError:
154
self.dialog.error_dialog('Branches have been diverged.')
155
self.comm.set_busy(self.window, False)
157
except errors.PathPrefixNotCreated:
158
self.dialog.error_dialog('Path prefix couldn\'t be created.')
159
self.comm.set_busy(self.window, False)
97
if self.branch is not None and self.branch.get_push_location() is None:
98
response = question_dialog(_i18n('Set default push location'),
99
_i18n('There is no default push location set.\nSet %r as default now?') % location)
100
if response == gtk.RESPONSE_OK:
101
self.branch.set_push_location(location)
104
revs = do_push(self.branch, location=location, overwrite=False)
105
except errors.DivergedBranches:
106
response = question_dialog(_i18n('Branches have been diverged'),
107
_i18n('You cannot push if branches have diverged.\nOverwrite?'))
108
if response == gtk.RESPONSE_YES:
109
revs = do_push(self.branch, location=location, overwrite=True)
111
self._history.add_entry(location)
112
info_dialog(_i18n('Push successful'),
113
_i18n("%d revision(s) pushed.") % revs)
115
self.response(gtk.RESPONSE_OK)
117
def do_push(br_from, location, overwrite):
118
""" Update a mirror of a branch.
120
:param br_from: the source branch
122
:param location: the location of the branch that you'd like to update
124
:param overwrite: overwrite target location if it diverged
126
:return: number of revisions pushed
128
from bzrlib.bzrdir import BzrDir
129
from bzrlib.transport import get_transport
131
transport = get_transport(location)
132
location_url = transport.base
137
dir_to = BzrDir.open(location_url)
138
br_to = dir_to.open_branch()
139
except errors.NotBranchError:
141
transport = transport.clone('..')
143
relurl = transport.relpath(location_url)
144
transport.mkdir(relurl)
145
except errors.NoSuchFile:
146
response = question_dialog(_i18n('Non existing parent directory'),
147
_i18n("The parent directory (%s)\ndoesn't exist. Create?") % location)
148
if response == gtk.RESPONSE_OK:
149
_create_prefix(transport)
152
dir_to = br_from.bzrdir.clone(location_url,
153
revision_id=br_from.last_revision())
154
br_to = dir_to.open_branch()
155
count = len(br_to.revision_history())
157
old_rh = br_to.revision_history()
159
tree_to = dir_to.open_workingtree()
160
except errors.NotLocalUrl:
161
# FIXME - what to do here? how should we warn the user?
162
count = br_to.pull(br_from, overwrite)
163
except errors.NoWorkingTree:
164
count = br_to.pull(br_from, overwrite)
164
# This should really never happen
168
self.dialog.info_dialog('%d revision(s) pushed.' % revs)
170
def close(self, widget=None):
171
self.window.destroy()
166
count = tree_to.pull(br_from, overwrite)