106
75
# Get some important menu items
107
76
self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
108
77
self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
109
self.menuitem_file_bookmark = self.toplevel.get_widget('menuitem_file_bookmark')
110
78
self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
111
79
self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
112
80
self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
113
81
self.menuitem_file_annotate = self.toplevel.get_widget('menuitem_file_annotate')
114
82
self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
115
self.menuitem_view_show_ignored_files = self.toplevel.get_widget('menuitem_view_show_ignored_files')
116
83
self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
117
84
self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
118
85
self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
119
86
self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
120
87
self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
121
88
self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
122
self.menuitem_branch_update = self.toplevel.get_widget('menuitem_branch_update')
123
89
self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
124
90
self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
125
91
self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
126
self.menuitem_branch_tags = self.toplevel.get_widget('menuitem_branch_tags')
127
92
self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
128
93
self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
129
94
self.menuitem_branch_conflicts = self.toplevel.get_widget('menuitem_branch_conflicts')
194
143
"on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
195
144
"on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
196
145
"on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
197
"on_toolbutton_update_clicked": self.on_menuitem_branch_update_activate,
198
146
"on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
199
147
"on_treeview_right_row_activated": self.on_treeview_right_row_activated,
200
148
"on_treeview_left_button_press_event": self.on_treeview_left_button_press_event,
201
"on_treeview_left_button_release_event": self.on_treeview_left_button_release_event,
202
"on_treeview_left_row_activated": self.on_treeview_left_row_activated,
203
"on_button_location_up_clicked": self.on_button_location_up_clicked,
204
"on_button_location_jump_clicked": self.on_button_location_jump_clicked,
205
"on_entry_location_key_press_event": self.on_entry_location_key_press_event,
206
"on_checkbutton_history_toggled": self.on_checkbutton_history_toggled,
207
"on_entry_history_revno_key_press_event": self.on_entry_history_revno_key_press_event,
208
"on_button_history_browse_clicked": self.on_button_history_browse_clicked
149
"on_treeview_left_row_activated": self.on_treeview_left_row_activated }
211
151
# Connect the signals to the handlers
212
152
self.toplevel.signal_autoconnect(dic)
243
183
# Apply menu state
244
184
self.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
245
self.menuitem_view_show_ignored_files.set_active(self.pref.get_preference('ignored_files', 'bool'))
247
# We're starting local
249
self.remote_branch = None
250
self.remote_path = None
251
self.remote_revision = None
253
186
self.set_path(os.getcwd())
254
187
self._load_right()
256
189
self._just_started = False
258
def set_path(self, path, force_remote=False):
191
def set_path(self, path):
259
193
self.notbranch = False
262
# Forcing remote mode (reading data from inventory)
263
self._show_stock_image(gtk.STOCK_DISCONNECT)
265
br = Branch.open_containing(path)[0]
266
except bzrerrors.NotBranchError:
267
self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
268
self.check_history.set_active(False)
269
self.check_history.set_sensitive(False)
271
except bzrerrors.UnsupportedProtocol:
272
self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
273
self.check_history.set_active(False)
274
self.check_history.set_sensitive(False)
277
self._show_stock_image(gtk.STOCK_CONNECT)
282
self.remote_branch, self.remote_path = Branch.open_containing(path)
284
if self.remote_revision is None:
285
self.remote_revision = self.remote_branch.last_revision()
287
self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
289
if len(self.remote_path) == 0:
290
self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
292
for (name, type) in self.remote_entries:
293
if name == self.remote_path:
294
self.remote_parent = type.file_id
297
if not path.endswith('/'):
300
if self.remote_branch.base == path:
301
self.button_location_up.set_sensitive(False)
303
self.button_location_up.set_sensitive(True)
305
if os.path.isdir(path):
306
self.image_location_error.destroy()
311
self.wt, self.wtpath = WorkingTree.open_containing(path)
312
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
313
self.notbranch = True
315
# If we're in the root, we cannot go up anymore
316
if sys.platform == 'win32':
317
drive, tail = os.path.splitdrive(path)
318
if tail in ('', '/', '\\'):
319
self.button_location_up.set_sensitive(False)
321
self.button_location_up.set_sensitive(True)
324
self.button_location_up.set_sensitive(False)
326
self.button_location_up.set_sensitive(True)
327
elif not os.path.isfile(path):
328
# Doesn't seem to be a file nor a directory, trying to open a
330
self._show_stock_image(gtk.STOCK_DISCONNECT)
332
br = Branch.open_containing(path)[0]
333
except bzrerrors.NotBranchError:
334
self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
335
self.check_history.set_active(False)
336
self.check_history.set_sensitive(False)
338
except bzrerrors.UnsupportedProtocol:
339
self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
340
self.check_history.set_active(False)
341
self.check_history.set_sensitive(False)
344
self._show_stock_image(gtk.STOCK_CONNECT)
349
self.remote_branch, self.remote_path = Branch.open_containing(path)
351
if self.remote_revision is None:
352
self.remote_revision = self.remote_branch.last_revision()
354
self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
356
if len(self.remote_path) == 0:
357
self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
359
for (name, type) in self.remote_entries:
360
if name == self.remote_path:
361
self.remote_parent = type.file_id
364
if not path.endswith('/'):
367
if self.remote_branch.base == path:
368
self.button_location_up.set_sensitive(False)
370
self.button_location_up.set_sensitive(True)
373
self.check_history.set_active(False)
374
self.check_history.set_sensitive(False)
376
self.check_history.set_sensitive(True)
196
self.wt, self.wtpath = WorkingTree.open_containing(self.path)
197
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
198
self.notbranch = True
378
200
self.statusbar.push(self.context_id, path)
379
self.entry_location.set_text(path)
383
202
def get_path(self):
388
if len(self.remote_path) > 0:
389
return self.remote_branch.base + self.remote_path + '/'
391
return self.remote_branch.base
393
205
def on_about_activate(self, widget):
206
from bzrlib.plugins.gtk.dialog import about
396
def on_button_history_browse_clicked(self, widget):
397
""" Browse for revision button handler. """
399
br = self.remote_branch
403
revb = RevisionBrowser(br, self.window)
404
response = revb.run()
405
if response != gtk.RESPONSE_NONE:
408
if response == gtk.RESPONSE_OK:
409
if revb.selected_revno is not None:
410
self.entry_history.set_text(revb.selected_revno)
414
def on_button_location_jump_clicked(self, widget):
415
""" Location Jump button handler. """
416
location = self.entry_location.get_text()
418
if self.set_path(location):
421
def on_button_location_up_clicked(self, widget):
422
""" Location Up button handler. """
425
self.set_path(os.path.split(self.get_path())[0])
429
newpath = delim.join(self.get_path().split(delim)[:-2])
431
self.set_path(newpath)
435
def on_checkbutton_history_toggled(self, widget):
436
""" History Mode toggle handler. """
437
if self.check_history.get_active():
438
# History Mode activated
439
self.entry_history.set_sensitive(True)
440
self.button_history.set_sensitive(True)
442
# History Mode deactivated
443
self.entry_history.set_sensitive(False)
444
self.button_history.set_sensitive(False)
447
def on_entry_history_revno_key_press_event(self, widget, event):
448
""" Key pressed handler for the history entry. """
449
if event.keyval == gtk.gdk.keyval_from_name('Return') or event.keyval == gtk.gdk.keyval_from_name('KP_Enter'):
450
# Return was hit, so we have to load that specific revision
451
# Emulate being remote, so inventory should be used
452
path = self.get_path()
455
self.remote_branch = self.wt.branch
457
revno = int(self.entry_history.get_text())
458
self.remote_revision = self.remote_branch.get_rev_id(revno)
459
if self.set_path(path, True):
462
def on_entry_location_key_press_event(self, widget, event):
463
""" Key pressed handler for the location entry. """
464
if event.keyval == gtk.gdk.keyval_from_name('Return') or event.keyval == gtk.gdk.keyval_from_name('KP_Enter'):
465
# Return was hit, so we have to jump
466
self.on_button_location_jump_clicked(widget)
468
209
def on_menuitem_add_files_activate(self, widget):
469
210
""" Add file(s)... menu handler. """
470
211
from add import OliveAdd
537
263
from bzrlib.plugins.gtk.merge import MergeDialog
539
265
if self.check_for_changes():
540
error_dialog(_i18n('There are local changes in the branch'),
541
_i18n('Please commit or revert the changes before merging.'))
266
error_dialog(_('There are local changes in the branch'),
267
_('Please commit or revert the changes before merging.'))
543
parent_branch_path = self.wt.branch.get_parent()
544
merge = MergeDialog(self.wt, self.wtpath,default_branch_path=parent_branch_path )
269
merge = MergeDialog(self.wt, self.wtpath)
548
273
def on_menuitem_branch_missing_revisions_activate(self, widget):
549
274
""" Branch/Missing revisions menu handler. """
551
from bzrlib.missing import find_unmerged, iter_log_revisions
553
275
local_branch = self.wt.branch
554
parent_branch_path = local_branch.get_parent()
555
if parent_branch_path is None:
556
error_dialog(_i18n('Parent location is unknown'),
557
_i18n('Cannot determine missing revisions if no parent location is known.'))
277
other_branch = local_branch.get_parent()
278
if other_branch is None:
279
error_dialog(_('Parent location is unknown'),
280
_('Cannot determine missing revisions if no parent location is known.'))
560
parent_branch = Branch.open(parent_branch_path)
562
if parent_branch.base == local_branch.base:
563
parent_branch = local_branch
565
local_extra, remote_extra = find_unmerged(local_branch,parent_branch)
567
if local_extra or remote_extra:
569
## def log_revision_one_line_text(log_revision):
570
## """ Generates one line description of log_revison ended with end of line."""
571
## revision = log_revision.rev
572
## txt = "- %s (%s)\n" % (revision.get_summary(), revision.committer, )
573
## txt = txt.replace("<"," ") # Seems < > chars are expected to be xml tags ...
574
## txt = txt.replace(">"," ")
579
dlg_txt += _i18n('%d local extra revision(s). \n') % (len(local_extra),)
580
## NOTE: We do not want such ugly info about missing revisions
581
## Revision Browser should be used there
582
## max_revisions = 10
583
## for log_revision in iter_log_revisions(local_extra, local_branch.repository, verbose=1):
584
## dlg_txt += log_revision_one_line_text(log_revision)
585
## if max_revisions <= 0:
586
## dlg_txt += _i18n("more ... \n")
588
## max_revisions -= 1
591
dlg_txt += _i18n('%d local missing revision(s).\n') % (len(remote_extra),)
592
## max_revisions = 10
593
## for log_revision in iter_log_revisions(remote_extra, parent_branch.repository, verbose=1):
594
## dlg_txt += log_revision_one_line_text(log_revision)
595
## if max_revisions <= 0:
596
## dlg_txt += _i18n("more ... \n")
598
## max_revisions -= 1
600
info_dialog(_i18n('There are missing revisions'),
283
remote_branch = Branch.open(other_branch)
285
if remote_branch.base == local_branch.base:
286
remote_branch = local_branch
288
ret = len(local_branch.missing_revisions(remote_branch))
291
info_dialog(_('There are missing revisions'),
292
_('%d revision(s) missing.') % ret)
603
info_dialog(_i18n('Local branch up to date'),
604
_i18n('There are no missing revisions.'))
294
info_dialog(_('Local branch up to date'),
295
_('There are no missing revisions.'))
607
298
def on_menuitem_branch_pull_activate(self, widget):
845
479
selected=self.get_selected_right(),
847
481
# get the menu items
848
m_open = menu.ui.get_widget('/context_right/open')
849
482
m_add = menu.ui.get_widget('/context_right/add')
850
483
m_remove = menu.ui.get_widget('/context_right/remove')
851
484
m_rename = menu.ui.get_widget('/context_right/rename')
852
485
m_revert = menu.ui.get_widget('/context_right/revert')
853
486
m_commit = menu.ui.get_widget('/context_right/commit')
854
m_annotate = menu.ui.get_widget('/context_right/annotate')
855
487
m_diff = menu.ui.get_widget('/context_right/diff')
856
488
# check if we're in a branch
858
490
from bzrlib.branch import Branch
859
491
Branch.open_containing(self.get_path())
861
m_open.set_sensitive(False)
862
m_add.set_sensitive(False)
863
m_remove.set_sensitive(False)
864
m_rename.set_sensitive(False)
865
m_revert.set_sensitive(False)
866
m_commit.set_sensitive(False)
867
m_annotate.set_sensitive(False)
868
m_diff.set_sensitive(False)
870
m_open.set_sensitive(True)
871
m_add.set_sensitive(True)
872
m_remove.set_sensitive(True)
873
m_rename.set_sensitive(True)
874
m_revert.set_sensitive(True)
875
m_commit.set_sensitive(True)
876
m_annotate.set_sensitive(True)
877
m_diff.set_sensitive(True)
492
m_add.set_sensitive(True)
493
m_remove.set_sensitive(True)
494
m_rename.set_sensitive(True)
495
m_revert.set_sensitive(True)
496
m_commit.set_sensitive(True)
497
m_diff.set_sensitive(True)
878
498
except bzrerrors.NotBranchError:
879
m_open.set_sensitive(True)
880
499
m_add.set_sensitive(False)
881
500
m_remove.set_sensitive(False)
882
501
m_rename.set_sensitive(False)
883
502
m_revert.set_sensitive(False)
884
503
m_commit.set_sensitive(False)
885
m_annotate.set_sensitive(False)
886
504
m_diff.set_sensitive(False)
889
menu.right_context_menu().popup(None, None, None, 0,
892
menu.remote_context_menu().popup(None, None, None, 0,
506
menu.right_context_menu().popup(None, None, None, 0,
895
509
def on_treeview_right_row_activated(self, treeview, path, view_column):
896
510
""" Occurs when somebody double-clicks or enters an item in the
1023
632
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1024
633
if rpathnew == filename:
1025
634
status = 'renamed'
1027
635
for rpath, id, kind in delta.added:
1028
636
if rpath == filename:
1029
637
status = 'added'
1031
638
for rpath, id, kind in delta.removed:
1032
639
if rpath == filename:
1033
640
status = 'removed'
1035
641
for rpath, id, kind, text_modified, meta_modified in delta.modified:
1036
642
if rpath == filename:
1037
643
status = 'modified'
1039
644
for rpath, id, kind in delta.unchanged:
1040
645
if rpath == filename:
1041
646
status = 'unchanged'
1043
647
for rpath, file_class, kind, id, entry in self.wt.list_files():
1044
648
if rpath == filename and file_class == 'I':
1045
649
status = 'ignored'
1047
651
self.wt.unlock()
654
# status = fileops.status(path + os.sep + item)
655
#except errors.PermissionDenied:
1049
658
if status == 'renamed':
1050
st = _i18n('renamed')
1051
660
elif status == 'removed':
1052
st = _i18n('removed')
1053
662
elif status == 'added':
1055
664
elif status == 'modified':
1056
st = _i18n('modified')
1057
666
elif status == 'unchanged':
1058
st = _i18n('unchanged')
1059
668
elif status == 'ignored':
1060
st = _i18n('ignored')
1062
st = _i18n('unknown')
1065
statinfo = os.stat(self.path + os.sep + item)
1071
liststore.append([gtk.STOCK_FILE,
1076
str(statinfo.st_size), # NOTE: if int used there it will fail for large files (size expressed as long int)
1077
self._format_size(statinfo.st_size),
1079
self._format_date(statinfo.st_mtime),
672
liststore.append([gtk.STOCK_FILE, item, st])
1082
674
# Create the columns and add them to the TreeView
1083
675
self.treeview_right.set_model(liststore)
1084
self._tvcolumn_filename = gtk.TreeViewColumn(_i18n('Filename'))
1085
self._tvcolumn_status = gtk.TreeViewColumn(_i18n('Status'))
1086
self._tvcolumn_size = gtk.TreeViewColumn(_i18n('Size'))
1087
self._tvcolumn_mtime = gtk.TreeViewColumn(_i18n('Last modified'))
1088
self.treeview_right.append_column(self._tvcolumn_filename)
1089
self.treeview_right.append_column(self._tvcolumn_status)
1090
self.treeview_right.append_column(self._tvcolumn_size)
1091
self.treeview_right.append_column(self._tvcolumn_mtime)
676
tvcolumn_filename = gtk.TreeViewColumn(_('Filename'))
677
tvcolumn_status = gtk.TreeViewColumn(_('Status'))
678
self.treeview_right.append_column(tvcolumn_filename)
679
self.treeview_right.append_column(tvcolumn_status)
1093
681
# Set up the cells
1094
682
cellpb = gtk.CellRendererPixbuf()
1095
683
cell = gtk.CellRendererText()
1096
self._tvcolumn_filename.pack_start(cellpb, False)
1097
self._tvcolumn_filename.pack_start(cell, True)
1098
self._tvcolumn_filename.set_attributes(cellpb, stock_id=0)
1099
self._tvcolumn_filename.add_attribute(cell, 'text', 2)
1100
self._tvcolumn_status.pack_start(cell, True)
1101
self._tvcolumn_status.add_attribute(cell, 'text', 3)
1102
self._tvcolumn_size.pack_start(cell, True)
1103
self._tvcolumn_size.add_attribute(cell, 'text', 6)
1104
self._tvcolumn_mtime.pack_start(cell, True)
1105
self._tvcolumn_mtime.add_attribute(cell, 'text', 8)
1107
# Set up the properties of the TreeView
1108
self.treeview_right.set_headers_visible(True)
1109
self.treeview_right.set_headers_clickable(True)
1110
self.treeview_right.set_search_column(1)
1111
self._tvcolumn_filename.set_resizable(True)
1112
self._tvcolumn_status.set_resizable(True)
1113
self._tvcolumn_size.set_resizable(True)
1114
self._tvcolumn_mtime.set_resizable(True)
1116
liststore.set_sort_func(13, self._sort_filelist_callback, None)
1117
liststore.set_sort_column_id(13, gtk.SORT_ASCENDING)
1118
self._tvcolumn_filename.set_sort_column_id(13)
1119
self._tvcolumn_status.set_sort_column_id(3)
1120
self._tvcolumn_size.set_sort_column_id(5)
1121
self._tvcolumn_mtime.set_sort_column_id(7)
684
tvcolumn_filename.pack_start(cellpb, False)
685
tvcolumn_filename.pack_start(cell, True)
686
tvcolumn_filename.set_attributes(cellpb, stock_id=0)
687
tvcolumn_filename.add_attribute(cell, 'text', 1)
688
tvcolumn_status.pack_start(cell, True)
689
tvcolumn_status.add_attribute(cell, 'text', 2)
1123
691
# Set sensitivity
1124
692
self.set_sensitivity()
1126
def get_selected_fileid(self):
1127
""" Get the file_id of the selected file. """
1128
treeselection = self.treeview_right.get_selection()
1129
(model, iter) = treeselection.get_selected()
1134
return model.get_value(iter, 9)
1136
694
def get_selected_right(self):
1137
695
""" Get the selected filename. """
1138
696
treeselection = self.treeview_right.get_selection()
1164
722
def set_sensitivity(self):
1165
723
""" Set menu and toolbar sensitivity. """
1168
self.menuitem_branch_init.set_sensitive(self.notbranch)
1169
self.menuitem_branch_get.set_sensitive(self.notbranch)
1170
self.menuitem_branch_checkout.set_sensitive(self.notbranch)
1171
self.menuitem_branch_pull.set_sensitive(not self.notbranch)
1172
self.menuitem_branch_push.set_sensitive(not self.notbranch)
1173
self.menuitem_branch_update.set_sensitive(not self.notbranch)
1174
self.menuitem_branch_revert.set_sensitive(not self.notbranch)
1175
self.menuitem_branch_merge.set_sensitive(not self.notbranch)
1176
self.menuitem_branch_commit.set_sensitive(not self.notbranch)
1177
self.menuitem_branch_tags.set_sensitive(not self.notbranch)
1178
self.menuitem_branch_status.set_sensitive(not self.notbranch)
1179
self.menuitem_branch_missing.set_sensitive(not self.notbranch)
1180
self.menuitem_branch_conflicts.set_sensitive(not self.notbranch)
1181
self.menuitem_stats.set_sensitive(not self.notbranch)
1182
self.menuitem_stats_diff.set_sensitive(not self.notbranch)
1183
self.menuitem_add_files.set_sensitive(not self.notbranch)
1184
self.menuitem_remove_files.set_sensitive(not self.notbranch)
1185
self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
1186
self.menuitem_file_rename.set_sensitive(not self.notbranch)
1187
self.menuitem_file_move.set_sensitive(not self.notbranch)
1188
self.menuitem_file_annotate.set_sensitive(not self.notbranch)
1189
#self.menutoolbutton_diff.set_sensitive(True)
1190
self.toolbutton_diff.set_sensitive(not self.notbranch)
1191
self.toolbutton_log.set_sensitive(not self.notbranch)
1192
self.toolbutton_commit.set_sensitive(not self.notbranch)
1193
self.toolbutton_pull.set_sensitive(not self.notbranch)
1194
self.toolbutton_push.set_sensitive(not self.notbranch)
1195
self.toolbutton_update.set_sensitive(not self.notbranch)
1198
self.menuitem_branch_init.set_sensitive(False)
1199
self.menuitem_branch_get.set_sensitive(True)
1200
self.menuitem_branch_checkout.set_sensitive(True)
1201
self.menuitem_branch_pull.set_sensitive(False)
1202
self.menuitem_branch_push.set_sensitive(False)
1203
self.menuitem_branch_update.set_sensitive(False)
1204
self.menuitem_branch_revert.set_sensitive(False)
1205
self.menuitem_branch_merge.set_sensitive(False)
1206
self.menuitem_branch_commit.set_sensitive(False)
1207
self.menuitem_branch_tags.set_sensitive(True)
1208
self.menuitem_branch_status.set_sensitive(False)
1209
self.menuitem_branch_missing.set_sensitive(False)
1210
self.menuitem_branch_conflicts.set_sensitive(False)
1211
self.menuitem_stats.set_sensitive(True)
1212
self.menuitem_stats_diff.set_sensitive(False)
1213
self.menuitem_add_files.set_sensitive(False)
1214
self.menuitem_remove_files.set_sensitive(False)
1215
self.menuitem_file_make_directory.set_sensitive(False)
1216
self.menuitem_file_rename.set_sensitive(False)
1217
self.menuitem_file_move.set_sensitive(False)
1218
self.menuitem_file_annotate.set_sensitive(False)
1219
#self.menutoolbutton_diff.set_sensitive(True)
1220
self.toolbutton_diff.set_sensitive(False)
1221
self.toolbutton_log.set_sensitive(True)
1222
self.toolbutton_commit.set_sensitive(False)
1223
self.toolbutton_pull.set_sensitive(False)
1224
self.toolbutton_push.set_sensitive(False)
1225
self.toolbutton_update.set_sensitive(False)
724
self.menuitem_branch_init.set_sensitive(self.notbranch)
725
self.menuitem_branch_get.set_sensitive(self.notbranch)
726
self.menuitem_branch_checkout.set_sensitive(self.notbranch)
727
self.menuitem_branch_pull.set_sensitive(not self.notbranch)
728
self.menuitem_branch_push.set_sensitive(not self.notbranch)
729
self.menuitem_branch_revert.set_sensitive(not self.notbranch)
730
self.menuitem_branch_merge.set_sensitive(not self.notbranch)
731
self.menuitem_branch_commit.set_sensitive(not self.notbranch)
732
self.menuitem_branch_status.set_sensitive(not self.notbranch)
733
self.menuitem_branch_missing.set_sensitive(not self.notbranch)
734
self.menuitem_branch_conflicts.set_sensitive(not self.notbranch)
735
self.menuitem_stats.set_sensitive(not self.notbranch)
736
self.menuitem_add_files.set_sensitive(not self.notbranch)
737
self.menuitem_remove_files.set_sensitive(not self.notbranch)
738
self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
739
self.menuitem_file_rename.set_sensitive(not self.notbranch)
740
self.menuitem_file_move.set_sensitive(not self.notbranch)
741
self.menuitem_file_annotate.set_sensitive(not self.notbranch)
742
#self.menutoolbutton_diff.set_sensitive(True)
743
self.toolbutton_diff.set_sensitive(not self.notbranch)
744
self.toolbutton_log.set_sensitive(not self.notbranch)
745
self.toolbutton_commit.set_sensitive(not self.notbranch)
746
self.toolbutton_pull.set_sensitive(not self.notbranch)
747
self.toolbutton_push.set_sensitive(not self.notbranch)
1227
749
def refresh_left(self):
1228
750
""" Refresh the bookmark list. """
1252
774
def refresh_right(self, path=None):
1253
775
""" Refresh the file list. """
1256
from bzrlib.workingtree import WorkingTree
1259
path = self.get_path()
1261
# A workaround for double-clicking Bookmarks
1262
if not os.path.exists(path):
1265
# Get ListStore and clear it
1266
liststore = self.treeview_right.get_model()
1269
# Show Status column
1270
self._tvcolumn_status.set_visible(True)
1275
# Fill the appropriate lists
1276
dotted_files = self.pref.get_preference('dotted_files', 'bool')
1277
ignored_files = self.pref.get_preference('ignored_files', 'bool')
1279
for item in os.listdir(path):
1280
if not dotted_files and item[0] == '.':
1282
if os.path.isdir(path + os.sep + item):
1287
# Try to open the working tree
1290
tree1 = WorkingTree.open_containing(path)[0]
1291
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
776
from bzrlib.workingtree import WorkingTree
779
path = self.get_path()
781
# A workaround for double-clicking Bookmarks
782
if not os.path.exists(path):
785
# Get ListStore and clear it
786
liststore = self.treeview_right.get_model()
792
# Fill the appropriate lists
793
dotted_files = self.pref.get_preference('dotted_files', 'bool')
794
for item in os.listdir(path):
795
if not dotted_files and item[0] == '.':
797
if os.path.isdir(path + os.sep + item):
806
# add updir link to dirs
807
self._add_updir_to_dirlist(dirs, path)
809
# Try to open the working tree
812
tree1 = WorkingTree.open_containing(path)[0]
813
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
817
branch = tree1.branch
818
tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
820
delta = tree1.changes_from(tree2, want_unchanged=True)
822
# Add'em to the ListStore
824
liststore.append([gtk.STOCK_DIRECTORY, item, ''])
1294
827
if not notbranch:
1295
branch = tree1.branch
1296
tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
1298
delta = tree1.changes_from(tree2, want_unchanged=True)
828
filename = tree1.relpath(path + os.sep + item)
1300
# Add'em to the ListStore
1303
statinfo = os.stat(self.path + os.sep + item)
1309
liststore.append([gtk.STOCK_DIRECTORY,
1317
self._format_date(statinfo.st_mtime),
1323
filename = tree1.relpath(path + os.sep + item)
1328
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1329
if rpathnew == filename:
1332
for rpath, id, kind in delta.added:
1333
if rpath == filename:
1336
for rpath, id, kind in delta.removed:
1337
if rpath == filename:
1340
for rpath, id, kind, text_modified, meta_modified in delta.modified:
1341
if rpath == filename:
1344
for rpath, id, kind in delta.unchanged:
1345
if rpath == filename:
1346
status = 'unchanged'
1348
for rpath, file_class, kind, id, entry in self.wt.list_files():
1349
if rpath == filename and file_class == 'I':
1354
if status == 'renamed':
1355
st = _i18n('renamed')
1356
elif status == 'removed':
1357
st = _i18n('removed')
1358
elif status == 'added':
1360
elif status == 'modified':
1361
st = _i18n('modified')
1362
elif status == 'unchanged':
1363
st = _i18n('unchanged')
1364
elif status == 'ignored':
1365
st = _i18n('ignored')
1366
if not ignored_files:
1369
st = _i18n('unknown')
1372
statinfo = os.stat(self.path + os.sep + item)
1378
liststore.append([gtk.STOCK_FILE,
1383
str(statinfo.st_size),
1384
self._format_size(statinfo.st_size),
1386
self._format_date(statinfo.st_mtime),
1391
# Get ListStore and clear it
1392
liststore = self.treeview_right.get_model()
1395
# Hide Status column
1396
self._tvcolumn_status.set_visible(False)
1401
self._show_stock_image(gtk.STOCK_REFRESH)
1403
for (name, type) in self.remote_entries:
1404
if type.kind == 'directory':
1406
elif type.kind == 'file':
1410
""" Cache based on revision history. """
1411
def __init__(self, history):
1412
self._history = history
1414
def _lookup_revision(self, revid):
1415
for r in self._history:
1416
if r.revision_id == revid:
1418
rev = repo.get_revision(revid)
1419
self._history.append(rev)
1422
repo = self.remote_branch.repository
1424
revhistory = self.remote_branch.revision_history()
1426
revs = repo.get_revisions(revhistory)
1427
cache = HistoryCache(revs)
1428
except bzrerrors.InvalidHttpResponse:
1429
# Fallback to dummy algorithm, because of LP: #115209
1430
cache = HistoryCache([])
1433
if item.parent_id == self.remote_parent:
1434
rev = cache._lookup_revision(item.revision)
1435
liststore.append([ gtk.STOCK_DIRECTORY,
1443
self._format_date(rev.timestamp),
1446
while gtk.events_pending():
1447
gtk.main_iteration()
1450
if item.parent_id == self.remote_parent:
1451
rev = cache._lookup_revision(item.revision)
1452
liststore.append([ gtk.STOCK_FILE,
1457
str(item.text_size),
1458
self._format_size(item.text_size),
1460
self._format_date(rev.timestamp),
1463
while gtk.events_pending():
1464
gtk.main_iteration()
1466
self.image_location_error.destroy()
1468
# Columns should auto-size
1469
self.treeview_right.columns_autosize()
833
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
834
if rpathnew == filename:
836
for rpath, id, kind in delta.added:
837
if rpath == filename:
839
for rpath, id, kind in delta.removed:
840
if rpath == filename:
842
for rpath, id, kind, text_modified, meta_modified in delta.modified:
843
if rpath == filename:
845
for rpath, id, kind in delta.unchanged:
846
if rpath == filename:
848
for rpath, file_class, kind, id, entry in self.wt.list_files():
849
if rpath == filename and file_class == 'I':
855
# status = fileops.status(path + os.sep + item)
856
#except errors.PermissionDenied:
859
if status == 'renamed':
861
elif status == 'removed':
863
elif status == 'added':
865
elif status == 'modified':
867
elif status == 'unchanged':
869
elif status == 'ignored':
873
liststore.append([gtk.STOCK_FILE, item, st])
875
# Add the ListStore to the TreeView
876
self.treeview_right.set_model(liststore)
1471
878
# Set sensitivity
1472
879
self.set_sensitivity()
1521
def _sort_filelist_callback(self, model, iter1, iter2, data):
1522
""" The sort callback for the file list, return values:
1527
name1 = model.get_value(iter1, 2)
1528
name2 = model.get_value(iter2, 2)
1530
if model.get_value(iter1, 1):
1531
# item1 is a directory
1532
if not model.get_value(iter2, 1):
1536
# both of them are directories, we compare their names
1539
elif name1 == name2:
1544
# item1 is not a directory
1545
if model.get_value(iter2, 1):
1549
# both of them are files, compare them
1552
elif name1 == name2:
1557
def _format_size(self, size):
1558
""" Format size to a human readable format. """
1560
return "%d[B]" % (size,)
1561
size = size / 1000.0
1563
for metric in ["kB","MB","GB","TB"]:
1566
size = size / 1000.0
1567
return "%.1f[%s]" % (size,metric)
1569
def _format_date(self, timestamp):
1570
""" Format the time (given in secs) to a human readable format. """
1571
return time.ctime(timestamp)
1573
def _is_remote_dir(self, location):
1574
""" Determine whether the given location is a directory or not. """
1576
# We're in local mode
1579
branch, path = Branch.open_containing(location)
1580
for (name, type) in self.remote_entries:
1581
if name == path and type.kind == 'directory':
1584
# Either it's not a directory or not in the inventory
1587
def _show_stock_image(self, stock_id):
1588
""" Show a stock image next to the location entry. """
1589
self.image_location_error.destroy()
1590
self.image_location_error = gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_BUTTON)
1591
self.hbox_location.pack_start(self.image_location_error, False, False, 0)
1592
if sys.platform == 'win32':
1593
self.hbox_location.reorder_child(self.image_location_error, 2)
1595
self.hbox_location.reorder_child(self.image_location_error, 1)
1596
self.image_location_error.show()
1597
while gtk.events_pending():
1598
gtk.main_iteration()
1600
928
import ConfigParser