File: C:/Users/fred/anaconda3/Lib/site-packages/spyder/plugins/breakpoints/plugin.py
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2009- Spyder Project Contributors
#
# Distributed under the terms of the MIT License
# (see spyder/__init__.py for details)
# -----------------------------------------------------------------------------
"""
Breakpoint Plugin.
"""
# Standard library imports
import os.path as osp
# Third party imports
from qtpy.QtCore import Signal
# Local imports
from spyder.api.plugins import Plugins, SpyderDockablePlugin
from spyder.api.plugin_registration.decorators import (
on_plugin_available, on_plugin_teardown)
from spyder.api.translations import _
from spyder.plugins.breakpoints.widgets.main_widget import BreakpointWidget
from spyder.plugins.mainmenu.api import ApplicationMenus
# --- Constants
# ----------------------------------------------------------------------------
class BreakpointsActions:
ListBreakpoints = 'list_breakpoints_action'
# --- Plugin
# ----------------------------------------------------------------------------
class Breakpoints(SpyderDockablePlugin):
"""
Breakpoint list Plugin.
"""
NAME = 'breakpoints'
REQUIRES = [Plugins.Editor]
OPTIONAL = [Plugins.MainMenu]
TABIFY = [Plugins.Help]
WIDGET_CLASS = BreakpointWidget
CONF_SECTION = NAME
CONF_FILE = False
# --- Signals
# ------------------------------------------------------------------------
sig_clear_all_breakpoints_requested = Signal()
"""
This signal is emitted to send a request to clear all assigned
breakpoints.
"""
sig_clear_breakpoint_requested = Signal(str, int)
"""
This signal is emitted to send a request to clear a single breakpoint.
Parameters
----------
filename: str
The path to filename containing the breakpoint.
line_number: int
The line number of the breakpoint.
"""
sig_edit_goto_requested = Signal(str, int, str)
"""
Send a request to open a file in the editor at a given row and word.
Parameters
----------
filename: str
The path to the filename containing the breakpoint.
line_number: int
The line number of the breakpoint.
word: str
Text `word` to select on given `line_number`.
"""
sig_conditional_breakpoint_requested = Signal()
"""
Send a request to set/edit a condition on a single selected breakpoint.
"""
# --- SpyderDockablePlugin API
# ------------------------------------------------------------------------
@staticmethod
def get_name():
return _("Breakpoints")
def get_description(self):
return _("Manage code breakpoints in a unified pane.")
def get_icon(self):
return self.create_icon('breakpoints')
def on_initialize(self):
widget = self.get_widget()
widget.sig_clear_all_breakpoints_requested.connect(
self.sig_clear_all_breakpoints_requested)
widget.sig_clear_breakpoint_requested.connect(
self.sig_clear_breakpoint_requested)
widget.sig_edit_goto_requested.connect(self.sig_edit_goto_requested)
widget.sig_conditional_breakpoint_requested.connect(
self.sig_conditional_breakpoint_requested)
self.create_action(
BreakpointsActions.ListBreakpoints,
_("List breakpoints"),
triggered=self.switch_to_plugin,
icon=self.get_icon(),
)
@on_plugin_available(plugin=Plugins.Editor)
def on_editor_available(self):
widget = self.get_widget()
editor = self.get_plugin(Plugins.Editor)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)
# TODO: change name of this signal on editor
editor.breakpoints_saved.connect(self.set_data)
widget.sig_clear_all_breakpoints_requested.connect(
editor.clear_all_breakpoints)
widget.sig_clear_breakpoint_requested.connect(editor.clear_breakpoint)
widget.sig_edit_goto_requested.connect(editor.load)
widget.sig_conditional_breakpoint_requested.connect(
editor.set_or_edit_conditional_breakpoint)
# TODO: Fix location once the sections are defined
editor.pythonfile_dependent_actions += [list_action]
@on_plugin_available(plugin=Plugins.MainMenu)
def on_main_menu_available(self):
mainmenu = self.get_plugin(Plugins.MainMenu)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)
mainmenu.add_item_to_application_menu(
list_action, menu_id=ApplicationMenus.Debug)
@on_plugin_teardown(plugin=Plugins.Editor)
def on_editor_teardown(self):
widget = self.get_widget()
editor = self.get_plugin(Plugins.Editor)
list_action = self.get_action(BreakpointsActions.ListBreakpoints)
editor.breakpoints_saved.disconnect(self.set_data)
widget.sig_clear_all_breakpoints_requested.disconnect(
editor.clear_all_breakpoints)
widget.sig_clear_breakpoint_requested.disconnect(
editor.clear_breakpoint)
widget.sig_edit_goto_requested.disconnect(editor.load)
widget.sig_conditional_breakpoint_requested.disconnect(
editor.set_or_edit_conditional_breakpoint)
editor.pythonfile_dependent_actions.remove(list_action)
@on_plugin_teardown(plugin=Plugins.MainMenu)
def on_main_menu_teardown(self):
mainmenu = self.get_plugin(Plugins.MainMenu)
mainmenu.remove_item_from_application_menu(
BreakpointsActions.ListBreakpoints, menu_id=ApplicationMenus.Debug)
# --- Private API
# ------------------------------------------------------------------------
def _load_data(self):
"""
Load breakpoint data from configuration file.
"""
breakpoints_dict = self.get_conf(
'breakpoints',
default={},
section='run',
)
for filename in list(breakpoints_dict.keys()):
if not osp.isfile(filename):
breakpoints_dict.pop(filename)
continue
# Make sure we don't have the same file under different names
new_filename = osp.normcase(filename)
if new_filename != filename:
bp = breakpoints_dict.pop(filename)
if new_filename in breakpoints_dict:
breakpoints_dict[new_filename].extend(bp)
else:
breakpoints_dict[new_filename] = bp
return breakpoints_dict
# --- Public API
# ------------------------------------------------------------------------
def set_data(self, data=None):
"""
Set breakpoint data on widget.
Parameters
----------
data: dict, optional
Breakpoint data to use. If None, data from the configuration
will be loaded. Default is None.
"""
if data is None:
data = self._load_data()
self.get_widget().set_data(data)