Esempio n. 1
0
        def page(self, title, contents):
            """Format an HTML page."""
            rich_text_font = get_font(option="rich_font").family()
            plain_text_font = get_font(option="font").family()

            if is_dark_interface():
                css_path = "static/css/dark_pydoc.css"
            else:
                css_path = "static/css/light_pydoc.css"

            css_link = ('<link rel="stylesheet" type="text/css" href="%s">' %
                        css_path)

            code_style = ('<style>code {font-family: "%s"}</style>' %
                          plain_text_font)

            html_page = '''\
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Pydoc: %s</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
%s%s</head><body style="clear:both;font-family:'%s'">
%s<div style="clear:both;padding-top:.7em;">%s</div>
</body></html>''' % (title, css_link, code_style, rich_text_font,
                     html_navbar(), contents)

            return html_page
Esempio n. 2
0
    def update_preview(self, index=None, scheme_name=None):
        """
        Update the color scheme of the preview editor and adds text.

        Note
        ----
        'index' is needed, because this is triggered by a signal that sends
        the selected index.
        """
        text = ('"""A string"""\n\n'
                '# A comment\n\n'
                '# %% A cell\n\n'
                'class Foo(object):\n'
                '    def __init__(self):\n'
                '        bar = 42\n'
                '        print(bar)\n'
                )
        show_blanks = CONF.get('editor', 'blank_spaces')
        update_scrollbar = CONF.get('editor', 'scroll_past_end')
        if scheme_name is None:
            scheme_name = self.current_scheme
        self.preview_editor.setup_editor(linenumbers=True,
                                         markers=True,
                                         tab_mode=False,
                                         font=get_font(),
                                         show_blanks=show_blanks,
                                         color_scheme=scheme_name,
                                         scroll_past_end=update_scrollbar)
        self.preview_editor.set_text(text)
        self.preview_editor.set_language('Python')
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     if role == Qt.DisplayRole or role == Qt.EditRole:
         column = index.column()
         row = index.row()
         value = self.get_value(row, column)
         if value is None:
             return ''
         elif np.isnan(value):
             return ''
         elif isinstance(value, float):
             try:
                 return to_qvariant(self._format % value)
             except (ValueError, TypeError):
                 # may happen if format = '%d' and value = NaN;
                 # see issue 4139
                 return to_qvariant(DEFAULT_FORMAT % value)
         elif is_type_text_string(value):
             # Don't perform any conversion on strings
             # because it leads to differences between
             # the data present in the dataframe and
             # what is shown by Spyder
             return value
         else:
             return to_qvariant(to_text_string(value))
     # elif role == Qt.BackgroundColorRole:
     #     return to_qvariant(self.get_bgcolor(index))
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     return to_qvariant()
Esempio n. 4
0
    def __init__(self, parent=None):
        CodeEditor.__init__(self, parent)

        # Editor options
        self.setup_editor(
            language='md',
            color_scheme='Scintilla',
            linenumbers=False,
            scrollflagarea=False,
            wrap=True,
            edge_line=False,
            highlight_current_line=False,
            highlight_current_cell=False,
            occurrence_highlighting=False,
            auto_unindent=False)

        # Set font
        self.set_font(get_font())

        # Header
        self.header = (
            "### What steps will reproduce the problem?\n\n"
            "<!--- You can use Markdown here --->\n\n")
        self.set_text(self.header)
        self.move_cursor(len(self.header))
        self.header_end_pos = self.get_position('eof')
Esempio n. 5
0
    def __init__(self, parent, text_color=None, max_results=1000):
        super().__init__(parent)
        self.search_text = None
        self.results = None
        self.max_results = max_results
        self.total_matches = None
        self.error_flag = None
        self.completed = None
        self.sorting = {}
        self.font = get_font()
        self.data = None
        self.files = None
        self.root_items = None
        self.text_color = text_color

        # Setup
        self.set_title('')
        self.set_sorting(OFF)
        self.setSortingEnabled(False)
        self.setItemDelegate(ItemDelegate(self))
        self.setUniformRowHeights(True)  # Needed for performance
        self.sortByColumn(0, Qt.AscendingOrder)

        # Only show the actions for collaps/expand all entries in the widget
        # For further information see spyder-ide/spyder#13178
        self.common_actions = self.common_actions[:2]

        # Signals
        self.header().sectionClicked.connect(self.sort_section)
Esempio n. 6
0
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     if role == Qt.DisplayRole or role == Qt.EditRole:
         column = index.column()
         row = index.row()
         if column == 0:
             return to_qvariant(to_text_string(self.df_index[row]))
         else:
             value = self.get_value(row, column - 1)
             if isinstance(value, float):
                 try:
                     return to_qvariant(self._format % value)
                 except (ValueError, TypeError):
                     # may happen if format = '%d' and value = NaN;
                     # see issue 4139
                     return to_qvariant(DEFAULT_FORMAT % value)
             else:
                 try:
                     return to_qvariant(to_text_string(value))
                 except UnicodeDecodeError:
                     return to_qvariant(encoding.to_unicode(value))
     elif role == Qt.BackgroundColorRole:
         return to_qvariant(self.get_bgcolor(index))
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     return to_qvariant()
Esempio n. 7
0
    def get_font(cls, rich_text=False):
        """
        Return plain or rich text font used in Spyder.

        Parameters
        ----------
        rich_text: bool
            Return rich text font (i.e. the one used in the Help pane)
            or plain text one (i.e. the one used in the Editor).

        Returns
        -------
        QFont
            QFont object to be passed to other Qt widgets.

        Notes
        -----
        All plugins in Spyder use the same, global font. This is a convenience
        method in case some plugins want to use a delta size based on the
        default one. That can be controlled by using FONT_SIZE_DELTA or
        RICH_FONT_SIZE_DELTA (declared in `SpyderPlugin`).
        """
        if rich_text:
            option = 'rich_font'
            font_size_delta = cls.RICH_FONT_SIZE_DELTA
        else:
            option = 'font'
            font_size_delta = cls.FONT_SIZE_DELTA

        return get_font(option=option, font_size_delta=font_size_delta)
Esempio n. 8
0
    def update_preview(self, index=None, scheme_name=None):
        """
        Update the color scheme of the preview editor and adds text.

        Note
        ----
        'index' is needed, because this is triggered by a signal that sends
        the selected index.
        """
        text = ('"""A string"""\n\n'
                '# A comment\n\n'
                'class Foo(object):\n'
                '    def __init__(self):\n'
                '        bar = 42\n'
                '        print(bar)\n'
                )

        if scheme_name is None:
            scheme_name = self.current_scheme

        self.preview_editor.setup_editor(
            font=get_font(),
            color_scheme=scheme_name,
            show_blanks=False,
            scroll_past_end=False,
        )
        self.preview_editor.set_language('Python')
        self.preview_editor.set_text(text)
Esempio n. 9
0
    def __init__(self, parent=None):
        CodeEditor.__init__(self, parent)

        # Editor options
        self.setup_editor(
            language='md',
            color_scheme='Scintilla',
            linenumbers=False,
            scrollflagarea=False,
            wrap=True,
            edge_line=False,
            highlight_current_line=False,
            highlight_current_cell=False,
            occurrence_highlighting=False,
            auto_unindent=False)

        # Set font
        self.set_font(get_font())

        # Header
        self.header = (
            "**What steps will reproduce your problem?**\n\n"
            "<!--- You can use Markdown here --->\n\n")
        self.set_text(self.header)
        self.move_cursor(len(self.header))
        self.header_end_pos = self.get_position('eof')
Esempio n. 10
0
    def _update_details_for_item(self, tree_item):
        """Shows the object details in the editor given an tree_item."""
        try:
            # obj = tree_item.obj
            button_id = self.button_group.checkedId()
            assert button_id >= 0, ("No radio button selected. "
                                    "Please report this bug.")
            attr_details = self._attr_details[button_id]
            data = attr_details.data_fn(tree_item)
            self.editor.setPlainText(data)
            self.editor.setWordWrapMode(attr_details.line_wrap)
            self.editor.setup_editor(
                font=get_font(font_size_delta=DEFAULT_SMALL_DELTA),
                show_blanks=False,
                color_scheme=CONF.get('appearance', 'selected'),
                scroll_past_end=False,
            )
            self.editor.set_text(data)

            if attr_details.name == 'Source code':
                self.editor.set_language('Python')
            else:
                self.editor.set_language('Rst')

        except Exception as ex:
            self.editor.setStyleSheet("color: red;")
            stack_trace = traceback.format_exc()
            self.editor.setPlainText("{}\n\n{}".format(ex, stack_trace))
            self.editor.setWordWrapMode(
                QTextOption.WrapAtWordBoundaryOrAnywhere)
Esempio n. 11
0
    def __init__(self, parent, text_color=None, max_results=1000):
        super().__init__(parent)
        self.search_text = None
        self.results = None
        self.max_results = max_results
        self.total_matches = None
        self.error_flag = None
        self.completed = None
        self.sorting = {}
        self.font = get_font()
        self.data = None
        self.files = None
        self.root_items = None
        self.text_color = text_color

        # Setup
        self.set_title('')
        self.set_sorting(OFF)
        self.setSortingEnabled(False)
        self.setItemDelegate(ItemDelegate(self))
        self.setUniformRowHeights(True)  # Needed for performance
        self.sortByColumn(0, Qt.AscendingOrder)

        # Signals
        self.header().sectionClicked.connect(self.sort_section)
Esempio n. 12
0
    def __init__(self, parent, color_scheme):
        super().__init__(parent)
        self.font = get_font()
        self.data = None
        self.threads = None
        self.color_scheme = color_scheme
        self.text_color = color_scheme['normal'][0]
        self.frames = None
        self.menu = None
        self.empty_ws_menu = None
        self.view_locals_action = None

        # Setup
        self.setItemsExpandable(True)
        self.setColumnCount(1)
        self.set_title('')
        self.setSortingEnabled(False)
        self.setItemDelegate(ItemDelegate(self))
        self.setUniformRowHeights(True)  # Needed for performance
        self.sortByColumn(0, Qt.AscendingOrder)

        # Signals
        self.header().sectionClicked.connect(self.sort_section)
        self.itemActivated.connect(self.activated)
        self.itemClicked.connect(self.activated)
Esempio n. 13
0
 def __repr__(self):
     match = to_text_string(self.match).rstrip()
     font = get_font()
     _str = to_text_string("<b>{1}</b> ({2}): "
                           "<span style='font-family:{0};"
                           "font-size:75%;'>{3}</span>")
     return _str.format(font.family(), self.lineno, self.colno, match)
Esempio n. 14
0
    def update_preview(self, index=None, scheme_name=None):
        """
        Update the color scheme of the preview editor and adds text.

        Note
        ----
        'index' is needed, because this is triggered by a signal that sends
        the selected index.
        """
        text = ('"""A string"""\n\n'
                '# A comment\n\n'
                '# %% A cell\n\n'
                'class Foo(object):\n'
                '    def __init__(self):\n'
                '        bar = 42\n'
                '        print(bar)\n')
        show_blanks = CONF.get('editor', 'blank_spaces')
        update_scrollbar = CONF.get('editor', 'scroll_past_end')
        underline_errors = CONF.get('editor', 'underline_errors')
        if scheme_name is None:
            scheme_name = self.current_scheme
        self.preview_editor.setup_editor(linenumbers=True,
                                         markers=True,
                                         tab_mode=False,
                                         font=get_font(),
                                         show_blanks=show_blanks,
                                         underline_errors=underline_errors,
                                         color_scheme=scheme_name,
                                         scroll_past_end=update_scrollbar)
        self.preview_editor.set_text(text)
        self.preview_editor.set_language('Python')
Esempio n. 15
0
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     value = self.get_value(index)
     if is_binary_string(value):
         try:
             value = to_text_string(value, 'utf8')
         except:
             pass
     if role == Qt.DisplayRole:
         if value is np.ma.masked:
             return ''
         else:
             try:
                 return to_qvariant(self._format % value)
             except TypeError:
                 self.readonly = True
                 return repr(value)
     elif role == Qt.TextAlignmentRole:
         return to_qvariant(int(Qt.AlignCenter|Qt.AlignVCenter))
     elif role == Qt.BackgroundColorRole and self.bgcolor_enabled \
       and value is not np.ma.masked:
         try:
             hue = (self.hue0 +
                    self.dhue * (float(self.vmax) - self.color_func(value))
                    / (float(self.vmax) - self.vmin))
             hue = float(np.abs(hue))
             color = QColor.fromHsvF(hue, self.sat, self.val, self.alp)
             return to_qvariant(color)
         except TypeError:
             return to_qvariant()
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     return to_qvariant()
Esempio n. 16
0
 def __repr__(self):
     match = to_text_string(self.match).rstrip()
     font = get_font()
     _str = to_text_string("<b>{1}</b> ({2}): "
                           "<span style='font-family:{0};"
                           "font-size:75%;'>{3}</span>")
     return _str.format(font.family(), self.lineno, self.colno, match)
Esempio n. 17
0
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     value = self.get_value(index)
     if is_binary_string(value):
         try:
             value = to_text_string(value, 'utf8')
         except:
             pass
     if role == Qt.DisplayRole:
         if value is np.ma.masked:
             return ''
         else:
             try:
                 return to_qvariant(self._format % value)
             except TypeError:
                 self.readonly = True
                 return repr(value)
     elif role == Qt.TextAlignmentRole:
         return to_qvariant(int(Qt.AlignCenter | Qt.AlignVCenter))
     elif role == Qt.BackgroundColorRole and self.bgcolor_enabled \
       and value is not np.ma.masked:
         try:
             hue = (self.hue0 + self.dhue *
                    (float(self.vmax) - self.color_func(value)) /
                    (float(self.vmax) - self.vmin))
             hue = float(np.abs(hue))
             color = QColor.fromHsvF(hue, self.sat, self.val, self.alp)
             return to_qvariant(color)
         except TypeError:
             return to_qvariant()
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     return to_qvariant()
Esempio n. 18
0
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     if role == Qt.DisplayRole or role == Qt.EditRole:
         column = index.column()
         row = index.row()
         if column == 0:
             return to_qvariant(to_text_string(self.df_index[row]))
         else:
             value = self.get_value(row, column-1)
             if isinstance(value, float):
                 try:
                     return to_qvariant(self._format % value)
                 except (ValueError, TypeError):
                     # may happen if format = '%d' and value = NaN;
                     # see issue 4139
                     return to_qvariant(DEFAULT_FORMAT % value)
             else:
                 try:
                     return to_qvariant(to_text_string(value))
                 except UnicodeDecodeError:
                     return to_qvariant(encoding.to_unicode(value))
     elif role == Qt.BackgroundColorRole:
         return to_qvariant(self.get_bgcolor(index))
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     return to_qvariant()
Esempio n. 19
0
    def __init__(self, text, title='', font=None, parent=None,
                 readonly=False, size=(400, 300)):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        self.text = None
        self.btn_save_and_close = None
        
        # Display text as unicode if it comes as bytes, so users see 
        # its right representation
        if is_binary_string(text):
            self.is_binary = True
            text = to_text_string(text, 'utf8')
        else:
            self.is_binary = False
        
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        # Text edit
        self.edit = QTextEdit(parent)
        self.edit.setReadOnly(readonly)
        self.edit.textChanged.connect(self.text_changed)
        self.edit.setPlainText(text)
        if font is None:
            font = get_font()
        self.edit.setFont(font)
        self.layout.addWidget(self.edit)

        # Buttons configuration
        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        if not readonly:
            self.btn_save_and_close = QPushButton(_('Save and Close'))
            self.btn_save_and_close.setDisabled(True)
            self.btn_save_and_close.clicked.connect(self.accept)
            btn_layout.addWidget(self.btn_save_and_close)

        self.btn_close = QPushButton(_('Close'))
        self.btn_close.setAutoDefault(True)
        self.btn_close.setDefault(True)
        self.btn_close.clicked.connect(self.reject)
        btn_layout.addWidget(self.btn_close)

        self.layout.addLayout(btn_layout)

        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)
        
        self.setWindowIcon(ima.icon('edit'))
        self.setWindowTitle(_("Text editor") + \
                            "%s" % (" - "+str(title) if str(title) else ""))
        self.resize(size[0], size[1])
Esempio n. 20
0
    def _get_font(self, rich_text=False):
        """Return plugin font."""
        if rich_text:
            option = 'rich_font'
            font_size_delta = self.RICH_FONT_SIZE_DELTA
        else:
            option = 'font'
            font_size_delta = self.FONT_SIZE_DELTA

        return get_font(option=option, font_size_delta=font_size_delta)
Esempio n. 21
0
    def __init__(self,
                 obj,
                 obj_name='',
                 attr_cols=None,
                 parent=None,
                 regular_font=None,
                 special_attribute_font=None):
        """
        Constructor

        :param obj: any Python object or variable
        :param obj_name: name of the object as it will appear in the root node
                         If empty, no root node will be drawn.
        :param attr_cols: list of AttributeColumn definitions
        :param parent: the parent widget
        """
        super(TreeModel, self).__init__(parent)
        self._attr_cols = attr_cols

        # Font for members (non-functions)
        self.regular_font = regular_font if regular_font else get_font()
        # Font for __special_attributes__
        self.special_attribute_font = (special_attribute_font
                                       if special_attribute_font
                                       else get_font())
        self.special_attribute_font.setItalic(False)

        self.regular_color = QBrush(QColor(ima.MAIN_FG_COLOR))
        self.callable_color = QBrush(
            QColor(ima.MAIN_FG_COLOR))  # for functions, methods, etc.

        # The following members will be initialized by populateTree
        # The rootItem is always invisible. If the obj_name
        # is the empty string, the inspectedItem
        # will be the rootItem (and therefore be invisible).
        # If the obj_name is given, an
        # invisible root item will be added and the
        # inspectedItem will be its only child.
        # In that case the inspected item will be visible.
        self._inspected_node_is_visible = None
        self._inspected_item = None
        self._root_item = None
        self.populateTree(obj, obj_name=obj_name)
Esempio n. 22
0
    def __init__(self,
                 text,
                 title='',
                 font=None,
                 parent=None,
                 readonly=False,
                 size=(400, 300)):
        QDialog.__init__(self, parent)

        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.text = None

        # Display text as unicode if it comes as bytes, so users see
        # its right representation
        if is_binary_string(text):
            self.is_binary = True
            text = to_text_string(text, 'utf8')
        else:
            self.is_binary = False

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        # Text edit
        self.edit = QTextEdit(parent)
        self.edit.textChanged.connect(self.text_changed)
        self.edit.setReadOnly(readonly)
        self.edit.setPlainText(text)
        if font is None:
            font = get_font()
        self.edit.setFont(font)
        self.layout.addWidget(self.edit)

        # Buttons configuration
        buttons = QDialogButtonBox.Ok
        if not readonly:
            buttons = buttons | QDialogButtonBox.Cancel
        bbox = QDialogButtonBox(buttons)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        self.layout.addWidget(bbox)

        # Make the dialog act as a window
        self.setWindowFlags(Qt.Window)

        self.setWindowIcon(ima.icon('edit'))
        self.setWindowTitle(_("Text editor") + \
                            "%s" % (" - "+str(title) if str(title) else ""))
        self.resize(size[0], size[1])
Esempio n. 23
0
 def clear_title(self, search_text):
     self.font = get_font()
     self.clear()
     self.setSortingEnabled(False)
     self.num_files = 0
     self.data = {}
     self.files = {}
     self.set_sorting(OFF)
     self.search_text = search_text
     title = "'%s' - " % search_text
     text = _('String not found')
     self.set_title(title + text)
Esempio n. 24
0
    def __init__(self, parent, statusbar):
        QWidget.__init__(self, parent)

        self.label_font = font = get_font(option='rich_font')
        font.setPointSize(self.font().pointSize())
        font.setBold(True)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        statusbar.addPermanentWidget(self)
Esempio n. 25
0
    def __init__(self, parent, statusbar):
        QWidget.__init__(self, parent)

        self.label_font = font = get_font(option='rich_font')
        font.setPointSize(self.font().pointSize())
        font.setBold(True)

        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        statusbar.addPermanentWidget(self)
Esempio n. 26
0
    def __init__(self, parent, statusbar):
        """Status bar widget base."""
        super(StatusBarWidget, self).__init__(parent)
        self.label_font = get_font(option='rich_font')
        self.label_font.setPointSize(self.font().pointSize())
        self.label_font.setBold(True)

        # Layouts
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Setup
        statusbar.addPermanentWidget(self)
Esempio n. 27
0
    def __init__(self, folder, parent=None):
        """Init."""
        super().__init__(parent)
        font = get_font()

        self.folder = folder
        self.path_selected = ""
        self.path_list = []
        self.results_old = {}
        self.setWindowTitle("Path Finder")
        self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint)
        self.setWindowOpacity(0.95)
        self.setFixedHeight(self._MAX_HEIGHT)
        self.setFont(font)

        # Set List widget
        self.list_viewer = QListView(self)
        self.list_viewer.setAttribute(Qt.WA_TransparentForMouseEvents)
        self.list_viewer.setFocusPolicy(Qt.NoFocus)
        self.list_viewer.setFixedWidth(self._MIN_WIDTH)
        self.list_viewer.setUniformItemSizes(True)
        self.list_model = QStringListModel()
        self.list_viewer.setModel(self.list_model)
        self.list_viewer.setFont(font)

        # Set edit
        self.edit = PathFinderEdit(self, textChanged=self.update_list)
        self.edit.setFont(font)
        self.edit.sig_esc_key_pressed.connect(self.close)
        self.edit.sig_enter_key_pressed.connect(self.enter)

        self.edit.sig_up_key_pressed.connect(lambda: self.prev_row(1))
        self.edit.sig_pg_up_key_pressed.connect(self.pg_up)
        self.edit.sig_pg_half_up_key_pressed.connect(self.pg_half_up)

        self.edit.sig_down_key_pressed.connect(lambda: self.next_row(1))
        self.edit.sig_pg_down_key_pressed.connect(self.pg_down)
        self.edit.sig_pg_half_down_key_pressed.connect(self.pg_half_down)

        layout = QVBoxLayout()
        layout.addWidget(self.edit)
        layout.addWidget(self.list_viewer)

        self.setLayout(layout)

        self.get_path_list()
        self.update_list()

        self.edit.setFocus()
Esempio n. 28
0
    def get_plugin_font(self, rich_text=False):
        """
        Return plugin font option.

        All plugins in Spyder use a global font. This is a convenience method
        in case some plugins will have a delta size based on the default size.
        """

        if rich_text:
            option = 'rich_font'
            font_size_delta = self.RICH_FONT_SIZE_DELTA
        else:
            option = 'font'
            font_size_delta = self.FONT_SIZE_DELTA

        return get_font(option=option, font_size_delta=font_size_delta)
Esempio n. 29
0
    def get_plugin_font(self, rich_text=False):
        """
        Return plugin font option.

        All plugins in Spyder use a global font. This is a convenience method
        in case some plugins will have a delta size based on the default size.
        """

        if rich_text:
            option = 'rich_font'
            font_size_delta = self.RICH_FONT_SIZE_DELTA
        else:
            option = 'font'
            font_size_delta = self.FONT_SIZE_DELTA

        return get_font(option=option, font_size_delta=font_size_delta)
Esempio n. 30
0
 def createEditor(self, parent, option, index):
     """Create editor widget"""
     model = index.model()
     value = model.get_value(index)
     if model._data.dtype.name == "bool":
         value = not value
         model.setData(index, to_qvariant(value))
         return
     elif value is not np.ma.masked:
         editor = QLineEdit(parent)
         editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
         editor.setAlignment(Qt.AlignCenter)
         if is_number(self.dtype):
             editor.setValidator(QDoubleValidator(editor))
         editor.returnPressed.connect(self.commitAndCloseEditor)
         return editor
Esempio n. 31
0
 def createEditor(self, parent, option, index):
     """Create editor widget"""
     model = index.model()
     value = model.get_value(index)
     if model._data.dtype.name == "bool":
         value = not value
         model.setData(index, to_qvariant(value))
         return
     elif value is not np.ma.masked:
         editor = QLineEdit(parent)
         editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
         editor.setAlignment(Qt.AlignCenter)
         if is_number(self.dtype):
             editor.setValidator(QDoubleValidator(editor))
         editor.returnPressed.connect(self.commitAndCloseEditor)
         return editor
Esempio n. 32
0
 def data(self, index, role=Qt.DisplayRole):
     """Cell content"""
     if not index.isValid():
         return to_qvariant()
     if role == Qt.DisplayRole or role == Qt.EditRole:
         column = index.column()
         row = index.row()
         if column == 0:
             df_idx = self.df_index[row]
             if is_type_text_string(df_idx):
                 # Don't perform any conversion on strings
                 # because it leads to differences between
                 # the data present in the dataframe and
                 # what is shown by Spyder
                 return df_idx
             else:
                 return to_qvariant(to_text_string(df_idx))
         else:
             value = self.get_value(row, column - 1)
             if isinstance(value, float):
                 try:
                     return to_qvariant(self._format % value)
                 except (ValueError, TypeError):
                     # may happen if format = '%d' and value = NaN;
                     # see issue 4139
                     return to_qvariant(DEFAULT_FORMAT % value)
             elif is_type_text_string(value):
                 # Don't perform any conversion on strings
                 # because it leads to differences between
                 # the data present in the dataframe and
                 # what is shown by Spyder
                 return value
             else:
                 try:
                     return to_qvariant(to_text_string(value))
                 except Exception:
                     self.display_error_idxs.append(index)
                     return u'Display Error!'
     elif role == Qt.BackgroundColorRole:
         return to_qvariant(self.get_bgcolor(index))
     elif role == Qt.FontRole:
         return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
     elif role == Qt.ToolTipRole:
         if index in self.display_error_idxs:
             return _("It is not possible to display this value because\n"
                      "an error ocurred while trying to do it")
     return to_qvariant()
Esempio n. 33
0
    def data(self, index, role=Qt.DisplayRole):
        """Cell content."""
        if not index.isValid():
            return to_qvariant()
        value = self.get_value(index)
        dtn = self._data.dtype.name

        # Tranform binary string to unicode so they are displayed
        # correctly
        if is_binary_string(value):
            try:
                value = to_text_string(value, 'utf8')
            except Exception:
                pass

        # Handle roles
        if role == Qt.DisplayRole:
            if value is np.ma.masked:
                return ''
            else:
                if dtn == 'object':
                    # We don't know what's inside an object array, so
                    # we can't trust value repr's here.
                    return value_to_display(value)
                else:
                    try:
                        return to_qvariant(self._format % value)
                    except TypeError:
                        self.readonly = True
                        return repr(value)
        elif role == Qt.TextAlignmentRole:
            return to_qvariant(int(Qt.AlignCenter | Qt.AlignVCenter))
        elif (role == Qt.BackgroundColorRole and self.bgcolor_enabled
              and value is not np.ma.masked and not self.has_inf):
            try:
                hue = (self.hue0 + self.dhue *
                       (float(self.vmax) - self.color_func(value)) /
                       (float(self.vmax) - self.vmin))
                hue = float(np.abs(hue))
                color = QColor.fromHsvF(hue, self.sat, self.val, self.alp)
                return to_qvariant(color)
            except (TypeError, ValueError):
                return to_qvariant()
        elif role == Qt.FontRole:
            return to_qvariant(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
        return to_qvariant()
Esempio n. 34
0
    def __init__(self, parent=None):
        super().__init__(parent)

        # Editor options
        self.setup_editor(
            language='md',
            font=get_font(),
            wrap=True,
            linenumbers=False,
            highlight_current_line=False,
        )

        # Header
        self.header = ("### What steps will reproduce the problem?\n\n"
                       "<!--- You can use Markdown here --->\n\n")
        self.set_text(self.header)

        self.move_cursor(len(self.header))
        self.header_end_pos = self.get_position('eof')
Esempio n. 35
0
 def createEditor(self, parent, option, index):
     """Create editor widget"""
     model = index.model()
     value = model.get_value(index)
     if type(value) == np.ndarray or model.readonly:
         # The editor currently cannot properly handle this case
         return
     elif model._data.dtype.name == "bool":
         value = not value
         model.setData(index, to_qvariant(value))
         return
     elif value is not np.ma.masked:
         editor = QLineEdit(parent)
         editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
         editor.setAlignment(Qt.AlignCenter)
         if is_number(self.dtype):
             validator = QDoubleValidator(editor)
             validator.setLocale(QLocale('C'))
             editor.setValidator(validator)
         editor.returnPressed.connect(self.commitAndCloseEditor)
         return editor
Esempio n. 36
0
    def __init__(self, parent, statusbar, icon=None):
        """Status bar widget base."""
        super(StatusBarWidget, self).__init__(parent)

        # Variables
        self.value = None

        # Widget
        self._status_bar = statusbar
        self._icon = None
        self._pixmap = None
        self._icon_size = QSize(16, 16)  # Should this be adjustable?
        self.label_icon = QLabel() if icon is not None else None
        self.label_value = QLabel()

        # Widget setup
        self.set_icon(icon)

        # See spyder-ide/spyder#9044.
        self.text_font = QFont(get_font(option='font'))
        self.text_font.setPointSize(self.font().pointSize())
        self.text_font.setBold(True)
        self.label_value.setAlignment(Qt.AlignRight)
        self.label_value.setFont(self.text_font)

        # Layout
        layout = QHBoxLayout()
        if icon is not None:
            layout.addWidget(self.label_icon)
        layout.addWidget(self.label_value)
        layout.addSpacing(20)

        # Layout setup
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Setup
        statusbar.addPermanentWidget(self)
        self.set_value('')
        self.update_tooltip()
Esempio n. 37
0
    def __init__(self, parent, statusbar, icon=None):
        """Status bar widget base."""
        super(StatusBarWidget, self).__init__(parent)

        # Variables
        self.value = None

        # Widget
        self._icon = icon
        self._pixmap = icon.pixmap(QSize(16, 16)) if icon is not None else None
        self.label_icon = QLabel() if icon is not None else None
        self.label_value = QLabel()

        # Widget setup
        if icon is not None:
            self.label_icon.setPixmap(self._pixmap)
        # See spyder-ide/spyder#9044.
        self.text_font = QFont(get_font(option='font'))
        self.text_font.setPointSize(self.font().pointSize())
        self.text_font.setBold(True)
        self.label_value.setAlignment(Qt.AlignRight)
        self.label_value.setFont(self.text_font)

        if self.TIP:
            self.setToolTip(self.TIP)
            self.label_value.setToolTip(self.TIP)

        # Layout
        layout = QHBoxLayout()
        if icon is not None:
            layout.addWidget(self.label_icon)
        layout.addWidget(self.label_value)
        layout.addSpacing(20)

        # Layout setup
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Setup
        statusbar.addPermanentWidget(self)
Esempio n. 38
0
    def __init__(self, parent, statusbar, icon=None):
        """Status bar widget base."""
        super(StatusBarWidget, self).__init__(parent)

        # Variables
        self.value = None

        # Widget
        self._icon = icon
        self._pixmap = icon.pixmap(QSize(16, 16)) if icon is not None else None
        self.label_icon = QLabel() if icon is not None else None
        self.label_value = QLabel()

        # Widget setup
        if icon is not None:
            self.label_icon.setPixmap(self._pixmap)
        self.text_font = QFont(get_font(option='font'))  # See Issue #9044
        self.text_font.setPointSize(self.font().pointSize())
        self.text_font.setBold(True)
        self.label_value.setAlignment(Qt.AlignRight)
        self.label_value.setFont(self.text_font)

        if self.TIP:
            self.setToolTip(self.TIP)
            self.label_value.setToolTip(self.TIP)

        # Layout
        layout = QHBoxLayout()
        if icon is not None:
            layout.addWidget(self.label_icon)
        layout.addWidget(self.label_value)
        layout.addSpacing(20)

        # Layout setup
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Setup
        statusbar.addPermanentWidget(self)
Esempio n. 39
0
def test():
    from spyder.utils.qthelpers import qapplication
    app = qapplication()

    from spyder.plugins.variableexplorer import VariableExplorer
    settings = VariableExplorer.get_settings()

    shell = ExternalPythonShell(pythonexecutable=sys.executable,
                                interact=True,
                                stand_alone=settings,
                                wdir=osp.dirname(__file__),
                                mpl_backend=0,
                                light_background=False)

    from spyder.config.gui import get_font
    
    font = get_font()
    shell.shell.set_font(font)

    shell.shell.toggle_wrap_mode(True)
    shell.start_shell(False)
    shell.show()
    sys.exit(app.exec_())
Esempio n. 40
0
def test():
    from spyder.utils.qthelpers import qapplication
    app = qapplication()

    from spyder.plugins.variableexplorer import VariableExplorer
    settings = VariableExplorer.get_settings()

    shell = ExternalPythonShell(pythonexecutable=sys.executable,
                                interact=True,
                                stand_alone=settings,
                                wdir=osp.dirname(__file__),
                                mpl_backend=0,
                                light_background=False)

    from spyder.config.gui import get_font

    font = get_font()
    shell.shell.set_font(font)

    shell.shell.toggle_wrap_mode(True)
    shell.start_shell(False)
    shell.show()
    sys.exit(app.exec_())
Esempio n. 41
0
 def setup_completion(self):
     size = CONF.get('main', 'completion/size')
     font = get_font()
     self.completion_widget.setup_appearance(size, font)
Esempio n. 42
0
    def __init__(self, parent, language=None, cmd='', host='127.0.0.1',
                 port=2084, args='', external=False, configurations={},
                 **kwargs):
        super(LSPServerEditor, self).__init__(parent)
        self.parent = parent
        self.external = external
        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        self.button_ok = bbox.button(QDialogButtonBox.Ok)
        self.button_cancel = bbox.button(QDialogButtonBox.Cancel)
        self.button_ok.setEnabled(False)

        description = _('To create a new configuration, '
                        'you need to select a programming '
                        'language, along with a executable '
                        'name for the server to execute '
                        '(If the instance is local), '
                        'and the host and port. Finally, '
                        'you need to provide the '
                        'arguments that the server accepts. '
                        'The placeholders <tt>%(host)s</tt> and '
                        '<tt>%(port)s</tt> refer to the host '
                        'and the port, respectively.')
        server_settings_description = QLabel(description)
        server_settings_description.setWordWrap(True)

        lang_label = QLabel(_('Language:'))
        self.lang_cb = QComboBox(self)
        self.lang_cb.setToolTip(_('Programming language provided '
                                  'by the LSP server'))
        self.lang_cb.addItem(_('Select a language'))
        self.lang_cb.addItems(LSP_LANGUAGES)

        if language is not None:
            idx = LSP_LANGUAGES.index(language)
            self.lang_cb.setCurrentIndex(idx + 1)
            self.button_ok.setEnabled(True)

        host_label = QLabel(_('Host:'))
        self.host_input = QLineEdit(self)
        self.host_input.setToolTip(_('Name of the host that will provide '
                                     'access to the server'))
        self.host_input.setText(host)
        self.host_input.textChanged.connect(lambda x: self.validate())

        port_label = QLabel(_('Port:'))
        self.port_spinner = QSpinBox(self)
        self.port_spinner.setToolTip(_('TCP port number of the server'))
        self.port_spinner.setMinimum(1)
        self.port_spinner.setMaximum(60000)
        self.port_spinner.setValue(port)

        cmd_label = QLabel(_('Command to execute:'))
        self.cmd_input = QLineEdit(self)
        self.cmd_input.setToolTip(_('Command used to start the '
                                    'LSP server locally'))
        self.cmd_input.setText(cmd)

        if not external:
            self.cmd_input.textChanged.connect(lambda x: self.validate())

        args_label = QLabel(_('Server arguments:'))
        self.args_input = QLineEdit(self)
        self.args_input.setToolTip(_('Additional arguments required to '
                                     'start the server'))
        self.args_input.setText(args)

        conf_label = QLabel(_('LSP Server Configurations:'))
        self.conf_input = CodeEditor(None)
        self.conf_input.textChanged.connect(self.validate)
        color_scheme = CONF.get('appearance', 'selected')
        self.conf_input.setup_editor(
            language='JSON',
            color_scheme=color_scheme,
            wrap=False,
            edge_line=True,
            highlight_current_line=True,
            highlight_current_cell=True,
            occurrence_highlighting=True,
            auto_unindent=True,
            font=get_font(),
            filename='config.json')
        self.conf_input.setToolTip(_('Additional LSP server configurations '
                                     'set at runtime. JSON required'))
        conf_text = '{}'
        try:
            conf_text = json.dumps(configurations, indent=4, sort_keys=True)
        except Exception:
            pass
        self.conf_input.set_text(conf_text)
        self.json_label = QLabel(self.JSON_VALID, self)

        self.external_cb = QCheckBox(_('External server'), self)
        self.external_cb.setToolTip(_('Check if the server runs '
                                      'on a remote location'))
        self.external_cb.setChecked(external)
        self.external_cb.stateChanged.connect(self.set_local_options)

        hlayout = QHBoxLayout()
        general_vlayout = QVBoxLayout()
        general_vlayout.addWidget(server_settings_description)

        vlayout = QVBoxLayout()
        lang_layout = QVBoxLayout()
        lang_layout.addWidget(lang_label)
        lang_layout.addWidget(self.lang_cb)

        # layout2 = QHBoxLayout()
        # layout2.addLayout(lang_layout)
        lang_layout.addWidget(self.external_cb)
        vlayout.addLayout(lang_layout)

        host_layout = QVBoxLayout()
        host_layout.addWidget(host_label)
        host_layout.addWidget(self.host_input)

        port_layout = QVBoxLayout()
        port_layout.addWidget(port_label)
        port_layout.addWidget(self.port_spinner)

        conn_info_layout = QHBoxLayout()
        conn_info_layout.addLayout(host_layout)
        conn_info_layout.addLayout(port_layout)
        vlayout.addLayout(conn_info_layout)

        cmd_layout = QVBoxLayout()
        cmd_layout.addWidget(cmd_label)
        cmd_layout.addWidget(self.cmd_input)
        vlayout.addLayout(cmd_layout)

        args_layout = QVBoxLayout()
        args_layout.addWidget(args_label)
        args_layout.addWidget(self.args_input)
        vlayout.addLayout(args_layout)

        conf_layout = QVBoxLayout()
        conf_layout.addWidget(conf_label)
        conf_layout.addWidget(self.conf_input)
        conf_layout.addWidget(self.json_label)

        hlayout.addLayout(vlayout)
        hlayout.addLayout(conf_layout)
        general_vlayout.addLayout(hlayout)

        general_vlayout.addWidget(bbox)
        self.setLayout(general_vlayout)
        bbox.accepted.connect(self.accept)
        bbox.rejected.connect(self.reject)
        self.lang_cb.currentIndexChanged.connect(
            self.lang_selection_changed)
        self.form_status(False)
        if language is not None:
            self.form_status(True)
            self.validate()
Esempio n. 43
0
 def get_font(self, option):
     """Return global font used in Spyder."""
     return get_font(option=option)
Esempio n. 44
0
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.setWindowTitle(_("Spyder internal error"))
        self.setModal(True)

        # To save the traceback sent to the internal console
        self.error_traceback = ""

        # Dialog main label
        self.main_label = QLabel(
            _("""<b>Spyder has encountered an internal problem</b><hr>
              Please enter below a step-by-step description of 
              your problem (in English). Issue reports without 
              a clear way to reproduce them will be closed.
              <br><br>
              <b>Note</b>: You need a Github account for this.
              """))
        self.main_label.setWordWrap(True)
        self.main_label.setAlignment(Qt.AlignJustify)

        # Field to input the description of the problem
        self.input_description = DescriptionWidget(self)

        # Only allow to submit to Github if we have a long enough description
        self.input_description.textChanged.connect(self._description_changed)

        # Widget to show errors
        self.details = ShowErrorWidget(self)
        self.details.set_pythonshell_font(get_font())
        self.details.hide()

        # Label to show missing chars
        self.initial_chars = len(self.input_description.toPlainText())
        self.chars_label = QLabel(_("Enter at least {} "
                                    "characters".format(MIN_CHARS)))

        # Checkbox to dismiss future errors
        self.dismiss_box = QCheckBox()
        self.dismiss_box.setText(_("Don't show again during this session"))

        # Labels layout
        labels_layout = QHBoxLayout()
        labels_layout.addWidget(self.chars_label)
        labels_layout.addWidget(self.dismiss_box, 0, Qt.AlignRight)

        # Dialog buttons
        self.submit_btn = QPushButton(_('Submit to Github'))
        self.submit_btn.setEnabled(False)
        self.submit_btn.clicked.connect(self._submit_to_github)

        self.details_btn = QPushButton(_('Show details'))
        self.details_btn.clicked.connect(self._show_details)

        self.close_btn = QPushButton(_('Close'))

        # Buttons layout
        buttons_layout = QHBoxLayout()
        buttons_layout.addWidget(self.submit_btn)
        buttons_layout.addWidget(self.details_btn)
        buttons_layout.addWidget(self.close_btn)

        # Main layout
        vlayout = QVBoxLayout()
        vlayout.addWidget(self.main_label)
        vlayout.addWidget(self.input_description)
        vlayout.addWidget(self.details)
        vlayout.addLayout(labels_layout)
        vlayout.addLayout(buttons_layout)
        self.setLayout(vlayout)

        self.resize(600, 420)
        self.input_description.setFocus()
Esempio n. 45
0
 def set_infowidget_font(self):
     """Set font for infowidget"""
     font = get_font(option='rich_font')
     self.infowidget.set_font(font)
Esempio n. 46
0
    def createEditor(self, parent, option, index):
        """Overriding method createEditor"""
        if self.show_warning(index):
            answer = QMessageBox.warning(
                self.parent(), _("Warning"),
                _("Opening this variable can be slow\n\n"
                  "Do you want to continue anyway?"),
                QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                return None
        try:
            value = self.get_value(index)
            try:
                self.old_obj = value.copy()
            except AttributeError:
                self.old_obj = copy.deepcopy(value)
            if value is None:
                return None
        except Exception as msg:
            QMessageBox.critical(
                self.parent(), _("Error"),
                _("Spyder was unable to retrieve the value of "
                  "this variable from the console.<br><br>"
                  "The error message was:<br>"
                  "<i>%s</i>") % to_text_string(msg))
            return
        self.current_index = index

        key = index.model().get_key(index).obj_name
        readonly = (isinstance(value, (tuple, set)) or self.parent().readonly
                    or not is_known_type(value))

        # CollectionsEditor for a list, tuple, dict, etc.
        if isinstance(value, (list, set, tuple, dict)):
            from spyder.widgets.collectionseditor import CollectionsEditor
            editor = CollectionsEditor(parent=parent)
            editor.setup(value,
                         key,
                         icon=self.parent().windowIcon(),
                         readonly=readonly)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # ArrayEditor for a Numpy array
        elif (isinstance(value, (ndarray, MaskedArray))
              and ndarray is not FakeObject):
            editor = ArrayEditor(parent=parent)
            if not editor.setup_and_check(value, title=key, readonly=readonly):
                return
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # ArrayEditor for an images
        elif (isinstance(value, Image) and ndarray is not FakeObject
              and Image is not FakeObject):
            arr = array(value)
            editor = ArrayEditor(parent=parent)
            if not editor.setup_and_check(arr, title=key, readonly=readonly):
                return
            conv_func = lambda arr: Image.fromarray(arr, mode=value.mode)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly,
                     conv=conv_func))
            return None
        # DataFrameEditor for a pandas dataframe, series or index
        elif (isinstance(value, (DataFrame, Index, Series))
              and DataFrame is not FakeObject):
            editor = DataFrameEditor(parent=parent)
            if not editor.setup_and_check(value, title=key):
                return
            editor.dataModel.set_format(index.model().dataframe_format)
            editor.sig_option_changed.connect(self.change_option)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # QDateEdit and QDateTimeEdit for a dates or datetime respectively
        elif isinstance(value, datetime.date):
            if readonly:
                return None
            else:
                if isinstance(value, datetime.datetime):
                    editor = QDateTimeEdit(value, parent=parent)
                else:
                    editor = QDateEdit(value, parent=parent)
                editor.setCalendarPopup(True)
                editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
                return editor
        # TextEditor for a long string
        elif is_text_string(value) and len(value) > 40:
            te = TextEditor(None, parent=parent)
            if te.setup_and_check(value):
                editor = TextEditor(value,
                                    key,
                                    readonly=readonly,
                                    parent=parent)
                self.create_dialog(
                    editor,
                    dict(model=index.model(),
                         editor=editor,
                         key=key,
                         readonly=readonly))
            return None
        # QLineEdit for an individual value (int, float, short string, etc)
        elif is_editable_type(value):
            if readonly:
                return None
            else:
                editor = QLineEdit(parent=parent)
                editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
                editor.setAlignment(Qt.AlignLeft)
                # This is making Spyder crash because the QLineEdit that it's
                # been modified is removed and a new one is created after
                # evaluation. So the object on which this method is trying to
                # act doesn't exist anymore.
                # editor.returnPressed.connect(self.commitAndCloseEditor)
                return editor
        # An arbitrary Python object.
        # Since we are already in the Object Explorer no editor is needed
        else:
            return None
Esempio n. 47
0
    def createEditor(self, parent, option, index, object_explorer=False):
        """Overriding method createEditor"""
        val_type = index.sibling(index.row(), 1).data()
        self.sig_open_editor.emit()
        if index.column() < 3:
            return None
        if self.show_warning(index):
            answer = QMessageBox.warning(
                self.parent(), _("Warning"),
                _("Opening this variable can be slow\n\n"
                  "Do you want to continue anyway?"),
                QMessageBox.Yes | QMessageBox.No)
            if answer == QMessageBox.No:
                return None
        try:
            value = self.get_value(index)
            if value is None:
                return None
        except ImportError as msg:
            self.sig_editor_shown.emit()
            module = str(msg).split("'")[1]
            if module in ['pandas', 'numpy']:
                if module == 'numpy':
                    val_type = 'array'
                else:
                    val_type = 'dataframe, series'
                QMessageBox.critical(
                    self.parent(), _("Error"),
                    _("Spyder is unable to show the {val_type} or object "
                      "you're trying to view because <tt>{module}</tt> was "
                      "not installed alongside Spyder. Please install "
                      "this package in your Spyder environment."
                      "<br>").format(val_type=val_type, module=module))
                return
            else:
                QMessageBox.critical(
                    self.parent(), _("Error"),
                    _("Spyder is unable to show the variable you're "
                      "trying to view because the module "
                      "<tt>{module}</tt> was not found in your  "
                      "Spyder environment. Please install "
                      "this package in your Spyder environment."
                      "<br>").format(module=module))
                return
        except Exception as msg:
            QMessageBox.critical(
                self.parent(), _("Error"),
                _("Spyder was unable to retrieve the value of "
                  "this variable from the console.<br><br>"
                  "The error message was:<br>"
                  "%s") % to_text_string(msg))
            return

        key = index.model().get_key(index)
        readonly = (isinstance(value, (tuple, set)) or self.parent().readonly
                    or not is_known_type(value))
        # CollectionsEditor for a list, tuple, dict, etc.
        if isinstance(value, (list, set, tuple, dict)) and not object_explorer:
            from spyder.widgets.collectionseditor import CollectionsEditor
            editor = CollectionsEditor(parent=parent)
            editor.setup(value,
                         key,
                         icon=self.parent().windowIcon(),
                         readonly=readonly)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # ArrayEditor for a Numpy array
        elif (isinstance(value, (ndarray, MaskedArray))
              and ndarray is not FakeObject and not object_explorer):
            editor = ArrayEditor(parent=parent)
            if not editor.setup_and_check(value, title=key, readonly=readonly):
                return
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # ArrayEditor for an images
        elif (isinstance(value, Image) and ndarray is not FakeObject
              and Image is not FakeObject and not object_explorer):
            arr = array(value)
            editor = ArrayEditor(parent=parent)
            if not editor.setup_and_check(arr, title=key, readonly=readonly):
                return
            conv_func = lambda arr: Image.fromarray(arr, mode=value.mode)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly,
                     conv=conv_func))
            return None
        # DataFrameEditor for a pandas dataframe, series or index
        elif (isinstance(value, (DataFrame, Index, Series))
              and DataFrame is not FakeObject and not object_explorer):
            editor = DataFrameEditor(parent=parent)
            if not editor.setup_and_check(value, title=key):
                return
            editor.dataModel.set_format(index.model().dataframe_format)
            editor.sig_option_changed.connect(self.change_option)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
        # QDateEdit and QDateTimeEdit for a dates or datetime respectively
        elif isinstance(value, datetime.date) and not object_explorer:
            # Needed to handle NaT values
            # See spyder-ide/spyder#8329
            try:
                value.time()
            except ValueError:
                self.sig_editor_shown.emit()
                return None
            if readonly:
                self.sig_editor_shown.emit()
                return None
            else:
                if isinstance(value, datetime.datetime):
                    editor = QDateTimeEdit(value, parent=parent)
                else:
                    editor = QDateEdit(value, parent=parent)
                editor.setCalendarPopup(True)
                editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
                self.sig_editor_shown.emit()
                return editor
        # TextEditor for a long string
        elif is_text_string(value) and len(value) > 40 and not object_explorer:
            te = TextEditor(None, parent=parent)
            if te.setup_and_check(value):
                editor = TextEditor(value,
                                    key,
                                    readonly=readonly,
                                    parent=parent)
                self.create_dialog(
                    editor,
                    dict(model=index.model(),
                         editor=editor,
                         key=key,
                         readonly=readonly))
            return None
        # QLineEdit for an individual value (int, float, short string, etc)
        elif is_editable_type(value) and not object_explorer:
            if readonly:
                self.sig_editor_shown.emit()
                return None
            else:
                editor = QLineEdit(parent=parent)
                editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA))
                editor.setAlignment(Qt.AlignLeft)
                # This is making Spyder crash because the QLineEdit that it's
                # been modified is removed and a new one is created after
                # evaluation. So the object on which this method is trying to
                # act doesn't exist anymore.
                # editor.returnPressed.connect(self.commitAndCloseEditor)
                self.sig_editor_shown.emit()
                return editor
        # ObjectExplorer for an arbitrary Python object
        else:
            show_callable_attributes = index.model().show_callable_attributes
            show_special_attributes = index.model().show_special_attributes
            dataframe_format = index.model().dataframe_format

            if show_callable_attributes is None:
                show_callable_attributes = False
            if show_special_attributes is None:
                show_special_attributes = False

            from spyder.plugins.variableexplorer.widgets.objectexplorer \
                import ObjectExplorer
            editor = ObjectExplorer(
                value,
                name=key,
                parent=parent,
                show_callable_attributes=show_callable_attributes,
                show_special_attributes=show_special_attributes,
                dataframe_format=dataframe_format,
                readonly=readonly)
            editor.sig_option_changed.connect(self.change_option)
            self.create_dialog(
                editor,
                dict(model=index.model(),
                     editor=editor,
                     key=key,
                     readonly=readonly))
            return None
Esempio n. 48
0
    def __init__(self, parent=None, is_report=False):
        QDialog.__init__(self, parent)
        self.is_report = is_report

        self.setWindowTitle(_("Issue reporter"))
        self.setModal(True)

        # To save the traceback sent to the internal console
        self.error_traceback = ""

        # Dialog main label
        if self.is_report:
            title = _("Please fill the following information")
        else:
            title = _("Spyder has encountered an internal problem!")
        main_label = QLabel(
            _("<h3>{title}</h3>"
              "Before reporting this problem, <i>please</i> consult our "
              "comprehensive "
              "<b><a href=\"{trouble_url}\">Troubleshooting Guide</a></b> "
              "which should help solve most issues, and search for "
              "<b><a href=\"{project_url}\">known bugs</a></b> "
              "matching your error message or problem description for a "
              "quicker solution."
              ).format(title=title, trouble_url=__trouble_url__,
                          project_url=__project_url__))
        main_label.setOpenExternalLinks(True)
        main_label.setWordWrap(True)
        main_label.setAlignment(Qt.AlignJustify)
        main_label.setStyleSheet('font-size: 12px;')

        # Issue title
        self.title = QLineEdit()
        self.title.textChanged.connect(self._contents_changed)
        self.title_chars_label = QLabel(_("{} more characters "
                                          "to go...").format(TITLE_MIN_CHARS))
        form_layout = QFormLayout()
        form_layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        red_asterisk = '<font color="Red">*</font>'
        title_label = QLabel(_("<b>Title</b>: {}").format(red_asterisk))
        form_layout.setWidget(0, QFormLayout.LabelRole, title_label)
        form_layout.setWidget(0, QFormLayout.FieldRole, self.title)

        # Description
        steps_header = QLabel(
            _("<b>Steps to reproduce:</b> {}").format(red_asterisk))
        steps_text = QLabel(_("Please enter a detailed step-by-step "
                              "description (in English) of what led up to "
                              "the problem below. Issue reports without a "
                              "clear way to reproduce them will be closed."))
        steps_text.setWordWrap(True)
        steps_text.setAlignment(Qt.AlignJustify)
        steps_text.setStyleSheet('font-size: 12px;')

        # Field to input the description of the problem
        self.input_description = DescriptionWidget(self)

        # Only allow to submit to Github if we have a long enough description
        self.input_description.textChanged.connect(self._contents_changed)

        # Widget to show errors
        self.details = ShowErrorWidget(self)
        self.details.set_pythonshell_font(get_font())
        self.details.hide()

        # Label to show missing chars
        self.initial_chars = len(self.input_description.toPlainText())
        self.desc_chars_label = QLabel(_("{} more characters "
                                         "to go...").format(DESC_MIN_CHARS))

        # Checkbox to dismiss future errors
        self.dismiss_box = QCheckBox(_("Hide all future errors during this "
                                       "session"))
        if self.is_report:
            self.dismiss_box.hide()

        # Dialog buttons
        gh_icon = ima.icon('github')
        self.submit_btn = QPushButton(gh_icon, _('Submit to Github'))
        self.submit_btn.setEnabled(False)
        self.submit_btn.clicked.connect(self._submit_to_github)

        self.details_btn = QPushButton(_('Show details'))
        self.details_btn.clicked.connect(self._show_details)
        if self.is_report:
            self.details_btn.hide()

        self.close_btn = QPushButton(_('Close'))
        if self.is_report:
            self.close_btn.clicked.connect(self.reject)

        # Buttons layout
        buttons_layout = QHBoxLayout()
        buttons_layout.addWidget(self.submit_btn)
        buttons_layout.addWidget(self.details_btn)
        buttons_layout.addWidget(self.close_btn)

        # Main layout
        layout = QVBoxLayout()
        layout.addWidget(main_label)
        layout.addSpacing(20)
        layout.addLayout(form_layout)
        layout.addWidget(self.title_chars_label)
        layout.addSpacing(12)
        layout.addWidget(steps_header)
        layout.addSpacing(-1)
        layout.addWidget(steps_text)
        layout.addSpacing(1)
        layout.addWidget(self.input_description)
        layout.addWidget(self.details)
        layout.addWidget(self.desc_chars_label)
        layout.addSpacing(15)
        layout.addWidget(self.dismiss_box)
        layout.addSpacing(15)
        layout.addLayout(buttons_layout)
        layout.setContentsMargins(25, 20, 25, 10)
        self.setLayout(layout)

        self.resize(570, 600)
        self.title.setFocus()

        # Set Tab key focus order
        self.setTabOrder(self.title, self.input_description)