4 from qtpy
import QtWidgets
5 from qtpy
.QtCore
import Qt
6 from qtpy
.QtCore
import Signal
13 from . import standard
16 class LogWidget(QtWidgets
.QFrame
):
17 """A simple dialog to display command logs."""
19 channel
= Signal(object)
21 def __init__(self
, context
, parent
=None, output
=None):
22 QtWidgets
.QFrame
.__init
__(self
, parent
)
24 self
.output_text
= text
.VimTextEdit(context
, parent
=self
)
25 self
.highlighter
= LogSyntaxHighlighter(self
.output_text
.document())
27 self
.set_output(output
)
28 self
.main_layout
= qtutils
.vbox(defs
.no_margin
, defs
.spacing
, self
.output_text
)
29 self
.setLayout(self
.main_layout
)
30 self
.channel
.connect(self
.append
, type=Qt
.QueuedConnection
)
31 self
.log(N_('Right-click links to open:'))
32 self
.log(' Documentation: https://git-cola.readthedocs.io/en/latest/')
34 ' Keyboard Shortcuts: '
35 'https://git-cola.gitlab.io/share/doc/git-cola/hotkeys.html\n'
39 self
.output_text
.clear()
41 def set_output(self
, output
):
42 self
.output_text
.set_value(output
)
44 def log_status(self
, status
, out
, err
=None):
51 msg
.append(N_('exit code %s') % status
)
52 self
.log('\n'.join(msg
))
54 def append(self
, msg
):
55 """Append to the end of the log message"""
58 msg
= core
.decode(msg
)
59 cursor
= self
.output_text
.textCursor()
60 cursor
.movePosition(cursor
.End
)
61 text_widget
= self
.output_text
62 # NOTE: the ': ' colon-SP-SP suffix is for the syntax highlighter
63 prefix
= core
.decode(time
.strftime('%Y-%m-%d %H:%M:%S: ')) # ISO-8601
64 for line
in msg
.split('\n'):
65 cursor
.insertText(prefix
+ line
+ '\n')
66 cursor
.movePosition(cursor
.End
)
67 text_widget
.setTextCursor(cursor
)
70 """Add output to the log window"""
71 # Funnel through a Qt queued to allow thread-safe logging from
72 # asynchronous QRunnables, filesystem notification, etc.
73 self
.channel
.emit(msg
)
76 class LogSyntaxHighlighter(QtGui
.QSyntaxHighlighter
):
77 """Implements the log syntax highlighting"""
79 def __init__(self
, doc
):
80 QtGui
.QSyntaxHighlighter
.__init
__(self
, doc
)
81 palette
= QtGui
.QPalette()
82 QPalette
= QtGui
.QPalette
83 self
.disabled_color
= palette
.color(QPalette
.Disabled
, QPalette
.Text
)
85 def highlightBlock(self
, block_text
):
86 end
= block_text
.find(': ')
88 self
.setFormat(0, end
+ 1, self
.disabled_color
)
91 class RemoteMessage(standard
.Dialog
):
92 """Provides a dialog to display remote messages"""
94 def __init__(self
, context
, message
, parent
=None):
95 standard
.Dialog
.__init
__(self
, parent
=parent
)
96 self
.context
= context
97 self
.model
= context
.model
99 self
.setWindowTitle(N_('Remote Messages'))
100 if parent
is not None:
101 self
.setWindowModality(Qt
.WindowModal
)
103 self
.text
= text
.VimTextEdit(context
, parent
=self
)
104 self
.text
.set_value(message
)
105 # Set a monospace font, as some remote git messages include ASCII art
106 self
.text
.setFont(qtutils
.default_monospace_font())
108 self
.close_button
= qtutils
.close_button()
109 self
.close_button
.setDefault(True)
111 self
.bottom_layout
= qtutils
.hbox(
112 defs
.no_margin
, defs
.button_spacing
, qtutils
.STRETCH
, self
.close_button
115 self
.main_layout
= qtutils
.vbox(
116 defs
.no_margin
, defs
.spacing
, self
.text
, self
.bottom_layout
118 self
.setLayout(self
.main_layout
)
120 qtutils
.connect_button(self
.close_button
, self
.close
)
122 self
.resize(defs
.scale(720), defs
.scale(400))
125 def show_remote_messages(context
):
126 """Return a closure for the `result` callback from RunTask.start()"""
128 def show_remote_messages_callback(result
):
129 """Display the asynchronous "result" when remote tasks complete"""
131 output
= '\n\n'.join(x
for x
in (out
, err
) if x
)
133 message
= N_('Right-click links to open:') + '\n\n' + output
137 # Display a window if the remote sent a message
139 view
= RemoteMessage(context
, message
, parent
=context
.view
)
143 return show_remote_messages_callback