# -*- coding: utf-8 -*-
# Copyright Martin Manns
# Distributed under the terms of the GNU General Public License
# --------------------------------------------------------------------
# pyspread is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyspread is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyspread. If not, see <http://www.gnu.org/licenses/>.
# --------------------------------------------------------------------
"""
**Provides**
* :class:`Action` is a quick one liner way to create `QAction`
* :class:`MainWindowActions`
* :class:`ChartDialogActions`
* :class:`SpellTextEditActions`
"""
from typing import Callable, List
from PyQt6.QtWidgets import QWidget
from PyQt6.QtGui import QKeySequence, QIcon, QAction, QActionGroup
try:
import matplotlib.figure as matplotlib_figure
except ImportError:
matplotlib_figure = None
try:
import enchant
except ImportError:
enchant = None
try:
from pyspread.icons import Icon
from pyspread.lib.attrdict import AttrDict
except ImportError:
from icons import Icon
from lib.attrdict import AttrDict
[docs]
class Action(QAction):
"""A convenience class for creating a `QAction`
.. Note: Parameter order has changed comparing with QAction
"""
def __init__(self, parent: QWidget, label: str, *callbacks: List[Callable],
icon: QIcon = None, shortcut: str = None,
statustip: str = None, checkable: bool = False,
role: QAction.MenuRole = None):
"""
:param parent: The parent object, normally :class:`pyspread.MainWindow`
:param label: The text to appear
:param callbacks: the callback functions
:param icon: the :class:`icons.Icon`
:param shortcut: The magic kestrokes if ant
:param statustip: The popup message
:param checkable: Has a checkbox
:param role: Menu role for action for macOS
"""
if icon is None:
super().__init__(label, parent, checkable=checkable)
else:
super().__init__(icon, label, parent, checkable=checkable)
if shortcut is not None:
self.setShortcut(shortcut)
if statustip is not None:
self.setStatusTip(statustip)
if role is not None:
self.setMenuRole(role)
for connect in callbacks:
self.triggered.connect(connect)
[docs]
class MainWindowActions(AttrDict):
"""Holds all QActions for the main window"""
def __init__(self, parent: QWidget, shortcuts: bool = True):
"""
:param parent: The parent object, normally :class:`pyspread.MainWindow`
:param shortcuts: Enable shortcuts for actions
"""
super().__init__()
self.parent = parent
self.shortcuts = shortcuts
self.create_file_actions()
self.create_edit_actions()
self.create_view_actions()
self.create_format_actions()
self.create_macro_actions()
self.create_help_actions()
self.disable_unavailable()
[docs]
def create_file_actions(self):
"""actions for File menu"""
self.new = Action(self.parent, "&New",
self.parent.workflows.file_new,
icon=Icon.new,
shortcut='Ctrl+n' if self.shortcuts else "",
statustip='Create a new, empty spreadsheet')
self.open = Action(self.parent, "&Open",
self.parent.workflows.file_open,
icon=Icon.open,
statustip='Open spreadsheet from file')
self.save = Action(self.parent, "&Save",
self.parent.workflows.file_save,
icon=Icon.save,
shortcut='Ctrl+s' if self.shortcuts else "",
statustip='Save spreadsheet')
self.save_as = Action(
self.parent, "Save &As",
self.parent.workflows.file_save_as,
icon=Icon.save_as,
shortcut='Shift+Ctrl+s' if self.shortcuts else "",
statustip='Save spreadsheet to a new file')
self.imprt = Action(self.parent, "&Import",
self.parent.workflows.file_import,
icon=Icon.imprt,
statustip='Import a file and paste it into the '
'current grid')
self.export = Action(self.parent, "&Export",
self.parent.workflows.file_export,
icon=Icon.export,
statustip="Export selection to a file")
self.approve = Action(self.parent, "&Approve file",
self.parent.on_approve,
icon=Icon.approve,
statustip='Approve, unfreeze and sign the '
'current file')
self.clear_globals = Action(self.parent, "&Clear globals",
self.parent.on_clear_globals,
icon=Icon.clear_globals,
statustip='Deletes global variables '
'and reloads base modules')
self.print_preview = Action(self.parent, "Print preview",
self.parent.on_preview,
icon=Icon.print_preview,
statustip='Print preview')
self.print = Action(self.parent, "Print", self.parent.on_print,
icon=Icon.print,
shortcut='Ctrl+p' if self.shortcuts else "",
statustip='Print current spreadsheet')
self.preferences = Action(self.parent, "Preferences...",
self.parent.on_preferences,
icon=Icon.preferences,
statustip='Pyspread setup parameters',
role=QAction.MenuRole.PreferencesRole)
self.quit = Action(self.parent, "&Quit", self.parent.closeEvent,
icon=Icon.quit,
shortcut='Ctrl+Q' if self.shortcuts else "",
statustip='Exit pyspread',
role=QAction.MenuRole.QuitRole)
[docs]
def create_edit_actions(self):
"""actions for Edit menu"""
self.undo = Action(self.parent, "&Undo",
self.parent.on_undo,
icon=Icon.undo,
shortcut='Ctrl+z' if self.shortcuts else "",
statustip='Undo last step')
self.redo = Action(self.parent, "&Redo",
self.parent.on_redo,
icon=Icon.redo,
shortcut='Shift+Ctrl+z' if self.shortcuts else "",
statustip='Redo last undone step')
self.cut = Action(self.parent, "Cut",
self.parent.workflows.edit_cut,
icon=Icon.cut,
shortcut='Ctrl+x' if self.shortcuts else "",
statustip='Cut cell to the clipboard')
self.copy = Action(self.parent, "&Copy",
self.parent.workflows.edit_copy,
icon=Icon.copy,
shortcut='Ctrl+c' if self.shortcuts else "",
statustip='Copy the input strings of the cells '
'to the clipboard')
self.copy_results = \
Action(self.parent, "Copy results",
self.parent.workflows.edit_copy_results,
icon=Icon.copy_results,
shortcut='Shift+Ctrl+c' if self.shortcuts else "",
statustip='Copy the result strings of the cells to the '
'clipboard')
self.paste = Action(self.parent, "&Paste",
self.parent.workflows.edit_paste,
icon=Icon.paste,
shortcut='Ctrl+v' if self.shortcuts else "",
statustip='Paste cells from the clipboard')
self.paste_as = Action(
self.parent, "Paste as...",
self.parent.workflows.edit_paste_as,
icon=Icon.paste_as,
shortcut='Shift+Ctrl+v' if self.shortcuts else "",
statustip='Transform clipboard and paste results')
self.find = Action(self.parent, "&Find...",
self.parent.workflows.edit_find,
icon=Icon.find,
shortcut='Ctrl+f' if self.shortcuts else "",
statustip='Find dialog')
self.find_next = Action(self.parent, "&Find next",
self.parent.workflows.edit_find_next,
icon=Icon.find_next,
shortcut='F3' if self.shortcuts else "",
statustip='Find next matching cell')
self.replace = Action(
self.parent, "&Replace...",
self.parent.workflows.edit_replace,
icon=Icon.replace,
shortcut='Shift+Ctrl+f' if self.shortcuts else "",
statustip='Replace sub-strings in cells')
self.sort_ascending = Action(
self.parent, "Sort ascending",
self.parent.workflows.edit_sort_ascending,
icon=Icon.sort_ascending,
statustip='Sort selected cells. The sort order is ascending and '
'follows the current column.')
self.sort_descending = Action(
self.parent, "Sort descending",
self.parent.workflows.edit_sort_descending,
icon=Icon.sort_descending,
statustip='Sort selected cells. The sort order is descending and '
'follows the current column.')
self.toggle_selection_mode = Action(
self.parent, "Selection mode",
self.parent.grid.toggle_selection_mode,
icon=Icon.selection_mode, checkable=True,
shortcut='Ins',
statustip='Enter/leave selection mode')
self.quote = Action(self.parent, "&Quote",
self.parent.grid.on_quote,
icon=Icon.quote,
shortcut='Ctrl+Return' if self.shortcuts else "",
statustip="Convert cells' code to strings by "
"addding quotes")
self.insert_rows = Action(self.parent, "Insert rows",
self.parent.grid.on_insert_rows,
icon=Icon.insert_row,
statustip='Insert max(1, no. selected '
'rows) rows at cursor')
self.insert_columns = Action(self.parent, "Insert columns",
self.parent.grid.on_insert_columns,
icon=Icon.insert_column,
statustip='Insert max(1, no. selected '
'columns) columns at cursor')
self.insert_table = Action(self.parent, "Insert table",
self.parent.grid.on_insert_table,
icon=Icon.insert_table,
statustip='Insert table before current '
'table')
self.delete_rows = Action(self.parent, "Delete rows",
self.parent.grid.on_delete_rows,
icon=Icon.delete_row,
statustip='Delete max(1, no. selected '
'rows) rows at cursor')
self.delete_columns = Action(self.parent, "Delete columns",
self.parent.grid.on_delete_columns,
icon=Icon.delete_column,
statustip='Delete max(1, no. selected '
'columns) columns at cursor')
self.delete_table = Action(self.parent, "Delete table",
self.parent.grid.on_delete_table,
icon=Icon.delete_table,
statustip='Delete current table')
self.resize_grid = Action(self.parent, "Resize grid",
self.parent.workflows.edit_resize,
icon=Icon.resize_grid,
statustip='Resizes the current grid')
[docs]
def create_view_actions(self):
"""actions for View menu"""
self.fullscreen = Action(self.parent, "Fullscreen",
self.parent.on_fullscreen,
icon=Icon.fullscreen,
shortcut='F11' if self.shortcuts else "",
statustip='Show grid in fullscreen mode '
'(press <F11> to leave)')
self.toggle_main_toolbar = Action(self.parent, "Main toolbar",
self.parent.on_toggle_main_toolbar,
checkable=True,
statustip='Show/hide the main '
'toolbar')
self.toggle_macro_toolbar = Action(self.parent, "Macro toolbar",
self.parent.on_toggle_macro_toolbar,
checkable=True,
statustip='Show/hide the macro '
'toolbar')
self.toggle_format_toolbar = \
Action(self.parent, "Format toolbar",
self.parent.on_toggle_format_toolbar,
checkable=True,
statustip='Show/hide the format toolbar')
self.toggle_find_toolbar = Action(self.parent, "Find toolbar",
self.parent.on_toggle_find_toolbar,
checkable=True,
statustip='Show/hide the find '
'toolbar')
self.toggle_entry_line_dock = Action(
self.parent, "Entry line", self.parent.on_toggle_entry_line_dock,
checkable=True, statustip='Show/hide the entry line')
self.toggle_macro_dock = Action(
self.parent, "Macro panel", self.parent.on_toggle_macro_dock,
checkable=True, shortcut='F4' if self.shortcuts else "",
statustip='Show/hide the macro panel')
self.goto_cell = Action(self.parent, "Go to cell",
self.parent.workflows.view_goto_cell,
icon=Icon.goto_cell,
shortcut='Ctrl+g' if self.shortcuts else "",
statustip='Select a cell and put it into view')
self.toggle_spell_checker = \
Action(self.parent, "Toggle spell checker",
self.parent.entry_line.on_toggle_spell_check,
icon=Icon.check_spelling,
checkable=True,
statustip='Turn the spell checker in the entry line on/off')
self.zoom_in = Action(self.parent, "Zoom in",
self.parent.grid.on_zoom_in,
icon=Icon.zoom_in,
shortcut='Ctrl++' if self.shortcuts else "",
statustip='Zoom in the grid')
self.zoom_out = Action(self.parent, "Zoom out",
self.parent.grid.on_zoom_out,
icon=Icon.zoom_out,
shortcut='Ctrl+-' if self.shortcuts else "",
statustip='Zoom out the grid')
self.zoom_1 = Action(self.parent, "Original size",
self.parent.grid.on_zoom_1,
icon=Icon.zoom_1,
shortcut='Ctrl+0' if self.shortcuts else "",
statustip='Show grid on standard zoom level')
self.refresh_cells = \
Action(self.parent, "Refresh selected cells",
self.parent.grid.refresh_selected_frozen_cells,
icon=Icon.refresh,
shortcut=QKeySequence.StandardKey.Refresh if self.shortcuts else "",
statustip='Refresh selected cells even when frozen')
self.toggle_periodic_updates = \
Action(self.parent, "Toggle periodic updates",
self.parent.on_toggle_refresh_timer,
icon=Icon.toggle_periodic_updates, checkable=True,
statustip='Toggles periodic updates for frozen cells')
self.show_frozen = Action(self.parent, "Show frozen",
self.parent.grid.on_show_frozen_pressed,
icon=Icon.show_frozen,
checkable=True,
statustip='Indicates frozen cells with a '
'background crosshatch')
[docs]
def create_format_actions(self):
"""actions for Format menu"""
self.copy_format = Action(self.parent, "&Copy format",
self.parent.workflows.format_copy_format,
icon=Icon.copy_format,
statustip='Copy format of selection to '
'the clipboard')
self.paste_format = \
Action(self.parent, "&Paste format",
self.parent.workflows.format_paste_format,
icon=Icon.paste_format,
statustip='Apply format from the clipboard to the selected '
'cells')
self.font = Action(self.parent, "&Font...",
self.parent.grid. on_font_dialog,
icon=Icon.font_dialog,
statustip='Lauch font dialog')
self.bold = Action(self.parent, "&Bold",
self.parent.grid.on_bold_pressed,
icon=Icon.bold,
shortcut='Ctrl+b' if self.shortcuts else "",
checkable=True,
statustip='Toggle bold font weight for the '
'selected cells')
self.italics = Action(self.parent, "&Italics",
self.parent.grid.on_italics_pressed,
icon=Icon.italics,
shortcut='Ctrl+i' if self.shortcuts else "",
checkable=True,
statustip='Toggle italics font style for the '
'selected cells')
self.underline = Action(self.parent, "&Underline",
self.parent.grid.on_underline_pressed,
icon=Icon.underline,
shortcut='Ctrl+u' if self.shortcuts else "",
checkable=True,
statustip='Toggle underline for the '
'selected cells')
self.strikethrough = Action(self.parent, "&Strikethrough",
self.parent.grid.on_strikethrough_pressed,
icon=Icon.strikethrough,
checkable=True,
statustip='Toggle strikethrough for the '
'selected cells')
self.text = Action(self.parent, "Text renderer",
self.parent.grid.on_text_renderer_pressed,
icon=Icon.text,
checkable=True,
statustip='Show cell results as text (default). '
'Formats affect the whole cell')
self.markup = Action(self.parent, "Markup renderer",
self.parent.grid.on_markup_renderer_pressed,
icon=Icon.markup,
checkable=True,
statustip='Show cell results as markup, which '
'allows partly formatted output')
self.image = Action(self.parent, "Image renderer",
self.parent.grid.on_image_renderer_pressed,
icon=Icon.image,
checkable=True,
statustip='Show cell results as image. A numpy '
'array of shape (x, y, 3) '
'is expected')
if matplotlib_figure is not None:
self.matplotlib = \
Action(self.parent, "Matplotlib chart renderer",
self.parent.grid.on_matplotlib_renderer_pressed,
icon=Icon.matplotlib,
checkable=True,
statustip='Show cell results as matplotlib chart. A '
'numpy array of shape (x, y, 3) is expected')
renderer_group = QActionGroup(self.parent)
renderer_group.addAction(self.text)
renderer_group.addAction(self.markup)
renderer_group.addAction(self.image)
if matplotlib_figure is not None:
renderer_group.addAction(self.matplotlib)
self.text_color = Action(
self.parent, "Text color...",
self.parent.widgets.text_color_button.on_pressed,
icon=Icon.text_color, statustip='Lauch text color dialog')
self.line_color = Action(
self.parent, "Line color...",
self.parent.widgets.line_color_button.on_pressed,
icon=Icon.line_color, statustip='Lauch line color dialog')
self.background_color = Action(
self.parent, "Background color...",
self.parent.widgets.background_color_button.on_pressed,
icon=Icon.background_color,
statustip='Lauch background color dialog')
self.freeze_cell = Action(self.parent, "Freeze cell",
self.parent.grid.on_freeze_pressed,
icon=Icon.freeze,
checkable=True,
statustip='Freeze the selected cell so that '
'is is only updated when <F5> is '
'pressed')
self.lock_cell = Action(self.parent, "Lock cell",
self.parent.grid.on_lock_pressed,
icon=Icon.lock,
checkable=True,
statustip='Lock cell so that its code '
'cannot be changed')
self.button_cell = Action(self.parent, "Button cell",
self.parent.grid.on_button_cell_pressed,
icon=Icon.button,
checkable=True,
statustip='Make cell a button cell that is '
'executed only when pressed')
self.merge_cells = Action(self.parent, "Merge cells",
self.parent.grid.on_merge_pressed,
icon=Icon.merge_cells,
checkable=True,
statustip='Merge/unmerge selected cells')
self.rotate_0 = Action(self.parent, "0°",
self.parent.grid.on_rotate_0,
icon=Icon.rotate_0,
checkable=True,
statustip='Set text rotation to 0°')
self.rotate_90 = Action(self.parent, "90°",
self.parent.grid.on_rotate_90,
icon=Icon.rotate_90,
checkable=True,
statustip='Set text rotation to 90°')
self.rotate_180 = Action(self.parent, "180°",
self.parent.grid.on_rotate_180,
icon=Icon.rotate_180,
checkable=True,
statustip='Set text rotation to 180°')
self.rotate_270 = Action(self.parent, "270°",
self.parent.grid.on_rotate_270,
icon=Icon.rotate_270,
checkable=True,
statustip='Set text rotation to 270°')
rotate_group = QActionGroup(self.parent)
rotate_group.addAction(self.rotate_0)
rotate_group.addAction(self.rotate_90)
rotate_group.addAction(self.rotate_180)
rotate_group.addAction(self.rotate_270)
self.justify_left = Action(self.parent, "Left",
self.parent.grid.on_justify_left,
icon=Icon.justify_left,
checkable=True,
statustip='Display cell result text '
'left justified')
self.justify_center = Action(self.parent, "Center",
self.parent.grid.on_justify_center,
checkable=True,
icon=Icon.justify_center,
statustip='Display cell result text '
'centered')
self.justify_right = Action(self.parent, "Right",
self.parent.grid.on_justify_right,
checkable=True,
icon=Icon.justify_right,
statustip='Display cell result text '
'right justified')
self.justify_fill = Action(self.parent, "Fill",
self.parent.grid.on_justify_fill,
icon=Icon.justify_fill,
checkable=True,
statustip='Display cell result text '
'filled into the cell')
justify_group = QActionGroup(self.parent)
justify_group.addAction(self.justify_left)
justify_group.addAction(self.justify_center)
justify_group.addAction(self.justify_right)
justify_group.addAction(self.justify_fill)
self.align_top = Action(self.parent, "Top",
self.parent.grid.on_align_top,
icon=Icon.align_top,
checkable=True,
statustip='Align cell result at the top of '
'the cell')
self.align_center = Action(self.parent, "Center",
self.parent.grid.on_align_middle,
icon=Icon.align_center,
checkable=True,
statustip='Center cell result within '
'the cell')
self.align_bottom = Action(self.parent, "Bottom",
self.parent.grid.on_align_bottom,
icon=Icon.align_bottom,
checkable=True,
statustip='Align cell result at the '
'bottom of the cell')
align_group = QActionGroup(self.parent)
align_group.addAction(self.align_top)
align_group.addAction(self.align_center)
align_group.addAction(self.align_bottom)
self.format_borders_all = \
Action(self.parent, "All borders",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_all, checkable=True,
statustip='Format all borders of selection')
self.format_borders_top = \
Action(self.parent, "Top border",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_top, checkable=True,
statustip='Format top border of selection')
self.format_borders_bottom = \
Action(self.parent, "Bottom border",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_bottom, checkable=True,
statustip='Format bottom border of selection')
self.format_borders_left = \
Action(self.parent, "Left border",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_left, checkable=True,
statustip='Format left border of selection')
self.format_borders_right = \
Action(self.parent, "Right border",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_right, checkable=True,
statustip='Format right border of selection')
self.format_borders_outer = \
Action(self.parent, "Outer borders",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_outer, checkable=True,
statustip='Format outer borders of selection')
self.format_borders_inner = \
Action(self.parent, "Inner borders",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_inner, checkable=True,
statustip='Format inner borders of selection')
self.format_borders_top_bottom = \
Action(self.parent, "Top and bottom borders",
self.parent.grid.on_border_choice,
icon=Icon.format_borders_top_bottom, checkable=True,
statustip='Format top and bottom borders of selection')
self.border_group = QActionGroup(self.parent)
self.border_group.addAction(self.format_borders_all)
self.border_group.addAction(self.format_borders_top)
self.border_group.addAction(self.format_borders_bottom)
self.border_group.addAction(self.format_borders_left)
self.border_group.addAction(self.format_borders_right)
self.border_group.addAction(self.format_borders_outer)
self.border_group.addAction(self.format_borders_inner)
self.border_group.addAction(self.format_borders_top_bottom)
self.format_borders_all.setChecked(True)
self.format_borders_0 = Action(self.parent, "Border width 0",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_0,
statustip='Set border width to 0')
self.format_borders_1 = Action(self.parent, "Border width 1",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_1,
statustip='Set border width to 1')
self.format_borders_2 = Action(self.parent, "Border width 2",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_2,
statustip='Set border width to 2')
self.format_borders_4 = Action(self.parent, "Border width 3",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_4,
statustip='Set border width to 3')
self.format_borders_8 = Action(self.parent, "Border width 4",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_8,
statustip='Set border width to 4')
self.format_borders_16 = Action(self.parent, "Border width 6",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_16,
statustip='Set border width to 6')
self.format_borders_32 = Action(self.parent, "Border width 8",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_32,
statustip='Set border width to 8')
self.format_borders_64 = Action(self.parent, "Border width 12",
self.parent.grid.on_borderwidth,
icon=Icon.format_borders_64,
statustip='Set border width to 12')
self.border_width_group = QActionGroup(self.parent)
self.border_width_group.addAction(self.format_borders_0)
self.border_width_group.addAction(self.format_borders_1)
self.border_width_group.addAction(self.format_borders_2)
self.border_width_group.addAction(self.format_borders_4)
self.border_width_group.addAction(self.format_borders_8)
self.border_width_group.addAction(self.format_borders_16)
self.border_width_group.addAction(self.format_borders_32)
self.border_width_group.addAction(self.format_borders_64)
self.format_borders_1.setChecked(True)
[docs]
def create_macro_actions(self):
"""Create actions for Macro menu"""
self.insert_image = Action(self.parent, "Insert image...",
self.parent.workflows.macro_insert_image,
icon=Icon.insert_image,
statustip='Load an image from a file '
'into a cell')
self.insert_chart = Action(self.parent, "Insert chart...",
self.parent.workflows.macro_insert_chart,
icon=Icon.insert_chart,
statustip='Create and display matplotlib '
'chart')
self.insert_sum = Action(self.parent, "Insert sum",
self.parent.workflows.macro_insert_sum,
icon=Icon.insert_sum,
statustip='Insert sum of selection into the'
'cell below the bottom right cell '
'of the selection')
[docs]
def create_help_actions(self):
"""actions for Help menu"""
self.manual = Action(self.parent, "Manual...",
self.parent.on_manual,
icon=Icon.help,
shortcut='F1' if self.shortcuts else "",
statustip='Display the pyspread manual')
self.tutorial = Action(self.parent, "Tutorial...",
self.parent.on_tutorial,
icon=Icon.tutorial,
statustip='Display a pyspread tutorial')
self.dependencies = Action(self.parent, "Dependencies...",
self.parent.on_dependencies,
icon=Icon.dependencies,
statustip='List and install dependencies')
self.about = Action(self.parent, "About pyspread...",
self.parent.on_about,
icon=Icon.pyspread,
statustip='About pyspread',
role=QAction.MenuRole.AboutRole)
[docs]
def disable_unavailable(self):
"""Disables unavailable menu items e.g. due to missing dependencies"""
if enchant is None:
self.toggle_spell_checker.setEnabled(False)
[docs]
class ChartDialogActions(AttrDict):
"""QActions for chart dialog
Reads out template files in share/templates/matplotlib and
adds a QAction for each template.
"""
def __init__(self, parent: QWidget):
"""
:param parent: The parent object
"""
super().__init__()
self.parent = parent
self._add_chart_template_actions()
[docs]
def _add_chart_template_actions(self):
"""Adds actions for chart dialog toolbar"""
self.chart_pie_1_1 = Action(self.parent, "Pie chart",
self.parent.on_template,
icon=Icon.chart_pie_1_1,
statustip='Insert code for pie chart')
self.chart_pie_1_1.setData("chart_pie_1_1.py")
self.chart_ring_1_1 = Action(self.parent, "Ring chart",
self.parent.on_template,
icon=Icon.chart_ring_1_1,
statustip='Insert code for ring chart')
self.chart_ring_1_1.setData("chart_ring_1_1.py")
self.chart_line_1_1 = Action(self.parent, "Line chart",
self.parent.on_template,
icon=Icon.chart_line_1_1,
statustip='Insert code for line chart')
self.chart_line_1_1.setData("chart_line_1_1.py")
self.chart_polar_1_1 = Action(self.parent, "Polar chart",
self.parent.on_template,
icon=Icon.chart_polar_1_1,
statustip='Insert code for polar '
'coordinates line chart')
self.chart_polar_1_1.setData("chart_polar_1_1.py")
self.chart_area_1_1 = Action(self.parent, "Area chart",
self.parent.on_template,
icon=Icon.chart_area_1_1,
statustip='Insert code for area chart')
self.chart_area_1_1.setData("chart_area_1_1.py")
self.chart_column_1_1 = Action(self.parent, "Grouped column chart",
self.parent.on_template,
icon=Icon.chart_column_1_1,
statustip='Insert code for grouped '
'column chart')
self.chart_column_1_1.setData("chart_column_1_1.py")
self.chart_column_1_2 = Action(self.parent, "Stacked column chart",
self.parent.on_template,
icon=Icon.chart_column_1_2,
statustip='Insert code for stacked '
'column chart')
self.chart_column_1_2.setData("chart_column_1_2.py")
self.chart_bar_1_3 = \
Action(self.parent, "Normalized stacked bar chart",
self.parent.on_template, icon=Icon.chart_bar_1_3,
statustip='Insert code for normalized stacked bar chart')
self.chart_bar_1_3.setData("chart_bar_1_3.py")
self.chart_scatter_1_1 = Action(self.parent, "Scatter chart",
self.parent.on_template,
icon=Icon.chart_scatter_1_1,
statustip='Insert code for a scatter '
'plot')
self.chart_scatter_1_1.setData("chart_scatter_1_1.py")
self.chart_bubble_1_1 = Action(self.parent, "Bubble chart",
self.parent.on_template,
icon=Icon.chart_bubble_1_1,
statustip='Insert code for a bubble '
'plot that is a scatter plot with '
'individual point sizes')
self.chart_bubble_1_1.setData("chart_bubble_1_1.py")
self.chart_boxplot_2_2 = Action(self.parent, "Boxplot chart",
self.parent.on_template,
icon=Icon.chart_boxplot_2_2,
statustip='Insert code for boxplot '
'chart')
self.chart_boxplot_2_2.setData("chart_boxplot_2_2.py")
self.chart_histogram_1_1 = Action(self.parent, "Histogram chart",
self.parent.on_template,
icon=Icon.chart_histogram_1_1,
statustip='Insert code for '
'histogram')
self.chart_histogram_1_1.setData("chart_histogram_1_1.py")
self.chart_histogram_1_4 = Action(self.parent,
"Multiple histogram charts",
self.parent.on_template,
icon=Icon.chart_histogram_1_4,
statustip='Insert code for multiple '
'histogram charts')
self.chart_histogram_1_4.setData("chart_histogram_1_4.py")
self.chart_scatterhist_1_1 = Action(self.parent,
"Scatter and histogram chart",
self.parent.on_template,
icon=Icon.chart_scatterhist_1_1,
statustip='Insert code for scatter'
' plot with histogram'
' for each axis')
self.chart_scatterhist_1_1.setData("chart_scatterhist_1_1.py")
self.chart_matrix_1_1 = Action(self.parent, "Matrix chart",
self.parent.on_template,
icon=Icon.chart_matrix_1_1,
statustip='Insert code for matrix '
'chart')
self.chart_matrix_1_1.setData("chart_matrix_1_1.py")
self.chart_contour_1_2 = Action(self.parent, "Contour chart",
self.parent.on_template,
icon=Icon.chart_contour_1_2,
statustip='Insert code for contour '
'chart')
self.chart_contour_1_2.setData("chart_contour_1_2.py")
self.chart_surface_2_1 = Action(self.parent, "Surface chart",
self.parent.on_template,
icon=Icon.chart_surface_2_1,
statustip='Insert code for surface '
'chart')
self.chart_surface_2_1.setData("chart_surface_2_1.py")
self.chart_plotnine_geom_bar_1_1 = \
Action(self.parent, "Plotnine geom_bar chart",
self.parent.on_template,
icon=Icon.chart_plotnine_geom_bar_1_1,
statustip='Insert code for plotnine geom_bar chart')
self.chart_plotnine_geom_bar_1_1.setData(
"chart_plotnine_geom_bar_1_1.py")
self.chart_r_graphics_barplot_1_1 = \
Action(self.parent, "R graphics barplot chart",
self.parent.on_template,
icon=Icon.chart_r_graphics_barplot_1_1,
statustip='Insert code for R graphics barplot chart')
self.chart_r_graphics_barplot_1_1.setData(
"chart_r_graphics_barplot_1_1.py")
self.chart_r_ggplot2_geom_boxplot_1_2 = \
Action(self.parent, "R ggplot2 geom_boxplot chart",
self.parent.on_template,
icon=Icon.chart_r_ggplot2_geom_boxplot_1_2,
statustip='Insert code for R ggplot2 geom_boxplot chart')
self.chart_r_ggplot2_geom_boxplot_1_2.setData(
"chart_r_ggplot2_geom_boxplot_1_2.py")
self.chart_r_ggplot2_geom_point_1_1 = \
Action(self.parent, "R ggplot2 geom_point chart",
self.parent.on_template,
icon=Icon.chart_r_ggplot2_geom_point_1_1,
statustip='Insert code for R ggplot2 geom_point chart')
self.chart_r_ggplot2_geom_point_1_1.setData(
"chart_r_ggplot2_geom_point_1_1.py")
self.chart_r_lattice_xyplot_1_1 = \
Action(self.parent, "R lattice xyplot chart",
self.parent.on_template,
icon=Icon.chart_r_lattice_xyplot_1_1,
statustip='Insert code for R lattice xyplot chart')
self.chart_r_lattice_xyplot_1_1.setData(
"chart_r_lattice_xyplot_1_1.py")
self.chart_r_ggplot2_geom_density2d_1_2 = \
Action(self.parent, "R ggplot2 geom_density2d chart",
self.parent.on_template,
icon=Icon.chart_r_ggplot2_geom_density2d_1_2,
statustip='Insert code for R ggplot2 geom_density2d chart')
self.chart_r_ggplot2_geom_density2d_1_2.setData(
"chart_r_ggplot2_geom_density2d_1_2.py")
self.chart_r_lattice_wireframe_2_1 = \
Action(self.parent, "R lattice wireframe chart",
self.parent.on_template,
icon=Icon.chart_r_lattice_wireframe_2_1,
statustip='Insert code for surface chart')
self.chart_r_lattice_wireframe_2_1.setData(
"chart_r_lattice_wireframe_2_1.py")
[docs]
class SpellTextEditActions(AttrDict):
"""Holds QActions for SpellTextEdit"""
def __init__(self, parent: QWidget):
"""
:param parent: The parent object, normally :class:`pyspread.MainWindow`
"""
super().__init__()
self.parent = parent
self.toggle_line_numbers = Action(self.parent, "Line numbers",
self.parent.show_line_numbers,
checkable=True,
statustip='Show/hide line numbers')