Skip to content

Commit

Permalink
Merge pull request #345 from jitseniesen/config-theme
Browse files Browse the repository at this point in the history
PR: Allow user to config notebook theme
  • Loading branch information
jitseniesen authored Dec 29, 2020
2 parents ea8ac44 + 07a8e69 commit 10aff84
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
38 changes: 38 additions & 0 deletions spyder_notebook/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
#
# Copyright (c) Spyder Project Contributors
# Licensed under the terms of the MIT License

"""Spyder configuration page for notebook plugin."""

# Qt imports
from qtpy.QtWidgets import QGridLayout, QGroupBox, QVBoxLayout

# Spyder imports
from spyder.api.preferences import PluginConfigPage

# Local imports
from spyder_notebook.utils.localization import _


class NotebookConfigPage(PluginConfigPage):
"""Widget with configuration options for notebook plugin."""

def setup_page(self):
"""Fill configuration page with widgets."""
themes = ['Same as Spyder', 'Light', 'Dark']
theme_choices = list(zip(themes,
[theme.lower() for theme in themes]))
theme_combo = self.create_combobox(
_('Notebook theme'), theme_choices, 'theme', restart=True)

interface_layout = QGridLayout()
interface_layout.addWidget(theme_combo.label, 0, 0)
interface_layout.addWidget(theme_combo.combobox, 0, 1)
interface_group = QGroupBox(_('Interface'))
interface_group.setLayout(interface_layout)

vlayout = QVBoxLayout()
vlayout.addWidget(interface_group)
vlayout.addStretch(1)
self.setLayout(vlayout)
26 changes: 21 additions & 5 deletions spyder_notebook/notebookplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from spyder.utils.switcher import shorten_paths

# Local imports
from spyder_notebook.config import NotebookConfigPage
from spyder_notebook.utils.localization import _
from spyder_notebook.utils.servermanager import ServerManager
from spyder_notebook.widgets.notebooktabwidget import NotebookTabWidget
Expand All @@ -40,8 +41,10 @@ class NotebookPlugin(SpyderPluginWidget):

CONF_SECTION = 'notebook'
CONF_DEFAULTS = [(CONF_SECTION, {
'recent_notebooks': [], # Items in "Open recent" menu
'opened_notebooks': []})] # Notebooks to open at start
'recent_notebooks': [], # Items in "Open recent" menu
'opened_notebooks': [], # Notebooks to open at start
'theme': 'same as spyder'})] # Notebook theme (light/dark)
CONFIGWIDGET_CLASS = NotebookConfigPage
focus_changed = Signal()

def __init__(self, parent, testing=False):
Expand Down Expand Up @@ -72,18 +75,31 @@ def __init__(self, parent, testing=False):
menu_btn.setPopupMode(menu_btn.InstantPopup)
corner_widgets = {Qt.TopRightCorner: [new_notebook_btn, menu_btn]}

dark_theme = is_dark_interface()
self.server_manager = ServerManager(dark_theme)
self.server_manager = ServerManager(self.dark_theme)
self.tabwidget = NotebookTabWidget(
self, self.server_manager, menu=self._options_menu,
actions=self.menu_actions, corner_widgets=corner_widgets,
dark_theme=dark_theme)
dark_theme=self.dark_theme)

self.tabwidget.currentChanged.connect(self.refresh_plugin)

layout.addWidget(self.tabwidget)
self.setLayout(layout)

@property
def dark_theme(self):
"""Whether to use the dark theme for notebooks (bool)."""
theme_config = self.get_option('theme', default='same as spyder')
if theme_config == 'same as spyder':
return is_dark_interface()
elif theme_config == 'dark':
return True
elif theme_config == 'light':
return False
else:
raise RuntimeError('theme config corrupted, value = {}'
.format(theme_config))

# ------ SpyderPluginMixin API --------------------------------------------
def on_first_registration(self):
"""Action to be performed on first plugin registration."""
Expand Down
32 changes: 32 additions & 0 deletions spyder_notebook/tests/test_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
#

"""Tests for config.py"""

# Third-party library imports
import pytest

# Spyder imports
from spyder.preferences.configdialog import ConfigDialog

# Local imports
from spyder_notebook.config import NotebookConfigPage
from spyder_notebook.tests.test_plugin import plugin_no_server


def test_config(mocker, plugin_no_server, qtbot):
"""Test that config page can be created and shown."""
dlg = ConfigDialog()
page = NotebookConfigPage(plugin_no_server, parent=plugin_no_server)
page.initialize()
dlg.add_page(page)
dlg.show()
qtbot.addWidget(dlg)
# no assert, just check that the config page can be created


if __name__ == "__main__":
pytest.main()
14 changes: 14 additions & 0 deletions spyder_notebook/tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,19 @@ def test_view_server_info(mocker, plugin_no_server):
mock_ServerInfoDialog.return_value.show.assert_called_once()


@pytest.mark.parametrize('config_value', ['same as spyder', 'dark', 'light'])
@pytest.mark.parametrize('spyder_is_dark', [True, False])
def test_dark_theme(mocker, plugin_no_server, config_value, spyder_is_dark):
plugin_no_server.set_option('theme', config_value)
mocker.patch('spyder_notebook.notebookplugin.is_dark_interface',
return_value=spyder_is_dark)

value = plugin_no_server.dark_theme

expected = (config_value == 'dark' or
(config_value == 'same as spyder' and spyder_is_dark))
assert value == expected


if __name__ == "__main__":
pytest.main()

0 comments on commit 10aff84

Please sign in to comment.