diff --git a/openlp/core/ui/settingsdialog.py b/openlp/core/ui/settingsdialog.py index fbac6a155..ab5931584 100644 --- a/openlp/core/ui/settingsdialog.py +++ b/openlp/core/ui/settingsdialog.py @@ -62,7 +62,6 @@ class Ui_SettingsDialog(object): self.button_box = create_button_box(settings_dialog, 'button_box', ['cancel', 'ok']) self.dialog_layout.addWidget(self.button_box, 1, 1, 1, 1) self.retranslateUi(settings_dialog) - self.setting_list_widget.currentRowChanged.connect(self.tab_changed) def retranslateUi(self, settings_dialog): """ diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py index a1077e1f4..e953da011 100644 --- a/openlp/core/ui/settingsform.py +++ b/openlp/core/ui/settingsform.py @@ -31,10 +31,10 @@ The :mod:`settingsform` provides a user interface for the OpenLP settings """ import logging -from PyQt4 import QtGui +from PyQt4 import QtCore, QtGui from openlp.core.common import Registry, RegistryProperties -from openlp.core.lib import PluginStatus, build_icon +from openlp.core.lib import build_icon from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab from openlp.core.ui.media import PlayerTab from .settingsdialog import Ui_SettingsDialog @@ -55,6 +55,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog, RegistryProperties): super(SettingsForm, self).__init__(parent) self.processes = [] self.setupUi(self) + self.setting_list_widget.currentRowChanged.connect(self.list_item_changed) def exec_(self): """ @@ -65,33 +66,30 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog, RegistryProperties): while self.stacked_layout.count(): # take at 0 and the rest shuffle up. self.stacked_layout.takeAt(0) - self.insert_tab(self.general_tab, 0, PluginStatus.Active) - self.insert_tab(self.themes_tab, 1, PluginStatus.Active) - self.insert_tab(self.advanced_tab, 2, PluginStatus.Active) - self.insert_tab(self.player_tab, 3, PluginStatus.Active) - count = 4 + self.insert_tab(self.general_tab) + self.insert_tab(self.themes_tab) + self.insert_tab(self.advanced_tab) + self.insert_tab(self.player_tab) for plugin in self.plugin_manager.plugins: if plugin.settings_tab: - self.insert_tab(plugin.settings_tab, count, plugin.status) - count += 1 + self.insert_tab(plugin.settings_tab, plugin.is_active()) self.setting_list_widget.setCurrentRow(0) return QtGui.QDialog.exec_(self) - def insert_tab(self, tab, location, is_active): + def insert_tab(self, tab_widget, is_visible=True): """ Add a tab to the form at a specific location + + :param tab_widget: The widget to add + :param is_visible: If this tab should be visible """ - log.debug('Inserting %s tab' % tab.tab_title) + log.debug('Inserting %s tab' % tab_widget.tab_title) # add the tab to get it to display in the correct part of the screen - pos = self.stacked_layout.addWidget(tab) - if is_active: - item_name = QtGui.QListWidgetItem(tab.tab_title_visible) - icon = build_icon(tab.icon_path) - item_name.setIcon(icon) - self.setting_list_widget.insertItem(location, item_name) - else: - # then remove tab to stop the UI displaying it even if it is not required. - self.stacked_layout.takeAt(pos) + self.stacked_layout.addWidget(tab_widget) + if is_visible: + list_item = QtGui.QListWidgetItem(build_icon(tab_widget.icon_path), tab_widget.tab_title_visible) + list_item.setData(QtCore.Qt.UserRole, tab_widget.tab_title) + self.setting_list_widget.addItem(list_item) def accept(self): """ @@ -137,12 +135,23 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog, RegistryProperties): if plugin.settings_tab: plugin.settings_tab.post_set_up() - def tab_changed(self, tab_index): + def list_item_changed(self, item_index): """ A different settings tab is selected + + :param item_index: The index of the item that was selected """ - self.stacked_layout.setCurrentIndex(tab_index) - self.stacked_layout.currentWidget().tab_visible() + # Get the item we clicked on + list_item = self.setting_list_widget.item(item_index) + # Loop through the list of tabs in the stacked layout + for tab_index in range(self.stacked_layout.count()): + # Get the widget + tab_widget = self.stacked_layout.itemAt(tab_index).widget() + # Check that the title of the tab (i.e. plugin name) is the same as the data in the list item + if tab_widget.tab_title == list_item.data(QtCore.Qt.UserRole): + # Make the matching tab visible + self.stacked_layout.setCurrentIndex(tab_index) + self.stacked_layout.currentWidget().tab_visible() def register_post_process(self, function): """ diff --git a/tests/__init__.py b/tests/__init__.py index e69de29bb..6917a5968 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2014 Raoul Snyman # +# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program 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; version 2 of the License. # +# # +# This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +All the tests +""" diff --git a/tests/functional/openlp_core_ui/test_servicemanager.py b/tests/functional/openlp_core_ui/test_servicemanager.py index d8d2be50e..4ff6b330a 100644 --- a/tests/functional/openlp_core_ui/test_servicemanager.py +++ b/tests/functional/openlp_core_ui/test_servicemanager.py @@ -35,7 +35,7 @@ from openlp.core.common import Registry, ThemeLevel from openlp.core.lib import ServiceItem, ServiceItemType, ItemCapabilities from openlp.core.ui import ServiceManager -from tests.interfaces import MagicMock, patch +from tests.functional import MagicMock class TestServiceManager(TestCase): diff --git a/tests/functional/openlp_core_ui/test_settingsform.py b/tests/functional/openlp_core_ui/test_settingsform.py new file mode 100644 index 000000000..5d9b413df --- /dev/null +++ b/tests/functional/openlp_core_ui/test_settingsform.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2014 Raoul Snyman # +# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program 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; version 2 of the License. # +# # +# This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +Package to test the openlp.core.ui.settingsform package. +""" +from unittest import TestCase + +from openlp.core.common import Registry +from openlp.core.ui.generaltab import GeneralTab +from openlp.core.ui.settingsform import SettingsForm + +from tests.functional import MagicMock, patch + + +class TestSettingsForm(TestCase): + + def setUp(self): + """ + Set up a few things for the tests + """ + Registry.create() + + def insert_tab_visible_test(self): + """ + Test that the insert_tab() method works correctly when a visible tab is inserted + """ + # GIVEN: A mocked tab and a Settings Form + settings_form = SettingsForm(None) + general_tab = MagicMock() + general_tab.tab_title = 'mock' + general_tab.tab_title_visible = 'Mock' + general_tab.icon_path = ':/icon/openlp-logo-16x16.png' + + # WHEN: We insert the general tab + with patch.object(settings_form.stacked_layout, 'addWidget') as mocked_add_widget, \ + patch.object(settings_form.setting_list_widget, 'addItem') as mocked_add_item: + settings_form.insert_tab(general_tab, is_visible=True) + + # THEN: Stuff should happen + mocked_add_widget.assert_called_with(general_tab) + self.assertEqual(1, mocked_add_item.call_count, 'addItem should have been called') + + def insert_tab_not_visible_test(self): + """ + Test that the insert_tab() method works correctly when a tab that should not be visible is inserted + """ + # GIVEN: A general tab and a Settings Form + settings_form = SettingsForm(None) + general_tab = MagicMock() + general_tab.tab_title = 'mock' + + # WHEN: We insert the general tab + with patch.object(settings_form.stacked_layout, 'addWidget') as mocked_add_widget, \ + patch.object(settings_form.setting_list_widget, 'addItem') as mocked_add_item: + settings_form.insert_tab(general_tab, is_visible=False) + + # THEN: Stuff should happen + mocked_add_widget.assert_called_with(general_tab) + self.assertEqual(0, mocked_add_item.call_count, 'addItem should not have been called')