def _draw_fold_indicator(self, top, mouse_over, collapsed, painter): """ Draw the fold indicator/trigger (arrow). :param top: Top position :param mouse_over: Whether the mouse is over the indicator :param collapsed: Whether the trigger is collapsed or not. :param painter: QPainter """ rect = QRect(0, top, self.sizeHint().width(), self.sizeHint().height()) if self._native_icons: opt = QStyleOptionViewItem() opt.rect = rect opt.state = (QStyle.State_Active | QStyle.State_Item | QStyle.State_Children) if not collapsed: opt.state |= QStyle.State_Open if mouse_over: opt.state |= (QStyle.State_MouseOver | QStyle.State_Enabled | QStyle.State_Selected) opt.palette.setBrush(QPalette.Window, self.palette().highlight()) opt.rect.translate(-2, 0) self.style().drawPrimitive(QStyle.PE_IndicatorBranch, opt, painter, self) else: index = 0 if not collapsed: index = 2 if mouse_over: index += 1 ima.icon(self._indicators_icons[index]).paint(painter, rect)
def setup_context_menu(self): """Reimplements ShellBaseWidget method""" ShellBaseWidget.setup_context_menu(self) self.copy_without_prompts_action = create_action( self, _("Copy without prompts"), icon=ima.icon('copywop'), triggered=self.copy_without_prompts) clear_line_action = create_action( self, _("Clear line"), QKeySequence(CONF.get_shortcut('console', 'Clear line')), icon=ima.icon('editdelete'), tip=_("Clear line"), triggered=self.clear_line) clear_action = create_action( self, _("Clear shell"), QKeySequence(CONF.get_shortcut('console', 'Clear shell')), icon=ima.icon('editclear'), tip=_("Clear shell contents ('cls' command)"), triggered=self.clear_terminal) add_actions(self.menu, (self.copy_without_prompts_action, clear_line_action, clear_action))
def _setup_bottom_toolbar(self): """Create bottom toolbar and actions.""" self.add_button = create_toolbutton( self, text=_('Add path'), icon=ima.icon('edit_add'), triggered=lambda x: self.add_path(), text_beside_icon=True) self.remove_button = create_toolbutton( self, text=_('Remove path'), icon=ima.icon('edit_remove'), triggered=lambda x: self.remove_path(), text_beside_icon=True) self.import_button = create_toolbutton( self, text=_("Import"), icon=ima.icon('fileimport'), triggered=self.import_pythonpath, tip=_("Import from PYTHONPATH environment variable"), text_beside_icon=True) self.export_button = create_toolbutton( self, text=_("Export"), icon=ima.icon('fileexport'), triggered=self.export_pythonpath, tip=_("Export to PYTHONPATH environment variable"), text_beside_icon=True) return [ self.add_button, self.remove_button, self.import_button, self.export_button ]
def __init__(self): Panel.__init__(self) self.setMouseTracking(True) self.scrollable = True self.linenumbers_color = QColor(Qt.darkGray) # Markers self._markers_margin = True # Icons self.error_icon = ima.icon('error') self.warning_icon = ima.icon('warning') self.info_icon = ima.icon('information') self.hint_icon = ima.icon('hint') self.todo_icon = ima.icon('todo') # Line number area management self._margin = True self._pressed = -1 self._released = -1 # This is a tuple composed of (number of digits, current width) self._width_cache = None # Cache line numbers self._static_line_numbers = None self._static_active_line = None # Static text must be flushed when dpi changes (qt bug?) self._static_text_dpi = None
def _setup_bottom_toolbar(self): """Create bottom toolbar and actions.""" self.add_button = create_toolbutton( self, text=_('Add path'), icon=ima.icon('edit_add'), triggered=lambda x: self.add_path(), text_beside_icon=True) self.remove_button = create_toolbutton( self, text=_('Remove path'), icon=ima.icon('edit_remove'), triggered=lambda x: self.remove_path(), text_beside_icon=True) self.sync_button = create_toolbutton( self, text=_("Synchronize..."), icon=ima.icon('fileimport'), triggered=self.synchronize, tip=_("Synchronize Spyder's path list with PYTHONPATH " "environment variable"), text_beside_icon=True) self.selection_widgets.append(self.remove_button) return [self.add_button, self.remove_button, None, self.sync_button]
def get_options_menu(self): """Return options menu""" env_action = create_action( self, _("Show environment variables"), icon=ima.icon('environ'), triggered=self.shellwidget.request_env ) syspath_action = create_action( self, _("Show sys.path contents"), icon=ima.icon('syspath'), triggered=self.shellwidget.request_syspath ) self.show_time_action.setChecked(self.show_elapsed_time) additional_actions = [MENU_SEPARATOR, env_action, syspath_action, self.show_time_action] if self.menu_actions is not None: console_menu = self.menu_actions + additional_actions return console_menu else: return additional_actions
def get_application_icon(fpath): """Return application icon or default icon if not found.""" from qtpy.QtGui import QIcon from spyder.utils.icon_manager import ima if os.path.isfile(fpath) or os.path.isdir(fpath): icon = ima.icon('no_match') if sys.platform == 'darwin': icon_path = _get_mac_application_icon_path(fpath) if icon_path and os.path.isfile(icon_path): icon = QIcon(icon_path) elif os.name == 'nt': pass else: entry_data = parse_linux_desktop_entry(fpath) icon_path = entry_data['icon_path'] if icon_path: if os.path.isfile(icon_path): icon = QIcon(icon_path) else: icon = QIcon.fromTheme(icon_path) else: icon = ima.icon('help') return icon
def create_scedit(self, text, option, default=NoDefault, tip=None, without_layout=False, section=None): if section is not None and section != self.CONF_SECTION: self.cross_section_options[option] = section label = QLabel(text) clayout = ColorLayout(QColor(Qt.black), self) clayout.lineedit.setMaximumWidth(80) if tip is not None: clayout.setToolTip(tip) cb_bold = QCheckBox() cb_bold.setIcon(ima.icon('bold')) cb_bold.setToolTip(_("Bold")) cb_italic = QCheckBox() cb_italic.setIcon(ima.icon('italic')) cb_italic.setToolTip(_("Italic")) self.scedits[(clayout, cb_bold, cb_italic)] = (section, option, default) if without_layout: return label, clayout, cb_bold, cb_italic layout = QHBoxLayout() layout.addWidget(label) layout.addLayout(clayout) layout.addSpacing(10) layout.addWidget(cb_bold) layout.addWidget(cb_italic) layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.setLayout(layout) return widget
def _setup_top_toolbar(self): """Create top toolbar and actions.""" self.movetop_button = create_toolbutton( self, text=_("Move to top"), icon=ima.icon('2uparrow'), triggered=lambda: self.move_to(absolute=0), text_beside_icon=True) self.moveup_button = create_toolbutton( self, text=_("Move up"), icon=ima.icon('1uparrow'), triggered=lambda: self.move_to(relative=-1), text_beside_icon=True) self.movedown_button = create_toolbutton( self, text=_("Move down"), icon=ima.icon('1downarrow'), triggered=lambda: self.move_to(relative=1), text_beside_icon=True) self.movebottom_button = create_toolbutton( self, text=_("Move to bottom"), icon=ima.icon('2downarrow'), triggered=lambda: self.move_to(absolute=1), text_beside_icon=True) toolbar = [ self.movetop_button, self.moveup_button, self.movedown_button, self.movebottom_button ] self.selection_widgets.extend(toolbar) return toolbar
def setup(self): self.menu = self.create_menu("context_menu") self.collapse_all_action = self.create_action( OneColumnTreeActions.CollapseAllAction, text=_("Collapse all"), icon=ima.icon("collapse"), triggered=self.collapseAll, register_shortcut=False, ) self.expand_all_action = self.create_action( OneColumnTreeActions.ExpandAllAction, text=_("Expand all"), icon=ima.icon("expand"), triggered=self.expandAll, register_shortcut=False, ) self.restore_action = self.create_action( OneColumnTreeActions.RestoreAction, text=_("Restore"), tip=_("Restore original tree layout"), icon=ima.icon("restore"), triggered=self.restore, register_shortcut=False, ) self.collapse_selection_action = self.create_action( OneColumnTreeActions.CollapseSelectionAction, text=_("Collapse section"), icon=ima.icon("collapse_selection"), triggered=self.collapse_selection, register_shortcut=False, ) self.expand_selection_action = self.create_action( OneColumnTreeActions.ExpandSelectionAction, text=_("Expand section"), icon=ima.icon("expand_selection"), triggered=self.expand_selection, register_shortcut=False, ) for item in [self.collapse_all_action, self.expand_all_action]: self.add_item_to_menu( item, self.menu, section=OneColumnTreeContextMenuSections.Global, ) self.add_item_to_menu( self.restore_action, self.menu, section=OneColumnTreeContextMenuSections.Restore, ) for item in [ self.collapse_selection_action, self.expand_selection_action ]: self.add_item_to_menu( item, self.menu, section=OneColumnTreeContextMenuSections.Section, )
def __init__(self, path, ref, treewidget, is_python=True): QTreeWidgetItem.__init__(self, treewidget, QTreeWidgetItem.Type) self.path = path self.ref = ref self.setIcon( 0, ima.icon('python') if is_python else ima.icon('TextFileIcon')) self.setToolTip(0, path) set_item_user_text(self, path)
def __init__(self, parent=None): super(BasePluginWidgetMixin, self).__init__() # Actions to add to the Options menu self._plugin_actions = None # Attribute to keep track if the plugin is undocked in a # separate window self._undocked_window = None self._ismaximized = False self._default_margins = None self._isvisible = False self.shortcut = None # Options buttons self.options_button = create_toolbutton(self, text=_('Options'), icon=ima.icon('tooloptions')) self.options_button.setPopupMode(QToolButton.InstantPopup) # Don't show menu arrow and remove padding if is_dark_interface(): self.options_button.setStyleSheet( ("QToolButton::menu-indicator{image: none;}\n" "QToolButton{padding: 3px;}")) else: self.options_button.setStyleSheet( "QToolButton::menu-indicator{image: none;}") # Options menu self._options_menu = QMenu(self) # We decided to create our own toggle action instead of using # the one that comes with dockwidget because it's not possible # to raise and focus the plugin with it. self._toggle_view_action = None # Default actions for Options menu self._dock_action = create_action(self, _("Dock"), icon=ima.icon('dock'), tip=_("Dock the pane"), triggered=self._close_window) self._undock_action = create_action(self, _("Undock"), icon=ima.icon('undock'), tip=_("Undock the pane"), triggered=self._create_window) self._close_plugin_action = create_action( self, _("Close"), icon=ima.icon('close_pane'), tip=_("Close the pane"), triggered=self._plugin_closed)
def __init__(self, parent=None): super(BasePluginWidgetMixin, self).__init__() # Actions to add to the Options menu self._plugin_actions = None # Attribute to keep track if the plugin is undocked in a # separate window self._undocked_window = None self._ismaximized = False self._default_margins = None self._isvisible = False self.shortcut = None # Options buttons self.options_button = create_toolbutton(self, text=_('Options'), icon=ima.icon('tooloptions')) self.options_button.setPopupMode(QToolButton.InstantPopup) # Options menu self._options_menu = QMenu(self) # We decided to create our own toggle action instead of using # the one that comes with dockwidget because it's not possible # to raise and focus the plugin with it. self._toggle_view_action = None # Default actions for Options menu self._dock_action = create_action(self, _("Dock"), icon=ima.icon('dock'), tip=_("Dock the pane"), triggered=self._close_window) self._lock_unlock_action = create_action( self, text=_("Unlock position"), tip=_("Unlock to move pane to another position"), icon=ima.icon('drag_dock_widget'), triggered=self._lock_unlock_position, ) self._undock_action = create_action(self, _("Undock"), icon=ima.icon('undock'), tip=_("Undock the pane"), triggered=self._create_window) self._close_plugin_action = create_action( self, _("Close"), icon=ima.icon('close_pane'), tip=_("Close the pane"), triggered=self._plugin_closed)
def __init__(self, *args, **kwargs): super(IconLineEdit, self).__init__(*args, **kwargs) self._status = True self._status_set = True self._valid_icon = ima.icon('todo') self._invalid_icon = ima.icon('warning') self._set_icon = ima.icon('todo_list') self._application_style = QApplication.style().objectName() self._refresh() self._paint_count = 0 self._icon_visible = False
def _on_title_bar_shown(self, visible): """Actions to perform when the title bar is shown/hidden.""" if visible: self._lock_unlock_action.setText(_('Lock position')) self._lock_unlock_action.setIcon(ima.icon('lock_open')) for method_name in ['setToolTip', 'setStatusTip']: method = getattr(self._lock_unlock_action, method_name) method(_("Lock pane to the current position")) else: self._lock_unlock_action.setText(_('Unlock position')) self._lock_unlock_action.setIcon(ima.icon('drag_dock_widget')) for method_name in ['setToolTip', 'setStatusTip']: method = getattr(self._lock_unlock_action, method_name) method(_("Unlock to move pane to another position"))
def update_dependencies(self, dependencies): self.clear() headers = (_("Module"), _("Package name"), _(" Required "), _(" Installed "), _("Provided features")) self.setHeaderLabels(headers) # Mandatory items mandatory_item = QTreeWidgetItem([_("Mandatory")]) font = mandatory_item.font(0) font.setBold(True) mandatory_item.setFont(0, font) # Optional items optional_item = QTreeWidgetItem([_("Optional")]) optional_item.setFont(0, font) # Spyder plugins spyder_plugins = QTreeWidgetItem([_("Spyder plugins")]) spyder_plugins.setFont(0, font) self.addTopLevelItems([mandatory_item, optional_item, spyder_plugins]) for dependency in sorted(dependencies, key=lambda x: x.modname.lower()): item = QTreeWidgetItem([ dependency.modname, dependency.package_name, dependency.required_version, dependency.installed_version, dependency.features ]) # Format content if dependency.check(): item.setIcon(0, ima.icon('dependency_ok')) elif dependency.kind == OPTIONAL: item.setIcon(0, ima.icon('dependency_warning')) item.setForeground(2, QColor('#ff6a00')) else: item.setIcon(0, ima.icon('dependency_error')) item.setForeground(2, QColor(Qt.darkRed)) # Add to tree if dependency.kind == OPTIONAL: optional_item.addChild(item) elif dependency.kind == PLUGIN: spyder_plugins.addChild(item) else: mandatory_item.addChild(item) self.expandAll()
def setup_context_menu(self): """Reimplement PythonShellWidget method""" PythonShellWidget.setup_context_menu(self) self.help_action = create_action(self, _("Help..."), icon=ima.icon('DialogHelpButton'), triggered=self.help) self.menu.addAction(self.help_action)
def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.pages_widget.setMinimumWidth(600) self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.ok_btn = bbox.button(QDialogButtonBox.Ok) # Widgets setup # 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.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) self.contents_widget.setMinimumWidth(220) self.contents_widget.setMinimumHeight(400) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setStretchFactor(0, 1) hsplitter.setStretchFactor(1, 2) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots if self.main: self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def setup_menu_actions(self): """Setup and update the menu actions.""" self.recent_project_menu.clear() self.recent_projects_actions = [] if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): name = project.replace(get_home_dir(), '~') action = create_action( self, name, icon=ima.icon('project'), triggered=self.build_opener(project), ) self.recent_projects_actions.append(action) else: self.recent_projects.remove(project) self.recent_projects_actions += [ None, self.clear_recent_projects_action, self.max_recent_action ] else: self.recent_projects_actions = [ self.clear_recent_projects_action, self.max_recent_action ] add_actions(self.recent_project_menu, self.recent_projects_actions) self.update_project_actions()
def create_browsefile(self, text, option, default=NoDefault, tip=None, filters=None, section=None): widget = self.create_lineedit(text, option, default, section=section, alignment=Qt.Horizontal) for edit in self.lineedits: if widget.isAncestorOf(edit): break msg = _('Invalid file path') self.validate_data[edit] = (osp.isfile, msg) browse_btn = QPushButton(ima.icon('FileIcon'), '', self) browse_btn.setToolTip(_("Select file")) browse_btn.clicked.connect(lambda: self.select_file(edit, filters)) layout = QHBoxLayout() layout.addWidget(widget) layout.addWidget(browse_btn) layout.setContentsMargins(0, 0, 0, 0) browsedir = QWidget(self) browsedir.setLayout(layout) return browsedir
def set_item_display(self, item_widget, item_info, height, width): """Set item text & icons using the info available.""" item_provider = item_info['provider'] item_type = self.ITEM_TYPE_MAP.get(item_info['kind'], 'no_match') item_label = item_info['label'] icon_provider = ("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0l" "EQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=") img_height = height - 2 img_width = img_height * 0.8 icon_provider, icon_scale = item_info.get('icon', (None, 1)) if icon_provider is not None: icon_height = img_height icon_width = icon_scale * icon_height icon_provider = ima.icon(icon_provider) icon_provider = ima.base64_from_icon_obj(icon_provider, icon_width, icon_height) item_text = self.get_html_item_representation( item_label, item_type, icon_provider=icon_provider, img_height=img_height, img_width=img_width, height=height, width=width) item_widget.setText(item_text) item_widget.setIcon(self._get_cached_icon(item_type))
def __init__(self, parent, regex_base=None, key_filter_dict=None, find_on_change=False): super().__init__(parent) # Parent is assumed to be a spyder widget self.text_finder = FinderLineEdit(self, regex_base=regex_base, key_filter_dict=key_filter_dict) self.text_finder.sig_find_requested.connect(self.do_find) if find_on_change: self.text_finder.textChanged.connect(self.do_find) self.text_finder.sig_hide_requested.connect( self.sig_hide_finder_requested) self.finder_close_button = QToolButton(self) self.finder_close_button.setIcon(ima.icon('DialogCloseButton')) self.finder_close_button.clicked.connect( self.sig_hide_finder_requested) finder_layout = QHBoxLayout() finder_layout.addWidget(self.finder_close_button) finder_layout.addWidget(self.text_finder) finder_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(finder_layout) self.setVisible(False)
def setup_menu_actions(self): """Setup and update the menu actions.""" if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): if os.name == 'nt': name = project else: name = project.replace(get_home_dir(), '~') try: action = self.get_action(name) except KeyError: action = self.create_action( name, text=name, icon=ima.icon('project'), triggered=self.build_opener(project), ) self.get_widget().add_item_to_menu( action, menu=self.recent_project_menu, section=RecentProjectsMenuSections.Recent) for item in [self.clear_recent_projects_action, self.max_recent_action]: self.get_widget().add_item_to_menu( item, menu=self.recent_project_menu, section=RecentProjectsMenuSections.Extras) self.update_project_actions()
def __init__(self): """Initialize panel.""" Panel.__init__(self) self.setMouseTracking(True) self.scrollable = True self.line_number_hint = None self._current_line_arrow = None self.stop = False # Diccionary of QIcons to draw in the panel self.icons = { 'breakpoint': ima.icon('breakpoint_big'), 'transparent': ima.icon('breakpoint_transparent'), 'condition': ima.icon('breakpoint_cond_big'), 'arrow': ima.icon('arrow_debugger') }
def show_syspath(self, syspath): """Show sys.path contents.""" if syspath is not None: editor = CollectionsEditor(self) editor.setup(syspath, title="sys.path contents", readonly=True, icon=ima.icon('syspath')) self.dialog_manager.show(editor) else: return
class CategoryItem(QTreeWidgetItem): """ Category item for results. Notes ----- Possible categories are Convention, Refactor, Warning and Error. """ CATEGORIES = { "Convention": { 'translation_string': _("Convention"), 'icon': ima.icon("convention") }, "Refactor": { 'translation_string': _("Refactor"), 'icon': ima.icon("refactor") }, "Warning": { 'translation_string': _("Warning"), 'icon': ima.icon("warning") }, "Error": { 'translation_string': _("Error"), 'icon': ima.icon("error") } } def __init__(self, parent, category, number_of_messages): # Messages string to append to category. if number_of_messages > 1 or number_of_messages == 0: messages = _('messages') else: messages = _('message') # Category title. title = self.CATEGORIES[category]['translation_string'] title += f" ({number_of_messages} {messages})" super().__init__(parent, [title], QTreeWidgetItem.Type) # Set icon icon = self.CATEGORIES[category]['icon'] self.setIcon(0, icon)
def __init__(self, parent, button_size): super().__init__(parent) self.parent = parent # Style self.setIconSize(button_size) self.setAutoRaise(True) self.setIcon(ima.icon('drag_dock_widget')) self.setToolTip(_("Drag and drop pane to a different position")) self.setStyleSheet(self._stylesheet)
def __init__(self, parent, button_size): super().__init__(parent) self.parent = parent # Style self.setIconSize(button_size) self.setAutoRaise(True) self.setIcon(ima.icon('lock_open')) self.setToolTip(_("Lock pane")) self._apply_stylesheet(QStylePalette.COLOR_BACKGROUND_3, 0)
def get_plugin_icon(self): """ Get plugin's associated icon. Returns ------- QIcon QIcon instance """ return ima.icon('outline_explorer')
def update_info(self, name, kind, position, status, selected): self.setIcon(0, ima.icon(SYMBOL_KIND_ICON.get(kind, 'no_match'))) identifier = SYMBOL_NAME_MAP.get(kind, '') identifier = identifier.replace('_', ' ').capitalize() self.setToolTip(0, '{3} {2}: {0} {1}'.format( identifier, name, position, _('Line'))) set_item_user_text(self, name) self.setText(0, name) self.setExpanded(status) self.setSelected(selected)