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 __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.setWindowTitle("First Aid - Debugger")

        self.text_edits = {
        }  # fully expanded path of the file -> associated SourceWidget
        self.toolbar = self.addToolBar("General")
        self.toolbar.setObjectName("ToolbarGeneral")

        self.tab_widget = QTabWidget()
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.tabCloseRequested.connect(self.on_tab_close_requested)
        self.tab_widget.currentChanged.connect(self.on_pos_changed)

        self.setCentralWidget(self.tab_widget)

        _icon = lambda x: QIcon(
            os.path.join(os.path.dirname(__file__), "icons", x + ".svg"))

        self.action_load = self.toolbar.addAction(_icon("folder-outline"),
                                                  "Load Python file (Ctrl+O)",
                                                  self.on_load)
        self.action_load.setShortcut("Ctrl+O")
        self.action_run = self.toolbar.addAction(_icon("run"),
                                                 "Run Python file (Ctrl+R)",
                                                 self.on_run)
        self.action_run.setShortcut("Ctrl+R")
        self.action_bp = self.toolbar.addAction(_icon("record"),
                                                "Toggle breakpoint (F9)",
                                                self.on_toggle_breakpoint)
        self.action_bp.setShortcut("F9")
        self.toolbar.addSeparator()
        self.action_continue = self.toolbar.addAction(_icon("play"),
                                                      "Continue (F5)",
                                                      self.on_continue)
        self.action_continue.setShortcut("F5")
        self.action_step_into = self.toolbar.addAction(
            _icon("debug-step-into"), "Step into (F11)", self.on_step_into)
        self.action_step_into.setShortcut("F11")
        self.action_step_over = self.toolbar.addAction(
            _icon("debug-step-over"), "Step over (F10)", self.on_step_over)
        self.action_step_over.setShortcut("F10")
        self.action_step_out = self.toolbar.addAction(_icon("debug-step-out"),
                                                      "Step out (Shift+F11)",
                                                      self.on_step_out)
        self.action_step_out.setShortcut("Shift+F11")
        self.action_run_to_cursor = self.toolbar.addAction(
            _icon("cursor-default-outline"), "Run to cursor (Ctrl+F10)",
            self.on_run_to_cursor)
        self.action_run_to_cursor.setShortcut("Ctrl+F10")

        self.vars_view = VariablesView()
        self.frames_view = FramesView()

        self.dock_frames = QDockWidget("Frames", self)
        self.dock_frames.setObjectName("DockFrames")
        self.dock_frames.setWidget(self.frames_view)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.dock_frames)

        self.dock_vars = QDockWidget("Variables", self)
        self.dock_vars.setObjectName("DockVariables")
        self.dock_vars.setWidget(self.vars_view)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.dock_vars)

        self.resize(800, 800)

        self.debugger = Debugger(self)

        self.update_buttons()

        settings = QSettings()
        self.restoreGeometry(
            settings.value("/plugins/firstaid/debugger-geometry", ''))
        self.restoreState(
            settings.value("/plugins/firstaid/debugger-windowstate", ''))

        filenames = settings.value("/plugins/firstaid/debugger-files", [])
        if filenames is None:
            filenames = []

        # load files from previous session
        for filename in filenames:
            self.load_file(filename)

        if self.tab_widget.count() > 1:
            self.tab_widget.setCurrentIndex(0)

        # start tracing
        self.start_tracing()