class DebugWidget(QWidget):
    def __init__(self, exc_info, parent=None):
        QWidget.__init__(self, parent)

        etype, value, tb = exc_info

        self.tb = tb
        self.entries = traceback.extract_tb(tb)

        self.setWindowTitle('Python Error')

        msg = unicode(value).replace("\n", "<br>").replace(" ", "&nbsp;")
        self.error = QLabel("<h1>" + etype.__name__ + "</h1><b>" + msg +
                            "</b>")
        self.error.setTextInteractionFlags(Qt.TextSelectableByMouse)

        self.frames = FramesView()
        self.frames.setTraceback(tb)
        self.frames.selectionModel().currentChanged.connect(
            self.current_frame_changed)

        self.source = SourceView()

        self.splitterSrc = QSplitter(Qt.Horizontal)
        self.splitterSrc.addWidget(self.frames)
        self.splitterSrc.addWidget(self.source)
        self.splitterSrc.setStretchFactor(0, 1)
        self.splitterSrc.setStretchFactor(1, 2)

        self.variables = VariablesView()

        self.console = ConsoleWidget(exc_info)

        self.splitterMain = QSplitter(Qt.Vertical)
        self.splitterMain.addWidget(self.splitterSrc)
        self.splitterMain.addWidget(self.variables)
        self.splitterMain.addWidget(self.console)

        l = QVBoxLayout()
        l.addWidget(self.error)
        l.addWidget(self.splitterMain)
        self.setLayout(l)

        self.resize(800, 600)

        s = QSettings()
        self.splitterSrc.restoreState(s.value("/FirstAid/splitterSrc", ""))
        self.splitterMain.restoreState(s.value("/FirstAid/splitterMain", ""))
        self.restoreGeometry(s.value("/FirstAid/geometry", ""))

        # select the last frame
        self.frames.setCurrentIndex(
            self.frames.model().index(len(self.entries) - 1))

    def closeEvent(self, event):
        s = QSettings()
        s.setValue("/FirstAid/splitterSrc", self.splitterSrc.saveState())
        s.setValue("/FirstAid/splitterMain", self.splitterMain.saveState())
        s.setValue("/FirstAid/geometry", self.saveGeometry())
        QWidget.closeEvent(self, event)

    def current_frame_changed(self, current, previous):
        row = current.row()
        if row >= 0 and row < len(self.entries):
            self.go_to_frame(row)

    def go_to_frame(self, index):

        filename = self.entries[index][0]
        lineno = self.entries[index][1]

        self.source.openFile(filename)
        self.source.jumpToLine(lineno)

        local_vars = frame_from_traceback(self.tb, index).f_locals
        self.variables.setVariables(local_vars)

        self.console.go_to_frame(index)
class DebugWidget(QWidget):
    def __init__(self, exc_info, parent=None):
        QWidget.__init__(self, parent)

        etype, value, tb = exc_info

        self.tb = tb
        self.entries = traceback.extract_tb(tb)

        self.setWindowTitle('Python Error')

        msg = unicode(value).replace("\n", "<br>").replace(" ", "&nbsp;")
        self.error = QLabel("<h1>"+etype.__name__+"</h1><b>"+msg+"</b>")
        self.error.setTextInteractionFlags(Qt.TextSelectableByMouse)

        self.frames = FramesView()
        self.frames.setTraceback(tb)
        self.frames.selectionModel().currentChanged.connect(self.current_frame_changed)

        self.source = SourceView()

        self.splitterSrc = QSplitter(Qt.Horizontal)
        self.splitterSrc.addWidget(self.frames)
        self.splitterSrc.addWidget(self.source)
        self.splitterSrc.setStretchFactor(0, 1)
        self.splitterSrc.setStretchFactor(1, 2)

        self.variables = VariablesView()

        self.console = ConsoleWidget(exc_info)

        self.splitterMain = QSplitter(Qt.Vertical)
        self.splitterMain.addWidget(self.splitterSrc)
        self.splitterMain.addWidget(self.variables)
        self.splitterMain.addWidget(self.console)

        l = QVBoxLayout()
        l.addWidget(self.error)
        l.addWidget(self.splitterMain)
        self.setLayout(l)

        self.resize(800,600)

        s = QSettings()
        self.splitterSrc.restoreState(s.value("/FirstAid/splitterSrc", ""))
        self.splitterMain.restoreState(s.value("/FirstAid/splitterMain", ""))
        self.restoreGeometry(s.value("/FirstAid/geometry", ""))

        # select the last frame
        self.frames.setCurrentIndex(self.frames.model().index(len(self.entries)-1))

    def closeEvent(self, event):
        s = QSettings()
        s.setValue("/FirstAid/splitterSrc", self.splitterSrc.saveState())
        s.setValue("/FirstAid/splitterMain", self.splitterMain.saveState())
        s.setValue("/FirstAid/geometry", self.saveGeometry())
        QWidget.closeEvent(self, event)

    def current_frame_changed(self, current, previous):
        row = current.row()
        if row >= 0 and row < len(self.entries):
            self.go_to_frame(row)

    def go_to_frame(self, index):

        filename = self.entries[index][0]
        lineno = self.entries[index][1]

        self.source.openFile(filename)
        self.source.jumpToLine(lineno)

        local_vars = frame_from_traceback(self.tb, index).f_locals
        self.variables.setVariables(local_vars)

        self.console.go_to_frame(index)