diff --git a/src/gui/Popups/UnexpectedErrorPopup.qml b/src/gui/Popups/UnexpectedErrorPopup.qml index 9a81ad24..158e5d2e 100644 --- a/src/gui/Popups/UnexpectedErrorPopup.qml +++ b/src/gui/Popups/UnexpectedErrorPopup.qml @@ -9,11 +9,12 @@ import "../Base/Buttons" import "../PythonBridge" as PythonBridge HColumnPopup { - id: popup + id: root - property string errorType - property string message: "" - property string traceback: "" + property var errors: [] // [{type, message, traceback}] + + + contentWidthLimit: Math.min(window.width / 1.5, 864 * theme.uiScale) page.footer: AutoDirectionLayout { PositiveButton { @@ -28,17 +29,37 @@ HColumnPopup { CancelButton { text: qsTr("Ignore") - onClicked: popup.close() + onClicked: root.close() } } + onErrorsChanged: if (errors.length) open() onOpened: reportButton.forceActiveFocus() + onClosed: { + errors = [] + errorsChanged() + } + + Behavior on implicitHeight { HNumberAnimation {} } SummaryLabel { - text: qsTr("Unexpected error occured: %1").arg( - utils.htmlColorize(errorType, theme.colors.accentText), - ) + readonly property string types: { + const colored = [] + const color = theme.colors.accentText + + for (const error of root.errors) { + const coloredType = utils.htmlColorize(error.type, color) + if (! colored.includes(coloredType)) colored.push(coloredType) + } + + return colored.join(", ") + } + textFormat: Text.StyledText + text: + root.errors.length > 1 ? + qsTr("Unexpected errors occured: %1").arg(types) : + qsTr("Unexpected error occured: %1").arg(types) } HScrollView { @@ -48,20 +69,37 @@ HColumnPopup { Layout.fillHeight: true HTextArea { - text: [message, traceback].join("\n\n") || qsTr("No info available") + id: detailsArea readOnly: true font.family: theme.fontFamily.mono focusItemOnTab: hideCheckBox + text: { + const parts = [] + + for (const error of root.errors) { + parts.push(error.type + ": " + (error.message || "...")) + parts.push(error.traceback || qsTr("Traceback missing")) + parts.push("─".repeat(30)) + } + + return parts.slice(0, -1).join("\n\n") // Leave out last ──── + } } } HCheckBox { id: hideCheckBox - text: qsTr("Hide this type of error until restart") - onCheckedChanged: - checked ? - PythonBridge.Globals.hideErrorTypes.add(errorType) : - PythonBridge.Globals.hideErrorTypes.delete(errorType) + text: + root.errors.length > 1 ? + qsTr("Hide these types of error until restart") : + qsTr("Hide this type of error until restart") + + onCheckedChanged: { + for (const error of errors) + checked ? + PythonBridge.Globals.hideErrorTypes.add(error.type) : + PythonBridge.Globals.hideErrorTypes.delete(error.type) + } Layout.fillWidth: true } diff --git a/src/gui/PythonBridge/PythonBridge.qml b/src/gui/PythonBridge/PythonBridge.qml index bfc08685..89c9575e 100644 --- a/src/gui/PythonBridge/PythonBridge.qml +++ b/src/gui/PythonBridge/PythonBridge.qml @@ -60,9 +60,8 @@ Python { return } - window.makePopup( - "Popups/UnexpectedErrorPopup.qml", - { errorType: type, message, traceback }, - ) + const popup = window.mainUI.unexpectedErrorPopup + popup.errors.unshift({type, message, traceback}) + popup.errorsChanged() } } diff --git a/src/gui/UI.qml b/src/gui/UI.qml index 5ef3dc1b..bb9e241f 100644 --- a/src/gui/UI.qml +++ b/src/gui/UI.qml @@ -9,6 +9,7 @@ import QtGraphicalEffects 1.12 import "." import "Base" import "MainPane" +import "Popups" Item { id: mainUI @@ -38,6 +39,7 @@ Item { readonly property alias debugConsole: debugConsole readonly property alias mainPane: mainPane readonly property alias pageLoader: pageLoader + readonly property alias unexpectedErrorPopup: unexpectedErrorPopup readonly property alias fontMetrics: fontMetrics readonly property alias idleManager: idleManager @@ -177,4 +179,8 @@ Item { GlobalTapHandlers { pageLoader: parent } } + + UnexpectedErrorPopup { + id: unexpectedErrorPopup + } }