Source code for toolbar
# -*- 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:`ChartTemplatesToolBar`
* :class:`FindToolbar`
* :class:`FormatToolbar`
* :class:`MacroToolbar`
* :func:`add_toolbutton_widget`
"""
from typing import Tuple
from PyQt6.QtWidgets import (
QToolBar, QToolButton, QMenu, QWidget, QHBoxLayout, QUndoView,
QMainWindow)
try:
import matplotlib.figure as matplotlib_figure
except ImportError:
matplotlib_figure = None
try:
import rpy2
from rpy2.robjects.packages import importr, PackageNotInstalledError
except ImportError:
rpy2 = None
try:
import plotnine
except ImportError:
plotnine = None
try:
from pyspread.actions import MainWindowActions, ChartDialogActions
from pyspread.icons import Icon
from pyspread.menus import ToolbarManagerMenu
from pyspread.widgets import FindEditor
except ImportError:
from actions import MainWindowActions, ChartDialogActions
from icons import Icon
from menus import ToolbarManagerMenu
from widgets import FindEditor
[docs]
def add_toolbutton_widget(button: QWidget, widget: QWidget,
minsize: Tuple[int, int] = (300, 200),
popup_mode: QToolButton.ToolButtonPopupMode
= QToolButton.ToolButtonPopupMode.MenuButtonPopup):
"""Adds a widget as menu to a tool_button
:param button: Tool button for menu
:param widget: Toolbar widget
:param minsize: Minimum menu size
:param popup_mode: Describes how the menu is popped up
"""
button.setPopupMode(popup_mode)
menu = QMenu(button)
menu.setMinimumSize(*minsize)
button.setMenu(menu)
menu_layout = QHBoxLayout()
menu_layout.addWidget(widget)
menu.setLayout(menu_layout)
menu.layout()
[docs]
class ToolBarBase(QToolBar):
"""Base toolbar class that provides toolbar manager button method"""
[docs]
def add_widget(self, widget: QWidget):
"""Adds widget with addWidget and assigns action text and icon
The widget must have a label attribute and an icon method.
:param widget: Widget to be added
"""
self.addWidget(widget)
self.actions()[-1].setText(widget.label)
self.actions()[-1].setIcon(widget.icon())
[docs]
def get_manager_button(self) -> QToolButton:
"""Returns QToolButton for managing the toolbar"""
button = QToolButton(self)
button.setText("Add/remove toolbar icons")
button.setMenu(ToolbarManagerMenu(self))
button.setIcon(Icon.menu_manager)
button.setFixedWidth(int(button.height()/3))
button.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
return button
[docs]
class MainToolBar(ToolBarBase):
"""The main toolbar"""
def __init__(self, main_window: QMainWindow):
"""
:param main_window: Application main window
"""
self.main_window = main_window
super().__init__("Main toolbar", main_window)
self.setObjectName("Main Toolbar")
self._create_toolbar(main_window.main_window_toolbar_actions)
[docs]
def _create_toolbar(self, actions: MainWindowActions):
"""Fills the main toolbar with QActions
:param actions: Main window actions
"""
self.addAction(actions.new)
self.addAction(actions.open)
self.addAction(actions.save)
self.addAction(actions.export)
self.addSeparator()
self.addAction(actions.print)
self.addSeparator()
self.addAction(actions.undo)
undo_button = self.widgetForAction(actions.undo)
undo_view = QUndoView(self.main_window.undo_stack)
add_toolbutton_widget(undo_button, undo_view)
self.addAction(actions.redo)
self.addSeparator()
self.addAction(actions.cut)
self.addAction(actions.copy)
self.addAction(actions.copy_results)
self.addAction(actions.paste)
self.addAction(actions.paste)
self.addSeparator()
self.addAction(actions.sort_ascending)
self.addAction(actions.sort_descending)
self.addSeparator()
self.addAction(actions.toggle_spell_checker)
self.addWidget(self.get_manager_button())
[docs]
class MacroToolbar(ToolBarBase):
"""The macro toolbar for pyspread"""
def __init__(self, main_window: QMainWindow):
"""
:param main_window: Application main window
"""
super().__init__("Macro toolbar", main_window)
self.setObjectName("Macro toolbar")
self._create_toolbar(main_window.main_window_toolbar_actions)
[docs]
def _create_toolbar(self, actions: MainWindowActions):
"""Fills the macro toolbar with QActions
:param actions: Main window actions
"""
self.addAction(actions.insert_image)
if matplotlib_figure is not None:
self.addAction(actions.insert_chart)
self.addSeparator()
self.addAction(actions.insert_sum)
self.addWidget(self.get_manager_button())
[docs]
class FindToolbar(ToolBarBase):
"""The find toolbar for pyspread"""
def __init__(self, main_window: QMainWindow):
"""
:param main_window: Application main window
"""
super().__init__("Find Toolbar", main_window)
self.main_window = main_window
self.setObjectName("Find Toolbar")
self._create_toolbar(main_window.main_window_toolbar_actions)
[docs]
def _create_toolbar(self, actions: MainWindowActions):
"""Fills the find toolbar with QActions
:param actions: Main window actions
"""
self.find_editor = FindEditor(self)
self.add_widget(self.find_editor)
self.addAction(actions.find)
self.addAction(actions.replace)
self.addWidget(self.get_manager_button())
[docs]
class FormatToolbar(ToolBarBase):
"""The format toolbar for pyspread"""
def __init__(self, main_window: QMainWindow):
"""
:param main_window: Application main window
"""
super().__init__("Format Toolbar", main_window)
self.main_window = main_window
self.setObjectName("Format Toolbar")
self._create_toolbar(main_window.main_window_toolbar_actions)
[docs]
def _create_toolbar(self, actions: MainWindowActions):
"""Fills the format toolbar with QActions
:param actions: Main window actions
"""
menubar = self.main_window.menuBar()
self.add_widget(self.main_window.widgets.font_combo)
self.add_widget(self.main_window.widgets.font_size_combo)
self.addAction(actions.bold)
self.addAction(actions.italics)
self.addAction(actions.underline)
self.addAction(actions.strikethrough)
self.addSeparator()
self.add_widget(self.main_window.widgets.renderer_button)
self.addSeparator()
self.addAction(actions.freeze_cell)
self.addAction(actions.lock_cell)
self.addAction(actions.button_cell)
self.addSeparator()
self.addAction(actions.merge_cells)
self.addSeparator()
self.add_widget(self.main_window.widgets.rotate_button)
self.add_widget(self.main_window.widgets.justify_button)
self.add_widget(self.main_window.widgets.align_button)
self.addSeparator()
self.border_menu_button = QToolButton(self)
self.border_menu_button.setText("Borders")
self.border_menu_button.label = "Borders"
border_submenu = menubar.format_menu.border_submenu
self.border_menu_button.setMenu(border_submenu)
self.border_menu_button.setIcon(Icon.border_menu)
self.add_widget(self.border_menu_button)
self.border_menu_button.setPopupMode(
QToolButton.ToolButtonPopupMode.InstantPopup)
self.line_width_button = QToolButton(self)
self.line_width_button.setText("Border Width")
self.line_width_button.label = "Border Width"
line_width_submenu = menubar.format_menu.line_width_submenu
self.line_width_button.setMenu(line_width_submenu)
self.line_width_button.setIcon(Icon.format_borders)
self.add_widget(self.line_width_button)
self.line_width_button.setPopupMode(
QToolButton.ToolButtonPopupMode.InstantPopup)
self.addSeparator()
text_color_button = self.main_window.widgets.text_color_button
text_color_button.set_max_size(self.iconSize())
self.add_widget(text_color_button)
line_color_button = self.main_window.widgets.line_color_button
line_color_button.set_max_size(self.iconSize())
self.add_widget(line_color_button)
background_color_button = \
self.main_window.widgets.background_color_button
background_color_button.set_max_size(self.iconSize())
self.add_widget(background_color_button)
self.addSeparator()
self.addAction(actions.copy_format)
self.addAction(actions.paste_format)
self.addSeparator()
self.addWidget(self.get_manager_button())
[docs]
class ChartTemplatesToolBar(ToolBarBase):
"""Toolbar for chart dialog for inserting template chart code"""
tooltip_tpl = "Package {} required but not installed"
def __init__(self, parent: QWidget):
"""
:param parent: Parent widget, e.g. chart dialog window
"""
super().__init__("Chart templates toolbar", parent)
self.setObjectName("Chart templates toolbar")
self._create_toolbar(parent.actions)
[docs]
def _create_toolbar(self, actions: ChartDialogActions):
"""Fills the chart dialog toolbar with QActions
:param actions: Chart dialog actions
"""
self.addAction(actions.chart_pie_1_1)
self.addAction(actions.chart_ring_1_1)
self.addAction(actions.chart_line_1_1)
self.addAction(actions.chart_polar_1_1)
self.addAction(actions.chart_area_1_1)
self.addAction(actions.chart_column_1_1)
self.addAction(actions.chart_column_1_2)
self.addAction(actions.chart_bar_1_3)
self.addAction(actions.chart_scatter_1_1)
self.addAction(actions.chart_bubble_1_1)
self.addAction(actions.chart_boxplot_2_2)
self.addAction(actions.chart_histogram_1_1)
self.addAction(actions.chart_histogram_1_4)
self.addAction(actions.chart_scatterhist_1_1)
self.addAction(actions.chart_matrix_1_1)
self.addAction(actions.chart_contour_1_2)
self.addAction(actions.chart_surface_2_1)
self.addWidget(self.get_manager_button())
[docs]
class RChartTemplatesToolBar(ToolBarBase):
"""Toolbar for chart dialog for inserting R template chart code
Requires rpy2 with ggplot, lattice and graphics packages
"""
tooltip_tpl = "R Package {} required but not installed"
def __init__(self, parent: QWidget):
"""
:param parent: Parent widget, e.g. chart dialog window
"""
super().__init__("Chart templates toolbar", parent)
if rpy2 is None:
self.close()
self.setObjectName("R Chart templates toolbar")
self._create_toolbar(parent.actions)
[docs]
@staticmethod
def is_r_package_installed(package_name):
"""True if the R package is installed
:param package_name: Name of R package to checked
"""
if rpy2 is None:
return False
try:
importr(package_name)
except RuntimeError:
return False
except PackageNotInstalledError:
return False
return True
[docs]
def _create_toolbar(self, actions: ChartDialogActions):
"""Fills the chart dialog toolbar with QActions
:param actions: Chart dialog actions
"""
self.addAction(actions.chart_r_graphics_barplot_1_1)
self.addAction(actions.chart_r_ggplot2_geom_boxplot_1_2)
self.addAction(actions.chart_r_ggplot2_geom_point_1_1)
self.addAction(actions.chart_r_lattice_xyplot_1_1)
self.addAction(actions.chart_r_ggplot2_geom_density2d_1_2)
self.addAction(actions.chart_r_lattice_wireframe_2_1)
self.addAction(actions.chart_plotnine_geom_bar_1_1)
if not self.is_r_package_installed("graphics"):
tooltip = self.tooltip_tpl.format("graphics")
actions.chart_r_graphics_barplot_1_1.setEnabled(False)
actions.chart_r_graphics_barplot_1_1.setToolTip(tooltip)
if not self.is_r_package_installed("lattice"):
tooltip = self.tooltip_tpl.format("lattice")
actions.chart_r_lattice_xyplot_1_1.setEnabled(False)
actions.chart_r_lattice_xyplot_1_1.setToolTip(tooltip)
actions.chart_r_lattice_wireframe_2_1.setEnabled(False)
actions.chart_r_lattice_wireframe_2_1.setToolTip(tooltip)
if not self.is_r_package_installed("ggplot2"):
tooltip = self.tooltip_tpl.format("ggplot2")
actions.chart_r_ggplot2_geom_boxplot_1_2.setEnabled(False)
actions.chart_r_ggplot2_geom_boxplot_1_2.setToolTip(tooltip)
actions.chart_r_ggplot2_geom_point_1_1.setEnabled(False)
actions.chart_r_ggplot2_geom_point_1_1.setToolTip(tooltip)
actions.chart_r_ggplot2_geom_density2d_1_2.setEnabled(False)
actions.chart_r_ggplot2_geom_density2d_1_2.setToolTip(tooltip)
if plotnine is None:
tooltip = self.tooltip_tpl.format("plotnine")
actions.chart_plotnine_geom_bar_1_1.setEnabled(False)
actions.chart_plotnine_geom_bar_1_1.setToolTip(tooltip)
self.addWidget(self.get_manager_button())