~ubuntu-branches/debian/sid/guake/sid

« back to all changes in this revision

Viewing changes to src/guake/terminal3.py

  • Committer: Package Import Robot
  • Author(s): Daniel Echeverry
  • Date: 2015-04-26 19:15:06 UTC
  • mfrom: (1.1.7)
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: package-import@ubuntu.com-20150426191506-mo8037vk6pueer5b
Tags: upstream-0.7.0
ImportĀ upstreamĀ versionĀ 0.7.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Copyright (C) 2009-2011  Lincoln de Sousa <lincoln@guake.org>
 
3
 
 
4
This program is free software; you can redistribute it and/or
 
5
modify it under the terms of the GNU General Public License as
 
6
published by the Free Software Foundation; either version 2 of the
 
7
License, or (at your option) any later version.
 
8
 
 
9
This program is distributed in the hope that it will be useful,
 
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
General Public License for more details.
 
13
 
 
14
You should have received a copy of the GNU General Public
 
15
License along with this program; if not, write to the
 
16
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
Boston, MA 02110-1301 USA
 
18
"""
 
19
from __future__ import absolute_import
 
20
from __future__ import division
 
21
from __future__ import print_function
 
22
 
 
23
from gi.repository import GConf
 
24
from gi.repository import Gdk
 
25
from gi.repository import GdkX11
 
26
from gi.repository import Gtk
 
27
from gi.repository import Pango
 
28
from gi.repository import Vte
 
29
 
 
30
from guake.common import clamp
 
31
from guake.globals import KEY
 
32
 
 
33
 
 
34
__all__ = ['Terminal', 'TerminalBox']
 
35
 
 
36
 
 
37
# regular expressions to highlight links in terminal. This code was
 
38
# lovely stolen from the great gnome-terminal project, thank you =)
 
39
USERCHARS = r"-[:alnum:]"
 
40
PASSCHARS = r"-[:alnum:],?;.:/!%$^*&~\"#'"
 
41
HOSTCHARS = r"-[:alnum:]"
 
42
HOST = r"[{hostchars}]+(\\.[{hostchars}]+)*".format(hostchars=HOSTCHARS)
 
43
PORT = r"(:[:digit:]{1,5})?"
 
44
PATHCHARS = r"-[:alnum:]_$.+!*(),;:@&=?/~#%"
 
45
SCHEME = r"(news:|telnet:|nntp:|file:/|https?:|ftps?:|webcal:)"
 
46
USER = r"[{userchars}]+(:[{passchars}]+)?".format(
 
47
    userchars=USERCHARS,
 
48
    passchars=PASSCHARS)
 
49
URLPATH = r"/[{pathchars}]*[^]'.>) \t\r\n,\\\"]".format(pathchars=PATHCHARS)
 
50
TERMINAL_MATCH_TAGS = 'schema', 'http', 'email'
 
51
TERMINAL_MATCH_EXPRS = [
 
52
    r"\<{scheme}//({user}@)?{host}{port}({urlpath})?\>/?".format(
 
53
        scheme=SCHEME,
 
54
        user=USER,
 
55
        host=HOST,
 
56
        port=PORT,
 
57
        urlpath=URLPATH,
 
58
    ),
 
59
    r"\<(www|ftp)[{hostchars}]*\.{host}{port}({urlpath})?\>/?".format(
 
60
        hostchars=HOSTCHARS,
 
61
        host=HOST,
 
62
        port=PORT,
 
63
        urlpath=URLPATH,
 
64
    ),
 
65
    r"\<(mailto:)?[{userchars}][{userchars}.]*@[{hostchars}]+\.{host}\>".format(
 
66
        hostchars=HOSTCHARS,
 
67
        userchars=USERCHARS,
 
68
        host=HOST,
 
69
    ),
 
70
]
 
71
 
 
72
# tuple (title/quick matcher/filename and line number extractor)
 
73
QUICK_OPEN_MATCHERS = [
 
74
    ("Python traceback",
 
75
     r"^\s\sFile\s\".*\",\sline\s[0-9]+",
 
76
     r"^\s\sFile\s\"(.*)\",\sline\s([0-9]+)"),
 
77
    ("line starts by 'Filename:line' pattern (GCC/make). File path should exists.",
 
78
     r"^[a-zA-Z0-9\/\_\-\.\ ]+\.?[a-zA-Z0-9]+\:[0-9]+",
 
79
     r"^(.*)\:([0-9]+)")
 
80
]
 
81
 
 
82
 
 
83
class Terminal(Vte.Terminal):
 
84
 
 
85
    """Just a Vte.Terminal with some properties already set.
 
86
    """
 
87
 
 
88
    def __init__(self):
 
89
        super(Terminal, self).__init__()
 
90
        self.configure_terminal()
 
91
        self.add_matches()
 
92
        self.connect('button-press-event', self.button_press)
 
93
        self.matched_value = ''
 
94
        self.font_scale_index = 0
 
95
 
 
96
    def configure_terminal(self):
 
97
        """Sets all customized properties on the terminal
 
98
        """
 
99
        client = GConf.Client.get_default()
 
100
        word_chars = client.get_string(KEY('/general/word_chars'))
 
101
        self.set_word_chars(word_chars)
 
102
        self.set_audible_bell(client.get_bool(KEY('/general/use_audible_bell')))
 
103
        self.set_visible_bell(client.get_bool(KEY('/general/use_visible_bell')))
 
104
        self.set_sensitive(True)
 
105
        self.set_can_default(True)
 
106
        self.set_can_focus(True)
 
107
 
 
108
    def add_matches(self):
 
109
        """Adds all regular expressions declared in TERMINAL_MATCH_EXPRS
 
110
        to the terminal to make vte highlight text that matches them.
 
111
        """
 
112
        # FIXME: match_add is deprecated we should use match_add_regex
 
113
        # witch takes GRegex as parameter but first we need to find
 
114
        # a way to construct GRegex objects (GLib.Regex)
 
115
        #
 
116
        # This is the error happening when trying to create a new
 
117
        # GRegex: https://bugzilla.gnome.org/show_bug.cgi?id=647249
 
118
        pass
 
119
 
 
120
        # for expr in TERMINAL_MATCH_EXPRS:
 
121
        #     tag = self.match_add_gregex(GLib.Regex(expr, 0))
 
122
        #     self.match_set_cursor_type(tag, Gdk.HAND2)
 
123
 
 
124
    def button_press(self, terminal, event):
 
125
        """Handles the button press event in the terminal widget. If
 
126
        any match string is caught, another aplication is open to
 
127
        handle the matched resource uri.
 
128
        """
 
129
        self.matched_value = ''
 
130
        matched_string = self.match_check(
 
131
            int(event.x / self.get_char_width()),
 
132
            int(event.y / self.get_char_height()))
 
133
        value, tag = matched_string
 
134
 
 
135
        if event.button == 1 \
 
136
                and event.get_state() & Gdk.ModifierType.CONTROL_MASK \
 
137
                and value:
 
138
            if TERMINAL_MATCH_TAGS[tag] == 'schema':
 
139
                # value here should not be changed, it is right and
 
140
                # ready to be used.
 
141
                pass
 
142
            elif TERMINAL_MATCH_TAGS[tag] == 'http':
 
143
                value = 'http://%s' % value
 
144
            elif TERMINAL_MATCH_TAGS[tag] == 'email':
 
145
                value = 'mailto:%s' % value
 
146
 
 
147
            Gtk.show_uri(self.get_screen(), value,
 
148
                         GdkX11.x11_get_server_time(self.get_window()))
 
149
        elif event.button == 3 and matched_string:
 
150
            self.matched_value = matched_string[0]
 
151
 
 
152
    def set_font(self, font):
 
153
        self.font = font
 
154
        self.set_font_scale_index(0)
 
155
 
 
156
    def set_font_scale_index(self, scale_index):
 
157
        self.font_scale_index = clamp(scale_index, -6, 12)
 
158
 
 
159
        font = Pango.FontDescription(self.font.to_string())
 
160
        scale_factor = 2 ** (self.font_scale_index / 6)
 
161
        new_size = int(scale_factor * font.get_size())
 
162
 
 
163
        if font.get_size_is_absolute():
 
164
            font.set_absolute_size(new_size)
 
165
        else:
 
166
            font.set_size(new_size)
 
167
 
 
168
        super(Terminal, self).set_font(font)
 
169
 
 
170
    font_scale = property(
 
171
        fset=set_font_scale_index,
 
172
        fget=lambda self: self.font_scale_index
 
173
    )
 
174
 
 
175
    def increase_font_size(self):
 
176
        self.font_scale += 1
 
177
 
 
178
    def decrease_font_size(self):
 
179
        self.font_scale -= 1
 
180
 
 
181
 
 
182
class TerminalBox(Gtk.HBox):
 
183
 
 
184
    """A box to group the terminal and a scrollbar.
 
185
    """
 
186
 
 
187
    def __init__(self):
 
188
        super(TerminalBox, self).__init__()
 
189
        self.terminal = Terminal()
 
190
        self.add_terminal()
 
191
        self.add_scrollbar()
 
192
 
 
193
    def add_terminal(self):
 
194
        """Packs the terminal widget.
 
195
        """
 
196
        self.pack_start(self.terminal, True, True, 0)
 
197
        self.terminal.show()
 
198
 
 
199
    def add_scrollbar(self):
 
200
        """Packs the scrollbar.
 
201
        """
 
202
        adj = self.terminal.get_vadjustment()
 
203
        scroll = Gtk.VScrollbar.new(adj)
 
204
        scroll.set_no_show_all(True)
 
205
        self.pack_start(scroll, False, False, 0)