Exemple #1
0
    def __init__(self):
        """Initialize the application

        Initializes all the different parts of the application.

        Creates the PugdebugDebugger object, sets up the application UI,
        connects signals to slots.
        """
        super(Pugdebug, self).__init__()

        self.debugger = PugdebugDebugger()

        # UI elements
        self.main_window = PugdebugMainWindow()
        self.file_browser = self.main_window.get_file_browser()
        self.projects_browser = self.main_window.get_projects_browser()
        self.document_viewer = self.main_window.get_document_viewer()
        self.variable_viewer = self.main_window.get_variable_viewer()
        self.stacktrace_viewer = self.main_window.get_stacktrace_viewer()
        self.breakpoint_viewer = self.main_window.get_breakpoint_viewer()
        self.expression_viewer = self.main_window.get_expression_viewer()

        self.documents = PugdebugDocuments()

        self.connect_signals()

        signal.signal(signal.SIGINT, signal.SIG_DFL)
        if settings.get_last_files('project/' + projects.active() +
                                   '/recent_files'):
            for item in settings.get_last_files('project/' +
                                                projects.active() +
                                                '/recent_files'):
                self.open_document(item, False)
Exemple #2
0
    def __set_debugger_features(self):
        with settings.open_group('project/' + projects.active()):
            max_depth = settings.value('debugger/max_depth')
            max_children = settings.value('debugger/max_children')
            max_data = settings.value('debugger/max_data')

        command = 'feature_set -i %d -n max_depth -v %d' % (
            self.__get_transaction_id(),
            max_depth
        )
        self.__send_command(command)

        command = 'feature_set -i %d -n max_children -v %d' % (
            self.__get_transaction_id(),
            max_children
        )
        self.__send_command(command)

        command = 'feature_set -i %d -n max_data -v %d' % (
            self.__get_transaction_id(),
            max_data
        )
        self.__send_command(command)

        return True
Exemple #3
0
    def __init__(self, parent=None):
        super().__init__(parent)

        model = get_instance()
        self.setModel(model)

        self.update_root_path()
        model.rootPathChanged.connect(self.update_root_path)
        model.root_path_change_failed.connect(self.update_root_path)

        self.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.header().setStretchLastSection(False)
        self.setHeaderHidden(True)

        # Hide extra columns (Size, Type, Date Modified)
        self.setColumnHidden(1, True)
        self.setColumnHidden(2, True)
        self.setColumnHidden(3, True)

        self.activated.connect(model.activate_item)
        for item in settings.get_last_files('project/' + projects.active() +
                                            '/last_folders'):
            self.expand(model.index(item))
        self.collapsed.connect(self.remove_last_folder)
        self.expanded.connect(self.save_last_folder)
Exemple #4
0
    def init_connection(self):
        """Init a new connection

        Read in the init message from xdebug and decide based on the
        idekey should this connection be accepted or not.

        Do note that it is not needed to call it from a new thread, as
        it is already called from a thread separate from the main application
        thread and thus should not block the main thread.
        """
        idekey = settings.value('project/' + projects.active() +
                                '/debugger/idekey')

        response = self.__receive_message()

        init_message = self.parser.parse_init_message(response)

        # See if the init message from xdebug is meant for us
        if idekey != '' and ('idekey' not in init_message or
                             init_message['idekey'] != idekey):
            return False

        self.init_message = init_message

        return True
Exemple #5
0
 def __cut_filename(self, filename):
     with settings.open_group('project/' + projects.active()):
         path_map = settings.value('path/path_mapping')
         if len(path_map) > 0:
             path_map = path_map.rstrip('/')
             if filename.startswith(path_map):
                 return '~' + filename[len(path_map):]
         else:
             root = settings.value('path/project_root')
             root = root.rstrip('/')
             if filename.startswith(root):
                 return '~' + filename[len(root):]
         return filename
Exemple #6
0
    def __listen(self, socket_server):
        """Listen to new incomming connections

        For every accepted connection, see if it is valid and emit a signal
        with that new connection.

        Otherwise silently disregard that connection.
        """
        with settings.open_group('project/' + projects.active()):
            host = settings.value('debugger/host')
            port_number = settings.value('debugger/port_number')

        try:
            socket_server.bind((host, port_number))
            socket_server.listen(5)

            while self.wait_for_accept:
                try:
                    sock, address = socket_server.accept()
                    sock.settimeout(None)

                    if sock is not None:
                        connection = PugdebugServerConnection(sock)

                        try:
                            is_valid = connection.init_connection()
                        except OSError as e:
                            # in case the debugged program closes
                            # the connection
                            is_valid = False
                            self.server_error_signal.emit(
                                '%s (during connection initialization)' %
                                e.strerror
                            )

                        if is_valid and self.wait_for_accept:
                            self.new_connection_established_signal.emit(
                                connection
                            )
                        else:
                            connection.disconnect()
                except socket.timeout:
                    pass

        except OSError as e:
            self.server_error_signal.emit(e.strerror)
        finally:
            socket_server.close()

        if not self.wait_for_accept:
            self.server_stopped_signal.emit()
Exemple #7
0
    def __get_path_mapped_to_remote(self, path):
        """Get a path mapped to remote

        Turns a path like /home/user/local/path to /var/www
        """
        with settings.open_group('project/' + projects.active()):
            root_path = settings.value('path/project_root')
            path_map = settings.value('path/path_mapping')

        if len(path_map) > 0 and path.find(root_path) == 0:
            path_map = path_map.rstrip('/')
            root_path = root_path.rstrip('/')
            path = path[len(root_path):]
            path = "%s%s" % (path_map, path)

        return path
Exemple #8
0
    def handle_debugging_post_start(self):
        """Handle post start debugging

        If the code should not break at first line, run the debugger.
        """
        logging.debug("Post start")
        break_at_first_line = settings.value('project/' + projects.active() +
                                             '/debugger/break_at_first_line')

        logging.debug("Break at first line: %s" %
                      ('Yes' if break_at_first_line else 'No'))

        if not break_at_first_line:
            self.run_debug()
        else:
            self.step_into()
Exemple #9
0
    def __get_path_mapped_to_local(self, path, map_paths=True):
        """Get a path mapped to local

        Turns a path like /var/www into /home/user/local/path
        """
        with settings.open_group('project/' + projects.active()):
            root_path = settings.value('path/project_root')
            path_map = settings.value('path/path_mapping')

        if (len(path_map) > 0 and map_paths is True
                and path.find(path_map) == 0):
            path_map = path_map.rstrip('/')
            path = path[len(path_map):]
            path = "%s%s" % (root_path, path)

            if not os.path.isfile(path):
                return False

        return path
Exemple #10
0
    def close_document(self, tab_index):
        """Close a document

        Get the document from the tab.
        Delete the document.
        Remove the tab.
        """
        document_widget = self.document_viewer.get_document(tab_index)
        path = document_widget.get_path()

        logging.debug("Closing document: %s" % path)

        self.documents.close_document(path)
        document_widget.deleteLater()
        self.document_viewer.close_tab(tab_index)

        self.remove_stale_breakpoints(path)
        settings.remove_last_file(
            'project/' + projects.active() + '/recent_files', path)
Exemple #11
0
    def start_listening(self):
        """Start listening to new incomming connections

        Clear the variable viewer.

        Clear the stacktrace viewer.

        Remove all line highlights.

        Start a debugging session.
        """
        logging.debug("Start listening")

        break_at_first_line = settings.value('project/' + projects.active() +
                                             '/debugger/break_at_first_line')

        logging.debug("Break at first line: %s" %
                      ('Yes' if break_at_first_line else 'No'))

        start_debugging = True

        if not break_at_first_line and len(self.breakpoints) == 0:
            messageBox = QMessageBox()
            messageBox.setText("There are no breakpoints set and the break at"
                               " first line setting is turned off.")
            messageBox.setInformativeText("Are you sure you want to start"
                                          " debugging?")
            messageBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            answer = messageBox.exec_()

            if answer == QMessageBox.No:
                start_debugging = False
                logging.debug("Don't start debugging, no breakpoints")

        if start_debugging:
            self.variable_viewer.clear()
            self.stacktrace_viewer.clear()

            self.document_viewer.remove_line_highlights()

            self.debugger.start_listening()
            self.main_window.set_debugging_status(1)
Exemple #12
0
 def update_window_title(self):
     self.setWindowTitle("pugdebug / " + projects.active())
Exemple #13
0
 def open_local_document(self, path):
     settings.set_last_file(
         'project/' + projects.active() + '/recent_files', path)
     return self.open_document(path, False)
Exemple #14
0
 def remove_last_folder(self, index):
     model = get_instance()
     settings.remove_last_file(
         'project/' + projects.active() + '/last_folders',
         model.filePath(index))
Exemple #15
0
 def update_root_path(self):
     project_root = settings.value('project/' + projects.active() +
                                   '/path/project_root')
     self.setRootPath(project_root)
Exemple #16
0
 def exec(self):
     self.project_root = settings.value('project/' + projects.active() +
                                        '/path/project_root')
     self.file_search = PugdebugFileSearch(self, self.project_root)
     super(PugdebugFileSearchWindow, self).exec()