From 7d72481b865fcdb78e8cd26c924f37a997533423 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 5 Jan 2022 18:31:08 +0100 Subject: [PATCH] create base of error dialog in utils --- openpype/tools/loader/widgets.py | 159 ++++++--------------------- openpype/tools/utils/__init__.py | 6 +- openpype/tools/utils/error_dialog.py | 143 ++++++++++++++++++++++++ 3 files changed, 180 insertions(+), 128 deletions(-) create mode 100644 openpype/tools/utils/error_dialog.py diff --git a/openpype/tools/loader/widgets.py b/openpype/tools/loader/widgets.py index a39ac7213a..3accaed5ab 100644 --- a/openpype/tools/loader/widgets.py +++ b/openpype/tools/loader/widgets.py @@ -11,15 +11,16 @@ from Qt import QtWidgets, QtCore, QtGui from avalon import api, pipeline from avalon.lib import HeroVersionType -from openpype.tools.utils import lib as tools_lib +from openpype.tools.utils import ( + ErrorMessageBox, + lib as tools_lib +) from openpype.tools.utils.delegates import ( VersionDelegate, PrettyTimeDelegate ) from openpype.tools.utils.widgets import ( OptionalMenu, - ClickableFrame, - ExpandBtn, PlaceholderLineEdit ) from openpype.tools.utils.views import ( @@ -66,66 +67,12 @@ class OverlayFrame(QtWidgets.QFrame): self.label_widget.setText(label) -class TracebackWidget(QtWidgets.QWidget): - def __init__(self, tb_text, parent): - super(TracebackWidget, self).__init__(parent) - - # Modify text to match html - # - add more replacements when needed - tb_text = ( - tb_text - .replace("<", "<") - .replace(">", ">") - .replace("\n", "
") - .replace(" ", " ") - ) - - expand_btn = ExpandBtn(self) - - clickable_frame = ClickableFrame(self) - clickable_layout = QtWidgets.QHBoxLayout(clickable_frame) - clickable_layout.setContentsMargins(0, 0, 0, 0) - - expand_label = QtWidgets.QLabel("Details", clickable_frame) - clickable_layout.addWidget(expand_label, 0) - clickable_layout.addStretch(1) - - show_details_layout = QtWidgets.QHBoxLayout() - show_details_layout.addWidget(expand_btn, 0) - show_details_layout.addWidget(clickable_frame, 1) - - text_widget = QtWidgets.QLabel(self) - text_widget.setText(tb_text) - text_widget.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) - text_widget.setVisible(False) - - layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.addLayout(show_details_layout, 0) - layout.addWidget(text_widget, 1) - - clickable_frame.clicked.connect(self._on_show_details_click) - expand_btn.clicked.connect(self._on_show_details_click) - - self._expand_btn = expand_btn - self._text_widget = text_widget - - def _on_show_details_click(self): - self._text_widget.setVisible(not self._text_widget.isVisible()) - self._expand_btn.set_collapsed(not self._text_widget.isVisible()) - - -class LoadErrorMessageBox(QtWidgets.QDialog): +class LoadErrorMessageBox(ErrorMessageBox): def __init__(self, messages, parent=None): - super(LoadErrorMessageBox, self).__init__(parent) - self.setWindowTitle("Loading failed") - self.setFocusPolicy(QtCore.Qt.StrongFocus) - - main_label = ( - "Failed to load items" - ) - main_label_widget = QtWidgets.QLabel(main_label, self) + self._messages = messages + super(LoadErrorMessageBox, self).__init__("Loading failed", parent) + def _create_content(self, content_layout): item_name_template = ( "Subset: {}
" "Version: {}
" @@ -133,31 +80,7 @@ class LoadErrorMessageBox(QtWidgets.QDialog): ) exc_msg_template = "{}" - content_scroll = QtWidgets.QScrollArea(self) - content_scroll.setWidgetResizable(True) - - content_widget = QtWidgets.QWidget(content_scroll) - content_scroll.setWidget(content_widget) - - content_layout = QtWidgets.QVBoxLayout(content_widget) - content_layout.setContentsMargins(0, 0, 0, 0) - - report_data = [] - for exc_msg, tb_text, repre, subset, version in messages: - report_message = ( - "During load error happened on Subset: \"{subset}\"" - " Representation: \"{repre}\" Version: {version}" - "\n\nError message: {message}" - ).format( - subset=subset, - repre=repre, - version=version, - message=exc_msg - ) - if tb_text: - report_message += "\n\n{}".format(tb_text) - report_data.append(report_message) - + for exc_msg, tb_text, repre, subset, version in self._messages: line = self._create_line() content_layout.addWidget(line) @@ -175,52 +98,34 @@ class LoadErrorMessageBox(QtWidgets.QDialog): if tb_text: line = self._create_line() - tb_widget = TracebackWidget(tb_text, self) + tb_widget = self._create_traceback_widget(tb_text, self) content_layout.addWidget(line) content_layout.addWidget(tb_widget) - content_layout.addStretch(1) + def _get_report_data(self): + report_data = [] + for exc_msg, tb_text, repre, subset, version in self._messages: + report_message = ( + "During load error happened on Subset: \"{subset}\"" + " Representation: \"{repre}\" Version: {version}" + "\n\nError message: {message}" + ).format( + subset=subset, + repre=repre, + version=version, + message=exc_msg + ) + if tb_text: + report_message += "\n\n{}".format(tb_text) + report_data.append(report_message) + return report_data - copy_report_btn = QtWidgets.QPushButton("Copy report", self) - ok_btn = QtWidgets.QPushButton("OK", self) - - footer_layout = QtWidgets.QHBoxLayout() - footer_layout.addWidget(copy_report_btn, 0) - footer_layout.addStretch(1) - footer_layout.addWidget(ok_btn, 0) - - bottom_line = self._create_line() - body_layout = QtWidgets.QVBoxLayout(self) - body_layout.addWidget(main_label_widget, 0) - body_layout.addWidget(content_scroll, 1) - body_layout.addWidget(bottom_line, 0) - body_layout.addLayout(footer_layout, 0) - - copy_report_btn.clicked.connect(self._on_copy_report) - ok_btn.clicked.connect(self._on_ok_clicked) - - self.resize(660, 350) - - self._report_data = report_data - - def _on_ok_clicked(self): - self.close() - - def _on_copy_report(self): - report_text = (10 * "*").join(self._report_data) - - mime_data = QtCore.QMimeData() - mime_data.setText(report_text) - QtWidgets.QApplication.instance().clipboard().setMimeData( - mime_data + def _create_top_widget(self, parent_widget): + label_widget = QtWidgets.QLabel(parent_widget) + label_widget.setText( + "Failed to load items" ) - - def _create_line(self): - line = QtWidgets.QFrame(self) - line.setObjectName("Separator") - line.setMinimumHeight(2) - line.setMaximumHeight(2) - return line + return label_widget class SubsetWidget(QtWidgets.QWidget): diff --git a/openpype/tools/utils/__init__.py b/openpype/tools/utils/__init__.py index 294b919b5c..4dd6bdd05f 100644 --- a/openpype/tools/utils/__init__.py +++ b/openpype/tools/utils/__init__.py @@ -5,10 +5,14 @@ from .widgets import ( ExpandBtn, ) +from .error_dialog import ErrorMessageBox + __all__ = ( "PlaceholderLineEdit", "BaseClickableFrame", "ClickableFrame", - "ExpandBtn" + "ExpandBtn", + + "ErrorMessageBox" ) diff --git a/openpype/tools/utils/error_dialog.py b/openpype/tools/utils/error_dialog.py new file mode 100644 index 0000000000..2f39ccf139 --- /dev/null +++ b/openpype/tools/utils/error_dialog.py @@ -0,0 +1,143 @@ +from Qt import QtWidgets, QtCore + +from .widgets import ClickableFrame, ExpandBtn + + +class TracebackWidget(QtWidgets.QWidget): + def __init__(self, tb_text, parent): + super(TracebackWidget, self).__init__(parent) + + # Modify text to match html + # - add more replacements when needed + tb_text = ( + tb_text + .replace("<", "<") + .replace(">", ">") + .replace("\n", "
") + .replace(" ", " ") + ) + + expand_btn = ExpandBtn(self) + + clickable_frame = ClickableFrame(self) + clickable_layout = QtWidgets.QHBoxLayout(clickable_frame) + clickable_layout.setContentsMargins(0, 0, 0, 0) + + expand_label = QtWidgets.QLabel("Details", clickable_frame) + clickable_layout.addWidget(expand_label, 0) + clickable_layout.addStretch(1) + + show_details_layout = QtWidgets.QHBoxLayout() + show_details_layout.addWidget(expand_btn, 0) + show_details_layout.addWidget(clickable_frame, 1) + + text_widget = QtWidgets.QLabel(self) + text_widget.setText(tb_text) + text_widget.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) + text_widget.setVisible(False) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(0, 0, 0, 0) + layout.addLayout(show_details_layout, 0) + layout.addWidget(text_widget, 1) + + clickable_frame.clicked.connect(self._on_show_details_click) + expand_btn.clicked.connect(self._on_show_details_click) + + self._expand_btn = expand_btn + self._text_widget = text_widget + + def _on_show_details_click(self): + self._text_widget.setVisible(not self._text_widget.isVisible()) + self._expand_btn.set_collapsed(not self._text_widget.isVisible()) + + +class ErrorMessageBox(QtWidgets.QDialog): + _default_width = 660 + _default_height = 350 + + def __init__(self, title, parent): + super(ErrorMessageBox, self).__init__(parent) + self.setWindowTitle(title) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + top_widget = self._create_top_widget(self) + + content_scroll = QtWidgets.QScrollArea(self) + content_scroll.setWidgetResizable(True) + + content_widget = QtWidgets.QWidget(content_scroll) + content_scroll.setWidget(content_widget) + + content_layout = QtWidgets.QVBoxLayout(content_widget) + content_layout.setContentsMargins(0, 0, 0, 0) + + self._create_content(content_layout) + + content_layout.addStretch(1) + + copy_report_btn = QtWidgets.QPushButton("Copy report", self) + ok_btn = QtWidgets.QPushButton("OK", self) + + footer_layout = QtWidgets.QHBoxLayout() + footer_layout.addWidget(copy_report_btn, 0) + footer_layout.addStretch(1) + footer_layout.addWidget(ok_btn, 0) + + bottom_line = self._create_line() + body_layout = QtWidgets.QVBoxLayout(self) + body_layout.addWidget(top_widget, 0) + body_layout.addWidget(content_scroll, 1) + body_layout.addWidget(bottom_line, 0) + body_layout.addLayout(footer_layout, 0) + + copy_report_btn.clicked.connect(self._on_copy_report) + ok_btn.clicked.connect(self._on_ok_clicked) + + self.resize(self._default_width, self._default_height) + + report_data = self._get_report_data() + if not report_data: + copy_report_btn.setVisible(False) + + self._report_data = report_data + self._content_widget = content_widget + + def _create_top_widget(self, parent_widget): + label_widget = QtWidgets.QLabel(parent_widget) + label_widget.setText( + "Something went wrong" + ) + return label_widget + + def _create_content(self, content_layout): + raise NotImplementedError( + "Method '_fill_content_layout' is not implemented!" + ) + + def _get_report_data(self): + return [] + + def _on_ok_clicked(self): + self.close() + + def _on_copy_report(self): + report_text = (10 * "*").join(self._report_data) + + mime_data = QtCore.QMimeData() + mime_data.setText(report_text) + QtWidgets.QApplication.instance().clipboard().setMimeData( + mime_data + ) + + def _create_line(self): + line = QtWidgets.QFrame(self) + line.setObjectName("Separator") + line.setMinimumHeight(2) + line.setMaximumHeight(2) + return line + + def _create_traceback_widget(self, traceback_text, parent=None): + if parent is None: + parent = self._content_widget + return TracebackWidget(traceback_text, parent)