Add an error dialog and use it to show plugin load/unload errors.
Will be used later for errors in plugin execution and general errors from signal handlers and etc. "Copy to PasteBin" still not implemented.
This commit is contained in:
parent
0584827087
commit
5c4ab7a592
54
src/mcedit2/dialogs/error_dialog.py
Normal file
54
src/mcedit2/dialogs/error_dialog.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""
|
||||
error_dialog
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import logging
|
||||
import traceback
|
||||
import sys
|
||||
import platform
|
||||
|
||||
from PySide import QtGui
|
||||
from mcedit2.util import qglcontext
|
||||
|
||||
from mcedit2.util.load_ui import load_ui
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def showErrorDialog(text, tb, fatal):
|
||||
dialog = ErrorDialog(text, tb, fatal)
|
||||
dialog.exec_()
|
||||
|
||||
class ErrorDialog(QtGui.QDialog):
|
||||
"""
|
||||
A dialog for displaying an error traceback when something goes wrong.
|
||||
|
||||
Used to report compile and run errors for plugin modules and classes, and might be
|
||||
used to report errors in MCEdit itself during signal or event handlers.
|
||||
"""
|
||||
def __init__(self, text, exc_info, fatal):
|
||||
super(ErrorDialog, self).__init__()
|
||||
load_ui("error_dialog.ui", baseinstance=self)
|
||||
|
||||
exc_type, exc_value, exc_tb = exc_info
|
||||
|
||||
self.errorDescriptionLabel.setText(text)
|
||||
tbText = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
|
||||
|
||||
contextInfo = qglcontext.getContextInfo() or ""
|
||||
|
||||
from mcedit2 import __version__
|
||||
tbText = "MCEdit version: %s\n" \
|
||||
"Python version: %s\n" \
|
||||
"Platform: %s\n" \
|
||||
"System version: %s\n" \
|
||||
"Processor: %s\n" \
|
||||
"\n" \
|
||||
"%s\n" \
|
||||
"------\n\n" \
|
||||
"%s" % (__version__, sys.version, sys.platform,
|
||||
platform.platform(), platform.processor(),
|
||||
contextInfo, tbText)
|
||||
self.tracebackView.setText(tbText)
|
||||
|
||||
self.restartMCEditLabel.setVisible(fatal)
|
||||
|
@ -6,6 +6,7 @@ import logging
|
||||
from PySide import QtGui, QtCore
|
||||
from PySide.QtCore import Qt
|
||||
from mcedit2 import plugins
|
||||
from mcedit2.dialogs.error_dialog import showErrorDialog
|
||||
from mcedit2.util.load_ui import load_ui
|
||||
from mcedit2.util.resources import resourcePath
|
||||
|
||||
@ -77,9 +78,13 @@ class PluginsTableModel(QtCore.QAbstractTableModel):
|
||||
pluginRef.enabled = value
|
||||
|
||||
if value:
|
||||
pluginRef.load()
|
||||
if not pluginRef.load():
|
||||
showErrorDialog("%s while loading plugin \"%s\"" % (pluginRef.loadError[0].__name__, pluginRef.displayName), pluginRef.loadError, False)
|
||||
|
||||
else:
|
||||
pluginRef.unload()
|
||||
if not pluginRef.unload():
|
||||
showErrorDialog("%s while unloading plugin \"%s\"" % (pluginRef.unloadError[0].__name__, pluginRef.displayName), pluginRef.unloadError, False)
|
||||
|
||||
|
||||
self.dataChanged.emit(index, index)
|
||||
|
||||
|
@ -12,6 +12,7 @@ import numpy
|
||||
import sys
|
||||
from mcedit2 import plugins
|
||||
from mcedit2.appsettings import RecentFilesSetting, EnableLightingSetting, DevModeSetting
|
||||
from mcedit2.dialogs.error_dialog import showErrorDialog
|
||||
from mcedit2.dialogs.plugins_dialog import PluginsDialog
|
||||
from mcedit2.library import LibraryWidget
|
||||
|
||||
@ -339,7 +340,8 @@ class MCEditApp(QtGui.QApplication):
|
||||
|
||||
for pluginRef in plugins.getAllPlugins():
|
||||
if pluginRef.enabled:
|
||||
pluginRef.load()
|
||||
if not pluginRef.load():
|
||||
showErrorDialog("%s while loading plugin \"%s\"" % (pluginRef.loadError[0].__name__, pluginRef.displayName), pluginRef.loadError, False)
|
||||
|
||||
log.info("Opening worlds from command line.")
|
||||
|
||||
@ -956,5 +958,7 @@ class MCEditApp(QtGui.QApplication):
|
||||
for pluginRef in plugins.getAllPlugins():
|
||||
if pluginRef.checkTimestamps():
|
||||
log.info("Plugin %s changed. Reloading plugin module...", pluginRef.displayName)
|
||||
pluginRef.unload()
|
||||
pluginRef.load()
|
||||
if not pluginRef.unload():
|
||||
showErrorDialog("%s while unloading plugin \"%s\"" % (pluginRef.unloadError[0].__name__, pluginRef.displayName), pluginRef.unloadError, False)
|
||||
if not pluginRef.load():
|
||||
showErrorDialog("%s while loading plugin \"%s\"" % (pluginRef.loadError[0].__name__, pluginRef.displayName), pluginRef.loadError, False)
|
||||
|
@ -121,14 +121,17 @@ class PluginRef(object):
|
||||
|
||||
log.info("Loaded %s (%s)", self.filename, self.displayName)
|
||||
except Exception as e:
|
||||
self.loadError = traceback.format_exc()
|
||||
self.loadError = sys.exc_info()
|
||||
log.exception("Error while loading plugin from %s: %r", self.filename, e)
|
||||
return False
|
||||
else:
|
||||
self.loadError = None
|
||||
finally:
|
||||
if io:
|
||||
io.close()
|
||||
|
||||
return True
|
||||
|
||||
def unload(self):
|
||||
if self.pluginModule is None:
|
||||
return
|
||||
@ -139,12 +142,14 @@ class PluginRef(object):
|
||||
sys.modules.pop(k)
|
||||
break
|
||||
except Exception as e:
|
||||
self.unloadError = traceback.format_exc()
|
||||
self.loadError = sys.exc_info()
|
||||
log.exception("Error while unloading plugin from %s: %r", self.filename, e)
|
||||
return False
|
||||
else:
|
||||
self.unloadError = None
|
||||
|
||||
self.pluginModule = None
|
||||
return True
|
||||
|
||||
@property
|
||||
def isLoaded(self):
|
||||
|
136
src/mcedit2/ui/error_dialog.ui
Normal file
136
src/mcedit2/ui/error_dialog.ui
Normal file
@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>690</width>
|
||||
<height>550</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MCEdit Error</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-size:12pt;">An Error Has Occurred:</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="errorDescriptionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(no error yet!)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="restartMCEditLabel">
|
||||
<property name="text">
|
||||
<string>It is recommended to undo the last command, save your work, and restart MCEdit.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Error Details:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="tracebackView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Send this error report to the plugin or application developer to help get it fixed. </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Clicking "Copy to PasteBin" will copy a Pastebin URL to your clipboard.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="copyToPastebinButton">
|
||||
<property name="text">
|
||||
<string>Copy to PasteBin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="continueButton">
|
||||
<property name="text">
|
||||
<string>Continue</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>continueButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>650</x>
|
||||
<y>523</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>505</x>
|
||||
<y>5</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -9,6 +9,11 @@ import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
_lastAcquiredContextInfo = None
|
||||
|
||||
def getContextInfo():
|
||||
return _lastAcquiredContextInfo
|
||||
|
||||
def setDefaultFormat():
|
||||
oglFormat = QtOpenGL.QGLFormat()
|
||||
oglFormat.setVersion(1, 3)
|
||||
@ -17,6 +22,7 @@ def setDefaultFormat():
|
||||
|
||||
def validateQGLContext(context):
|
||||
context.makeCurrent()
|
||||
|
||||
versionFlags = QtOpenGL.QGLFormat.openGLVersionFlags()
|
||||
log.info("OpenGL Version Info:")
|
||||
for flag in (
|
||||
@ -61,6 +67,8 @@ def validateQGLContext(context):
|
||||
detailedText += "GL_RENDERER: %s\n" % GL.glGetString(GL.GL_RENDERER)
|
||||
|
||||
log.info("%s", detailedText)
|
||||
global _lastAcquiredContextInfo
|
||||
_lastAcquiredContextInfo = detailedText
|
||||
|
||||
if (not context.isValid() or not actualFormat.directRendering()
|
||||
or not versionFlags & QtOpenGL.QGLFormat.OpenGL_Version_1_3
|
||||
|
Reference in New Issue
Block a user