/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to olive/__init__.py

  • Committer: Szilveszter Farkas (Phanatic)
  • Date: 2007-05-18 11:09:31 UTC
  • mto: This revision was merged to the branch mainline in revision 201.
  • Revision ID: szilveszter.farkas@gmail.com-20070518110931-eo97taeu5l90hqto
Make the Revision Browser feel faster.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 #!/usr/bin/python
2
 
 
3
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
4
2
#
5
3
# This program is free software; you can redistribute it and/or modify
41
39
from bzrlib.ui import ui_factory
42
40
from bzrlib.workingtree import WorkingTree
43
41
 
44
 
from bzrlib.plugins.gtk import _i18n
45
42
from bzrlib.plugins.gtk.dialog import error_dialog, info_dialog, warning_dialog
46
43
from bzrlib.plugins.gtk.errors import show_bzr_error
47
44
from guifiles import GLADEFILENAME
56
53
from bzrlib.plugins.gtk.conflicts import ConflictsDialog
57
54
from bzrlib.plugins.gtk.initialize import InitDialog
58
55
from bzrlib.plugins.gtk.push import PushDialog
59
 
from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
60
 
 
61
 
def about():
62
 
    """ Display the AboutDialog. """
63
 
    from bzrlib.plugins.gtk import __version__
64
 
    from bzrlib.plugins.gtk.olive.guifiles import GLADEFILENAME
65
 
 
66
 
    # Load AboutDialog description
67
 
    dglade = gtk.glade.XML(GLADEFILENAME, 'aboutdialog')
68
 
    dialog = dglade.get_widget('aboutdialog')
69
 
 
70
 
    # Set version
71
 
    dialog.set_version(__version__)
72
 
    dialog.set_authors([ _i18n("Lead Developer:"),
73
 
                         "Szilveszter Farkas <szilveszter.farkas@gmail.com>",
74
 
                         _i18n("Contributors:"),
75
 
                         "Jelmer Vernooij <jelmer@samba.org>",
76
 
                         "Mateusz Korniak <mateusz.korniak@ant.gliwice.pl>",
77
 
                         "Gary van der Merwe <garyvdm@gmail.com>" ])
78
 
    dialog.set_artists([ "Simon Pascal Klein <klepas@klepas.org>",
79
 
                         "Jakub Steiner <jimmac@novell.com>" ])
80
 
 
81
 
    dialog.run()
82
 
    # Destroy the dialog
83
 
    dialog.destroy()
84
56
 
85
57
class OliveGtk:
86
58
    """ The main Olive GTK frontend class. This is called when launching the
106
78
        # Get some important menu items
107
79
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
108
80
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
109
 
        self.menuitem_file_bookmark = self.toplevel.get_widget('menuitem_file_bookmark')
110
81
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
111
82
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
112
83
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
113
84
        self.menuitem_file_annotate = self.toplevel.get_widget('menuitem_file_annotate')
114
85
        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
86
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
117
87
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
118
88
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
119
89
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
120
90
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
121
91
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
122
 
        self.menuitem_branch_update = self.toplevel.get_widget('menuitem_branch_update')
123
92
        self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
124
93
        self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
125
94
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
137
106
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
138
107
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
139
108
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
140
 
        self.toolbutton_update = self.toplevel.get_widget('toolbutton_update')
141
109
        # Get the drive selector
142
110
        self.combobox_drive = gtk.combo_box_new_text()
143
111
        self.combobox_drive.connect("changed", self._refresh_drives)
149
117
        self.entry_location = self.toplevel.get_widget('entry_location')
150
118
        self.image_location_error = self.toplevel.get_widget('image_location_error')
151
119
        
152
 
        # Get the History widgets
153
 
        self.check_history = self.toplevel.get_widget('checkbutton_history')
154
 
        self.entry_history = self.toplevel.get_widget('entry_history_revno')
155
 
        self.button_history = self.toplevel.get_widget('button_history_browse')
156
 
        
157
120
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
158
121
        
159
122
        # Dictionary for signal_autoconnect
163
126
                "on_about_activate": self.on_about_activate,
164
127
                "on_menuitem_add_files_activate": self.on_menuitem_add_files_activate,
165
128
                "on_menuitem_remove_file_activate": self.on_menuitem_remove_file_activate,
166
 
                "on_menuitem_file_bookmark_activate": self.on_menuitem_file_bookmark_activate,
167
129
                "on_menuitem_file_make_directory_activate": self.on_menuitem_file_make_directory_activate,
168
130
                "on_menuitem_file_move_activate": self.on_menuitem_file_move_activate,
169
131
                "on_menuitem_file_rename_activate": self.on_menuitem_file_rename_activate,
170
132
                "on_menuitem_file_annotate_activate": self.on_menuitem_file_annotate_activate,
171
133
                "on_menuitem_view_show_hidden_files_activate": self.on_menuitem_view_show_hidden_files_activate,
172
 
                "on_menuitem_view_show_ignored_files_activate": self.on_menuitem_view_show_ignored_files_activate,
173
134
                "on_menuitem_view_refresh_activate": self.on_menuitem_view_refresh_activate,
174
135
                "on_menuitem_branch_initialize_activate": self.on_menuitem_branch_initialize_activate,
175
136
                "on_menuitem_branch_get_activate": self.on_menuitem_branch_get_activate,
179
140
                "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
180
141
                "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
181
142
                "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
182
 
                "on_menuitem_branch_update_activate": self.on_menuitem_branch_update_activate,                
183
143
                "on_menuitem_branch_tags_activate": self.on_menuitem_branch_tags_activate,
184
144
                "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
185
145
                "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
194
154
                "on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
195
155
                "on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
196
156
                "on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
197
 
                "on_toolbutton_update_clicked": self.on_menuitem_branch_update_activate,
198
157
                "on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
199
158
                "on_treeview_right_row_activated": self.on_treeview_right_row_activated,
200
159
                "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
160
                "on_treeview_left_row_activated": self.on_treeview_left_row_activated,
203
161
                "on_button_location_up_clicked": self.on_button_location_up_clicked,
204
162
                "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
 
163
                "on_entry_location_key_press_event": self.on_entry_location_key_press_event
209
164
            }
210
165
        
211
166
        # Connect the signals to the handlers
242
197
 
243
198
        # Apply menu state
244
199
        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'))
246
200
 
247
201
        # We're starting local
248
202
        self.remote = False
249
203
        self.remote_branch = None
250
204
        self.remote_path = None
251
 
        self.remote_revision = None
252
205
        
253
206
        self.set_path(os.getcwd())
254
207
        self._load_right()
255
208
        
256
209
        self._just_started = False
257
210
 
258
 
    def set_path(self, path, force_remote=False):
 
211
    def set_path(self, path):
259
212
        self.notbranch = False
260
213
        
261
 
        if force_remote:
262
 
            # Forcing remote mode (reading data from inventory)
 
214
        if os.path.isdir(path):
 
215
            self.image_location_error.destroy()
 
216
            self.remote = False
 
217
            
 
218
            # We're local
 
219
            try:
 
220
                self.wt, self.wtpath = WorkingTree.open_containing(path)
 
221
            except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
 
222
                self.notbranch = True
 
223
            
 
224
            # If we're in the root, we cannot go up anymore
 
225
            if sys.platform == 'win32':
 
226
                drive, tail = os.path.splitdrive(path)
 
227
                if tail in ('', '/', '\\'):
 
228
                    self.button_location_up.set_sensitive(False)
 
229
                else:
 
230
                    self.button_location_up.set_sensitive(True)
 
231
            else:
 
232
                if self.path == '/':
 
233
                    self.button_location_up.set_sensitive(False)
 
234
                else:
 
235
                    self.button_location_up.set_sensitive(True)
 
236
        elif not os.path.isfile(path):
 
237
            # Doesn't seem to be a file nor a directory, trying to open a
 
238
            # remote location
263
239
            self._show_stock_image(gtk.STOCK_DISCONNECT)
264
240
            try:
265
241
                br = Branch.open_containing(path)[0]
266
242
            except bzrerrors.NotBranchError:
267
243
                self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
268
 
                self.check_history.set_active(False)
269
 
                self.check_history.set_sensitive(False)
270
244
                return False
271
245
            except bzrerrors.UnsupportedProtocol:
272
246
                self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
273
 
                self.check_history.set_active(False)
274
 
                self.check_history.set_sensitive(False)
275
247
                return False
276
248
            
277
249
            self._show_stock_image(gtk.STOCK_CONNECT)
281
253
            # We're remote
282
254
            self.remote_branch, self.remote_path = Branch.open_containing(path)
283
255
            
284
 
            if self.remote_revision is None:
285
 
                self.remote_revision = self.remote_branch.last_revision()
286
 
            
287
 
            self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
 
256
            self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).entries()
288
257
            
289
258
            if len(self.remote_path) == 0:
290
259
                self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
301
270
                self.button_location_up.set_sensitive(False)
302
271
            else:
303
272
                self.button_location_up.set_sensitive(True)
304
 
        else:
305
 
            if os.path.isdir(path):
306
 
                self.image_location_error.destroy()
307
 
                self.remote = False
308
 
                
309
 
                # We're local
310
 
                try:
311
 
                    self.wt, self.wtpath = WorkingTree.open_containing(path)
312
 
                except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
313
 
                    self.notbranch = True
314
 
                
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)
320
 
                    else:
321
 
                        self.button_location_up.set_sensitive(True)
322
 
                else:
323
 
                    if self.path == '/':
324
 
                        self.button_location_up.set_sensitive(False)
325
 
                    else:
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
329
 
                # remote location
330
 
                self._show_stock_image(gtk.STOCK_DISCONNECT)
331
 
                try:
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)
337
 
                    return 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)
342
 
                    return False
343
 
                
344
 
                self._show_stock_image(gtk.STOCK_CONNECT)
345
 
                
346
 
                self.remote = True
347
 
               
348
 
                # We're remote
349
 
                self.remote_branch, self.remote_path = Branch.open_containing(path)
350
 
                
351
 
                if self.remote_revision is None:
352
 
                    self.remote_revision = self.remote_branch.last_revision()
353
 
                
354
 
                self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
355
 
                
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
358
 
                else:
359
 
                    for (name, type) in self.remote_entries:
360
 
                        if name == self.remote_path:
361
 
                            self.remote_parent = type.file_id
362
 
                            break
363
 
                
364
 
                if not path.endswith('/'):
365
 
                    path += '/'
366
 
                
367
 
                if self.remote_branch.base == path:
368
 
                    self.button_location_up.set_sensitive(False)
369
 
                else:
370
 
                    self.button_location_up.set_sensitive(True)
371
 
        
372
 
        if self.notbranch:
373
 
            self.check_history.set_active(False)
374
 
            self.check_history.set_sensitive(False)
375
 
        else:
376
 
            self.check_history.set_sensitive(True)
377
273
        
378
274
        self.statusbar.push(self.context_id, path)
379
275
        self.entry_location.set_text(path)
391
287
                return self.remote_branch.base
392
288
   
393
289
    def on_about_activate(self, widget):
 
290
        from bzrlib.plugins.gtk.dialog import about
394
291
        about()
395
 
    
396
 
    def on_button_history_browse_clicked(self, widget):
397
 
        """ Browse for revision button handler. """
398
 
        if self.remote:
399
 
            br = self.remote_branch
400
 
        else:
401
 
            br = self.wt.branch
402
 
            
403
 
        revb = RevisionBrowser(br, self.window)
404
 
        response = revb.run()
405
 
        if response != gtk.RESPONSE_NONE:
406
 
            revb.hide()
407
 
        
408
 
            if response == gtk.RESPONSE_OK:
409
 
                if revb.selected_revno is not None:
410
 
                    self.entry_history.set_text(revb.selected_revno)
411
 
            
412
 
            revb.destroy()
413
 
    
414
 
    def on_button_location_jump_clicked(self, widget):
415
 
        """ Location Jump button handler. """
416
 
        location = self.entry_location.get_text()
417
 
        
418
 
        if self.set_path(location):
419
 
            self.refresh_right()
420
 
    
 
292
        
421
293
    def on_button_location_up_clicked(self, widget):
422
294
        """ Location Up button handler. """
423
295
        if not self.remote:
432
304
 
433
305
        self.refresh_right()
434
306
    
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)
441
 
        else:
442
 
            # History Mode deactivated
443
 
            self.entry_history.set_sensitive(False)
444
 
            self.button_history.set_sensitive(False)
445
 
    
446
 
    @show_bzr_error
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()
453
 
            if not self.remote:
454
 
                self.remote = True
455
 
                self.remote_branch = self.wt.branch
456
 
            
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):
460
 
                self.refresh_right()
 
307
    def on_button_location_jump_clicked(self, widget):
 
308
        """ Location Jump button handler. """
 
309
        location = self.entry_location.get_text()
 
310
        
 
311
        if self.set_path(location):
 
312
            self.refresh_right()
461
313
    
462
314
    def on_entry_location_key_press_event(self, widget, event):
463
315
        """ 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'):
 
316
        if event.keyval == 65293:
465
317
            # Return was hit, so we have to jump
466
318
            self.on_button_location_jump_clicked(widget)
467
319
    
508
360
    @show_bzr_error
509
361
    def on_menuitem_branch_commit_activate(self, widget):
510
362
        """ Branch/Commit... menu handler. """
511
 
#     def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
512
 
        selected = self.get_selected_right()
513
 
        if selected:
514
 
            selected = os.path.join(self.wtpath, selected)
515
 
        commit = CommitDialog(wt=self.wt,
516
 
                              parent=self.window,
517
 
                              selected=selected,
518
 
                             )
 
363
        commit = CommitDialog(self.wt, self.wtpath, self.notbranch, self.get_selected_right(), self.window)
519
364
        response = commit.run()
520
365
        if response != gtk.RESPONSE_NONE:
521
366
            commit.hide()
537
382
        from bzrlib.plugins.gtk.merge import MergeDialog
538
383
        
539
384
        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.'))
 
385
            error_dialog(_('There are local changes in the branch'),
 
386
                         _('Please commit or revert the changes before merging.'))
542
387
        else:
543
 
            parent_branch_path = self.wt.branch.get_parent()
544
 
            merge = MergeDialog(self.wt, self.wtpath,default_branch_path=parent_branch_path )
 
388
            merge = MergeDialog(self.wt, self.wtpath)
545
389
            merge.display()
546
390
 
547
391
    @show_bzr_error
548
392
    def on_menuitem_branch_missing_revisions_activate(self, widget):
549
393
        """ Branch/Missing revisions menu handler. """
550
 
        
551
 
        from bzrlib.missing import find_unmerged, iter_log_revisions
552
 
        
553
394
        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.'))
 
395
        
 
396
        other_branch = local_branch.get_parent()
 
397
        if other_branch is None:
 
398
            error_dialog(_('Parent location is unknown'),
 
399
                         _('Cannot determine missing revisions if no parent location is known.'))
558
400
            return
559
401
        
560
 
        parent_branch = Branch.open(parent_branch_path)
561
 
        
562
 
        if parent_branch.base == local_branch.base:
563
 
            parent_branch = local_branch
564
 
        
565
 
        local_extra, remote_extra = find_unmerged(local_branch,parent_branch)
566
 
 
567
 
        if local_extra or remote_extra:
568
 
            
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(">"," ")
575
 
            ##    return txt
576
 
            
577
 
            dlg_txt = ""
578
 
            if local_extra:
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")
587
 
                ##        break
588
 
                ## max_revisions -= 1
589
 
            ## dlg_txt += "\n"
590
 
            if remote_extra:
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")
597
 
                ##        break
598
 
                ##    max_revisions -= 1
599
 
                
600
 
            info_dialog(_i18n('There are missing revisions'),
601
 
                        dlg_txt)
 
402
        remote_branch = Branch.open(other_branch)
 
403
        
 
404
        if remote_branch.base == local_branch.base:
 
405
            remote_branch = local_branch
 
406
 
 
407
        ret = len(local_branch.missing_revisions(remote_branch))
 
408
 
 
409
        if ret > 0:
 
410
            info_dialog(_('There are missing revisions'),
 
411
                        _('%d revision(s) missing.') % ret)
602
412
        else:
603
 
            info_dialog(_i18n('Local branch up to date'),
604
 
                        _i18n('There are no missing revisions.'))
 
413
            info_dialog(_('Local branch up to date'),
 
414
                        _('There are no missing revisions.'))
605
415
 
606
416
    @show_bzr_error
607
417
    def on_menuitem_branch_pull_activate(self, widget):
610
420
 
611
421
        location = branch_to.get_parent()
612
422
        if location is None:
613
 
            error_dialog(_i18n('Parent location is unknown'),
614
 
                                     _i18n('Pulling is not possible until there is a parent location.'))
 
423
            error_dialog(_('Parent location is unknown'),
 
424
                                     _('Pulling is not possible until there is a parent location.'))
615
425
            return
616
426
 
617
427
        branch_from = Branch.open(location)
621
431
 
622
432
        ret = branch_to.pull(branch_from)
623
433
        
624
 
        info_dialog(_i18n('Pull successful'), _i18n('%d revision(s) pulled.') % ret)
625
 
        
626
 
    @show_bzr_error
627
 
    def on_menuitem_branch_update_activate(self, widget):
628
 
        """ Brranch/checkout update menu handler. """
629
 
        
630
 
        ret = self.wt.update()
631
 
        conflicts = self.wt.conflicts()
632
 
        if conflicts:
633
 
            info_dialog(_i18n('Update successful but conflicts generated'), _i18n('Number of conflicts generated: %d.') % (len(conflicts),) )
634
 
        else:
635
 
            info_dialog(_i18n('Update successful'), _i18n('No conflicts generated.') )
 
434
        info_dialog(_('Pull successful'), _('%d revision(s) pulled.') % ret)
636
435
    
637
436
    def on_menuitem_branch_push_activate(self, widget):
638
437
        """ Branch/Push... menu handler. """
639
 
        push = PushDialog(repository=None,revid=None,branch=self.wt.branch, parent=self.window)
 
438
        push = PushDialog(self.wt.branch, self.window)
640
439
        response = push.run()
641
440
        if response != gtk.RESPONSE_NONE:
642
441
            push.destroy()
646
445
        """ Branch/Revert all changes menu handler. """
647
446
        ret = self.wt.revert([])
648
447
        if ret:
649
 
            warning_dialog(_i18n('Conflicts detected'),
650
 
                           _i18n('Please have a look at the working tree before continuing.'))
 
448
            warning_dialog(_('Conflicts detected'),
 
449
                           _('Please have a look at the working tree before continuing.'))
651
450
        else:
652
 
            info_dialog(_i18n('Revert successful'),
653
 
                        _i18n('All files reverted to last revision.'))
 
451
            info_dialog(_('Revert successful'),
 
452
                        _('All files reverted to last revision.'))
654
453
        self.refresh_right()
655
454
    
656
455
    def on_menuitem_branch_status_activate(self, widget):
685
484
    def on_menuitem_file_annotate_activate(self, widget):
686
485
        """ File/Annotate... menu handler. """
687
486
        if self.get_selected_right() is None:
688
 
            error_dialog(_i18n('No file was selected'),
689
 
                         _i18n('Please select a file from the list.'))
 
487
            error_dialog(_('No file was selected'),
 
488
                         _('Please select a file from the list.'))
690
489
            return
691
490
        
692
491
        branch = self.wt.branch
693
492
        file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
694
493
        
695
 
        window = GAnnotateWindow(all=False, plain=False, parent=self.window)
 
494
        window = GAnnotateWindow(all=False, plain=False)
696
495
        window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
697
496
        config = GAnnotateConfig(window)
698
497
        window.show()
702
501
        finally:
703
502
            branch.unlock()
704
503
    
705
 
    def on_menuitem_file_bookmark_activate(self, widget):
706
 
        """ File/Bookmark current directory menu handler. """
707
 
        if self.pref.add_bookmark(self.path):
708
 
            info_dialog(_i18n('Bookmark successfully added'),
709
 
                        _i18n('The current directory was bookmarked. You can reach\nit by selecting it from the left panel.'))
710
 
            self.pref.write()
711
 
        else:
712
 
            warning_dialog(_i18n('Location already bookmarked'),
713
 
                           _i18n('The current directory is already bookmarked.\nSee the left panel for reference.'))
714
 
        
715
 
        self.refresh_left()
716
 
    
717
504
    def on_menuitem_file_make_directory_activate(self, widget):
718
505
        """ File/Make directory... menu handler. """
719
506
        from mkdir import OliveMkdir
751
538
    
752
539
    def on_menuitem_stats_diff_activate(self, widget):
753
540
        """ Statistics/Differences... menu handler. """
754
 
        window = DiffWindow(parent=self.window)
 
541
        window = DiffWindow()
755
542
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
756
543
        window.set_diff(self.wt.branch.nick, self.wt, parent_tree)
757
544
        window.show()
767
554
    
768
555
    def on_menuitem_stats_log_activate(self, widget):
769
556
        """ Statistics/Log... menu handler. """
770
 
 
 
557
        window = branchwin.BranchWindow()
771
558
        if not self.remote:
772
 
            branch = self.wt.branch
 
559
            window.set_branch(self.wt.branch, self.wt.branch.last_revision(), None)
773
560
        else:
774
 
            branch = self.remote_branch
775
 
 
776
 
        window = branchwin.BranchWindow(branch, branch.last_revision(), None, parent=self.window)
 
561
            window.set_branch(self.remote_branch, self.remote_branch.last_revision(), None)
777
562
        window.show()
778
563
    
779
564
    def on_menuitem_view_refresh_activate(self, widget):
789
574
        if self.path is not None:
790
575
            self.refresh_right()
791
576
 
792
 
    def on_menuitem_view_show_ignored_files_activate(self, widget):
793
 
        """ Hide/Show ignored files menu handler. """
794
 
        self.pref.set_preference('ignored_files', widget.get_active())
795
 
        if self.path is not None:
796
 
            self.refresh_right()
797
 
            
798
577
    def on_treeview_left_button_press_event(self, widget, event):
799
578
        """ Occurs when somebody right-clicks in the bookmark list. """
800
579
        if event.button == 3:
811
590
            menu.left_context_menu().popup(None, None, None, 0,
812
591
                                           event.time)
813
592
 
814
 
    def on_treeview_left_button_release_event(self, widget, event):
815
 
        """ Occurs when somebody just clicks a bookmark. """
816
 
        if event.button != 3:
817
 
            # Allow one-click bookmark opening
818
 
            if self.get_selected_left() == None:
819
 
                return
820
 
            
821
 
            newdir = self.get_selected_left()
822
 
            if newdir == None:
823
 
                return
824
 
 
825
 
            if self.set_path(newdir):
826
 
                self.refresh_right()
827
 
 
828
593
    def on_treeview_left_row_activated(self, treeview, path, view_column):
829
594
        """ Occurs when somebody double-clicks or enters an item in the
830
595
        bookmark list. """
885
650
                m_annotate.set_sensitive(False)
886
651
                m_diff.set_sensitive(False)
887
652
 
888
 
            if not self.remote:
889
 
                menu.right_context_menu().popup(None, None, None, 0,
890
 
                                                event.time)
891
 
            else:
892
 
                menu.remote_context_menu().popup(None, None, None, 0,
893
 
                                                 event.time)
 
653
            menu.right_context_menu().popup(None, None, None, 0,
 
654
                                            event.time)
894
655
        
895
656
    def on_treeview_right_row_activated(self, treeview, path, view_column):
896
657
        """ Occurs when somebody double-clicks or enters an item in the
940
701
        bookmarks = self.pref.get_bookmarks()
941
702
        
942
703
        # Add them to the TreeStore
943
 
        titer = treestore.append(None, [_i18n('Bookmarks'), None])
 
704
        titer = treestore.append(None, [_('Bookmarks'), None])
944
705
        for item in bookmarks:
945
706
            title = self.pref.get_bookmark_title(item)
946
707
            treestore.append(titer, [title, item])
947
708
        
948
709
        # Create the column and add it to the TreeView
949
710
        self.treeview_left.set_model(treestore)
950
 
        tvcolumn_bookmark = gtk.TreeViewColumn(_i18n('Bookmark'))
 
711
        tvcolumn_bookmark = gtk.TreeViewColumn(_('Bookmark'))
951
712
        self.treeview_left.append_column(tvcolumn_bookmark)
952
713
        
953
714
        # Set up the cells
961
722
    def _load_right(self):
962
723
        """ Load data into the right panel. (Filelist) """
963
724
        # Create ListStore
964
 
        # Model: [ icon, dir, name, status text, status, size (int), size (human), mtime (int), mtime (local), fileid ]
965
 
        liststore = gtk.ListStore(gobject.TYPE_STRING,
966
 
                                  gobject.TYPE_BOOLEAN,
967
 
                                  gobject.TYPE_STRING,
968
 
                                  gobject.TYPE_STRING,
969
 
                                  gobject.TYPE_STRING,
970
 
                                  gobject.TYPE_STRING,
971
 
                                  gobject.TYPE_STRING,
972
 
                                  gobject.TYPE_INT,
973
 
                                  gobject.TYPE_STRING,
974
 
                                  gobject.TYPE_STRING)
 
725
        # Model: [icon, dir, name, status text, status, size (int), size (human), mtime (int), mtime (local)]
 
726
        liststore = gtk.ListStore(str, gobject.TYPE_BOOLEAN, str, str, str, gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
975
727
        
976
728
        dirs = []
977
729
        files = []
994
746
        
995
747
        # Add'em to the ListStore
996
748
        for item in dirs:
997
 
            try:
998
 
                statinfo = os.stat(self.path + os.sep + item)
999
 
            except OSError, e:
1000
 
                if e.errno == 40:
1001
 
                    continue
1002
 
                else:
1003
 
                    raise
1004
 
            liststore.append([ gtk.STOCK_DIRECTORY,
1005
 
                               True,
1006
 
                               item,
1007
 
                               '',
1008
 
                               '',
1009
 
                               "<DIR>",
1010
 
                               "<DIR>",
1011
 
                               statinfo.st_mtime,
1012
 
                               self._format_date(statinfo.st_mtime),
1013
 
                               ''])
 
749
            statinfo = os.stat(self.path + os.sep + item)
 
750
            liststore.append([gtk.STOCK_DIRECTORY, True, item, '', '', statinfo.st_size, self._format_size(statinfo.st_size), statinfo.st_mtime, self._format_date(statinfo.st_mtime)])
1014
751
        for item in files:
1015
752
            status = 'unknown'
1016
 
            fileid = ''
1017
753
            if not self.notbranch:
1018
754
                filename = self.wt.relpath(self.path + os.sep + item)
1019
755
                
1023
759
                    for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1024
760
                        if rpathnew == filename:
1025
761
                            status = 'renamed'
1026
 
                            fileid = id
1027
762
                    for rpath, id, kind in delta.added:
1028
763
                        if rpath == filename:
1029
764
                            status = 'added'
1030
 
                            fileid = id
1031
765
                    for rpath, id, kind in delta.removed:
1032
766
                        if rpath == filename:
1033
767
                            status = 'removed'
1034
 
                            fileid = id
1035
768
                    for rpath, id, kind, text_modified, meta_modified in delta.modified:
1036
769
                        if rpath == filename:
1037
770
                            status = 'modified'
1038
 
                            fileid = id
1039
771
                    for rpath, id, kind in delta.unchanged:
1040
772
                        if rpath == filename:
1041
773
                            status = 'unchanged'
1042
 
                            fileid = id
1043
774
                    for rpath, file_class, kind, id, entry in self.wt.list_files():
1044
775
                        if rpath == filename and file_class == 'I':
1045
776
                            status = 'ignored'
1046
777
                finally:
1047
778
                    self.wt.unlock()
1048
779
            
 
780
            #try:
 
781
            #    status = fileops.status(path + os.sep + item)
 
782
            #except errors.PermissionDenied:
 
783
            #    continue
 
784
            
1049
785
            if status == 'renamed':
1050
 
                st = _i18n('renamed')
 
786
                st = _('renamed')
1051
787
            elif status == 'removed':
1052
 
                st = _i18n('removed')
 
788
                st = _('removed')
1053
789
            elif status == 'added':
1054
 
                st = _i18n('added')
 
790
                st = _('added')
1055
791
            elif status == 'modified':
1056
 
                st = _i18n('modified')
 
792
                st = _('modified')
1057
793
            elif status == 'unchanged':
1058
 
                st = _i18n('unchanged')
 
794
                st = _('unchanged')
1059
795
            elif status == 'ignored':
1060
 
                st = _i18n('ignored')
 
796
                st = _('ignored')
1061
797
            else:
1062
 
                st = _i18n('unknown')
 
798
                st = _('unknown')
1063
799
            
1064
 
            try:
1065
 
                statinfo = os.stat(self.path + os.sep + item)
1066
 
            except OSError, e:
1067
 
                if e.errno == 40:
1068
 
                    continue
1069
 
                else:
1070
 
                    raise
1071
 
            liststore.append([gtk.STOCK_FILE,
1072
 
                              False,
1073
 
                              item,
1074
 
                              st,
1075
 
                              status,
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),
1078
 
                              statinfo.st_mtime,
1079
 
                              self._format_date(statinfo.st_mtime),
1080
 
                              fileid])
 
800
            statinfo = os.stat(self.path + os.sep + item)
 
801
            liststore.append([gtk.STOCK_FILE, False, item, st, status, statinfo.st_size, self._format_size(statinfo.st_size), statinfo.st_mtime, self._format_date(statinfo.st_mtime)])
1081
802
        
1082
803
        # Create the columns and add them to the TreeView
1083
804
        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'))
 
805
        self._tvcolumn_filename = gtk.TreeViewColumn(_('Filename'))
 
806
        self._tvcolumn_status = gtk.TreeViewColumn(_('Status'))
 
807
        self._tvcolumn_size = gtk.TreeViewColumn(_('Size'))
 
808
        self._tvcolumn_mtime = gtk.TreeViewColumn(_('Last modified'))
1088
809
        self.treeview_right.append_column(self._tvcolumn_filename)
1089
810
        self.treeview_right.append_column(self._tvcolumn_status)
1090
811
        self.treeview_right.append_column(self._tvcolumn_size)
1123
844
        # Set sensitivity
1124
845
        self.set_sensitivity()
1125
846
        
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()
1130
 
        
1131
 
        if iter is None:
1132
 
            return None
1133
 
        else:
1134
 
            return model.get_value(iter, 9)
1135
 
    
1136
847
    def get_selected_right(self):
1137
848
        """ Get the selected filename. """
1138
849
        treeselection = self.treeview_right.get_selection()
1170
881
            self.menuitem_branch_checkout.set_sensitive(self.notbranch)
1171
882
            self.menuitem_branch_pull.set_sensitive(not self.notbranch)
1172
883
            self.menuitem_branch_push.set_sensitive(not self.notbranch)
1173
 
            self.menuitem_branch_update.set_sensitive(not self.notbranch)
1174
884
            self.menuitem_branch_revert.set_sensitive(not self.notbranch)
1175
885
            self.menuitem_branch_merge.set_sensitive(not self.notbranch)
1176
886
            self.menuitem_branch_commit.set_sensitive(not self.notbranch)
1192
902
            self.toolbutton_commit.set_sensitive(not self.notbranch)
1193
903
            self.toolbutton_pull.set_sensitive(not self.notbranch)
1194
904
            self.toolbutton_push.set_sensitive(not self.notbranch)
1195
 
            self.toolbutton_update.set_sensitive(not self.notbranch)
1196
905
        else:
1197
906
            # We're remote
1198
907
            self.menuitem_branch_init.set_sensitive(False)
1200
909
            self.menuitem_branch_checkout.set_sensitive(True)
1201
910
            self.menuitem_branch_pull.set_sensitive(False)
1202
911
            self.menuitem_branch_push.set_sensitive(False)
1203
 
            self.menuitem_branch_update.set_sensitive(False)
1204
912
            self.menuitem_branch_revert.set_sensitive(False)
1205
913
            self.menuitem_branch_merge.set_sensitive(False)
1206
914
            self.menuitem_branch_commit.set_sensitive(False)
1222
930
            self.toolbutton_commit.set_sensitive(False)
1223
931
            self.toolbutton_pull.set_sensitive(False)
1224
932
            self.toolbutton_push.set_sensitive(False)
1225
 
            self.toolbutton_update.set_sensitive(False)
1226
933
    
1227
934
    def refresh_left(self):
1228
935
        """ Refresh the bookmark list. """
1238
945
        bookmarks = self.pref.get_bookmarks()
1239
946
 
1240
947
        # Add them to the TreeStore
1241
 
        titer = treestore.append(None, [_i18n('Bookmarks'), None])
 
948
        titer = treestore.append(None, [_('Bookmarks'), None])
1242
949
        for item in bookmarks:
1243
950
            title = self.pref.get_bookmark_title(item)
1244
951
            treestore.append(titer, [title, item])
1274
981
    
1275
982
            # Fill the appropriate lists
1276
983
            dotted_files = self.pref.get_preference('dotted_files', 'bool')
1277
 
            ignored_files = self.pref.get_preference('ignored_files', 'bool')
1278
 
 
1279
984
            for item in os.listdir(path):
1280
985
                if not dotted_files and item[0] == '.':
1281
986
                    continue
1299
1004
                
1300
1005
            # Add'em to the ListStore
1301
1006
            for item in dirs:
1302
 
                try:
1303
 
                    statinfo = os.stat(self.path + os.sep + item)
1304
 
                except OSError, e:
1305
 
                    if e.errno == 40:
1306
 
                        continue
1307
 
                    else:
1308
 
                        raise
1309
 
                liststore.append([gtk.STOCK_DIRECTORY,
1310
 
                                  True,
1311
 
                                  item,
1312
 
                                  '',
1313
 
                                  '',
1314
 
                                  "<DIR>",
1315
 
                                  "<DIR>",
1316
 
                                  statinfo.st_mtime,
1317
 
                                  self._format_date(statinfo.st_mtime),
1318
 
                                  ''])
 
1007
                statinfo = os.stat(self.path + os.sep + item)
 
1008
                liststore.append([gtk.STOCK_DIRECTORY, True, item, '', '', statinfo.st_size, self._format_size(statinfo.st_size), statinfo.st_mtime, self._format_date(statinfo.st_mtime)])
1319
1009
            for item in files:
1320
1010
                status = 'unknown'
1321
 
                fileid = ''
1322
1011
                if not notbranch:
1323
1012
                    filename = tree1.relpath(path + os.sep + item)
1324
1013
                    
1328
1017
                        for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1329
1018
                            if rpathnew == filename:
1330
1019
                                status = 'renamed'
1331
 
                                fileid = id
1332
1020
                        for rpath, id, kind in delta.added:
1333
1021
                            if rpath == filename:
1334
 
                                status = 'added'
1335
 
                                fileid = id
 
1022
                                status = 'added'                
1336
1023
                        for rpath, id, kind in delta.removed:
1337
1024
                            if rpath == filename:
1338
1025
                                status = 'removed'
1339
 
                                fileid = id
1340
1026
                        for rpath, id, kind, text_modified, meta_modified in delta.modified:
1341
1027
                            if rpath == filename:
1342
1028
                                status = 'modified'
1343
 
                                fileid = id
1344
1029
                        for rpath, id, kind in delta.unchanged:
1345
1030
                            if rpath == filename:
1346
1031
                                status = 'unchanged'
1347
 
                                fileid = id
1348
1032
                        for rpath, file_class, kind, id, entry in self.wt.list_files():
1349
1033
                            if rpath == filename and file_class == 'I':
1350
1034
                                status = 'ignored'
1352
1036
                        self.wt.unlock()
1353
1037
                
1354
1038
                if status == 'renamed':
1355
 
                    st = _i18n('renamed')
 
1039
                    st = _('renamed')
1356
1040
                elif status == 'removed':
1357
 
                    st = _i18n('removed')
 
1041
                    st = _('removed')
1358
1042
                elif status == 'added':
1359
 
                    st = _i18n('added')
 
1043
                    st = _('added')
1360
1044
                elif status == 'modified':
1361
 
                    st = _i18n('modified')
 
1045
                    st = _('modified')
1362
1046
                elif status == 'unchanged':
1363
 
                    st = _i18n('unchanged')
 
1047
                    st = _('unchanged')
1364
1048
                elif status == 'ignored':
1365
 
                    st = _i18n('ignored')
1366
 
                    if not ignored_files:
1367
 
                        continue
 
1049
                    st = _('ignored')
1368
1050
                else:
1369
 
                    st = _i18n('unknown')
 
1051
                    st = _('unknown')
1370
1052
                
1371
 
                try:
1372
 
                    statinfo = os.stat(self.path + os.sep + item)
1373
 
                except OSError, e:
1374
 
                    if e.errno == 40:
1375
 
                        continue
1376
 
                    else:
1377
 
                        raise
1378
 
                liststore.append([gtk.STOCK_FILE,
1379
 
                                  False,
1380
 
                                  item,
1381
 
                                  st,
1382
 
                                  status,
1383
 
                                  str(statinfo.st_size),
1384
 
                                  self._format_size(statinfo.st_size),
1385
 
                                  statinfo.st_mtime,
1386
 
                                  self._format_date(statinfo.st_mtime),
1387
 
                                  fileid])
 
1053
                statinfo = os.stat(self.path + os.sep + item)
 
1054
                liststore.append([gtk.STOCK_FILE, False, item, st, status, statinfo.st_size, self._format_size(statinfo.st_size), statinfo.st_mtime, self._format_date(statinfo.st_mtime)])
1388
1055
        else:
1389
1056
            # We're remote
1390
1057
            
1437
1104
                                       item.name,
1438
1105
                                       '',
1439
1106
                                       '',
1440
 
                                       "<DIR>",
1441
 
                                       "<DIR>",
 
1107
                                       0,
 
1108
                                       self._format_size(0),
1442
1109
                                       rev.timestamp,
1443
 
                                       self._format_date(rev.timestamp),
1444
 
                                       ''
 
1110
                                       self._format_date(rev.timestamp)
1445
1111
                                   ])
1446
1112
                while gtk.events_pending():
1447
1113
                    gtk.main_iteration()
1454
1120
                                       item.name,
1455
1121
                                       '',
1456
1122
                                       '',
1457
 
                                       str(item.text_size),
 
1123
                                       item.text_size,
1458
1124
                                       self._format_size(item.text_size),
1459
1125
                                       rev.timestamp,
1460
 
                                       self._format_date(rev.timestamp),
1461
 
                                       item.file_id
 
1126
                                       self._format_date(rev.timestamp)
1462
1127
                                   ])
1463
1128
                while gtk.events_pending():
1464
1129
                    gtk.main_iteration()
1556
1221
    
1557
1222
    def _format_size(self, size):
1558
1223
        """ Format size to a human readable format. """
1559
 
        if size < 1000:
1560
 
            return "%d[B]" % (size,)
1561
 
        size = size / 1000.0
1562
 
        
1563
 
        for metric in ["kB","MB","GB","TB"]:
1564
 
            if size < 1000:
1565
 
                break
1566
 
            size = size / 1000.0
1567
 
        return "%.1f[%s]" % (size,metric) 
 
1224
        return size
1568
1225
    
1569
1226
    def _format_date(self, timestamp):
1570
1227
        """ Format the time (given in secs) to a human readable format. """
1606
1263
        # Some default options
1607
1264
        self.defaults = { 'strict_commit' : False,
1608
1265
                          'dotted_files'  : False,
1609
 
                          'ignored_files' : True,
1610
1266
                          'window_width'  : 700,
1611
1267
                          'window_height' : 400,
1612
1268
                          'window_x'      : 40,