27
from errors import show_bzr_error
28
29
from bzrlib.branch import Branch
29
import bzrlib.bzrdir as bzrdir
30
import bzrlib.errors as errors
30
from bzrlib.config import GlobalConfig
33
from olive import gladefile
34
32
from dialog import error_dialog
37
""" Display checkout dialog and perform the needed operations. """
38
def __init__(self, path=None):
34
from history import UrlHistory
35
from olive import Preferences
37
class CheckoutDialog(gtk.Dialog):
38
""" New implementation of the Checkout dialog. """
39
def __init__(self, path=None, parent=None, remote_path=None):
39
40
""" Initialize the Checkout dialog. """
40
self.glade = gtk.glade.XML(gladefile, 'window_checkout', 'olive-gtk')
42
self.window = self.glade.get_widget('window_checkout')
44
# Dictionary for signal_autoconnect
45
dic = { "on_button_checkout_checkout_clicked": self.checkout,
46
"on_button_checkout_cancel_clicked": self.close }
48
# Connect the signals to the handlers
49
self.glade.signal_autoconnect(dic)
51
# Save FileChooser state
52
self.filechooser = self.glade.get_widget('filechooserbutton_checkout')
54
self.filechooser.set_filename(path)
57
""" Display the Checkout dialog. """
58
self.window.show_all()
60
def checkout(self, widget):
61
entry_location = self.glade.get_widget('entry_checkout_location')
62
location = entry_location.get_text()
41
gtk.Dialog.__init__(self, title="Checkout - Olive",
44
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
50
self._button_checkout = gtk.Button(_("Check_out"), use_underline=True)
51
self._button_revision = gtk.Button('')
52
self._image_browse = gtk.Image()
53
self._filechooser = gtk.FileChooserButton(_("Please select a folder"))
54
self._combo = gtk.ComboBoxEntry()
55
self._label_location = gtk.Label(_("Branch location:"))
56
self._label_destination = gtk.Label(_("Destination:"))
57
self._label_nick = gtk.Label(_("Branck nick:"))
58
self._label_revision = gtk.Label(_("Revision:"))
59
self._hbox_revision = gtk.HBox()
60
self._entry_revision = gtk.Entry()
61
self._entry_nick = gtk.Entry()
62
self._check_lightweight = gtk.CheckButton(_("_Lightweight checkout"),
66
self._button_checkout.connect('clicked', self._on_checkout_clicked)
67
self._button_revision.connect('clicked', self._on_revision_clicked)
68
self._combo.child.connect('focus-out-event', self._on_combo_changed)
70
# Create the table and pack the widgets into it
71
self._table = gtk.Table(rows=3, columns=2)
72
self._table.attach(self._label_location, 0, 1, 0, 1)
73
self._table.attach(self._label_destination, 0, 1, 1, 2)
74
self._table.attach(self._label_nick, 0, 1, 2, 3)
75
self._table.attach(self._label_revision, 0, 1, 3, 4)
76
self._table.attach(self._combo, 1, 2, 0, 1)
77
self._table.attach(self._filechooser, 1, 2, 1, 2)
78
self._table.attach(self._entry_nick, 1, 2, 2, 3)
79
self._table.attach(self._hbox_revision, 1, 2, 3, 4)
80
self._table.attach(self._check_lightweight, 1, 2, 4, 5)
83
self._image_browse.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
84
self._button_revision.set_image(self._image_browse)
85
self._button_revision.set_sensitive(False)
86
self._filechooser.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
87
self._label_location.set_alignment(0, 0.5)
88
self._label_destination.set_alignment(0, 0.5)
89
self._label_nick.set_alignment(0, 0.5)
90
self._label_revision.set_alignment(0, 0.5)
91
self._table.set_row_spacings(3)
92
self._table.set_col_spacings(3)
93
self.vbox.set_spacing(3)
94
if self.path is not None:
95
self._filechooser.set_filename(self.path)
96
if remote_path is not None:
97
self._combo.child.set_text(remote_path)
100
self._hbox_revision.pack_start(self._entry_revision, True, True)
101
self._hbox_revision.pack_start(self._button_revision, False, False)
102
self.vbox.add(self._table)
103
self.action_area.pack_end(self._button_checkout)
108
# Build checkout history
109
self._history = UrlHistory(GlobalConfig(), 'branch_history')
110
self._build_history()
112
def _build_history(self):
113
""" Build up the checkout history. """
114
self._combo_model = gtk.ListStore(str)
116
for item in self._history.get_entries():
117
self._combo_model.append([ item ])
120
for item in pref.get_bookmarks():
121
self._combo_model.append([ item ])
123
self._combo.set_model(self._combo_model)
124
self._combo.set_text_column(0)
126
def _get_last_revno(self):
127
""" Get the revno of the last revision (if any). """
128
location = self._combo.get_child().get_text()
130
br = Branch.open(location)
136
def _on_revision_clicked(self, button):
137
""" Browse for revision button clicked handler. """
138
from revbrowser import RevisionBrowser
140
location = self._combo.get_child().get_text()
143
br = Branch.open(location)
147
revb = RevisionBrowser(br, self)
148
response = revb.run()
149
if response != gtk.RESPONSE_NONE:
152
if response == gtk.RESPONSE_OK:
153
if revb.selected_revno is not None:
154
self._entry_revision.set_text(revb.selected_revno)
159
def _on_checkout_clicked(self, button):
160
""" Checkout button clicked handler. """
161
location = self._combo.get_child().get_text()
63
162
if location is '':
64
163
error_dialog(_('Missing branch location'),
65
164
_('You must specify a branch location.'))
68
destination = self.filechooser.get_filename()
70
spinbutton_revno = self.glade.get_widget('spinbutton_checkout_revno')
71
revno = spinbutton_revno.get_value_as_int()
73
checkbutton_lightweight = self.glade.get_widget('checkbutton_checkout_lightweight')
74
lightweight = checkbutton_lightweight.get_active()
167
destination = self._filechooser.get_filename()
77
source = Branch.open(location)
78
rev_id = source.get_rev_id(revno)
80
# if the source and destination are the same,
81
# and there is no working tree,
82
# then reconstitute a branch
83
if (bzrlib.osutils.abspath(destination) ==
84
bzrlib.osutils.abspath(location)):
86
source.bzrdir.open_workingtree()
87
except errors.NoWorkingTree:
88
source.bzrdir.create_workingtree()
91
destination = destination + '/' + os.path.basename(location.rstrip("/\\"))
95
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
96
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
100
checkout = bzrdir.BzrDirMetaFormat1().initialize(destination)
101
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
103
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
104
destination, force_new_tree=False)
105
checkout = checkout_branch.bzrdir
106
checkout_branch.bind(source)
107
if rev_id is not None:
108
rh = checkout_branch.revno_history()
109
checkout_branch.set_revno_history(rh[:rh.index(rev_id) + 1])
111
checkout.create_workingtree(rev_id)
113
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
114
except errors.NotBranchError, errmsg:
115
error_dialog(_('Location is not a branch'),
116
_('The specified location has to be a branch.'))
118
except errors.TargetAlreadyExists, errmsg:
119
error_dialog(_('Target already exists'),
120
_('Target directory (%s)\nalready exists. Please select another target.') % errmsg)
122
except errors.NonExistingParent, errmsg:
123
error_dialog(_('Non existing parent directory'),
124
_("The parent directory (%s)\ndoesn't exist.") % errmsg)
128
self.comm.refresh_right()
130
def close(self, widget=None):
131
self.window.destroy()
169
revno = int(self._entry_revision.get_text())
173
nick = self._entry_nick.get_text()
175
nick = os.path.basename(location.rstrip("/\\"))
177
br_from = Branch.open(location)
179
revision_id = br_from.get_rev_id(revno)
180
lightweight = self._check_lightweight.get_active()
181
to_location = destination + os.sep + nick
183
os.mkdir(to_location)
185
br_from.create_checkout(to_location, revision_id, lightweight)
187
self._history.add_entry(location)
189
self.response(gtk.RESPONSE_OK)
191
def _on_combo_changed(self, widget, event):
192
""" We try to get the last revision if focus lost. """
193
rev = self._get_last_revno()
195
self._entry_revision.set_text(_('N/A'))
196
self._button_revision.set_sensitive(False)
198
self._entry_revision.set_text(str(rev))
199
self._button_revision.set_sensitive(True)
200
if self._entry_nick.get_text() == '':
201
self._entry_nick.set_text(os.path.basename(self._combo.get_child().get_text().rstrip("/\\")))