Updated
This commit is contained in:
139
Scripts/Animation/epic_pose_wrangler/view/log_widget.py
Normal file
139
Scripts/Animation/epic_pose_wrangler/view/log_widget.py
Normal file
@ -0,0 +1,139 @@
|
||||
# Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
import logging
|
||||
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
class LogWidget(logging.Handler):
|
||||
"""
|
||||
Custom Log Handler with embedded QtWidgets.QDockWidget
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(LogWidget, self).__init__()
|
||||
# Set default formatting
|
||||
self.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s', '%Y-%m-%d %H:%M:%S'))
|
||||
# Create dock
|
||||
self._log_dock = QtWidgets.QDockWidget()
|
||||
# Only allow it to be parented to the bottom
|
||||
self._log_dock.setAllowedAreas(QtCore.Qt.BottomDockWidgetArea)
|
||||
|
||||
central_widget = QtWidgets.QWidget()
|
||||
central_widget.setContentsMargins(0, 0, 0, 0)
|
||||
self._log_dock.setWidget(central_widget)
|
||||
main_layout = QtWidgets.QVBoxLayout()
|
||||
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
central_widget.setLayout(main_layout)
|
||||
|
||||
toolbar_layout = QtWidgets.QHBoxLayout()
|
||||
toolbar_layout.setContentsMargins(0, 0, 0, 0)
|
||||
main_layout.addLayout(toolbar_layout)
|
||||
|
||||
self._output_log = QtWidgets.QListWidget()
|
||||
self._output_log.setProperty("Log", True)
|
||||
self._output_log.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
|
||||
self._output_log.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||
self._output_log.customContextMenuRequested.connect(self._show_context_menu)
|
||||
main_layout.addWidget(self._output_log)
|
||||
|
||||
icon_size_px = 25
|
||||
icon_size = QtCore.QSize(icon_size_px, icon_size_px)
|
||||
btn_size_px = 30
|
||||
btn_size = QtCore.QSize(btn_size_px, btn_size_px)
|
||||
|
||||
self._debug_btn = QtWidgets.QPushButton()
|
||||
self._debug_btn.setIcon(QtGui.QIcon(QtGui.QPixmap("PoseWrangler:debug.png")))
|
||||
self._debug_btn.setIconSize(icon_size)
|
||||
self._debug_btn.setProperty("LogButton", True)
|
||||
self._debug_btn.setCheckable(True)
|
||||
self._debug_btn.setChecked(False)
|
||||
self._debug_btn.setFixedSize(btn_size)
|
||||
self._debug_btn.clicked.connect(self._refresh_log)
|
||||
toolbar_layout.addWidget(self._debug_btn)
|
||||
|
||||
self._info_btn = QtWidgets.QPushButton()
|
||||
self._info_btn.setIcon(QtGui.QIcon(QtGui.QPixmap("PoseWrangler:info.png")))
|
||||
self._info_btn.setIconSize(icon_size)
|
||||
self._info_btn.setProperty("LogButton", True)
|
||||
self._info_btn.setCheckable(True)
|
||||
self._info_btn.setChecked(True)
|
||||
self._info_btn.setFixedSize(btn_size)
|
||||
self._info_btn.clicked.connect(self._refresh_log)
|
||||
toolbar_layout.addWidget(self._info_btn)
|
||||
|
||||
self._warning_btn = QtWidgets.QPushButton()
|
||||
self._warning_btn.setIcon(QtGui.QIcon(QtGui.QPixmap("PoseWrangler:warning.png")))
|
||||
self._warning_btn.setIconSize(icon_size)
|
||||
self._warning_btn.setProperty("LogButton", True)
|
||||
self._warning_btn.setCheckable(True)
|
||||
self._warning_btn.setChecked(True)
|
||||
self._warning_btn.setFixedSize(btn_size)
|
||||
self._warning_btn.clicked.connect(self._refresh_log)
|
||||
toolbar_layout.addWidget(self._warning_btn)
|
||||
|
||||
self._error_btn = QtWidgets.QPushButton()
|
||||
self._error_btn.setIcon(QtGui.QIcon(QtGui.QPixmap("PoseWrangler:error.png")))
|
||||
self._error_btn.setIconSize(icon_size)
|
||||
self._error_btn.setProperty("LogButton", True)
|
||||
self._error_btn.setCheckable(True)
|
||||
self._error_btn.setChecked(True)
|
||||
self._error_btn.setFixedSize(btn_size)
|
||||
self._error_btn.clicked.connect(self._refresh_log)
|
||||
toolbar_layout.addWidget(self._error_btn)
|
||||
toolbar_layout.addStretch(0)
|
||||
|
||||
self._clear_log_btn = QtWidgets.QPushButton()
|
||||
self._clear_log_btn.setIcon(QtGui.QIcon(QtGui.QPixmap("PoseWrangler:clear.png")))
|
||||
self._clear_log_btn.setIconSize(icon_size)
|
||||
self._clear_log_btn.setProperty("LogButton", True)
|
||||
self._clear_log_btn.setFixedSize(btn_size)
|
||||
self._clear_log_btn.clicked.connect(self._output_log.clear)
|
||||
toolbar_layout.addWidget(self._clear_log_btn)
|
||||
|
||||
@property
|
||||
def log_dock(self):
|
||||
return self._log_dock
|
||||
|
||||
def emit(self, record):
|
||||
level_colour_map = {
|
||||
logging.DEBUG: QtGui.QColor(91, 192, 222),
|
||||
logging.INFO: QtGui.QColor(247, 247, 247),
|
||||
logging.WARNING: QtGui.QColor(240, 173, 78),
|
||||
logging.ERROR: QtGui.QColor(217, 83, 79)
|
||||
}
|
||||
msg = self.format(record)
|
||||
item = QtWidgets.QListWidgetItem(msg)
|
||||
item.setData(QtCore.Qt.UserRole, record.levelno)
|
||||
item.setForeground(QtGui.QBrush(level_colour_map[record.levelno]))
|
||||
self._output_log.addItem(item)
|
||||
self._refresh_log()
|
||||
|
||||
def _refresh_log(self):
|
||||
level_btn_map = {
|
||||
logging.DEBUG: self._debug_btn,
|
||||
logging.INFO: self._info_btn,
|
||||
logging.WARNING: self._warning_btn,
|
||||
logging.ERROR: self._error_btn
|
||||
}
|
||||
for i in range(0, self._output_log.count()):
|
||||
item = self._output_log.item(i)
|
||||
data = item.data(QtCore.Qt.UserRole)
|
||||
item.setHidden(not level_btn_map[data].isChecked())
|
||||
|
||||
def _copy_to_clipboard(self):
|
||||
clipboard_text = ""
|
||||
for item in self._output_log.selectedItems():
|
||||
text = item.text()
|
||||
clipboard_text += text
|
||||
if text:
|
||||
clipboard_text += "\n"
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
clipboard.setText(clipboard_text)
|
||||
|
||||
def _show_context_menu(self, pos):
|
||||
if not self._output_log.selectedItems():
|
||||
return
|
||||
menu = QtWidgets.QMenu(parent=self._output_log)
|
||||
copy_action = menu.addAction("Copy")
|
||||
copy_action.triggered.connect(self._copy_to_clipboard)
|
||||
menu.exec_(QtGui.QCursor.pos())
|
Reference in New Issue
Block a user