/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: Curtis Hovey
  • Date: 2011-09-04 20:04:03 UTC
  • mto: This revision was merged to the branch mainline in revision 741.
  • Revision ID: sinzui.is@verizon.net-20110904200403-t38t3o2q1j600dho
Added missing tests for BranchTreeModel and CellRendererGraph.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
 
11
11
from cStringIO import StringIO
12
12
 
13
 
import pygtk
14
 
pygtk.require("2.0")
15
 
import gtk
16
 
import pango
 
13
from gi.repository import Gtk
 
14
from gi.repository import Pango
17
15
import os
18
16
import re
19
17
import sys
 
18
import inspect
20
19
try:
21
20
    from xml.etree.ElementTree import Element, SubElement, tostring
22
21
except ImportError:
23
22
    from elementtree.ElementTree import Element, SubElement, tostring
24
23
 
25
24
try:
26
 
    import gtksourceview2
 
25
    from gi.repository import GtkSource
27
26
    have_gtksourceview = True
28
27
except ImportError:
29
28
    have_gtksourceview = False
30
29
try:
31
 
    import gconf
 
30
    from gi.repository import GConf
32
31
    have_gconf = True
33
32
except ImportError:
34
33
    have_gconf = False
35
34
 
36
35
from bzrlib import (
 
36
    errors,
37
37
    merge as _mod_merge,
38
38
    osutils,
39
 
    progress,
40
39
    urlutils,
41
40
    workingtree,
42
41
)
43
 
from bzrlib.diff import show_diff_trees, internal_diff
44
 
from bzrlib.errors import NoSuchFile
 
42
from bzrlib.diff import show_diff_trees
45
43
from bzrlib.patches import parse_patches
46
44
from bzrlib.trace import warning
47
 
from bzrlib.plugins.gtk import _i18n
 
45
from bzrlib.plugins.gtk.dialog import (
 
46
    error_dialog,
 
47
    info_dialog,
 
48
    warning_dialog,
 
49
    )
 
50
from bzrlib.plugins.gtk.i18n import _i18n
48
51
from bzrlib.plugins.gtk.window import Window
49
 
from dialog import error_dialog, info_dialog, warning_dialog
50
52
 
51
53
 
52
54
def fallback_guess_language(slm, content_type):
62
64
    pass
63
65
 
64
66
 
65
 
class DiffFileView(gtk.ScrolledWindow):
 
67
class DiffFileView(Gtk.ScrolledWindow):
66
68
    """Window for displaying diffs from a diff file"""
67
69
 
68
70
    def __init__(self):
69
 
        gtk.ScrolledWindow.__init__(self)
 
71
        Gtk.ScrolledWindow.__init__(self)
70
72
        self.construct()
71
73
        self._diffs = {}
72
74
 
73
75
    def construct(self):
74
 
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
75
 
        self.set_shadow_type(gtk.SHADOW_IN)
 
76
        self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
 
77
        self.set_shadow_type(Gtk.ShadowType.IN)
76
78
 
77
79
        if have_gtksourceview:
78
 
            self.buffer = gtksourceview2.Buffer()
79
 
            slm = gtksourceview2.LanguageManager()
80
 
            guess_language = getattr(gtksourceview2.LanguageManager, 
81
 
                "guess_language", fallback_guess_language)
82
 
            gsl = guess_language(slm, content_type="text/x-patch")
 
80
            self.buffer = GtkSource.Buffer()
 
81
            lang_manager = GtkSource.LanguageManager.get_default()
 
82
            language = lang_manager.guess_language(None, "text/x-patch")
83
83
            if have_gconf:
84
84
                self.apply_gedit_colors(self.buffer)
85
85
            self.apply_colordiff_colors(self.buffer)
86
 
            self.buffer.set_language(gsl)
 
86
            self.buffer.set_language(language)
87
87
            self.buffer.set_highlight_syntax(True)
88
88
 
89
 
            self.sourceview = gtksourceview2.View(self.buffer)
 
89
            self.sourceview = GtkSource.View(buffer=self.buffer)
90
90
        else:
91
 
            self.buffer = gtk.TextBuffer()
92
 
            self.sourceview = gtk.TextView(self.buffer)
 
91
            self.buffer = Gtk.TextBuffer()
 
92
            self.sourceview = Gtk.TextView(self.buffer)
93
93
 
94
94
        self.sourceview.set_editable(False)
95
 
        self.sourceview.modify_font(pango.FontDescription("Monospace"))
 
95
        self.sourceview.modify_font(Pango.FontDescription("Monospace"))
96
96
        self.add(self.sourceview)
97
97
        self.sourceview.show()
98
98
 
102
102
 
103
103
        This method needs the gconf module.
104
104
 
105
 
        :param buf: a gtksourceview2.Buffer object.
 
105
        :param buf: a GtkSource.Buffer object.
106
106
        """
107
107
        GEDIT_SCHEME_PATH = '/apps/gedit-2/preferences/editor/colors/scheme'
 
108
        GEDIT_USER_STYLES_PATH = os.path.expanduser('~/.gnome2/gedit/styles')
108
109
 
109
 
        client = gconf.client_get_default()
 
110
        client = GConf.Client.get_default()
110
111
        style_scheme_name = client.get_string(GEDIT_SCHEME_PATH)
111
112
        if style_scheme_name is not None:
112
 
            style_scheme = gtksourceview2.StyleSchemeManager().get_scheme(style_scheme_name)
113
 
            
114
 
            buf.set_style_scheme(style_scheme)
 
113
            style_scheme_mgr = GtkSource.StyleSchemeManager()
 
114
            style_scheme_mgr.append_search_path(GEDIT_USER_STYLES_PATH)
 
115
            
 
116
            style_scheme = style_scheme_mgr.get_scheme(style_scheme_name)
 
117
            
 
118
            if style_scheme is not None:
 
119
                buf.set_style_scheme(style_scheme)
115
120
 
116
121
    @classmethod
117
122
    def apply_colordiff_colors(klass, buf):
119
124
 
120
125
        Both ~/.colordiffrc and ~/.colordiffrc.bzr-gtk are read.
121
126
 
122
 
        :param buf: a "Diff" gtksourceview2.Buffer object.
 
127
        :param buf: a "Diff" GtkSource.Buffer object.
123
128
        """
124
 
        scheme_manager = gtksourceview2.StyleSchemeManager()
 
129
        scheme_manager = GtkSource.StyleSchemeManager()
125
130
        style_scheme = scheme_manager.get_scheme('colordiff')
126
131
        
127
132
        # if style scheme not found, we'll generate it from colordiffrc
275
280
        self.buffer.set_text(decoded.encode('UTF-8'))
276
281
 
277
282
 
278
 
class DiffWidget(gtk.HPaned):
 
283
class DiffWidget(Gtk.HPaned):
279
284
    """Diff widget
280
285
 
281
286
    """
283
288
        super(DiffWidget, self).__init__()
284
289
 
285
290
        # The file hierarchy: a scrollable treeview
286
 
        scrollwin = gtk.ScrolledWindow()
287
 
        scrollwin.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
288
 
        scrollwin.set_shadow_type(gtk.SHADOW_IN)
 
291
        scrollwin = Gtk.ScrolledWindow()
 
292
        scrollwin.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
 
293
        scrollwin.set_shadow_type(Gtk.ShadowType.IN)
289
294
        self.pack1(scrollwin)
290
295
        scrollwin.show()
291
296
        
292
 
        self.model = gtk.TreeStore(str, str)
293
 
        self.treeview = gtk.TreeView(self.model)
 
297
        self.model = Gtk.TreeStore(str, str)
 
298
        self.treeview = Gtk.TreeView(model=self.model)
294
299
        self.treeview.set_headers_visible(False)
295
300
        self.treeview.set_search_column(1)
296
301
        self.treeview.connect("cursor-changed", self._treeview_cursor_cb)
297
302
        scrollwin.add(self.treeview)
298
303
        self.treeview.show()
299
304
 
300
 
        cell = gtk.CellRendererText()
 
305
        cell = Gtk.CellRendererText()
301
306
        cell.set_property("width-chars", 20)
302
 
        column = gtk.TreeViewColumn()
303
 
        column.pack_start(cell, expand=True)
 
307
        column = Gtk.TreeViewColumn()
 
308
        column.pack_start(cell, True)
304
309
        column.add_attribute(cell, "text", 0)
305
310
        self.treeview.append_column(column)
306
311
 
376
381
                    tv_path = child.path
377
382
                    break
378
383
        if tv_path is None:
379
 
            raise NoSuchFile(file_path)
380
 
        self.treeview.set_cursor(tv_path)
 
384
            raise errors.NoSuchFile(file_path)
 
385
        self.treeview.set_cursor(tv_path, None, False)
381
386
        self.treeview.scroll_to_cell(tv_path)
382
387
 
383
388
    def _treeview_cursor_cb(self, *args):
394
399
    def _on_wraplines_toggled(self, widget=None, wrap=False):
395
400
        """Callback for when the wrap lines checkbutton is toggled"""
396
401
        if wrap or widget.get_active():
397
 
            self.diff_view.sourceview.set_wrap_mode(gtk.WRAP_WORD)
 
402
            self.diff_view.sourceview.set_wrap_mode(Gtk.WrapMode.WORD)
398
403
        else:
399
 
            self.diff_view.sourceview.set_wrap_mode(gtk.WRAP_NONE)
 
404
            self.diff_view.sourceview.set_wrap_mode(Gtk.WrapMode.NONE)
400
405
 
401
406
class DiffWindow(Window):
402
407
    """Diff window.
420
425
 
421
426
    def construct(self, operations):
422
427
        """Construct the window contents."""
423
 
        self.vbox = gtk.VBox()
 
428
        self.vbox = Gtk.VBox()
424
429
        self.add(self.vbox)
425
430
        self.vbox.show()
426
431
        self.diff = DiffWidget()
435
440
        
436
441
    
437
442
    def _get_menu_bar(self):
438
 
        menubar = gtk.MenuBar()
 
443
        menubar = Gtk.MenuBar()
439
444
        # View menu
440
 
        mb_view = gtk.MenuItem(_i18n("_View"))
441
 
        mb_view_menu = gtk.Menu()
442
 
        mb_view_wrapsource = gtk.CheckMenuItem(_i18n("Wrap _Long Lines"))
 
445
        mb_view = Gtk.MenuItem.new_with_mnemonic(_i18n("_View"))
 
446
        mb_view_menu = Gtk.Menu()
 
447
        mb_view_wrapsource = Gtk.CheckMenuItem.new_with_mnemonic(
 
448
            _i18n("Wrap _Long Lines"))
443
449
        mb_view_wrapsource.connect('activate', self.diff._on_wraplines_toggled)
444
450
        mb_view_wrapsource.show()
445
451
        mb_view_menu.append(mb_view_wrapsource)
457
463
        """
458
464
        if operations is None:
459
465
            return None
460
 
        hbox = gtk.HButtonBox()
461
 
        hbox.set_layout(gtk.BUTTONBOX_START)
 
466
        hbox = Gtk.HButtonBox()
 
467
        hbox.set_layout(Gtk.ButtonBoxStyle.START)
462
468
        for title, method in operations:
463
 
            merge_button = gtk.Button(title)
 
469
            merge_button = Gtk.Button(title)
464
470
            merge_button.show()
465
 
            merge_button.set_relief(gtk.RELIEF_NONE)
 
471
            merge_button.set_relief(Gtk.ReliefStyle.NONE)
466
472
            merge_button.connect("clicked", method)
467
473
            hbox.pack_start(merge_button, expand=False, fill=True)
468
474
        hbox.show()
469
475
        return hbox
470
476
 
471
477
    def _get_merge_target(self):
472
 
        d = gtk.FileChooserDialog('Merge branch', self,
473
 
                                  gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
474
 
                                  buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
475
 
                                           gtk.STOCK_CANCEL,
476
 
                                           gtk.RESPONSE_CANCEL,))
 
478
        d = Gtk.FileChooserDialog('Merge branch', self,
 
479
                                  Gtk.FileChooserAction.SELECT_FOLDER,
 
480
                                  buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK,
 
481
                                           Gtk.STOCK_CANCEL,
 
482
                                           Gtk.ResponseType.CANCEL,))
477
483
        try:
478
484
            result = d.run()
479
 
            if result != gtk.RESPONSE_OK:
 
485
            if result != Gtk.ResponseType.OK:
480
486
                raise SelectCancelled()
481
487
            return d.get_current_folder_uri()
482
488
        finally:
496
502
        error_dialog('Error', str(e))
497
503
 
498
504
    def _get_save_path(self, basename):
499
 
        d = gtk.FileChooserDialog('Save As', self,
500
 
                                  gtk.FILE_CHOOSER_ACTION_SAVE,
501
 
                                  buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK,
502
 
                                           gtk.STOCK_CANCEL,
503
 
                                           gtk.RESPONSE_CANCEL,))
 
505
        d = Gtk.FileChooserDialog('Save As', self,
 
506
                                  Gtk.FileChooserAction.SAVE,
 
507
                                  buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK,
 
508
                                           Gtk.STOCK_CANCEL,
 
509
                                           Gtk.ResponseType.CANCEL,))
504
510
        d.set_current_name(basename)
505
511
        try:
506
512
            result = d.run()
507
 
            if result != gtk.RESPONSE_OK:
 
513
            if result != Gtk.ResponseType.OK:
508
514
                raise SelectCancelled()
509
515
            return urlutils.local_path_from_url(d.get_uri())
510
516
        finally:
525
531
 
526
532
class DiffController(object):
527
533
 
528
 
    def __init__(self, path, patch, window=None):
 
534
    def __init__(self, path, patch, window=None, allow_dirty=False):
529
535
        self.path = path
530
536
        self.patch = patch
 
537
        self.allow_dirty = allow_dirty
531
538
        if window is None:
532
539
            window = DiffWindow(operations=self._provide_operations())
533
540
            self.initialize_window(window)
539
546
 
540
547
    def get_diff_sections(self):
541
548
        yield "Complete Diff", None, ''.join(self.patch)
542
 
        for patch in parse_patches(self.patch):
 
549
        # allow_dirty was added to parse_patches in bzrlib 2.2b1
 
550
        if 'allow_dirty' in inspect.getargspec(parse_patches).args:
 
551
            patches = parse_patches(self.patch, allow_dirty=self.allow_dirty)
 
552
        else:
 
553
            patches = parse_patches(self.patch)
 
554
        for patch in patches:
543
555
            oldname = patch.oldname.split('\t')[0]
544
556
            newname = patch.newname.split('\t')[0]
545
557
            yield oldname, newname, str(patch)
584
596
        tree.lock_write()
585
597
        try:
586
598
            try:
587
 
                merger, verified = _mod_merge.Merger.from_mergeable(tree,
588
 
                    self.directive, progress.DummyProgress())
589
 
                merger.check_basis(True)
 
599
                if tree.has_changes():
 
600
                    raise errors.UncommittedChanges(tree)
 
601
                merger, verified = _mod_merge.Merger.from_mergeable(
 
602
                    tree, self.directive, pb=None)
590
603
                merger.merge_type = _mod_merge.Merge3Merger
591
604
                conflict_count = merger.do_merge()
592
605
                merger.set_pending()