/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 diff.py

  • Committer: Vincent Ladeuil
  • Date: 2008-05-05 18:16:46 UTC
  • mto: (487.1.1 gtk)
  • mto: This revision was merged to the branch mainline in revision 490.
  • Revision ID: v.ladeuil+lp@free.fr-20080505181646-n95l8ltw2u6jtr26
Fix bug #187283 fix replacing _() by _i18n().

* genpot.sh 
Remove duplication. Add the ability to specify the genrated pot
file on command-line for debugging purposes.

* po/olive-gtk.pot:
Regenerated.

* __init__.py, branch.py, branchview/treeview.py, checkout.py,
commit.py, conflicts.py, diff.py, errors.py, initialize.py,
merge.py, nautilus-bzr.py, olive/__init__.py, olive/add.py,
olive/bookmark.py, olive/guifiles.py, olive/info.py,
olive/menu.py, olive/mkdir.py, olive/move.py, olive/remove.py,
olive/rename.py, push.py, revbrowser.py, status.py, tags.py:
Replace all calls to _() by calls to _i18n(), the latter being
defined in __init__.py and imported in the other modules from
there. This fix the problem encountered countless times when
running bzr selftest and getting silly error messages about
boolean not being callables.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
except ImportError:
31
31
    have_gconf = False
32
32
 
33
 
from bzrlib import osutils
 
33
from bzrlib import (
 
34
    merge as _mod_merge,
 
35
    osutils,
 
36
    progress,
 
37
    urlutils,
 
38
    workingtree,
 
39
)
34
40
from bzrlib.diff import show_diff_trees, internal_diff
35
41
from bzrlib.errors import NoSuchFile
 
42
from bzrlib.patches import parse_patches
36
43
from bzrlib.trace import warning
 
44
from bzrlib.plugins.gtk import _i18n
37
45
from bzrlib.plugins.gtk.window import Window
38
 
 
39
 
 
40
 
class DiffView(gtk.ScrolledWindow):
41
 
    """This is the soft and chewy filling for a DiffWindow."""
 
46
from dialog import error_dialog, info_dialog, warning_dialog
 
47
 
 
48
 
 
49
class SelectCancelled(Exception):
 
50
 
 
51
    pass
 
52
 
 
53
 
 
54
class DiffFileView(gtk.ScrolledWindow):
 
55
    """Window for displaying diffs from a diff file"""
42
56
 
43
57
    def __init__(self):
44
58
        gtk.ScrolledWindow.__init__(self)
45
 
 
46
59
        self.construct()
47
 
        self.rev_tree = None
48
 
        self.parent_tree = None
 
60
        self._diffs = {}
49
61
 
50
62
    def construct(self):
51
63
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
134
146
 
135
147
            lang.set_tag_style(tag_id, style)
136
148
 
137
 
    @staticmethod
138
 
    def apply_colordiff_colors(lang):
 
149
    @classmethod
 
150
    def apply_colordiff_colors(klass, lang):
139
151
        """Set style colors for lang using the colordiff configuration file.
140
152
 
141
153
        Both ~/.colordiffrc and ~/.colordiffrc.bzr-gtk are read.
152
164
                except IOError, e:
153
165
                    warning('could not open file %s: %s' % (f, str(e)))
154
166
                else:
155
 
                    colors.update(DiffView.parse_colordiffrc(f))
 
167
                    colors.update(klass.parse_colordiffrc(f))
156
168
                    f.close()
157
169
 
158
170
        if not colors:
216
228
#        self.parent_tree.lock_read()
217
229
#        self.rev_tree.lock_read()
218
230
#        try:
219
 
#            self.delta = _iter_changes_to_status(self.parent_tree, self.rev_tree)
 
231
#            self.delta = iter_changes_to_status(self.parent_tree, self.rev_tree)
220
232
#            self.path_to_status = {}
221
233
#            self.path_to_diff = {}
222
234
#            source_inv = self.parent_tree.inventory
237
249
#            self.parent_tree.unlock()
238
250
 
239
251
    def show_diff(self, specific_files):
 
252
        sections = []
 
253
        if specific_files is None:
 
254
            self.buffer.set_text(self._diffs[None])
 
255
        else:
 
256
            for specific_file in specific_files:
 
257
                sections.append(self._diffs[specific_file])
 
258
            self.buffer.set_text(''.join(sections))
 
259
 
 
260
 
 
261
class DiffView(DiffFileView):
 
262
    """This is the soft and chewy filling for a DiffWindow."""
 
263
 
 
264
    def __init__(self):
 
265
        DiffFileView.__init__(self)
 
266
        self.rev_tree = None
 
267
        self.parent_tree = None
 
268
 
 
269
    def show_diff(self, specific_files):
 
270
        """Show the diff for the specified files"""
240
271
        s = StringIO()
241
272
        show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files,
242
273
                        old_label='', new_label='',
290
321
        column.add_attribute(cell, "text", 0)
291
322
        self.treeview.append_column(column)
292
323
 
 
324
    def set_diff_text(self, lines):
 
325
        """Set the current diff from a list of lines
 
326
 
 
327
        :param lines: The diff to show, in unified diff format
 
328
        """
293
329
        # The diffs of the  selected file: a scrollable source or
294
330
        # text view
 
331
        self.diff_view = DiffFileView()
 
332
        self.diff_view.show()
 
333
        self.pack2(self.diff_view)
 
334
        self.model.append(None, [ "Complete Diff", "" ])
 
335
        self.diff_view._diffs[None] = ''.join(lines)
 
336
        for patch in parse_patches(lines):
 
337
            oldname = patch.oldname.split('\t')[0]
 
338
            newname = patch.newname.split('\t')[0]
 
339
            self.model.append(None, [oldname, newname])
 
340
            self.diff_view._diffs[newname] = str(patch)
 
341
        self.diff_view.show_diff(None)
 
342
 
 
343
    def set_diff(self, rev_tree, parent_tree):
 
344
        """Set the differences showed by this window.
 
345
 
 
346
        Compares the two trees and populates the window with the
 
347
        differences.
 
348
        """
295
349
        self.diff_view = DiffView()
296
350
        self.pack2(self.diff_view)
297
351
        self.diff_view.show()
298
 
 
299
 
    def set_diff(self, rev_tree, parent_tree):
300
 
        """Set the differences showed by this window.
301
 
 
302
 
        Compares the two trees and populates the window with the
303
 
        differences.
304
 
        """
305
352
        self.diff_view.set_trees(rev_tree, parent_tree)
306
353
        self.rev_tree = rev_tree
307
354
        self.parent_tree = parent_tree
335
382
        self.treeview.expand_all()
336
383
 
337
384
    def set_file(self, file_path):
 
385
        """Select the current file to display"""
338
386
        tv_path = None
339
387
        for data in self.model:
340
388
            for child in data.iterchildren():
381
429
 
382
430
    def construct(self):
383
431
        """Construct the window contents."""
 
432
        self.vbox = gtk.VBox()
 
433
        self.add(self.vbox)
 
434
        self.vbox.show()
 
435
        hbox = self._get_button_bar()
 
436
        if hbox is not None:
 
437
            self.vbox.pack_start(hbox, expand=False, fill=True)
384
438
        self.diff = DiffWidget()
385
 
        self.add(self.diff)
 
439
        self.vbox.add(self.diff)
386
440
        self.diff.show_all()
387
441
 
 
442
    def _get_button_bar(self):
 
443
        """Return a button bar to use.
 
444
 
 
445
        :return: None, meaning that no button bar will be used.
 
446
        """
 
447
        return None
 
448
 
 
449
    def set_diff_text(self, description, lines):
 
450
        """Set the diff from a text.
 
451
 
 
452
        The diff must be in unified diff format, and will be parsed to
 
453
        determine filenames.
 
454
        """
 
455
        self.diff.set_diff_text(lines)
 
456
        self.set_title(description + " - bzrk diff")
 
457
 
388
458
    def set_diff(self, description, rev_tree, parent_tree):
389
459
        """Set the differences showed by this window.
390
460
 
398
468
        self.diff.set_file(file_path)
399
469
 
400
470
 
401
 
def _iter_changes_to_status(source, target):
 
471
class MergeDirectiveWindow(DiffWindow):
 
472
 
 
473
    def __init__(self, directive, path):
 
474
        DiffWindow.__init__(self, None)
 
475
        self._merge_target = None
 
476
        self.directive = directive
 
477
        self.path = path
 
478
 
 
479
    def _get_button_bar(self):
 
480
        """The button bar has only the Merge button"""
 
481
        merge_button = gtk.Button('Merge')
 
482
        merge_button.show()
 
483
        merge_button.set_relief(gtk.RELIEF_NONE)
 
484
        merge_button.connect("clicked", self.perform_merge)
 
485
 
 
486
        save_button = gtk.Button('Save')
 
487
        save_button.show()
 
488
        save_button.set_relief(gtk.RELIEF_NONE)
 
489
        save_button.connect("clicked", self.perform_save)
 
490
 
 
491
        hbox = gtk.HButtonBox()
 
492
        hbox.set_layout(gtk.BUTTONBOX_START)
 
493
        hbox.pack_start(merge_button, expand=False, fill=True)
 
494
        hbox.pack_start(save_button, expand=False, fill=True)
 
495
        hbox.show()
 
496
        return hbox
 
497
 
 
498
    def perform_merge(self, window):
 
499
        try:
 
500
            tree = self._get_merge_target()
 
501
        except SelectCancelled:
 
502
            return
 
503
        tree.lock_write()
 
504
        try:
 
505
            try:
 
506
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
 
507
                    self.directive, progress.DummyProgress())
 
508
                merger.check_basis(True)
 
509
                merger.merge_type = _mod_merge.Merge3Merger
 
510
                conflict_count = merger.do_merge()
 
511
                merger.set_pending()
 
512
                if conflict_count == 0:
 
513
                    # No conflicts found.
 
514
                    info_dialog(_i18n('Merge successful'),
 
515
                                _i18n('All changes applied successfully.'))
 
516
                else:
 
517
                    # There are conflicts to be resolved.
 
518
                    warning_dialog(_i18n('Conflicts encountered'),
 
519
                                   _i18n('Please resolve the conflicts manually'
 
520
                                         ' before committing.'))
 
521
                self.destroy()
 
522
            except Exception, e:
 
523
                error_dialog('Error', str(e))
 
524
        finally:
 
525
            tree.unlock()
 
526
 
 
527
    def _get_merge_target(self):
 
528
        if self._merge_target is not None:
 
529
            return self._merge_target
 
530
        d = gtk.FileChooserDialog('Merge branch', self,
 
531
                                  gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
 
532
                                  buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
 
533
                                           gtk.STOCK_CANCEL,
 
534
                                           gtk.RESPONSE_CANCEL,))
 
535
        try:
 
536
            result = d.run()
 
537
            if result != gtk.RESPONSE_OK:
 
538
                raise SelectCancelled()
 
539
            uri = d.get_current_folder_uri()
 
540
        finally:
 
541
            d.destroy()
 
542
        return workingtree.WorkingTree.open(uri)
 
543
 
 
544
    def perform_save(self, window):
 
545
        d = gtk.FileChooserDialog('Save As', self,
 
546
                                  gtk.FILE_CHOOSER_ACTION_SAVE,
 
547
                                  buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
 
548
                                           gtk.STOCK_CANCEL,
 
549
                                           gtk.RESPONSE_CANCEL,))
 
550
        d.set_current_name(osutils.basename(self.path))
 
551
        try:
 
552
            try:
 
553
                result = d.run()
 
554
                if result != gtk.RESPONSE_OK:
 
555
                    raise SelectCancelled()
 
556
                uri = d.get_uri()
 
557
            finally:
 
558
                d.destroy()
 
559
        except SelectCancelled:
 
560
            return
 
561
        source = open(self.path, 'rb')
 
562
        try:
 
563
            target = open(urlutils.local_path_from_url(uri), 'wb')
 
564
            try:
 
565
                target.write(source.read())
 
566
            finally:
 
567
                target.close()
 
568
        finally:
 
569
            source.close()
 
570
 
 
571
 
 
572
def iter_changes_to_status(source, target):
402
573
    """Determine the differences between trees.
403
574
 
404
 
    This is a wrapper around _iter_changes which just yields more
 
575
    This is a wrapper around iter_changes which just yields more
405
576
    understandable results.
406
577
 
407
578
    :param source: The source tree (basis tree)
423
594
        source.lock_read()
424
595
        try:
425
596
            for (file_id, paths, changed_content, versioned, parent_ids, names,
426
 
                 kinds, executables) in target._iter_changes(source):
 
597
                 kinds, executables) in target.iter_changes(source):
427
598
 
428
599
                # Skip the root entry if it isn't very interesting
429
600
                if parent_ids == (None, None):