Custom cleanup

This commit is contained in:
Tim Bentley 2013-12-24 07:02:47 +00:00
parent bb99be7f10
commit 7e18ced2c4
7 changed files with 90 additions and 83 deletions

View File

@ -42,35 +42,33 @@ from openlp.plugins.custom.lib.mediaitem import CustomSearch
log = logging.getLogger(__name__)
__default_settings__ = {
'custom/db type': 'sqlite',
'custom/last search type': CustomSearch.Titles,
'custom/display footer': True,
'custom/add custom from service': True
'custom/db type': 'sqlite',
'custom/last search type': CustomSearch.Titles,
'custom/display footer': True,
'custom/add custom from service': True
}
class CustomPlugin(Plugin):
"""
This plugin enables the user to create, edit and display
custom slide shows. Custom shows are divided into slides.
This plugin enables the user to create, edit and display custom slide shows. Custom shows are divided into slides.
Each show is able to have it's own theme.
Custom shows are designed to replace the use of songs where
the songs plugin has become restrictive. Examples could be
Welcome slides, Bible Reading information, Orders of service.
Custom shows are designed to replace the use of songs where the songs plugin has become restrictive.
Examples could be Welcome slides, Bible Reading information, Orders of service.
"""
log.info('Custom Plugin loaded')
def __init__(self):
super(CustomPlugin, self).__init__('custom', __default_settings__, CustomMediaItem, CustomTab)
self.weight = -5
self.manager = Manager('custom', init_schema)
self.db_manager = Manager('custom', init_schema)
self.icon_path = ':/plugins/plugin_custom.png'
self.icon = build_icon(self.icon_path)
def about(self):
about_text = translate('CustomPlugin', '<strong>Custom Slide Plugin </strong><br />The custom slide plugin '
'provides the ability to set up custom text slides that can be displayed on the screen '
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
'provides the ability to set up custom text slides that can be displayed on the screen '
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
return about_text
def uses_theme(self, theme):
@ -79,11 +77,11 @@ class CustomPlugin(Plugin):
Returns True if the theme is being used, otherwise returns False.
"""
if self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):
if self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme):
return True
return False
def rename_theme(self, oldTheme, newTheme):
def rename_theme(self, old_theme, new_theme):
"""
Renames a theme the custom plugin is using making the plugin use the
new name.
@ -94,10 +92,10 @@ class CustomPlugin(Plugin):
``newTheme``
The new name the plugin should now use.
"""
customs_using_theme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
customs_using_theme = self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == old_theme)
for custom in customs_using_theme:
custom.theme_name = newTheme
self.manager.save_object(custom)
custom.theme_name = new_theme
self.db_manager.save_object(custom)
def set_plugin_text_strings(self):
"""
@ -130,5 +128,5 @@ class CustomPlugin(Plugin):
Time to tidy up on exit
"""
log.info('Custom Finalising')
self.manager.finalise()
self.db_manager.finalise()
Plugin.finalise(self)

View File

@ -70,14 +70,14 @@ class Ui_CustomEditDialog(object):
self.edit_all_button.setObjectName('edit_all_button')
self.button_layout.addWidget(self.edit_all_button)
self.delete_button = create_button(custom_edit_dialog, 'delete_button', role='delete',
click=custom_edit_dialog.on_delete_button_clicked)
click=custom_edit_dialog.on_delete_button_clicked)
self.delete_button.setEnabled(False)
self.button_layout.addWidget(self.delete_button)
self.button_layout.addStretch()
self.up_button = create_button(custom_edit_dialog, 'up_button', role='up', enabled=False,
click=custom_edit_dialog.on_up_button_clicked)
click=custom_edit_dialog.on_up_button_clicked)
self.down_button = create_button(custom_edit_dialog, 'down_button', role='down', enabled=False,
click=custom_edit_dialog.on_down_button_clicked)
click=custom_edit_dialog.on_down_button_clicked)
self.button_layout.addWidget(self.up_button)
self.button_layout.addWidget(self.down_button)
self.central_layout.addLayout(self.button_layout)

View File

@ -82,7 +82,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
Called when editing or creating a new custom.
``id``
The cutom's id. If zero, then a new custom is created.
The custom's id. If zero, then a new custom is created.
``preview``
States whether the custom is edited while being previewed in the
@ -98,8 +98,8 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
self.custom_slide = self.manager.get_object(CustomSlide, id)
self.title_edit.setText(self.custom_slide.title)
self.credit_edit.setText(self.custom_slide.credits)
custom_XML = CustomXMLParser(self.custom_slide.text)
slide_list = custom_XML.get_verses()
custom_xml = CustomXMLParser(self.custom_slide.text)
slide_list = custom_xml.get_verses()
self.slide_list_view.addItems([slide[1] for slide in slide_list])
theme = self.custom_slide.theme_name
find_and_set_in_combo_box(self.theme_combo_box, theme)
@ -136,22 +136,22 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
"""
Move a slide up in the list when the "Up" button is clicked.
"""
selectedRow = self.slide_list_view.currentRow()
if selectedRow != 0:
qw = self.slide_list_view.takeItem(selectedRow)
self.slide_list_view.insertItem(selectedRow - 1, qw)
self.slide_list_view.setCurrentRow(selectedRow - 1)
selected_row = self.slide_list_view.currentRow()
if selected_row != 0:
qw = self.slide_list_view.takeItem(selected_row)
self.slide_list_view.insertItem(selected_row - 1, qw)
self.slide_list_view.setCurrentRow(selected_row - 1)
def on_down_button_clicked(self):
"""
Move a slide down in the list when the "Down" button is clicked.
"""
selectedRow = self.slide_list_view.currentRow()
selected_row = self.slide_list_view.currentRow()
# zero base arrays
if selectedRow != self.slide_list_view.count() - 1:
qw = self.slide_list_view.takeItem(selectedRow)
self.slide_list_view.insertItem(selectedRow + 1, qw)
self.slide_list_view.setCurrentRow(selectedRow + 1)
if selected_row != self.slide_list_view.count() - 1:
qw = self.slide_list_view.takeItem(selected_row)
self.slide_list_view.insertItem(selected_row + 1, qw)
self.slide_list_view.setCurrentRow(selected_row + 1)
def on_add_button_clicked(self):
"""
@ -256,6 +256,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
# We must have at least one slide.
if self.slide_list_view.count() == 0:
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm',
'You need to add at least one slide.'))
'You need to add at least one slide.'))
return False
return True

View File

@ -55,4 +55,4 @@ class Ui_CustomSlideEditDialog(object):
self.split_button.setToolTip(UiStrings().SplitToolTip)
self.insert_button.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
self.insert_button.setToolTip(translate('CustomPlugin.EditCustomForm',
'Split a slide into two by inserting a slide splitter.'))
'Split a slide into two by inserting a slide splitter.'))

View File

@ -67,7 +67,7 @@ class CustomTab(SettingsTab):
self.custom_mode_group_box.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
self.display_footer_check_box.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
'Import missing custom slides from service files'))
'Import missing custom slides from service files'))
def on_display_footer_check_box_changed(self, check_state):
"""

View File

@ -37,6 +37,7 @@ from sqlalchemy.orm import mapper
from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import get_locale_key
class CustomSlide(BaseModel):
"""
CustomSlide model
@ -65,11 +66,11 @@ def init_schema(url):
session, metadata = init_db(url)
custom_slide_table = Table('custom_slide', metadata,
Column('id', types.Integer(), primary_key=True),
Column('title', types.Unicode(255), nullable=False),
Column('text', types.UnicodeText, nullable=False),
Column('credits', types.UnicodeText),
Column('theme_name', types.Unicode(128))
Column('id', types.Integer(), primary_key=True),
Column('title', types.Unicode(255), nullable=False),
Column('text', types.UnicodeText, nullable=False),
Column('credits', types.UnicodeText),
Column('theme_name', types.Unicode(128))
)
mapper(CustomSlide, custom_slide_table)

View File

@ -33,8 +33,8 @@ from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_, func, and_
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus,\
check_item_selected
from openlp.core.lib import Registry, MediaManagerItem, ItemCapabilities, ServiceItemContext, PluginStatus, \
check_item_selected
from openlp.plugins.custom.forms.editcustomform import EditCustomForm
from openlp.plugins.custom.lib import CustomXMLParser, CustomXMLBuilder
from openlp.plugins.custom.lib.db import CustomSlide
@ -64,14 +64,13 @@ class CustomMediaItem(MediaManagerItem):
"""
Do some additional setup.
"""
self.edit_custom_form = EditCustomForm(self, self.main_window, self.plugin.manager)
self.edit_custom_form = EditCustomForm(self, self.main_window, self.plugin.db_manager)
self.single_service_item = False
self.quick_preview_allowed = True
self.has_search = True
# Holds information about whether the edit is remotely triggered and
# which Custom is required.
self.remote_custom = -1
self.manager = self.plugin.manager
def add_end_header_bar(self):
self.toolbar.addSeparator()
@ -79,7 +78,7 @@ class CustomMediaItem(MediaManagerItem):
# Signals and slots
QtCore.QObject.connect(self.search_text_edit, QtCore.SIGNAL('cleared()'), self.on_clear_text_button_click)
QtCore.QObject.connect(self.search_text_edit, QtCore.SIGNAL('searchTypeChanged(int)'),
self.on_search_text_button_clicked)
self.on_search_text_button_clicked)
Registry().register_function('custom_load_list', self.load_list)
Registry().register_function('custom_preview', self.on_preview_click)
Registry().register_function('custom_create_from_service', self.create_from_service_item)
@ -96,14 +95,14 @@ class CustomMediaItem(MediaManagerItem):
self.search_text_button.setText(UiStrings().Search)
def initialise(self):
self.search_text_edit.set_search_types([
(CustomSearch.Titles, ':/songs/song_search_title.png',
translate('SongsPlugin.MediaItem', 'Titles'),
translate('SongsPlugin.MediaItem', 'Search Titles...')),
(CustomSearch.Themes, ':/slides/slide_theme.png', UiStrings().Themes, UiStrings().SearchThemes)
])
self.search_text_edit.set_search_types([(CustomSearch.Titles, ':/songs/song_search_title.png',
translate('SongsPlugin.MediaItem', 'Titles'),
translate('SongsPlugin.MediaItem', 'Search Titles...')),
(CustomSearch.Themes, ':/slides/slide_theme.png', UiStrings().Themes,
UiStrings().SearchThemes)
])
self.search_text_edit.set_current_search_type(Settings().value('%s/last search type' % self.settings_section))
self.load_list(self.manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
self.load_list(self.plugin.db_manager.get_all_objects(CustomSlide, order_by_ref=CustomSlide.title))
self.config_update()
def load_list(self, custom_slides, target_group=None):
@ -135,7 +134,7 @@ class CustomMediaItem(MediaManagerItem):
indicator to say which type of display is required.
"""
custom_id = int(custom_id)
valid = self.manager.get_object(CustomSlide, custom_id)
valid = self.plugin.db_manager.get_object(CustomSlide, custom_id)
if valid:
self.edit_custom_form.load_custom(custom_id, preview)
if self.edit_custom_form.exec_() == QtGui.QDialog.Accepted:
@ -168,26 +167,27 @@ class CustomMediaItem(MediaManagerItem):
"""
if check_item_selected(self.list_view, UiStrings().SelectDelete):
items = self.list_view.selectedIndexes()
if QtGui.QMessageBox.question(self,
UiStrings().ConfirmDelete,
translate('CustomPlugin.MediaItem',
'Are you sure you want to delete the %n selected custom slide(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
if QtGui.QMessageBox.question(self, UiStrings().ConfirmDelete,
translate('CustomPlugin.MediaItem',
'Are you sure you want to delete the %n selected custom slide(s)?',
'',
QtCore.QCoreApplication.CodecForTr, len(items)),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes
| QtGui.QMessageBox.No),
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
return
row_list = [item.row() for item in self.list_view.selectedIndexes()]
row_list.sort(reverse=True)
id_list = [(item.data(QtCore.Qt.UserRole)) for item in self.list_view.selectedIndexes()]
for id in id_list:
self.plugin.manager.delete_object(CustomSlide, id)
self.plugin.db_manager.delete_object(CustomSlide, id)
self.on_search_text_button_clicked()
def on_focus(self):
self.search_text_edit.setFocus()
def generate_slide_data(self, service_item, item=None, xmlVersion=False,
remote=False, context=ServiceItemContext.Service):
def generate_slide_data(self, service_item, item=None, xml_version=False,
remote=False, context=ServiceItemContext.Service):
"""
Generate the slide data. Needs to be implemented by the plugin.
"""
@ -197,7 +197,7 @@ class CustomMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.CanLoop)
service_item.add_capability(ItemCapabilities.CanSoftBreak)
service_item.add_capability(ItemCapabilities.OnLoadUpdate)
custom_slide = self.plugin.manager.get_object(CustomSlide, item_id)
custom_slide = self.plugin.db_manager.get_object(CustomSlide, item_id)
title = custom_slide.title
credit = custom_slide.credits
service_item.edit_id = item_id
@ -217,22 +217,25 @@ class CustomMediaItem(MediaManagerItem):
return True
def on_search_text_button_clicked(self):
"""
Search the plugin database
"""
# Save the current search type to the configuration.
Settings().setValue('%s/last search type' % self.settings_section, self.search_text_edit.current_search_type())
# Reload the list considering the new search type.
search_keywords = self.search_text_edit.displayText()
search_type = self.search_text_edit.current_search_type()
search_keywords = '%' + self.whitespace.sub(' ', self.search_text_edit.displayText()) + '%'
if search_type == CustomSearch.Titles:
log.debug('Titles Search')
search_results = self.plugin.manager.get_all_objects(CustomSlide,
CustomSlide.title.like('%' + self.whitespace.sub(' ', search_keywords) + '%'),
order_by_ref=CustomSlide.title)
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
CustomSlide.title.like(search_keywords),
order_by_ref=CustomSlide.title)
self.load_list(search_results)
elif search_type == CustomSearch.Themes:
log.debug('Theme Search')
search_results = self.plugin.manager.get_all_objects(CustomSlide,
CustomSlide.theme_name.like('%' + self.whitespace.sub(' ', search_keywords) + '%'),
order_by_ref=CustomSlide.title)
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
CustomSlide.theme_name.like(search_keywords),
order_by_ref=CustomSlide.title)
self.load_list(search_results)
self.check_search_result()
@ -249,14 +252,15 @@ class CustomMediaItem(MediaManagerItem):
def service_load(self, item):
"""
Triggered by a song being loaded by the service manager.
Triggered by a custom item being loaded by the service manager.
"""
log.debug('service_load')
if self.plugin.status != PluginStatus.Active:
return
custom = self.plugin.manager.get_object_filtered(CustomSlide,
and_(CustomSlide.title == item.title, CustomSlide.theme_name == item.theme,
CustomSlide.credits == item.raw_footer[0][len(item.title) + 1:]))
custom = self.plugin.db_manager.get_object_filtered(CustomSlide, and_(CustomSlide.title == item.title,
CustomSlide.theme_name == item.theme,
CustomSlide.credits ==
item.raw_footer[0][len(item.title) + 1:]))
if custom:
item.edit_id = custom.id
return item
@ -286,7 +290,7 @@ class CustomMediaItem(MediaManagerItem):
for (idx, slide) in enumerate(item._raw_frames):
custom_xml.add_verse_to_lyrics('custom', str(idx + 1), slide['raw_slide'])
custom.text = str(custom_xml.extract_xml(), 'utf-8')
self.plugin.manager.save_object(custom)
self.plugin.db_manager.save_object(custom)
self.on_search_text_button_clicked()
def on_clear_text_button_click(self):
@ -296,10 +300,14 @@ class CustomMediaItem(MediaManagerItem):
self.search_text_edit.clear()
self.on_search_text_button_clicked()
def search(self, string, showError):
search_results = self.manager.get_all_objects(CustomSlide,
or_(func.lower(CustomSlide.title).like('%' + string.lower() + '%'),
func.lower(CustomSlide.text).like('%' + string.lower() + '%')),
order_by_ref=CustomSlide.title)
def search(self, string, show_error):
"""
Search the database for a given item.
"""
search = '%' + string.lower() + '%'
search_results = self.plugin.db_manager.get_all_objects(CustomSlide,
or_(func.lower(CustomSlide.title).like(search),
func.lower(CustomSlide.text).like(search)),
order_by_ref=CustomSlide.title)
return [[custom.id, custom.title] for custom in search_results]