File: log.py

package info (click to toggle)
git-cola 4.16.0-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 6,844 kB
  • sloc: python: 37,972; sh: 298; makefile: 223; xml: 106; tcl: 62
file content (151 lines) | stat: -rw-r--r-- 5,084 bytes parent folder | download | duplicates (2)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import time

from qtpy import QtGui
from qtpy import QtWidgets
from qtpy.QtCore import Qt
from qtpy.QtCore import Signal

from .. import core
from .. import qtutils
from ..i18n import N_
from . import defs
from . import text
from . import standard


class LogWidget(QtWidgets.QFrame):
    """A simple dialog to display command logs."""

    channel = Signal(object)

    def __init__(self, context, parent=None, output=None, display_usage=True):
        QtWidgets.QFrame.__init__(self, parent)

        self.output_text = text.VimTextEdit(context, parent=self)
        self.highlighter = LogSyntaxHighlighter(self.output_text.document())
        if output:
            self.set_output(output)
        self.main_layout = qtutils.vbox(defs.no_margin, defs.spacing, self.output_text)
        self.setLayout(self.main_layout)
        self.setFocusProxy(self.output_text)
        self.channel.connect(self.append, type=Qt.QueuedConnection)
        clear_action = qtutils.add_action(self, N_('Clear'), self.output_text.clear)
        self.output_text.menu_actions.append(clear_action)
        if display_usage:
            self._display_usage()

    def _display_usage(self):
        """Show the default usage message"""
        self.log(N_('Right-click links to open:'))
        self.log('  Documentation: https://git-cola.readthedocs.io/en/latest/')
        self.log(
            '  Keyboard Shortcuts: '
            'https://git-cola.gitlab.io/share/doc/git-cola/hotkeys.html\n'
        )

    def clear(self):
        self.output_text.clear()

    def set_output(self, output):
        self.output_text.set_value(output)

    def log_status(self, status, out, err=None):
        msg = []
        if out:
            msg.append(out)
        if err:
            msg.append(err)
        if status:
            msg.append(N_('exit code %s') % status)
        self.log('\n'.join(msg))

    def append(self, msg):
        """Append to the end of the log message"""
        if not msg:
            return
        msg = core.decode(msg)
        cursor = self.output_text.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        text_widget = self.output_text
        # NOTE: the ':  ' colon-SP-SP suffix is for the syntax highlighter
        prefix = core.decode(time.strftime('%Y-%m-%d %H:%M:%S:  '))  # ISO-8601
        for line in msg.split('\n'):
            cursor.insertText(prefix + line + '\n')
        cursor.movePosition(QtGui.QTextCursor.End)
        text_widget.setTextCursor(cursor)

    def log(self, msg):
        """Add output to the log window"""
        # Funnel through a Qt queued to allow thread-safe logging from
        # asynchronous QRunnables, filesystem notification, etc.
        self.channel.emit(msg)


class LogSyntaxHighlighter(QtGui.QSyntaxHighlighter):
    """Implements the log syntax highlighting"""

    def __init__(self, doc):
        QtGui.QSyntaxHighlighter.__init__(self, doc)
        palette = QtGui.QPalette()
        QPalette = QtGui.QPalette
        self.disabled_color = palette.color(QPalette.Disabled, QPalette.Text)

    def highlightBlock(self, block_text):
        end = block_text.find(':  ')
        if end > 0:
            self.setFormat(0, end + 1, self.disabled_color)


class RemoteMessage(standard.Dialog):
    """Provides a dialog to display remote messages"""

    def __init__(self, context, message, parent=None):
        standard.Dialog.__init__(self, parent=parent)
        self.context = context
        self.model = context.model

        self.setWindowTitle(N_('Remote Messages'))
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        self.text = text.VimTextEdit(context, parent=self)
        self.text.set_value(message)
        # Set a monospace font, as some remote git messages include ASCII art
        self.text.setFont(qtutils.default_monospace_font())

        self.close_button = qtutils.close_button()
        self.close_button.setDefault(True)

        self.bottom_layout = qtutils.hbox(
            defs.no_margin, defs.button_spacing, qtutils.STRETCH, self.close_button
        )

        self.main_layout = qtutils.vbox(
            defs.no_margin, defs.spacing, self.text, self.bottom_layout
        )
        self.setLayout(self.main_layout)

        qtutils.connect_button(self.close_button, self.close)

        self.resize(defs.scale(720), defs.scale(400))


def show_remote_messages(parent, context):
    """Return a closure for the `result` callback from RunTask.start()"""

    def show_remote_messages_callback(result):
        """Display the asynchronous "result" when remote tasks complete"""
        _, out, err = result
        output = '\n\n'.join(x for x in (out, err) if x)
        if output:
            message = N_('Right-click links to open:') + '\n\n' + output
        else:
            message = output

        # Display a window if the remote sent a message
        if message:
            view = RemoteMessage(context, message, parent=parent)
            view.show()
            view.exec_()

    return show_remote_messages_callback