summaryrefslogtreecommitdiff
path: root/UpdateManager/ReleaseNotesViewer.py
blob: 9cecc895a709221cef1f80d78f3fd4daea494f71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python

import pygtk
import gtk
import pango
import subprocess
import os

class ReleaseNotesViewer(gtk.TextView):
    def __init__(self, notes):
        gtk.TextView.__init__(self)
        self.hovering = False
        self.buffer = gtk.TextBuffer()
        self.set_buffer(self.buffer)
        self.buffer.set_text(notes)
        self.connect("event-after", self.event_after)
        self.connect("motion-notify-event", self.motion_notify_event)
        self.connect("visibility-notify-event", self.visibility_notify_event)
        self.search_links()
        self.set_property("editable", False)
        self.set_cursor_visible(False)

    def tag_link(self, start, end, url):
        tag = self.buffer.create_tag(None, foreground="blue",
                                     underline=pango.UNDERLINE_SINGLE)
        tag.set_data("url", url)
        self.buffer.apply_tag(tag , start, end)

    def search_links(self):
        iter = self.buffer.get_iter_at_offset(0)
        while 1:
            ret = iter.forward_search("http://", gtk.TEXT_SEARCH_VISIBLE_ONLY,
                                      None)
            if not ret:
                break
            (match_start, match_end) = ret
            match_tmp = match_end.copy()
            while 1:
                if match_tmp.forward_char():
                    text =  match_end.get_text(match_tmp)
                    if text in (" ", ")", "]", "\n", "\t"):
                        break
                else:
                    break
                match_end = match_tmp.copy()
            url = match_start.get_text(match_end)
            self.tag_link(match_start, match_end, url)
            iter = match_end

    def event_after(self, text_view, event):
        if event.type != gtk.gdk.BUTTON_RELEASE:
            return False
        if event.button != 1:
            return False

        try:
            (start, end) = self.buffer.get_selection_bounds()
        except ValueError:
            pass
        else:
            if start.get_offset() != end.get_offset():
                return False

        (x, y) = self.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
                                              int(event.x), int(event.y))
        iter = self.get_iter_at_location(x, y)
        
        tags = iter.get_tags()
        for tag in tags:
            url = tag.get_data("url")
            if url != "":
                self.open_url(url)
                break

    def open_url(self, url):
        if os.path.exists('usr/bin/gnome-open'):
            command = ['gnome-open', url]
        else:
            command = ['x-www-browser', url]

        if os.getuid() == 0 and os.environ.has_key('SUDO_USER'):
            command = ['sudo', '-u', os.environ['SUDO_USER']] + command

        subprocess.Popen(command)

    def motion_notify_event(self, text_view, event):
        x, y = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET,
                                                 int(event.x), int(event.y))
        self.check_hovering(x, y)
        self.window.get_pointer()
        return False
    
    def visibility_notify_event(self, text_view, event):
        (wx, wy, mod) = text_view.window.get_pointer()
        (bx, by) = text_view.window_to_buffer_coords(gtk.TEXT_WINDOW_WIDGET, wx,
                                                     wy)
        self.check_hovering(bx, by)
        return False

    def check_hovering(self, x, y):
        _hovering = False
        iter = self.get_iter_at_location(x, y)

        tags = iter.get_tags()
        for tag in tags:
            url = tag.get_data("url")
            if url != "":
                _hovering = True
                break
        
        if _hovering != self.hovering:
            self.hovering = _hovering

        if self.hovering:
            self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
        else:
            self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))