106
74
# Get some important menu items
107
75
self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
108
76
self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
109
self.menuitem_file_bookmark = self.toplevel.get_widget('menuitem_file_bookmark')
110
77
self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
111
78
self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
112
79
self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
113
80
self.menuitem_file_annotate = self.toplevel.get_widget('menuitem_file_annotate')
114
81
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
82
self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
117
83
self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
118
84
self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
119
85
self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
120
86
self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
121
87
self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
122
self.menuitem_branch_update = self.toplevel.get_widget('menuitem_branch_update')
123
88
self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
124
89
self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
125
90
self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
126
self.menuitem_branch_tags = self.toplevel.get_widget('menuitem_branch_tags')
127
91
self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
128
92
self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
129
93
self.menuitem_branch_conflicts = self.toplevel.get_widget('menuitem_branch_conflicts')
194
142
"on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
195
143
"on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
196
144
"on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
197
"on_toolbutton_update_clicked": self.on_menuitem_branch_update_activate,
198
145
"on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
199
146
"on_treeview_right_row_activated": self.on_treeview_right_row_activated,
200
147
"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
148
"on_treeview_left_row_activated": self.on_treeview_left_row_activated }
211
150
# Connect the signals to the handlers
212
151
self.toplevel.signal_autoconnect(dic)
243
182
# Apply menu state
244
183
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
185
self.set_path(os.getcwd())
254
186
self._load_right()
256
188
self._just_started = False
258
def set_path(self, path, force_remote=False):
190
def set_path(self, path):
259
192
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)
195
self.wt, self.wtpath = WorkingTree.open_containing(self.path)
196
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
197
self.notbranch = True
378
199
self.statusbar.push(self.context_id, path)
379
self.entry_location.set_text(path)
383
201
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
204
def on_about_activate(self, widget):
205
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
208
def on_menuitem_add_files_activate(self, widget):
469
209
""" Add file(s)... menu handler. """
470
210
from add import OliveAdd
537
262
from bzrlib.plugins.gtk.merge import MergeDialog
539
264
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.'))
265
error_dialog(_('There are local changes in the branch'),
266
_('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 )
268
merge = MergeDialog(self.wt, self.wtpath)
548
272
def on_menuitem_branch_missing_revisions_activate(self, widget):
549
273
""" Branch/Missing revisions menu handler. """
551
from bzrlib.missing import find_unmerged, iter_log_revisions
553
274
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.'))
276
other_branch = local_branch.get_parent()
277
if other_branch is None:
278
error_dialog(_('Parent location is unknown'),
279
_('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'),
282
remote_branch = Branch.open(other_branch)
284
if remote_branch.base == local_branch.base:
285
remote_branch = local_branch
287
ret = len(local_branch.missing_revisions(remote_branch))
290
info_dialog(_('There are missing revisions'),
291
_('%d revision(s) missing.') % ret)
603
info_dialog(_i18n('Local branch up to date'),
604
_i18n('There are no missing revisions.'))
293
info_dialog(_('Local branch up to date'),
294
_('There are no missing revisions.'))
607
297
def on_menuitem_branch_pull_activate(self, widget):
646
330
""" Branch/Revert all changes menu handler. """
647
331
ret = self.wt.revert([])
649
warning_dialog(_i18n('Conflicts detected'),
650
_i18n('Please have a look at the working tree before continuing.'))
333
warning_dialog(_('Conflicts detected'),
334
_('Please have a look at the working tree before continuing.'))
652
info_dialog(_i18n('Revert successful'),
653
_i18n('All files reverted to last revision.'))
336
info_dialog(_('Revert successful'),
337
_('All files reverted to last revision.'))
654
338
self.refresh_right()
656
340
def on_menuitem_branch_status_activate(self, widget):
657
341
""" Branch/Status... menu handler. """
658
342
from bzrlib.plugins.gtk.status import StatusDialog
659
343
status = StatusDialog(self.wt, self.wtpath)
660
response = status.run()
661
if response != gtk.RESPONSE_NONE:
664
347
def on_menuitem_branch_initialize_activate(self, widget):
665
348
""" Initialize current directory. """
666
init = InitDialog(self.path, self.window)
667
response = init.run()
668
if response != gtk.RESPONSE_NONE:
671
if response == gtk.RESPONSE_OK:
676
def on_menuitem_branch_tags_activate(self, widget):
677
""" Branch/Tags... menu handler. """
678
from bzrlib.plugins.gtk.tags import TagsWindow
680
window = TagsWindow(self.wt.branch, self.window)
349
import bzrlib.bzrdir as bzrdir
351
if not os.path.exists(self.path):
355
existing_bzrdir = bzrdir.BzrDir.open(self.path)
356
except bzrerrors.NotBranchError:
357
bzrdir.BzrDir.create_branch_convenience(self.path)
682
window = TagsWindow(self.remote_branch, self.window)
359
if existing_bzrdir.has_branch():
360
if existing_bzrdir.has_workingtree():
361
raise bzrerrors.AlreadyBranchError(self.path)
363
raise bzrerrors.BranchExistsWithoutWorkingTree(self.path)
365
existing_bzrdir.create_branch()
366
existing_bzrdir.create_workingtree()
367
info_dialog(_('Initialize successful'),
368
_('Directory successfully initialized.'))
685
371
def on_menuitem_file_annotate_activate(self, widget):
686
372
""" File/Annotate... menu handler. """
687
373
if self.get_selected_right() is None:
688
error_dialog(_i18n('No file was selected'),
689
_i18n('Please select a file from the list.'))
374
error_dialog(_('No file was selected'),
375
_('Please select a file from the list.'))
692
378
branch = self.wt.branch
693
379
file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
695
window = GAnnotateWindow(all=False, plain=False, parent=self.window)
381
window = GAnnotateWindow(all=False, plain=False)
696
382
window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
697
383
config = GAnnotateConfig(window)
845
491
selected=self.get_selected_right(),
847
493
# get the menu items
848
m_open = menu.ui.get_widget('/context_right/open')
849
494
m_add = menu.ui.get_widget('/context_right/add')
850
495
m_remove = menu.ui.get_widget('/context_right/remove')
851
496
m_rename = menu.ui.get_widget('/context_right/rename')
852
497
m_revert = menu.ui.get_widget('/context_right/revert')
853
498
m_commit = menu.ui.get_widget('/context_right/commit')
854
m_annotate = menu.ui.get_widget('/context_right/annotate')
855
499
m_diff = menu.ui.get_widget('/context_right/diff')
856
500
# check if we're in a branch
858
502
from bzrlib.branch import Branch
859
503
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)
504
m_add.set_sensitive(True)
505
m_remove.set_sensitive(True)
506
m_rename.set_sensitive(True)
507
m_revert.set_sensitive(True)
508
m_commit.set_sensitive(True)
509
m_diff.set_sensitive(True)
878
510
except bzrerrors.NotBranchError:
879
m_open.set_sensitive(True)
880
511
m_add.set_sensitive(False)
881
512
m_remove.set_sensitive(False)
882
513
m_rename.set_sensitive(False)
883
514
m_revert.set_sensitive(False)
884
515
m_commit.set_sensitive(False)
885
m_annotate.set_sensitive(False)
886
516
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,
518
menu.right_context_menu().popup(None, None, None, 0,
895
521
def on_treeview_right_row_activated(self, treeview, path, view_column):
896
522
""" Occurs when somebody double-clicks or enters an item in the
993
631
delta = self.wt.changes_from(tree2, want_unchanged=True)
995
633
# Add'em to the ListStore
998
statinfo = os.stat(self.path + os.sep + item)
1004
liststore.append([ gtk.STOCK_DIRECTORY,
1012
self._format_date(statinfo.st_mtime),
635
liststore.append([gtk.STOCK_DIRECTORY, item, ''])
1014
636
for item in files:
1015
637
status = 'unknown'
1017
638
if not self.notbranch:
1018
639
filename = self.wt.relpath(self.path + os.sep + item)
1023
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1024
if rpathnew == filename:
1027
for rpath, id, kind in delta.added:
1028
if rpath == filename:
1031
for rpath, id, kind in delta.removed:
1032
if rpath == filename:
1035
for rpath, id, kind, text_modified, meta_modified in delta.modified:
1036
if rpath == filename:
1039
for rpath, id, kind in delta.unchanged:
1040
if rpath == filename:
1041
status = 'unchanged'
1043
for rpath, file_class, kind, id, entry in self.wt.list_files():
1044
if rpath == filename and file_class == 'I':
641
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
642
if rpathnew == filename:
644
for rpath, id, kind in delta.added:
645
if rpath == filename:
647
for rpath, id, kind in delta.removed:
648
if rpath == filename:
650
for rpath, id, kind, text_modified, meta_modified in delta.modified:
651
if rpath == filename:
653
for rpath, id, kind in delta.unchanged:
654
if rpath == filename:
656
for rpath, file_class, kind, id, entry in self.wt.list_files():
657
if rpath == filename and file_class == 'I':
661
# status = fileops.status(path + os.sep + item)
662
#except errors.PermissionDenied:
1049
665
if status == 'renamed':
1050
st = _i18n('renamed')
1051
667
elif status == 'removed':
1052
st = _i18n('removed')
1053
669
elif status == 'added':
1055
671
elif status == 'modified':
1056
st = _i18n('modified')
1057
673
elif status == 'unchanged':
1058
st = _i18n('unchanged')
1059
675
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),
679
liststore.append([gtk.STOCK_FILE, item, st])
1082
681
# Create the columns and add them to the TreeView
1083
682
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)
683
tvcolumn_filename = gtk.TreeViewColumn(_('Filename'))
684
tvcolumn_status = gtk.TreeViewColumn(_('Status'))
685
self.treeview_right.append_column(tvcolumn_filename)
686
self.treeview_right.append_column(tvcolumn_status)
1093
688
# Set up the cells
1094
689
cellpb = gtk.CellRendererPixbuf()
1095
690
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)
691
tvcolumn_filename.pack_start(cellpb, False)
692
tvcolumn_filename.pack_start(cell, True)
693
tvcolumn_filename.set_attributes(cellpb, stock_id=0)
694
tvcolumn_filename.add_attribute(cell, 'text', 1)
695
tvcolumn_status.pack_start(cell, True)
696
tvcolumn_status.add_attribute(cell, 'text', 2)
1123
698
# Set sensitivity
1124
699
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
701
def get_selected_right(self):
1137
702
""" Get the selected filename. """
1138
703
treeselection = self.treeview_right.get_selection()
1164
729
def set_sensitivity(self):
1165
730
""" 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)
731
self.menuitem_branch_init.set_sensitive(self.notbranch)
732
self.menuitem_branch_get.set_sensitive(self.notbranch)
733
self.menuitem_branch_checkout.set_sensitive(self.notbranch)
734
self.menuitem_branch_pull.set_sensitive(not self.notbranch)
735
self.menuitem_branch_push.set_sensitive(not self.notbranch)
736
self.menuitem_branch_revert.set_sensitive(not self.notbranch)
737
self.menuitem_branch_merge.set_sensitive(not self.notbranch)
738
self.menuitem_branch_commit.set_sensitive(not self.notbranch)
739
self.menuitem_branch_status.set_sensitive(not self.notbranch)
740
self.menuitem_branch_missing.set_sensitive(not self.notbranch)
741
self.menuitem_branch_conflicts.set_sensitive(not self.notbranch)
742
self.menuitem_stats.set_sensitive(not self.notbranch)
743
self.menuitem_add_files.set_sensitive(not self.notbranch)
744
self.menuitem_remove_files.set_sensitive(not self.notbranch)
745
self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
746
self.menuitem_file_rename.set_sensitive(not self.notbranch)
747
self.menuitem_file_move.set_sensitive(not self.notbranch)
748
self.menuitem_file_annotate.set_sensitive(not self.notbranch)
749
#self.menutoolbutton_diff.set_sensitive(True)
750
self.toolbutton_diff.set_sensitive(not self.notbranch)
751
self.toolbutton_log.set_sensitive(not self.notbranch)
752
self.toolbutton_commit.set_sensitive(not self.notbranch)
753
self.toolbutton_pull.set_sensitive(not self.notbranch)
754
self.toolbutton_push.set_sensitive(not self.notbranch)
1227
756
def refresh_left(self):
1228
757
""" Refresh the bookmark list. """
1252
781
def refresh_right(self, path=None):
1253
782
""" 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):
783
from bzrlib.workingtree import WorkingTree
786
path = self.get_path()
788
# A workaround for double-clicking Bookmarks
789
if not os.path.exists(path):
792
# Get ListStore and clear it
793
liststore = self.treeview_right.get_model()
799
# Fill the appropriate lists
800
dotted_files = self.pref.get_preference('dotted_files', 'bool')
801
for item in os.listdir(path):
802
if not dotted_files and item[0] == '.':
804
if os.path.isdir(path + os.sep + item):
813
# add updir link to dirs
814
self._add_updir_to_dirlist(dirs, path)
816
# Try to open the working tree
819
tree1 = WorkingTree.open_containing(path)[0]
820
except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
824
branch = tree1.branch
825
tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
827
delta = tree1.changes_from(tree2, want_unchanged=True)
829
# Add'em to the ListStore
831
liststore.append([gtk.STOCK_DIRECTORY, item, ''])
1294
834
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)
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()
835
filename = tree1.relpath(path + os.sep + item)
837
for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
838
if rpathnew == filename:
840
for rpath, id, kind in delta.added:
841
if rpath == filename:
843
for rpath, id, kind in delta.removed:
844
if rpath == filename:
846
for rpath, id, kind, text_modified, meta_modified in delta.modified:
847
if rpath == filename:
849
for rpath, id, kind in delta.unchanged:
850
if rpath == filename:
852
for rpath, file_class, kind, id, entry in self.wt.list_files():
853
if rpath == filename and file_class == 'I':
857
# status = fileops.status(path + os.sep + item)
858
#except errors.PermissionDenied:
861
if status == 'renamed':
863
elif status == 'removed':
865
elif status == 'added':
867
elif status == 'modified':
869
elif status == 'unchanged':
871
elif status == 'ignored':
875
liststore.append([gtk.STOCK_FILE, item, st])
877
# Add the ListStore to the TreeView
878
self.treeview_right.set_model(liststore)
1471
880
# Set sensitivity
1472
881
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
930
import ConfigParser
1602
932
class Preferences:
1603
933
""" A class which handles Olive's preferences. """
1604
def __init__(self, path=None):
1605
935
""" Initialize the Preferences class. """
1606
936
# Some default options
1607
937
self.defaults = { 'strict_commit' : False,
1608
938
'dotted_files' : False,
1609
'ignored_files' : True,
1610
939
'window_width' : 700,
1611
940
'window_height' : 400,
1612
941
'window_x' : 40,